毕设题目要使用到新浪微博数据,所以要爬取新浪微博的数据。一般而言,新浪微博的爬虫有两种模式:新浪官方API和模拟登录新浪微博。两种方法的异同点和适用情况就无须赘述了。前辈的文章已经非常多了。写这篇文章主要记录自己的探究过程。
背景知识: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的值。‘_’参数的值是当前时间(毫秒值)。其余参数值一般不变。
向服务器发送这个请求后,会得到服务器的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
固定值
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 = newsinaSSOEncoder.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内容)。
ÐÂÀËͨÐÐÖ¤
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");