如何使用Charles和requests模擬微博登錄-創(chuàng)新互聯(lián)

這篇文章主要講解了“如何使用Charles和requests模擬微博登錄”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“如何使用Charles和requests模擬微博登錄”吧!

為企業(yè)提供網(wǎng)站建設(shè)、做網(wǎng)站、網(wǎng)站優(yōu)化、成都全網(wǎng)營銷、競價(jià)托管、品牌運(yùn)營等營銷獲客服務(wù)。創(chuàng)新互聯(lián)公司擁有網(wǎng)絡(luò)營銷運(yùn)營團(tuán)隊(duì),以豐富的互聯(lián)網(wǎng)營銷經(jīng)驗(yàn)助力企業(yè)精準(zhǔn)獲客,真正落地解決中小企業(yè)營銷獲客難題,做到“讓獲客更簡單”。自創(chuàng)立至今,成功用技術(shù)實(shí)力解決了企業(yè)“網(wǎng)站建設(shè)、網(wǎng)絡(luò)品牌塑造、網(wǎng)絡(luò)營銷”三大難題,同時(shí)降低了營銷成本,提高了有效客戶轉(zhuǎn)化率,獲得了眾多企業(yè)客戶的高度認(rèn)可!

1. 用Charles記錄整個(gè)登錄過程

首先,我們運(yùn)行Charles并開始記錄。然后打開Chrome瀏覽器,選擇使用Charles代理,打開微博 首頁  ,出現(xiàn)登錄頁面(如果之前登錄過微博,要先退出登錄)。輸入用戶名和密碼進(jìn)行登錄,登錄成功后就可以停止Charles的記錄。這樣我們就用Charles完整記錄下了微博的登錄過程。見圖:

如何使用Charles和requests模擬微博登錄

我們把整個(gè)登錄過程寫出一個(gè)Python類,它的定義為:

class WeiboLogin:
    user_agent = (
        'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.11 (KHTML, like Gecko) '
        'Chrome/20.0.1132.57 Safari/536.11'
    )
    def __init__(self, username, password, cookies_tosave='weibo.cookies'):
        self.weibo_user = username
        self.weibo_password = password
        self.cookies_tosave = cookies_tosave
        self.session = requests.session()
        self.session.headers['User-Agent'] = self.user_agent

接下來我們分析登錄過程,并逐一實(shí)現(xiàn)這個(gè)類的各個(gè)方法。

2. 分析登錄過程

把Charles的主窗口切換到“Sequence”標(biāo)簽頁,

如何使用Charles和requests模擬微博登錄

我們可以按加載時(shí)間順序觀察Charles記錄的微博登錄過程,我們發(fā)現(xiàn)第一個(gè)可疑的請求的Host是:

  • login.sina.com.cn

點(diǎn)擊該條記錄,下方出現(xiàn)該條請求的完整內(nèi)容,它的路徑是:

GET /sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=&rsakt=mod&client=ssologin.js(v1.4.19)&_=1542456042531 HTTP/1.1

這個(gè)GET請求的參數(shù)_=1542456042531看起來是個(gè)時(shí)間戳,這個(gè)在ssologin.js(看后面是如何找到的)定義為preloginTimeStart,可以用int(time.time()*1000)得到。

從prelogin.php這個(gè)名字看,它是一個(gè)預(yù)登陸,即在你輸入用戶名和密碼前,它先從服務(wù)器拿點(diǎn)東西過來:

如何使用Charles和requests模擬微博登錄

用Python實(shí)現(xiàn)這個(gè)prelogin:

    def prelogin(self):
        preloginTimeStart = int(time.time()*1000)
        url = ('https://login.sina.com.cn/sso/prelogin.php?'
               'entry=weibo&callback=sinaSSOController.preloginCallBack&'
               'su=&rsakt=mod&client=ssologin.js(v1.4.19)&'
               '_=%s') % preloginTimeStart
        resp = self.session.get(url)
        pre_login_str = re.match(r'[^{]+({.+?})', resp.text).group(1)
        pre_login = json.loads(pre_login_str)
        pre_login['preloginTimeStart'] = preloginTimeStart
        print ('pre_login 1:', pre_login)
        return pre_login

這些預(yù)先拿過來的東西有什么用呢?目前為止還不知道,繼續(xù)往下看。

補(bǔ)充:關(guān)于認(rèn)證碼

昨天最初寫這篇教程的時(shí)候,沒有碰到驗(yàn)證碼。今天就碰到驗(yàn)證碼跳出來了,真是大快人心,可以把這部分補(bǔ)充上了。

對比昨天的prelogin的URL參數(shù)不能發(fā)現(xiàn),今天的多了兩個(gè)參數(shù):

  • su=xxxxx 就是加密的那個(gè)(實(shí)為base64編碼)用戶名

  • checkpin=1 告訴服務(wù)器要檢查驗(yàn)證碼(我去,自己寫爬蟲絕對不會這么干)

帶著這兩個(gè)參數(shù)請求服務(wù)器,返回來的也會多了showpin的值:

如何使用Charles和requests模擬微博登錄

既然要顯示pin(驗(yàn)證碼),就要下載驗(yàn)證碼,它的地址是:

https://login.sina.com.cn/cgi/pin.php?r=2855501&s=0&p=aliyun-a34a347956ab8e98d6eb1a99dfddd83bc708

這個(gè)是怎么來的呢?直接按Ctrl+F 打開“Text to Find”窗口搜索“pin.php”:

如何使用Charles和requests模擬微博登錄

這個(gè)Find窗口很有用,它讓我們可以在記錄的所有請求和響應(yīng)里面查找特定文本,并且它還支持正則表達(dá)式、大小寫敏感、只找全詞。只找全詞,對查找su這樣的短詞很有幫助,可以過濾大量包含它的詞,比如super。

這里要特別說明一下,為什么只選在”Response Body”里面查找。
因?yàn)槲覀兪且疑厦娴腢RL是如何生成的,我們認(rèn)為它是在某個(gè)js文件的某段代碼實(shí)現(xiàn)的,所以它一定是在 Response Body 里面的,這樣也可以過濾掉很多無關(guān)信息。

通過上面的過濾,直接就定位了相關(guān)代碼,雙擊進(jìn)去,再稍微一搜,就發(fā)現(xiàn)對應(yīng)的代碼了:

var pincodeUrl = "https://login.sina.com.cn/cgi/pin.php";
...
return pincodeUrl + "?r=" + Math.floor(Math.random() * 100000000) + "&s=" + size + (pcid.length > 0 ? "&p=" + pcid : "")

有了這個(gè)js,用Python來實(shí)現(xiàn)就易如反掌了,小猿們可以自己試試看。

有了驗(yàn)證碼的URL,我們就用self.session下載它并保存為文件,在POST 所有l(wèi)ogin數(shù)據(jù)前,通過<code>pin = input('>>please input pin:')</code>來獲取,加入到POST數(shù)據(jù)里面一起POST發(fā)送即可。

第二條可疑的請求的Host跟第一條一樣,路徑是:

POST /sso/login.php?client=ssologin.js(v1.4.19) HTTP/1.1

這是一條POST,我來看看它POST的數(shù)據(jù),選擇這條記錄,點(diǎn)擊“Contents”標(biāo)簽,再點(diǎn)擊“Form”標(biāo)簽,可以看到它POST的數(shù)據(jù):

如何使用Charles和requests模擬微博登錄

這時(shí)候我們可以把這寫POST的參數(shù)和prelogin得到的聯(lián)系起來了。

參數(shù):su
這個(gè)看上去是“加密”的username,即用戶名。那它是怎么加密的呢?瀏覽器運(yùn)行的是JavaScript,所以我們猜測是通過JS加密的,那么是哪段JS呢?看上面login.php路徑里給了參數(shù)client=ssologin.js(v1.4.19),那我們就去ssologin.js里面找找,選擇加載這個(gè)js文件的請求,“Contents”標(biāo)簽下面就會顯示JS代碼,按Ctrl+F查找username:

如何使用Charles和requests模擬微博登錄

charles weibo login su

果然在這里,其實(shí)就是用base64編碼了一下,算不上加密,于是我們就有了獲得su的方法:

    def encrypt_user(self, username):
        user = urllib.parse.quote(username)
        su = base64.b64encode(user.encode())
        return su

參數(shù):sp
跟su同樣的思路,還是在ssologin.js里面查找password,我們發(fā)現(xiàn)了加密password的算法:

如何使用Charles和requests模擬微博登錄

image

于是有了獲得sp的方法:

    def encrypt_passwd(self, passwd, pubkey, servertime, nonce):
        key = rsa.PublicKey(int(pubkey, 16), int('10001', 16))
        message = str(servertime) + '\t' + str(nonce) + '\n' + str(passwd)
        passwd = rsa.encrypt(message.encode('utf-8'), key)
        return binascii.b2a_hex(passwd)

參數(shù):prelt

既然ssologin.js就是管登錄的,那我們還是在這里找prelt,Ctrl+F 查找到

request.prelt = preloginTime;

原理prelt就是preloginTime的簡稱,那我們再搜索preloginTime:

preloginTime = (new Date()).getTime() - preloginTimeStart - (parseInt(result.exectime, 10) || 0)

這里的preloginTimeStart就是請求prelogin.php時(shí)的時(shí)間戳,result.exectime就是prelogin請求返回結(jié)果里面的exectime。
哈哈哈,又找到了prelt的算法,其實(shí)這個(gè)prelt就是從請求開始到現(xiàn)在的時(shí)間差,似乎也沒那么重要,隨機(jī)一個(gè)就可以,不過還是用Python實(shí)現(xiàn)一下:

    def get_prelt(self, pre_login):
        prelt = int(time.time() * 1000) - pre_login['preloginTimeStart'] - pre_login['exectime']
        return prelt

目前,我們已經(jīng)獲得了登錄的重要參數(shù),接下來再看看登錄請求的流程,在“Sequence”的 “Filter” 輸入login,我們可以看到過濾后的請求,其中前三個(gè)就是登錄的先后順序:

如何使用Charles和requests模擬微博登錄

其詳細(xì)流程就是:

  1. prelogin從服務(wù)器獲得一些參數(shù)

  2. 把加密的用戶名密碼等參數(shù)POST給 https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19)

  3. 第2步返回的是html代碼,html代碼里面重定向到另外的url (所以我們代碼里面也要實(shí)現(xiàn)這個(gè)重定向)

  4. 第3步返回的還是html代碼,里面通過JS先實(shí)現(xiàn)幾個(gè)跨域設(shè)置,最后重定向到另外一個(gè)url(我們也要實(shí)現(xiàn)這部分操作)

第4步返回的HTTP頭里面重定向到另外的URL,request會跟隨這個(gè)重定向,不用我們實(shí)現(xiàn)。
用Python實(shí)現(xiàn)html代碼里面的JS重定向的方法就是,用正則表達(dá)式提取出JS代碼里面的重定向URL,然后用requests做GET請求。

完整的登錄流程的代碼就是:

    def login(self):
        # step-1\. prelogin
        pre_login = self.prelogin()
        su = self.encrypt_user(self.weibo_user)
        sp = self.encrypt_passwd(
            self.weibo_password,
            pre_login['pubkey'],
            pre_login['servertime'],
            pre_login['nonce']
        )
        prelt = self.get_prelt(pre_login)
        data = {
            'entry': 'weibo',
            'gateway': 1,
            'from': '',
            'savestate': 7,
            'qrcode_flag': 'false',
            'userticket': 1,
            'pagerefer': '',
            'vsnf': 1,
            'su': su,
            'service': 'miniblog',
            'servertime': pre_login['servertime'],
            'nonce': pre_login['nonce'],
            'vsnf': 1,
            'pwencode': 'rsa2',
            'sp': sp,
            'rsakv' : pre_login['rsakv'],
            'encoding': 'UTF-8',
            'prelt': prelt,
            'sr': "1280*800",
            'url': 'http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.'
                   'sinaSSOController.feedBackUrlCallBack',
            'returntype': 'META'
        }
        # step-2 login POST
        login_url = 'https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19)'
        resp = self.session.post(login_url, data=data)
        print(resp.headers)
        print(resp.content)
        print('Step-2 response:', resp.text)
        # step-3 follow redirect
        redirect_url = re.findall(r'location\.replace\("(.*?)"', resp.text)[0]
        print('Step-3 to redirect:', redirect_url)
        resp = self.session.get(redirect_url)
        print('Step-3 response:', resp.text)
        # step-4 process step-3's response
        arrURL = re.findall(r'"arrURL":(.*?)\}', resp.text)[0]
        arrURL = json.loads(arrURL)
        print('CrossDomainUrl:', arrURL)
        for url in arrURL:
            print('set CrossDomainUrl:', url)
            resp_cross = self.session.get(url)
            print(resp_cross.text)
        redirect_url = re.findall(r'location\.replace\(\'(.*?)\'', resp.text)[0]
        print('Step-4 redirect_url:', redirect_url)
        resp = self.session.get(redirect_url)
        print(resp.text)
        with open(self.cookies_tosave, 'wb') as f:
            pickle.dump(self.session.cookies, f)
        return True

代碼中打印了很多信息,方便我們過程整個(gè)登錄過程。

要測試我們的實(shí)現(xiàn)就很簡單了:

if __name__ == '__main__':
    weibo_user = 'your-weibo-username'
    weibo_password = 'your-weibo-password'
    wb = WeiboLogin(weibo_user, weibo_password)
    wb.login()

修改為你的微博賬戶和密碼就可以測試起來啦。

感謝各位的閱讀,以上就是“如何使用Charles和requests模擬微博登錄”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對如何使用Charles和requests模擬微博登錄這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!

網(wǎng)站名稱:如何使用Charles和requests模擬微博登錄-創(chuàng)新互聯(lián)
標(biāo)題鏈接:http://muchs.cn/article34/djijpe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站策劃網(wǎng)站制作、網(wǎng)頁設(shè)計(jì)公司、品牌網(wǎng)站建設(shè)、定制網(wǎng)站、軟件開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站優(yōu)化排名