QQ空间定时留言

为什么要做这样的事?就是闲的蛋疼。

思路很简单,空间留言抓包,利用Python的requests库自定义评论内容发包即可实现评论。配合Linux crontab定时任务即可实现定时评论。

用手机上的Packet Capture抓qq空间网页版留言动作的数据包,这个工具主要好用在可以分应用抓包,另外同过自建vpn的方式实现免Root抓包也是他的一大特色。虽然Root权限对于搞基的大部分人来说都不算什么。

除此之外,通过安装证书的方式可以解密https数据包。不过安卓7.0以上的版本,对系统证书和用户证书的区分更严格了,导致在抓https的数据包时,会一直弹出警告窗口。暂不影响使用,按下不表,网上也有一些途径。

把第一步抓到的包用wireshark打开,进一步分析。

典型的POST方法,其中有两个url参数。分别为g_tk和qzonetoken。以及一个url编码的表单数据,一目了然。

重点便可放在构造请求url上。js一塌糊涂所以选择上网上找前人的经验。很幸运

hashes = 5381
for letter in cookie['p_skey']:
    hashes += (hashes << 5) + ord(letter)
g_tk = hashes & 0x7fffffff

g_tk是通过登录成功后的cookie来算的。而qzonetoken可以从登录成功的网页源码中可以直接找到。

重点又到了登录上来。而登录过程的js加密更为复杂,网上现有的qqlib库也有很长一段时间没有更新了,最后选择Selenium模拟登录。

网上大多教程是Selenium配合Phantomjs,实际使用过程中发现selenium放弃了对Phantomjs的支持,遂选择Chrome进行开发调试,最后部署至服务器时添加headless Options即可。

由于选择的是移动版QQ空间,所以连UA也一并模拟了。实际上看来并不需要,电脑版的浏览器也可以直接打开移动版页面。

options = webdriver.ChromeOptions()
#设置中文
options.add_argument('lang=zh_CN.UTF-8')
#自定义ua
useragent = 'Mozilla/5.0 (Linux; Android 7.1.2; Redmi 4 Prime Build/NJH47F; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/60.0.3112.78 Mobile Safari/537.36url)'
options.add_argument(useragent)
#配置headless chrome
options.add_argument('headless')
#配置options
driver = webdriver.Chrome(chrome_options=options)

剩下便简单了,找到文本框输入账号密码,回车登录即可。

需要注意的是,频繁的登录会触发划动验证码,这也是我放置在服务器上的脚本执行失败报以下错误的原因。

Traceback (most recent call last):
File "/home/ali/qzone/newhello.py", line 90, in <module>
cookies, g_tk, qzonetoken = login()
File "/home/ali/qzone/newhello.py", line 46, in login
for letter in cookie['p_skey']:
KeyError: 'p_skey'

初步解决措施是把登录成功后的Cookie以及根据Cookie得到的g_tk和qzonetoken存入一个元组中,同过json模块将其保存至硬盘。

result = (cookie, g_tk, qzonetoken)
with open('data.json', 'w') as f:
json.dump(result, f)

在下次运行时,将其再次导入至程序中。

try:
    with open('data.json', 'r') as f:
        data = json.load(f)
    cookies = data[0]
    g_tk = data[1]
    qzonetoken = data[2]
except IOError:
    cookies, g_tk, qzonetoken = login()

事实上程序也是这么工作的。可毕竟人算不如天算,由于服务器ip对于常用的本地登录ip不同,所以也是很大几率会触发异常登录,弹出划动验证窗口。

本想直接做到底,顺带着把划动验证码给解决了,可是对Selenium还不太熟悉,加上对前端知识也不是太熟,导致难度略大。

最后灵机一动,通过ssh 代理的方式,来实现服务器ip代理访问QQ空间,相当于人肉解决验证问题。应该能顶一段时间。

不试不知道,又发现一个问题,可能是我多次触发验证又未解决,我在多次验证成功后,登录依然不能成功,故又尝试登录了QQ空间电脑版网页,之后再次访问移动端登录成功。

看来选择的移动端网页并不是百利而无一害。

滑动验证码留着以后解决。

定时任务很简单。需要注意的是我使用的是virtualenv,需要首先加载虚拟指定环境,另外crontab里的路径皆为绝对路径。

00 00 __ * /home/ali/qzone/py3/bin/python /home/ali/qzone/newhello.py » /home/ali/qzlog.txt 2>&1

最后完整代码附上

https://gist.github.com/jiefangjun/a680b8d9c932911247d91730323500ce

参考链接:

Selenium文档

用python爬取qq好友十万条说说并简单进行数据分析