Python爬蟲入門教程 66-100 對微博登錄好奇嘛,用Python試試

寫在前面

原計劃這篇博客寫在6月1日,沒想到竟然由於寫pandas給耽誤了
查看pandas系列請移步

課程 鏈接
Python數據分析庫之pandas,你該這麼學!No.1 https://dream.blog.csdn.net/article/details/90169175
看一篇,學一篇,今日份的pandas,你該這麼學!No.2 https://dream.blog.csdn.net/article/details/90199748
點開,看一段,你就會喜歡上學習pandas,你該這麼學!No.3 https://dream.blog.csdn.net/article/details/90212197
學習也可以有趣,喜歡上pandas,你該這麼學!No.4 https://dream.blog.csdn.net/article/details/90229919
“戲精少女”的pandas學習之路,你該這麼學!No.5 https://dream.blog.csdn.net/article/details/90241420
對不起,給pandas配表情包太難了,pandas你該這麼學,No.6 https://dream.blog.csdn.net/article/details/90303728
大週末的不休息,繼續學習pandas吧,pandas你該這麼學,No.7 https://dream.blog.csdn.net/article/details/90340844
週一不睡覺,也要把pandas groupy 肝完,你該這麼學,No.8 https://dream.blog.csdn.net/article/details/90379695
破週三,前不着村後不着店的,只好學pandas了,你該這麼學,No.9 https://dream.blog.csdn.net/article/details/90445734
學習pandas apply方法,看這一篇就夠了,你該這麼學,No.10 https://dream.blog.csdn.net/article/details/90665922
pandas越來越難學,只能自己找趣味了,你該這麼學,No.11 https://dream.blog.csdn.net/article/details/90897493

略微休息一下,繼續爬蟲百例教程,本篇是66講,偏後期的教程了

今天研究一下如何登錄微博

登錄操作是爬蟲coder必須要掌握的基本技能之一

打開模擬登錄,這個步驟可以使用不同的抓包工具,谷歌自帶的開發者工具也可以實現

請注意,微博實現登錄,入口和方式很多

最常見的

移動版 難度係數★★

https://passport.weibo.cn/signin/login?entry=mweibo
在這裏插入圖片描述

新浪其他版塊做跳板 難度係數 ★★★

http://my.sina.com.cn/profile/unlogin/
在這裏插入圖片描述

微博首頁右側登錄框 難度係數 ★★★★

在這裏插入圖片描述
找到登錄入口,就需要開始抓取登錄關鍵數據

關鍵數據分析

通過在網頁填寫用戶名和密碼,點擊登錄進行數據抓取

這個地方發現一個比較神奇的事情,用谷歌的開發者工具抓取,竟然空白,啥都沒有

在這裏插入圖片描述
神奇了,不過我知道,這個地方一定是存在數據的
更換 青花瓷 軟件
看圖,果然有的
在這裏插入圖片描述
到這個地方,不用着急,開始着重分析login.php,我們必須要知道微博登錄的所有參數
在這裏插入圖片描述
提取參數,能直接理解的參數,直接標註上含義

	entry=weibo   //入口,目測永久爲weibo
	gateway=1     //入口?1
	from=         // from 空
	savestate=7  // 存儲狀態 7
	qrcode_flag=false   //二維碼相關
	useticket=1   // 用戶憑證
	pagerefer=https.......一個超鏈接 //某個頁面
	vsnf=1
	su=bmV0ZHolNDBzaW5hLmNvbQ%3D%3D   // su是什麼???
	service=miniblog   // 忽略
	servertime=1560214975   //服務器時間????
	nonce=87F5BK   // nonce 是什麼?
	pwencode=rsa2
	rsakv=1330428213   // rsakv ???  rsa加密參數?
	sp=一段加密的字符串   // sp加密的字符串
	sr=1920*1080
	encoding=UTF8
	prelt=54
	url=https......一個超鏈接
	returntype=META

簡單分析之後,你可以提取一些關鍵的參數出來,有些參數保持默認值即可

我們看一下,有哪些參數是最重要的
su,servertime,nonce,sp
這四個參數最爲重要

一一拆解參數

翻看一下剛纔的鏈接,不難發現servertimenonce兩個參數已經被找到了
在這裏插入圖片描述
重點來了,sp和su是什麼?

繼續關注抓包數據
在這裏插入圖片描述
發現一個ssologin.js這種js文件出現在這個位置,一定是用來加密的(爬蟲寫的多了,就知道了)

進入到內部,找數據來源

javascript格式化,自行進行即可

在這裏插入圖片描述

在這個鏈接中,我們找到一個回調函數 preloginCallBack 請注意,這個地方還有一個參數爲su

查看su的值su: bmV0ZHolNDBzaW5hLmNvbQ==
簡單猜測一下,比較容易,爲Base64加密,Base64加密一般是一個=結尾?這裏咋出現了兩個?

沒事,一會刪掉一個即可

繼續翻ssologin.js在裏面找相關的方法
然後找到這部分源碼

    var makeRequest = function(username, password, savestate, qrcode_flag) {
        var request = {
            entry: me.getEntry(),
            gateway: 1,
            from: me.from,
            savestate: savestate,
            qrcode_flag: qrcode_flag,
            useticket: me.useTicket ? 1 : 0
        };
        if (me.failRedirect) {
            me.loginExtraQuery.frd = 1
        }
        request = objMerge(request, {
            pagerefer: document.referrer || ""
        });
        request = objMerge(request, me.loginExtraFlag);
        request = objMerge(request, me.loginExtraQuery);
        request.su = sinaSSOEncoder.base64.encode(urlencode(username));
        if (me.service) {
            request.service = me.service
        }
        if ((me.loginType & rsa) && me.servertime && sinaSSOEncoder && sinaSSOEncoder.RSAKey) {
            request.servertime = me.servertime;
            request.nonce = me.nonce;
            request.pwencode = "rsa2";
            request.rsakv = me.rsakv;
            var RSAKey = new sinaSSOEncoder.RSAKey();
            RSAKey.setPublic(me.rsaPubkey, "10001");
            password = RSAKey.encrypt([me.servertime, me.nonce].join("\t") + "\n" + password)
        } else {
            if ((me.loginType & wsse) && me.servertime && sinaSSOEncoder && sinaSSOEncoder.hex_sha1) {
                request.servertime = me.servertime;
                request.nonce = me.nonce;
                request.pwencode = "wsse";
                password = sinaSSOEncoder.hex_sha1("" + sinaSSOEncoder.hex_sha1(sinaSSOEncoder.hex_sha1(password)) + me.servertime + me.nonce)
            }
        }
        request.sp = password;
        try {
            request.sr = window.screen.width + "*" + window.screen.height
        } catch(e) {}
        return request
    };

哇,發現所有的參數都找到了,厲害了

注意看request.sp = password
password是通過三次sha1加密實現的

所有的參數目前爲止,我們都找到了,下面要實現的就是寫代碼了

核心編碼

獲取servertime、nonce、rsakv等參數

from urllib.parse import quote
import requests,re,json,time,base64


def prelogin(username):
    su = base64.b64encode(username.encode())
    url = "https://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su={}&rsakt=mod&checkpin=1&client=ssologin.js(v1.4.19)&_={}".format(quote(su),int(time.time()*1000))
    data = requests.request('GET', url).text

    p = re.compile('\((.*)\)')
    try:
        json_data = p.search(data).group(1)
        data = json.loads(json_data)
        servertime = str(data['servertime'])
        nonce = data['nonce']
        rsakv = data['rsakv']
        pubkey = data['pubkey']
        return servertime, nonce,rsakv,pubkey
    except:
        print('沒有獲取到 severtime、nonce、rsakv 、pubkey')
        return None


if __name__ == '__main__':
    params = prelogin("你的微博登錄郵箱")
    print(params)

上述代碼,可以成功的得到一些關鍵參數,拿到參數之後,就要進行下一步操作了

獲取加密的sp

在這裏插入圖片描述
這個步驟是對JS加密過程的一個翻譯
請注意,使用的RSA加密
代碼模仿我框選的部分即可
安裝rsa庫
pip install rsa

from urllib.parse import quote
from binascii import b2a_hex
import requests,re,json,time,base64,rsa



def prelogin(username):
    pass 

def get_sp(pubkey,servertime,nonce,password):
    '''用rsa對明文密碼進行加密,加密規則翻譯JS代碼'''

    # 生成公鑰
    # var RSAKey = new sinaSSOEncoder.RSAKey();
    # RSAKey.setPublic(me.rsaPubkey, "10001");
    # password = RSAKey.encrypt([me.servertime, me.nonce].join("\t") + "\n" + password)
    publickey = rsa.PublicKey(int(pubkey, 16), int('10001', 16))
    message = str(servertime) + '\t' + str(nonce) + '\n' + str(password)
    sp = rsa.encrypt(message.encode(), publickey)
    return b2a_hex(sp)

if __name__ == '__main__':
    servertime, nonce, rsakv, pubkey = prelogin("你的郵箱")
    sp = get_sp(pubkey, servertime, nonce, "你的密碼")

一番努力之下,你已經成功獲取到加密之後的sp參數

在這裏插入圖片描述

僞造請求

這部分代碼比較簡單了,就是湊齊請求參數,發起請求即可
重要的請注意,參數一定要寫準

如果碰到還不清楚的參數,可以多嘗試一下

比如返回類型這裏,多次嘗試後,發現使用

returntype = ‘TEXT’ 可以返回正確的JSON
而設置 META則需要獲取content了(自己試試吧)

def login(username,password,servertime,nonce,rsakv,pubkey):

    data = {
       'entry': 'weibo',
       'gateway': '1',
       'from': 'null',
       'savestate': '7',
       'useticket': '1',
       'vsnf': '1',
       'su': get_su(username),
       'service': 'account',
       'servertime':  servertime,
       'nonce':  nonce,
       'pwencode': 'rsa2',
       'rsakv': rsakv,
       'sp': get_sp(pubkey,servertime,nonce,password),
       'sr': '1920*1080',
       'encoding': 'UTF-8',
       'prelt': random.randint(1,100),
       'url': 'https://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack',
       'returntype': 'TEXT'
    }

    print(data)


    url = 'https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19)'
    json_data = session.post(url,data=data).json()
    print(json_data)

    #判斷post登錄是否成功
    if json_data['retcode'] == '0':
       params = {
           'ticket': json_data['ticket'],
           'ssosavestate': int(time.time()),
           'callback': 'sinaSSOController.doCrossDomainCallBack',
           'scriptId': 'ssoscript0',
           'client': 'ssologin.js(v1.4.19)',
           '_': int(time.time()*1000)
       }


       #二次登錄網頁驗證
       url = 'https://passport.weibo.com/wbsso/login'
       res = session.get(url,params=params)
       print(res.text)
       json_data1 = json.loads(re.search(r'({"result":.*})', res.text).group())
       #判斷是否登錄成功
       if json_data1['result'] is True:
           print(res.cookies)
           print(json_data1)
       else:
           print(json_data1)
    else:
       print(json_data)

最終得到重要信息,表示登錄成功
在這裏插入圖片描述
如果設置META

 url = 'https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19)'
    json_data = session.post(url,data=data).content.decode("GBK")
    print(json_data)
    return

返回的數據,需要使用正則表達式進行匹配

代碼完成,閱讀起來有任何不明白的,可以私聊我

怎麼找到我,自己想辦法把

關注公主號,博客左側有

回覆微博,獲取源碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章