Java實現模擬登陸新浪微博

畢設題目要使用到新浪微博數據,因此要爬取新浪微博的數據。通常而言,新浪微博的爬蟲有兩種模式:新浪官方API和模擬登陸新浪微博。兩種方法的異同點和適用狀況就無須贅述了。前輩的文章已經很是多了。寫這篇文章主要記錄本身的探究過程。javascript

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

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

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

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

1,微博登錄流程算法

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

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

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

 

如上圖四個高亮項所示,微博的登陸過程主要爲四步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來實現跳轉。可是我沒有具體分析。

相關文章
相關標籤/搜索