首先呢,因为以前重装系统,又要从新配置环境,而后还有一些别的事,致使我一直没有写爬虫了,不过如今又能够继续写了。php
而后我此次说的模拟登陆新浪微博呢,不是使用Selenium模拟浏览器操做,毕竟Selenium的效率是真的有些低,因此我选择用Python发送请求实现模拟登陆,整个过程还算是有点小曲折吧。git
Windows10 + Python3.7 + Pycharm + Fiddlergithub
首先打开新浪微博,网址为:https://weibo.com/,这里咱们只须要关注登陆这一部分,以下图:浏览器
这样看是看不出来东西的,打开开发者工具,刷新一下页面,找找看有没有什么可疑的东西,而后就能找到下面这个包:ide
看到prelogin就能猜到应该是和登陆有关的了,因而点击“Preview”查看具体内容:工具
到这里仍是什么都看不出来,也不知道这些数据有什么用。这时候Fiddler就能派上用场了,首先打开Fiddler,而后在网页上输入用户名和密码并登陆新浪微博,登陆成功以后在Fiddler中找寻相关信息,能够找到下面这个url:测试
https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19)ui
点开以后能够看到携带了不少参数:加密
在这些参数中,咱们须要关注的参数为:su,sp,servertime,nonce,pubkey,rsakv。其中su是用户名加密后的结果,sp是密码加密后的结果,servertime是一个时间戳,而剩余三个参数都来源于咱们前面找到的prelogin.php。那么如今的问题就在于用户名和密码是怎么加密的?url
首先仍是找到prelogin.php,在它携带的参数中看到有一个ssologin.js,猜想它可能和加密规则有关系,因此找一下这个ssologin.js。
这里须要打开新浪的登陆页面:https://login.sina.com.cn/,而后右键查看源码,再搜索“ssologin.js”,就能找到这个js文件了:
打开以后搜索“username”,就能找到加密规则了,以下图(红框框出来的分别是用户名加密规则和密码加密规则):
用户名的加密是很简单的,使用base64加密就好了。可是对于密码的加密有一些复杂,虽然有if和else,但其实这里咱们只须要看if部分:
request.servertime = me.servertime;
request.nonce = me.nonce;
request.pwencode = "rsa2";
request.rsakv = me.rsakv;
var RSAKey = new sinaSSOEncoder.RSAKey();
RSAKey.setPublic(me.rsaPubkey, "10001");
password = RSAKey.encrypt([me.servertime, me.nonce].join("\t") + "\n" + password)
密码的加密过程为:首先建立一个rsa公钥,公钥的两个参数都是固定值,第一个参数是prelogin.php中的pubkey,第二个参数是加密的ssologin.js文件中指定的10001,这两个值须要先从16进制转换成10进制,其中10001转成十进制为65537。最后再加入servertime时间戳和nonce字段,以及一个“\t”和一个"\n"进行进一步加密。
因为使用了rsa加密,因此须要使用导入rsa模块,没有安装的可使用pip install rsa进行安装。
这里主要说一下加密用户名和密码部分的代码:
# Base64加密用户名
def encode_username(usr):
return base64.b64encode(usr.encode('utf-8'))[:-1]
须要注意的是要使用base64加密,须要先转换成字节型数据,并且加密以后末尾会多一个"\n",所以须要用[:-1]来去掉多余字符。
# RSA加密密码
def encode_password(code_str):
pub_key = rsa.PublicKey(int(pubkey, 16), 65537)
crypto = rsa.encrypt(code_str.encode('utf8'), pub_key)
return binascii.b2a_hex(crypto) # 转换成16进制
在加密密码的时候传入的这个code_str参数就是servertime + '\t' + nonce + '\n' + password获得的结果,而在整个加密过程完成以后要转换成16进制再返回。
可是作了这两步以后并无真的登陆微博,还须要提取连接并进行跳转,不过对于咱们来讲作到这一步就已经够了,咱们只须要保存此时的Cookie就好了,为了验证这个Cookie是否有效,我还写了一段代码进行测试,这里就不放出来了。
完整代码已上传到GitHub!