Web QQ協議分析(二)登陸
原諒部分文字手懶複製的前輩文字:語法部分改為Python
目前版本的Web QQ協議,整個登入流程包含以下五步:
1. 獲取二維碼
2. 確認二維碼已被掃描
3. 獲取鑑權引數ptwebqq
4. 獲取鑑權引數vfwebqq
5. 獲取鑑權引數uin
和psessionid
登入的目的是獲得以下五個引數,用於之後請求其它介面:
- ptwebqq:儲存在Cookie中的鑑權資訊
- vfwebqq:類似於Token的鑑權資訊
- psessionid:類似於SessionId的鑑權資訊
- clientid:裝置id,為固定值53999199
- uin:登入使用者id(其實就是當前登入的QQ號)
流程一:獲取二維碼
請求方式:Get
url:https://ssl.ptlogin2.qq.com/ptqrshow
引數:
params = {
'appid' : 501004106,
'e' : 0,
'l' : 'M',
's' : 5,
'd' : 72,
'v' : 4,
't' : time.time()
}
返回內容:二維碼圖片(PNG格式)
流程二:獲取二維碼掃描狀態
請求方式:Get
url:https://ssl.ptlogin2.qq.com/ptqrlogin?webqq_type=10&remember_uin=1&login2qq=1&aid=501004106&u1=http%3A%2F%2Fw.qq.com%2Fproxy.html%3Flogin2qq%3D1%26webqq_type%3D10&ptredirect=0&ptlang=2052&daid=164&from_ui=1&pttype=1&dumy=&fp=loginerroralert&action=0-0-4190&mibao_css=m_webqq&t=undefined&g=1&js_type=0&js_ver=10151&login_sig=&pt_randsalt=0
headers = {
'Referer':'https://ui.ptlogin2.qq.com/cgi-bin/login?daid=164&target=self&style=16&mibao_css=m_webqq&appid=501004106&enable_qlogin=0&no_verifyimg=1 &s_url=http%3A%2F%2Fw.qq.com%2Fproxy.html&f_url=loginerroralert &strong_login=1&login_state=10&t=20131024001' ,
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2774.3 Safari/537.36'
}
返回內容:
掃描前(未失效):
ptuiCB('66','0','','0','二維碼未失效。(3203423232)','');
掃描前(已失效):
ptuiCB('65','0','','0','二維碼已失效。(4012918406)', '');
掃描後,認證前:
ptuiCB('66','0','','0','二維碼認證中。(3203423232)','');
認證後:
ptuiCB('66','0','','0','http://ptlogin4.web2.qq.com/check_sig?xxxxxx','');
這個請求可以直接輪訓請求,直到認證成功後,將返回的地址儲存下來用作下次請求。
流程三:獲取ptwebqq
請求方式:Get
url:剛才獲得的地址(http://ptlogin4.web2.qq.com/check_sig?xxxxxx
)
referer:http://s.web2.qq.com/proxy.html?v=20130916001&callback=1&id=1
這個請求成功後的Http狀態碼是302
,之後需要將Cookie中的ptwebqq
儲存下來。
流程四:獲取vfwebqq
請求方式:Get
url:http://s.web2.qq.com/api/getvfwebqq
headers = {
'Referer':'http://s.web2.qq.com/proxy.html?v=20130916001&callback=1&id=1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2774.3 Safari/537.36'
}
params= {
'ptwebqq':ptwebqq ,
'clientid':'53999199',
'psessionid': '',
't':time.time()
}
url中需要填入上一步獲取到的ptwebqq
,請求成功後會返回一個JSON
,將reponse.json()['result']['vfwebqq']
儲存下來。
流程五:獲取psessionid
和uin
請求方式:Post
url:http://d1.web2.qq.com/channel/login2
headers = {
'Referer': 'http://d1.web2.qq.com/proxy.html?v=20151105001&callback=1&id=2',
'Origin' :'http://d1.web2.qq.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36'
}
data = {
"r" : json.dumps({
"ptwebqq": ptwebqq,
"clientid": 53999199,
"psessionid": "",
"status": "online",
}) ,
}
其中真正的動態引數只有ptwebqq
,請求成功後會返回一個JSON,將reponse.json()['result']['psessionid']
和reponse.json()['result']['uin']
儲存下來。
需要注意的是,這裡也返回了一個reponse.json()['result']['vfwebqq']
,但是這個值是無用的。
雖然說按照這個流程可以爬出所有的資料,但是我在自己測試的時候發現了許多不一樣的結果,比如uin
其實在第二步的時候就可以獲取,ptwebqq
也並不是只有第三步才是第一次出現。所以具體看各位的愛好了。不過這個獲取的流程騰訊一直在變,既然我覺得寫三翼的機器人,那麼這個專案我也會一隻維護下去。所以這個部落格會時時更新的。也歡迎大家提醒或幫助我更新。