Java實現模擬登錄新浪微博


畢設題目要使用到新浪微博數據,所以要爬取新浪微博的數據。一般而言,新浪微博的爬蟲有兩種模式:新浪官方API和模擬登錄新浪微博。兩種方法的異同點和適用情況就無須贅述了。前輩的文章已經非常多了。寫這篇文章主要記錄自己的探究過程。

參考文章:1,解析新浪微博的登錄過程

     2,[Javascript] 爬蟲 模擬新浪微博登陸

     3,用java程序模擬登陸新浪微博

背景知識:Http協議,HttpClient開源包。

1,微博登陸流程

使用Firefox下的HttpFox或者Chrome下的[工具]->[開發者工具](F12快捷鍵啟動)可以查看瀏覽器與網站服務器之間的報文交換信息。

我使用的是FireFox下面的HttpFox。建議提前刪除FireFox之前保存的關於新浪微博的Cookies。這樣登錄過程更明顯。

首先在地址欄中輸入weibo.com網址,進入到登陸界面。然后開啟HttpFox,輸入賬號(account)和密碼(password),單擊登錄按鍵,正常登陸。

 

如上圖四個高亮項所示,微博的登錄過程主要為四步HTTP請求:

(1)GET  http://login.sina.com.cn/sso/prelogin.php

(2)POST http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.11)

(3)GET http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack&sudaref=weibo.com

(4)GET http://weibo.com/u/5081950920/home?wvr=5&uut=fin&from=reg

 

下面對四步進行解析:

(1)GET http://login.sina.com.cn/sso/prelogin.php

此步驟是向服務器請求servertime,nonce等參數。此時可暫不了解這些參數的用處。

首先GET請求的參數為:

這里,‘su’參數是登錄賬戶account經過BASE64加密過后得到的字符串,先將account中的‘@’替換為'%40',然后對其BASE64加密,得到su的值。‘_’參數的值是當前時間(毫秒值)。其余參數值一般不變。

樣例:

http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=Y29tbWVudHN3ZWlibyU0MDE2My5jb20%3D&rsakt=mod&checkpin=1&client=ssologin.js(v1.4.11)&_=1395726032529

向服務器發送這個請求后,會得到服務器的JSon格式的返回值:

sinaSSOController.preloginCallBack({"retcode":0,"servertime":1395726033,"pcid":"gz-3271d864f76816bbfbd651c6887ba9eabf59","nonce":"04DGHY","pubkey":"EB2A38568661887FA180BDDB5CABD5F21C7BFD59C090CB2D245A87AC253062882729293E5506350508E7F9AA3BB77F4333231490F915F6D63C55FE2F08A49B353F444AD3993CACC02DB784ABBB8E42A9B1BBFFFB38BE18D78E87A0E41B9B8F73A928EE0CCEE1F6739884B9777E4FE9E88A1BBE495927AC4A799B3181D6442443","rsakv":"1330428213","showpin":0,"exectime":157})

retcode為0表示執行成功;servertime,nonce是后期對用戶密碼password加密用的參數。pubkey是加密用的公鑰,它的值一般為固定不變的,任何一次請求返回值都一樣。raskv也是加密使用的參數。其余參數用處不大。

(2)POST http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.11)

這一步就是向服務器提交表單,表單參數為:

Parameter Value 說明
entry weibo 固定值                                                  
gateway 1 固定值
from   空值
savestate 7 固定值
useticket 1 固定值
pagerefer   空值
vsnf 1 固定值
su Y29tbWVudHN3ZWlibyU0MDE2My5jb20= 賬號account經過BASE64加密后得到的值
service miniblog 固定值
servertime 1395726063 上一步獲取的值
nonce 04DGHY 上一步獲取的值
pwencode rsa2 新浪所使用的加密方法,具體值與新浪使用算法有關。短期內應該為固定值
rsakv 1330428213 上一步獲取的值
sp

一個256位的密文

密碼password加密后的值,具體加密方法下面詳細介紹
encoding UTF-8 固定值
prelt 171 一個在[100, 1000]內取隨機值
url http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack 固定值
returntype META 固定值

將該表單提交到URL:

http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.11)

這個URL版本不斷變化,現在為版本1.4.11。自己開發代碼時,可以注意一下當時的具體版本。

上述參數pagerefer有時候會改為

ssosimplelogin                                 1                           固定值           
但是,經過驗證,兩者互換無差別。
重點為su和sp的獲取。
su:用戶名usrname,就是輸入的賬戶account,一般為郵件地址,經過BASE64加密后獲得。
 
sp:密碼password經過加密后獲得。加密算法有兩種。登陸 weibo.com時,會獲取新浪微博的一個名字為ssologin.js的 js 腳本文件,在weibo.com的頁面中連接為  http://js.t.sinajs.cn/t35/miniblog/static/js/sso.js?version=8818b2c42b785af9 。上面截圖沒有截取,可自行截取,在輸入weibo.com前打開HttpFox即可。

該腳本文件中包含了整個登陸過程,同時包含了 RSA加密算法,WSSE加密算法和BASE64加密算法。目前該腳本文件的版本為 1.4.11 ,版本一直在升級,升級過程加密算法可能會做更改。具體加密過程此處不表,課查看js該文件,或者翻閱文章開頭的鏈接博文,里面講解比較詳細。

具體而言,就是RSA加密算法是將servertime,nonce與賬戶密碼鏈接,同時設置rsaPubkey和‘10001’(固定值)作為參數,進行RSA加密,現在執行的是這一版本。

RSA:
request["servertime"] = me.servertime;
request["nonce"] = me.nonce;
request["pwencode"] = "rsa2";
equest["rsakv"] = me.rsakv;
var RSAKey = new sinaSSOEncoder.RSAKey();
RSAKey.setPublic(me.rsaPubkey, '10001');
password = RSAKey.encrypt([me.servertime, me.nonce].join("\t") + "\n" + password);

WSSE加密算法曾經作為sp的加密算法,現在不采用,以后或許也會重新采用。具體行為就是兩次SHA1加密password,然后加入servertime和nonce再SHA1加密一次。

WSSE:
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);

然后表單提交之后,會得到一個html文件(在HttpFox中查看Content內容)。

        <html>
        <head>
        <title>ÐÂÀËͨÐÐÖ¤</title>
        <meta http-equiv="refresh" content="0; url=&#39;http://weibo.com/sso/login.php?url=http%3A%2F%2Fweibo.com%2Fajaxlogin.php%3Fframelogin%3D1%26callback%3Dparent.sinaSSOController.feedBackUrlCallBack%26sudaref%3Dweibo.com&ticket=ST-NTA4MTk1MDkyMA==-1395726048-gz-E9A629068822EF01DD1427CA6D0C14D9&retcode=0&#39;"/>
        <meta http-equiv="Content-Type" content="text/html; charset=GBK" />
        </head>
        <body bgcolor="#ffffff" text="#000000" link="#0000cc" vlink="#551a8b" alink="#ff0000">
        <script type="text/javascript" language="javascript">
        location.replace("http://weibo.com/sso/login.php?url=http%3A%2F%2Fweibo.com%2Fajaxlogin.php%3Fframelogin%3D1%26callback%3Dparent.sinaSSOController.feedBackUrlCallBack%26sudaref%3Dweibo.com&ticket=ST-NTA4MTk1MDkyMA==-1395726048-gz-E9A629068822EF01DD1427CA6D0C14D9&retcode=0");
        </script>
        </body>
        </html>

重點在於

<script type="text/javascript" language="javascript">
        location.replace("http://weibo.com/sso/login.php?url=http%3A%2F%2Fweibo.com%2Fajaxlogin.php%3Fframelogin%3D1%26callback%3Dparent.sinaSSOController.feedBackUrlCallBack%26sudaref%3Dweibo.com&ticket=ST-NTA4MTk1MDkyMA==-1395726048-gz-E9A629068822EF01DD1427CA6D0C14D9&retcode=0");
        </script>

在location.replace中會有個URL地址。我們要抽取出這個URL。

注意:如果rectcode不為0,則表示到此為止一切步驟都正常執行。如果返回其他值,則表示執行錯誤,無法向下繼續執行。

(3)這步在HttpFox中表現為Redirect to第二步抽取的URL,所以我們在Coding時,直接請求這個網址即可獲得微博登陸權限。

(4)這步是做個示范,微博登錄成功以后,即可訪問新浪微博的URL了。

 

上述過程如果是用Java實現,使用HttpClient來訪問URL,一定要注意,Login時,從頭到尾只能使用一個HttpClient,因為HttpClient會保存一系列的cookie,如果new一個新的HttpClient,這些保存全部沒有,訪問無法進行。

第三四部,會涉及一系列的Cookies,可以使用Cookies來實現跳轉。但是我沒有具體分析。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM