pc登录新浪微博时,在客户端用js预先对用户名、密码都进行了加密,而且在post之前会get一组参数,这也将作为post_data的一部分。这样,就不能用通常的那种简单方法来模拟post登录(比如人人网)。
通过爬虫获取新浪微博数据,模拟登录是必不可少的。
1、在提交post请求之前,需要get获取四个参数(servertime,nonce,pubkey和rsakv),不是之前提到的只是获取简单的servertime,nonce,这里主要是由于js对用户名、密码加密方式改变了。
1.1 由于加密方式的改变,我们这里将使用到rsa模块,有关rsa公钥加密算法的介绍可以参考网络中的有关内容。下载并安装rsa模块:
下载:https://pypi.python.org/pypi/rsa/3.1.1
rsa模块文档地址:http://stuvel.eu/files/python-rsa-doc/index.html
根据自己的python版本选择适合自己的rsa安装包(.egg),在win下安装需要通过命令行使用easy_install.exe(win上安装setuptool从这里下载:setuptools-0.6c11.win32-py2.6.exe 安装文件 )进行安装,例如:easy_install rsa-3.1.1-py2.6.egg,最终命令行下测试import rsa,未报错则安装成功。
1.2 获得以及查看新浪微博登录js文件
查看新浪通行证url (http://login.sina.com.cn/signup/signin.php)的源代码,其中可以找到该js的地址 http://login.sina.com.cn/js/sso/ssologin.js,不过打开后里面的内容是加密过的,可以在网上找个在线解密站点解密,查看最终用户名和密码的加密方式。
1.3 登录
登录第一步,添加自己的用户名(username),请求prelogin_url链接地址:
prelogin_url = ‘http://login.sina.com.cn/sso/prelogin.php?entry=sso&callback=sinassocontroller.prelogincallback&su=%s&rsakt=mod&client=ssologin.js(v1.4.4)’ % username
使用get方法得到以下类似内容:
sinassocontroller.prelogincallback({“retcode”:0,”servertime”:1362041092,”pcid”:”gz-6664c3dea2bfdaa3c94e8734c9ec2c9e6a1f”,”nonce”:”iryp4n”,”pubkey”:”eb2a38568661887fa180bddb5cabd5f21c7bfd59c090cb2d245a87ac253062882729293e5506350508e7f9aa3bb77f4333231490f915f6d63c55fe2f08a49b353f444ad3993cacc02db784abbb8e42a9b1bbfffb38be18d78e87a0e41b9b8f73a928ee0ccee1f6739884b9777e4fe9e88a1bbe495927ac4a799b3181d6442443″,”rsakv”:”1330428213″,”exectime”:1})
进而从中提取到我们想要的servertime,nonce,pubkey和rsakv。当然,pubkey和rsakv的值我们可以写死在代码中,它们是固定值。
2、之前username 经过base64计算:
代码如下:
username_ = urllib.quote(username)username = base64.encodestring(username)[:-1]
password经过三次sha1加密,且其中加入了 servertime 和 nonce 的值来干扰。即:两次sha1加密后,结果加上servertime和nonce的值,再sha1算一次。
在最新的rsa加密方法中,username还是以前一样的处理;
password加密方式和原来有所不同:
2.1 先创建一个rsa公钥,公钥的两个参数新浪微博都给了固定值,不过给的都是16进制的字符串,第一个是登录第一步中的pubkey,第二个是js加密文件中的‘10001’。
这两个值需要先从16进制转换成10进制,不过也可以写死在代码里。这里就把10001直接写死为65537。代码如下:
代码如下:
rsapublickey = int(pubkey, 16)key = rsa.publickey(rsapublickey, 65537) #创建公钥message = str(servertime) + ‘\t’ + str(nonce) + ‘\n’ + str(password) #拼接明文js加密文件中得到passwd = rsa.encrypt(message, key) #加密passwd = binascii.b2a_hex(passwd) #将加密信息转换为16进制。
2.2 请求通行证url:login_url =‘http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.4)’
需要发送的报头信息
代码如下:
postpara = { ‘entry’: ‘weibo’, ‘gateway’: ‘1’, ‘from’: ”, ‘savestate’: ‘7’, ‘userticket’: ‘1’, ‘ssosimplelogin’: ‘1’, ‘vsnf’: ‘1’, ‘vsnval’: ”, ‘su’: encodedusername, ‘service’: ‘miniblog’, ‘servertime’: servertime, ‘nonce’: nonce, ‘pwencode’: ‘rsa2’, ‘sp’: encodedpassword, ‘encoding’: ‘utf-8’, ‘prelt’: ‘115’, ‘rsakv’ : rsakv, ‘url’: ‘http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinassocontroller.feedbackurlcallback’, ‘returntype’: ‘meta’ }
请求的内容中添加了rsakv,将pwencode的值修改为rsa2,其他跟以前一致。
将参数组织好,post请求。检验是否登录成功,可以参考post后得到的内容中的一句 location.replace(“http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinassocontroller.feedbackurlcallback&retcode=101&reason=%b5%c7%c2%bc%c3%fb%bb%f2%c3%dc%c2%eb%b4%ed%ce%f3”);
如果retcode=101则表示登录失败。登录成功后结果与之类似,不过retcode的值是0。
3、登录成功后,在body中的replace信息中的url就是我们下一步要使用的url。然后对上面的url使用get方法来向服务器发请求,保存这次请求的cookie信息,就是我们需要的登录cookie了。