一次爬虫的记录与分享
0x00准备
安装selenium库,使用urllib库,re库
0x01实现
selenium模拟登录
emmm,起因是为了实现自动在qzone发送说说,然后到github上去翻了翻,发现轮子都已经失效了(大概没人喜欢做这么无聊的事吧
登录qzone: i.qq.com,查看到qzone的登录是利用js实现的
并没有想去分析qzone的js算法,决定使用selenium模拟登录qzone,不难操作,然后取得当前页面,也就是登录完成的页面的cookie,(注意!用sleep来等待大量数据加载完成,许多操作不能达到预计效果可能是因为网络不佳造成的)
除了cookie,还有当前页面的源代码也要保存下来(笑
分析说说发送过程
在首页随便发送一条说说,截获一条post请求
分析结构,发现请求地址很长
1 | https://user.qzone.qq.com/proxy/domain/taotao.qzone.qq.com/cgi-bin/emotion_cgi_publish_v6?g_tk=91245527&qzonetoken=010dee36790ae077dbba7521e3e0838b6d9ef25271a9260c8040cd2c2e976f58f614e3ab913c683dfb5c90 |
前面一部分是固定的(除非人为的话,后面有两个参数g_tk和qzonetoken,这是两个为了加密而设置的参数,通过js来获得,qzonetoken的函数源码没有找到,查询网络上的也是一些过时的(算法早就改变了,于是我从主页的源码中扣下来,在最底下,用正则来截取
g_tk无法在源码中找到,于是刷新主页,查到在一个interface_mini.js?max_age=60628
的js文件里有定义
1 | QZONE.FrontPage.getACSRFToken = function(url) { |
简单分析一下,用python来重写了g_tk的计算函数(这种操作会因为腾×更新算法而失效,而腾×的更新恰好是比较快的2333
urllib发送post请求
没啥好说的,构造post请求头,主体,发送请求
源码地址:https://github.com/void0red/code/blob/master/qzone.py
0x03后记
最滑稽的是,这个爬虫并没有实现,运行结果是Bad Request,233333
已经解决,问题在于没有计算请求头中Content-Length的值(笑
总的来说,程序可用性不高:
- 登录是用selenium实现的,加载会占用大量内存与cpu,不适宜在小型设备(例如树莓派)上运行
- 两个加密函数有时效性,qzonetoken还好,g_tk的计算就显得有些鸡肋,一旦腾×更改其中的某段代码中的某个参数值,该爬虫就得重新编写(事实上他也是这么做的,可以考虑用正则把js扣出来,放在本地运行,这样程序大概能健壮一些
- 程序容错率不高,一旦有环节出错,整个过程无法实现
可喜的是,终于成功爬了qzone,2333
void0red 2017.10.13