您的位置:首页 > Web前端 > JavaScript

[Javascript] 爬虫 模拟新浪微博登陆

2015-06-05 17:10 666 查看
概述:

由于业务需要,要编写爬虫代码去爬去新浪微博用户的信息。

虽然在网上能找到不少信息,但由于新浪微博改版,其登陆机制进行了修改,故很多老的文章就不适合用了。

经过一番摸索,成功模拟新浪微博的登陆操作,项目使用的是Javascript语言,在ChromeExtension中运行, 跟大家分享一下这一过程和心得。

注意,本文写于2013.08.16,由于微博业务经常变化,随年月老去,文章可能不再适用。

正文:探索的过程

1. 了解大致过程

登陆微博,使用fiddler工具监视HTTP请求,截获如下操作:



可以看到在微博登陆的整个过程中,有四次重要的HTTP请求,分别是:

(1) GET /sso/prelogin.php

(2) POST /sso/login.php

(3) GET /ajaxlogin.php

(4) GET /u/2813262187

其中,sso是single sign on

(1) 是登陆前的预处理,名字也显而易见--pre,这一步操作主要是拿到了几个重要的参数,用作下一步POST表单的参数。

可以在浏览器中访问这一请求的地址,查看返回的结果:
http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=&rsakt=mod&client=ssologin.js(v1.4.11)
结果如下:

1 sinaSSOController.preloginCallBack({"retcode":0,

2 "servertime":1376533839,

3 "pcid":"gz-7bdd82b8980057a8bbc1f86b21d5a86184dd",

4 "nonce":"R1KGHZ",

5 "pubkey":"EB2A38568661887FA180BDDB5CABD5F21C7BFD59C090CB2D245A87AC253062882729293E5506350508E7F9AA3BB77F4333231490F915F6D63C55FE2F08A49B353F444AD3993CACC02DB784ABBB8E42A9B1BBFFFB38BE18D78E87A0E41B9B8F73A928EE0CCEE1F6739884B9777E4FE9E88A1BBE495927AC4A799B3181D6442443",

6 "rsakv":"1330428213",

7 "exectime":2})

返回的数据有servertime:服务时间戳,nonce:是一个6位随机码,pubkey:是用于rsa2密码加密的公钥,rsakv:显然也是加密用的。

这四个值都是需要在下一步用到的。

在久版本的新浪微博登陆机制当中,使用的是sha的加密方式,没有pubkey和rsakv参数,

因此,在网上看到的2012年的爬虫代码模拟登陆的代码都已经不适合用,但总体逻辑是没多大变化的,只需要稍作修改还是能用的,我就是这么走过来的,碰壁无数=.=

给出两篇参考文章:

For Python http://www.douban.com/note/201767245/
For PHP http://www.2cto.com/kf/201210/159591.html
(2) 提交表单的操作,我们依然是查看HTTP请求,看表单内容



看到了,servertime、nonce、rsakv,还有su:加密后的用户名,sp:加密后的密码。现在问题就是用户名跟密码是怎么加密的了,很容易地我们的目光聚焦到js代码上面

请求新浪登陆页面:http://login.sina.com.cn/signup/signin.php,里面有用于密码加密的js代码http://login.sina.com.cn/js/sso/ssologin.js,

里面的代码是加密过的,找个工具解密一下(http://js.clicki.cn/), 勉强还能看到其中的逻辑的。

(3) 分析ssologin.js

既然我们知道了servertime跟nonce是用于加密的,不妨在文件中搜一下这两个关键字,一搜找到了好东西:



翻回去上文看看,表单中有个su和sp,都在这里了,可以看到su使用的是base64加密方式;而su就稍微复杂一点了,

if中的是新浪当前版本的密码加密方式rsa2的代码,而else中的是就版本sha加密的代码,我们只需要关心if中的内容,

加密过程很简单,先是生成一个RSAKey对象, set PublicKey,然后就加密了。

一项一项地倒推回去,可以知道最后一步加密中最后的一个参数ag是原始的密码值,不会看到眼花的~

概括一下,就是用好长的那一串pubkey和10001作参数调用setPublic() ,注意的是它们都十六进制数;然后用(servertime
+ nonce + pwd)作参数调用Encrypt()。

我们去看看sinaSSOEncoder是个什么东西,它的定义在解密了的代码的1118行,从这开始截取到文件末尾,挪出来我们自己用,

1 }).call(sinaSSOEncoder);

2 //sinaSSOController = new SSOController();

3 //sinaSSOController.init();

这就解决了密码加密的问题了。

2. 模拟请求过程

既然知道大致的原理,就可以开始模拟整个登录的过程了,

(1) GET请求 http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=&rsakt=mod&client=ssologin.js(v1.4.11)
返回的数据中正则匹配到servertime、nonce和rsakv,注意,在请求的时候要把时间戳也一并传到服务器。我们看看fiddler监控到的QueryString:



前五个参数都在URL里面显示声明了,最后的_就自己在发请求的时候补上,传过去吧。

我使用的是Javascript,用Jquery,$.ajax中的data属性里面加进去就好了。

(2) POST请求 http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.11) 提交登录表单

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

2 {type: 'POST', headers: { Referer : 'http://weibo.com/?from=bp&lang=zh-cn'},

3 data : {

4 entry:'weibo',

5 gateway:1,

6 from:'',

7 savestate:7,

8 useticket:1,

9 pagerefer:'http://weibo.com/a/download',

10 vsnf:1,

11 su:'MTgxMDU0MjMzNyU0MHFxLmNvbQ==',

12 service:'miniblog',

13 servertime: servertime,

14 nonce: nonce,

15 pwencode:'rsa2',

16 rsakv: rsakv,

17 sp: sp,

18 encoding:'UTF-8',

19 prelt:505,

20 url:'http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack',

21 returntype:'META'

22 }

23 }, function(err, data){
... });

agent是发送请求事务的封装模块,重点看里面的data对象,其中su是base64加密的用户名,每次调用都是固定的,因此写死在这里;

servertime、nonce、rsakv都是在前一步截取的;

sp是加密后的密码,参考上文的加密方式可得。

(代码会在后面分享出来)

(3) 上一步页面请求完成后,返回的数据如下所示



这段代码执行后,页面直接跳转到新的地址上,虽然我们上微博的时候感觉不到有中间页面的跳转,

其中retcode是从服务器返回过来的,为0时才表示正确,能继续访问,如果返回的是其它值,可以看看ssologin.js的源码,里面有各种错误的说明,

本人也在这个地方纠结了很久,之前尝试都是2092(好像是),后来把前面两步的参数传完整(如_),补上Referer,就好了。所以要尽量模拟完整。

第三步就是要截取这个URL,请求之。至此,登录操作完成。

(4) GET请求 http://weibo.com/u/2813262187?wvr=5&wvr=5&lf=reg ,这是个人主页,能返回个人信息则表示前面的操作成功了,如果是返回登录页,那不好意思,前面的步骤还是再检查一下吧~

参考文章:

老版本新浪,Python http://www.douban.com/note/201767245/
老版本新浪,PHP http://www.2cto.com/kf/201210/159591.html
新版本新浪,Python http://www.cnblogs.com/mouse-coder/archive/2013/03/03/2941265.html
JQuery Ajax API http:// href="http://cpro.baidu.com/cpro/ui/uijs.php?app_id=0&c=news&cf=1001&ch=0&di=128&fv=17&is_app=0&jk=c0ed8d532c716121&k=api&k0=api&kdi0=0&luki=5&n=10&p=baidu&q=smileking_cpr&rb=0&rs=1&seller_id=1&sid=2161712c538dedc0&ssp2=1&stid=0&t=tpclicked3_hc&tu=u1682280&u=http%3A%2F%2Fwww%2Eth7%2Ecn%2Fweb%2Fjs%2F201308%2F12198%2Eshtml&urlid=0" target=_blank>api.jquery.com/jQuery.ajax/

ChromeExtension https://developer.chrome.com/extensions/webRequest.html#event-onHeadersReceived
附:代码 http://files.cnblogs.com/sysuys/weiboLogin.rar
说明:

1. 这几个文件是从爬虫项目抽取出来的,所以这些文件跑不起来,但可供参考,代码没有完善,没注释

2. 项目是运行在Chrome插件中的

3. 使用了requirejs.js

转载:http://www.th7.cn/web/js/201308/12198.shtml
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: