pythonurllib新浪微博_python爬虫之新浪微博登录
fiddler 之前了解了一些常見到的反爬措施,JS加密算是比較困難,而微博的登錄中正是用JS加密來反爬,今天來了解一下。
分析過程
首先我們去抓包,從登錄到微博首頁加載出來的過程。我們重點關注一下登錄操作,其次是首頁的請求,登錄一般是POST請求。我們搜索一下:
得知登錄的url為https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19),然后點擊WebForms菜單查看參數:
里面有很多參數要提交,一般的參數的值有3種情況:
參數值固定。一般我們多次抓包發現某個參數值不變,就認為是固定的;
參數值來自于之前服務器的響應。多次抓包發現參數值變化,此時我們可以把參數的值在fiddler中查找一下,看看能否在之前的響應中找到。例如這里的nonce、rsakv、servertime
參數值來自于js生成。如果多次抓包參數的值既不是固定,也不能在之前的響應中找到,那么最可能的結果是這個參數的值是由js代碼生成。
我們在fiddler中查找nonce:
發現有一個前面的請求高亮了,說明這個參數之前就出現過。點擊這個請求,在響應里查找這個值:
可以找到這個參數,所以我們要想登錄,就得獲取nonce的值,而要獲取nonce的值,就要先請求這個找到的請求,這個請求的url為https://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=MTgzMTI0OTMxMDc%3D&rsakt=mod&checkpin=1&client=ssologin.js(v1.4.19)&_=1533119627438,url中的su在后面會講到,最后那個參數看起來像時間戳,我們可以先用時間戳模擬一下。而servertime、rsakv等必須的參數也都可以在這個響應中找到。
現在我們解決了大部分參數的問題,但是有兩個難啃的骨頭:sp和su,這兩個值在之前的響應中找不到。而且我們會發現,我們登錄輸入的賬號和密碼沒有出現在這些參數中,我們大膽猜測:su和sp就是賬號和密碼!那么我們怎么找到它們的值呢。答案是找到相應的JS代碼,并用python重寫它。
現在我們的難題到了怎么定位這倆個值的JS代碼,我們之前學習Chrome調試的時候,學會了打斷點,這個地方正是用斷點的方式來找。我們每次登錄都要點擊頁面的“登錄”按鈕,我們在填寫完賬號密碼后,設置一個點擊事件的斷點,然后點擊登錄。這樣請求在進行登錄的時候會暫停,而su和sp參數也是這個時候被加密!
然后,我們用調試界面右上角的
這些功能鍵進行逐步分析。
注意:一般只是賦值的操作,我們可以跳過,如果是函數的執行,我們要到函數里面去看,特別是函數的參數是攜帶重要參數,要重點關注。在控制臺界面,我們還可以查看某些參數的值。
另外,如果退出某個函數后,光標仍在這一行,說明這一行還有個函數,切不可直接下一步,很多關鍵信息就在這個函數里。
微博登錄的JS定位過程就不細說了,我們最后定位到su和sp加密代碼如下:
即su是用base64進行了編碼,而sp是用rsa加密,我們把js代碼用python代碼實現即可。
目前,登錄的問題解決了。現在看看請求首頁的問題。我們逐個查看,可以知道首頁的請求如下:
url為https://weibo.com/u/6505689778/home?wvr=5&lf=reg,而這個url里有個6505689778,這個值我們在fiddler中查找,在請求https://passport.weibo.com/wbsso/login?ticket=ST-NjUwNTY4OTc3OA%3D%3D-1533119623-gz-0DEAF5775E6F1D983147B0B96EE915B9-1&ssosavestate=1564655623&callback=sinaSSOController.doCrossDomainCallBack&scriptId=ssoscript0&client=ssologin.js(v1.4.19)&_=1533119634900的響應里能找到它的。
而請求這個頁面,又要獲取參數ticket、ssosavestate的值,我們再次查找,可以知道這兩個值在另一個請求https://login.sina.com.cn/crossdomain2.php?action=login&entry=weibo&r=https%3A%2F%2Fpassport.weibo.com%2Fwbsso%2Flogin%3Fssosavestate%3D1564655623%26url%3Dhttps%253A%252F%252Fweibo.com%252Fajaxlogin.php%253Fframelogin%253D1%2526callback%253Dparent.sinaSSOController.feedBackUrlCallBack%2526sudaref%253Dweibo.com%26display%3D0%26ticket%3DST-NjUwNTY4OTc3OA%3D%3D-1533119623-gz-39B6B6D3D3979D6DA2860B54E4E61A01-1%26retcode%3D0&login_time=1533119622&sign=0db5e9f42ceb691c&sr=1536%2A864的響應里。
那么這個很長的url怎么來的呢,我們再次查找,可以得知它就在登錄之后響應里。
到了這里,步驟已經走通了!
我們理一下步驟:
1、先把賬號、密碼加密后的密文得到
2、請求https://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=MTgzMTI0OTMxMDc%3D&rsakt=mod&checkpin=1&client=ssologin.js(v1.4.19)&_=1533119627438得到nonce、rsakv等參數
3、構造參數并請求登錄的url:https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19),在響應里得到跳轉的url
4、請求跳轉的url:https://login.sina.com.cn/crossdomain2.php?action=login&entry=weibo&r=https%3A%2F%2Fpassport.weibo.com%2Fwbsso%2Flogin%3Fssosavestate%3D1564655623%26url%3Dhttps%253A%252F%252Fweibo.com%252Fajaxlogin.php%253Fframelogin%253D1%2526callback%253Dparent.sinaSSOController.feedBackUrlCallBack%2526sudaref%253Dweibo.com%26display%3D0%26ticket%3DST-NjUwNTY4OTc3OA%3D%3D-1533119623-gz-39B6B6D3D3979D6DA2860B54E4E61A01-1%26retcode%3D0&login_time=1533119622&sign=0db5e9f42ceb691c&sr=1536%2A864,得到ticket、ssosavestate參數的值
5、請求https://passport.weibo.com/wbsso/login?ticket=ST-NjUwNTY4OTc3OA%3D%3D-1533119623-gz-0DEAF5775E6F1D983147B0B96EE915B9-1&ssosavestate=1564655623&callback=sinaSSOController.doCrossDomainCallBack&scriptId=ssoscript0&client=ssologin.js(v1.4.19)&_=1533119634900得到uniqueid參數
6、請求首頁:https://weibo.com/u/6505689778/home?wvr=5&lf=reg
OK,至此,我們已成功登錄了微博,后面你要獲取微博上的數據,可以自行請求。
實現代碼
importrequestsimportrsaimporttimeimportreimportrandomimporturllib3importbase64from urllib.parse importquotefrom binascii importb2a_hex
urllib3.disable_warnings()#取消警告
defget_timestamp():return int(time.time()*1000) #獲取13位時間戳
classWeiBo():def __init__(self,username,password):
self.username=username
self.password=password
self.session= requests.session() #登錄用session
self.session.headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'}
self.session.verify= False #取消證書驗證
defprelogin(self):'''預登錄,獲取一些必須的參數'''self.su= base64.b64encode(self.username.encode()) #閱讀js得知用戶名進行base64轉碼
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(self.su),get_timestamp()) #注意su要進行quote轉碼
response =self.session.get(url).content.decode()#print(response)
self.nonce = re.findall(r'"nonce":"(.*?)"',response)[0]
self.pubkey= re.findall(r'"pubkey":"(.*?)"',response)[0]
self.rsakv= re.findall(r'"rsakv":"(.*?)"',response)[0]
self.servertime= re.findall(r'"servertime":(.*?),',response)[0]returnself.nonce,self.pubkey,self.rsakv,self.servertimedefget_sp(self):'''用rsa對明文密碼進行加密,加密規則通過閱讀js代碼得知'''publickey= rsa.PublicKey(int(self.pubkey,16),int('10001',16))
message= str(self.servertime) + '\t' + str(self.nonce) + '\n' +str(self.password)
self.sp=rsa.encrypt(message.encode(),publickey)returnb2a_hex(self.sp)deflogin(self):
url= 'https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19)'data={'entry': 'weibo','gateway': '1','from':'','savestate': '7','qrcode_flag': 'false','useticket': '1','pagerefer': 'https://login.sina.com.cn/crossdomain2.php?action=logout&r=https%3A%2F%2Fweibo.com%2Flogout.php%3Fbackurl%3D%252F','vsnf': '1','su': self.su,'service': 'miniblog','servertime': str(int(self.servertime)+random.randint(1,20)),'nonce': self.nonce,'pwencode': 'rsa2','rsakv': self.rsakv,'sp': self.get_sp(),'sr': '1536 * 864','encoding': 'UTF - 8','prelt': '35','url': 'https://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack','returntype': 'META',
}
response= self.session.post(url,data=data,allow_redirects=False).text #提交賬號密碼等參數
redirect_url = re.findall(r'location.replace\("(.*?)"\);',response)[0] #微博在提交數據后會跳轉,此處獲取跳轉的url
result = self.session.get(redirect_url,allow_redirects=False).text #請求跳轉頁面
ticket,ssosavestate = re.findall(r'ticket=(.*?)&ssosavestate=(.*?)"',result)[0] #獲取ticket和ssosavestate參數
uid_url = 'https://passport.weibo.com/wbsso/login?ticket={}&ssosavestate={}&callback=sinaSSOController.doCrossDomainCallBack&scriptId=ssoscript0&client=ssologin.js(v1.4.19)&_={}'.format(ticket,ssosavestate,get_timestamp())
data= self.session.get(uid_url).text #請求獲取uid
uid = re.findall(r'"uniqueid":"(.*?)"',data)[0]print(uid)
home_url= 'https://weibo.com/u/{}/home?wvr=5&lf=reg'.format(uid) #請求首頁
html =self.session.get(home_url)
html.encoding= 'utf-8'
print(html.text)defmain(self):
self.prelogin()
self.get_sp()
self.login()if __name__ == '__main__':
username= 'xxxxxxxxx' #微博賬號
password = 'xxxxxxxxx' #微博密碼
weibo =WeiBo(username,password)
weibo.main()
結果:
總結
以上是生活随笔為你收集整理的pythonurllib新浪微博_python爬虫之新浪微博登录的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ios专题 - 斯坦福大学iOS开发公开
- 下一篇: Farpoint_Spread5_Win