Python爬虫之QQ空间登陆获取信息!不忍直视啊!

一、背景:前几天收到了一个需求:获取QQ好友,QQ群,QQ群友的账号。但是我却抓不到QQ程序的包就很尴尬,我觉得应该是QQ程序之间的通讯协议大部分不是HTTP或者HTTPS,而我用的是Fillder所以找不到包,但是不影响我完成需求的进度,我找了QQ的大部分相关应用,最后在QQ空间找到了能满足这个需求的数据,于是我换了个思路和方法,去QQ空间里面抓数据。

Python爬虫之QQ空间登陆获取信息!不忍直视啊!_第1张图片

二、分析: QQ空间一般是两种登陆方式:一是账号密码登陆,二是扫码登陆,领导要求的是扫码登陆,于是我就做扫码登陆把。

经过反复抓包查看数据,发现登陆的相关接口有下面这几个(先记着后文中不使用连接而使用接口名字):

https://xui.ptlogin2.qq.com/cgi-bin/xlogin 登陆页面

https://ssl.ptlogin2.qq.com/ptqrshow 二维码图片

https://ssl.ptlogin2.qq.com/ptqrlogin 登陆校验

首先,我们分析下登陆校验需要哪些参数(因为最容易发现,一进去就一直在等待校验):

Python爬虫之QQ空间登陆获取信息!不忍直视啊!_第2张图片

经过反复抓包测试,发现所需要的不定参数:ptqrtoken,action,login_sig。一眼就可以看出action是一个时间戳拼接字段,而其他的两个字段应该是进入页面请求时候设置的cookie值,通过全局搜索字段发现login_sig就是登陆页面的pt_login_sig。

然后,去访问登陆页面获取cookie中的pt_login_sig对应的值,多次抓包发现接口的参数是固定的:

Python爬虫之QQ空间登陆获取信息!不忍直视啊!_第3张图片

至于,ptqrtoken全局搜索会发现一个c_login_2.js的js文件,到preview视图格式化js代码查找ptqrtoken会发现有下面这样一段代码:

很明显,他的意思就是get某个cookie中的qrsig字段,然后进行hash33加密,先全局找下qrsig,发现二维码图片的cookie中有这个字段,获取字段的同时把二维码保存下来,这个接口除了一个参数是0-1之间的随机数其他的都是固定的。

再全局找下hash33加密过程,结果还是在c_login_2.js这个文件中找到以下代码段:

Python爬虫之QQ空间登陆获取信息!不忍直视啊!_第4张图片

把js代码转换为python代码:

    def __decrypt_qrsig(self, qrsig):

        e = 0

        for c in qrsig:

            e += (e << 5) + ord(c)

        return 2147483647 & e

以上代码主要对qrsig的值进行逐个转换返回 ASCII 数值,然后和e每次计算结果左移5个单位进行相加,每次计算都要转换为二进制。

OK,最终经过加密之后的返回结果就是我们所需要的ptqrtoken了

最后,我们带上不变的参数、构造的action、获取到的login_sig和破解后的ptqrtoken去访问登陆校验就行了,不难发现登陆校验是一个循环,所有我们程序设计的时候也要写一个循环。

以上就完成了QQ空间登陆了,接下来获取QQ好友等信息了:

我们登陆之后url发生一次重定向请求下重定向的地址,发现返回的内容信息没有一个

使我们想要的。于是再次反复抓包,发现所要的数据都保存在了三个js文件中(先记着后文中不使用连接而使用接口名字):

https://user.qzone.qq.com/proxy/domain/r.qzone.qq.com/cgi-bin/tfriend/friend_ship_manager.cgi QQ好友

https://user.qzone.qq.com/proxy/domain/r.qzone.qq.com/cgi-bin/tfriend/qqgroupfriend_extend.cgi QQ群

group_friend = 'https://user.qzone.qq.com/proxy/domain/r.qzone.qq.com/cgi-bin/tfriend/qqgroupfriend_groupinfo.cgi QQ群友

首先,观察QQ好友的接口:

Python爬虫之QQ空间登陆获取信息!不忍直视啊!_第5张图片

uin,rd,g_tk(接口需要两个,实际给一个就够了)三个字段在变化,其中uin就是用户的QQ号,rd是一个0-1之间的随机数,g_tk是一个加密后的数值,uin其实就在登陆之后的cookie的uin对应的值中,g_tk全局查找会在一个qzfl_v8_2.1.65.js文件中找到

他,而这里面出现了大量的**“g_tk=” + QZFL.pluginsDefine.getACSRFToken(参数)**,于是就去找找看这个js函数到底做了什么:

Python爬虫之QQ空间登陆获取信息!不忍直视啊!_第6张图片

这里大概就是获取p_skey这个cookie对应的值然后return arguments.callee._DJB,找到_DJB对应的函数:

Python爬虫之QQ空间登陆获取信息!不忍直视啊!_第7张图片

这个函数刚才分析ptqrtoken字段的时候分析过了,这里就不做赘述了。最后我们就可以得到g_tk值了,就可以请求QQ好友接口获取想要的信息了。

然后,观察QQ群友接口:

Python爬虫之QQ空间登陆获取信息!不忍直视啊!_第8张图片

uin,gid,g_tk

这上参数在变,而uin和g_tk之前已经获取过了,剩下的就是gid了,而如果要找一个方法来群发一个群里面的群友,我自己唯一想到的是群号,于是去找QQ群信息,果然在QQ群接口中找到了所有gid对应的值,即就是QQ群接口返回的groupcode对应的值。

最后,观察QQ群接口:

Python爬虫之QQ空间登陆获取信息!不忍直视啊!_第9张图片

uin,rd,g_tk这上参数在变,而前面获取好友的时候分析过了,我就不再赘述。OK,获取到群信息之后我们就可以成功获取到所有不是好友的群友了,注意是不是好友的群友,如果要获取一个群的所有成员还有其他方法获取,只要认真观察就能发现新大陆。

三、实现

OK实现部分就不贴代码了,感兴趣的同学可以去我的github上面查看源码:

github地址

四、结束

获取空间的其他信息也是一样的方法哦。

我自己刚入IT行不久,如果有什么地方理解不到位的欢迎指出,欢迎各位留言。

著作权归作者所有,如有侵权联系小编删除!

原址:https://blog.csdn.net/xiaoxin_OK/article/details/107683555

你可能感兴趣的:(Python爬虫之QQ空间登陆获取信息!不忍直视啊!)