qq好友列表获取之动态爬虫清洗爬取好友列表数据 - 获取qq好友、群、群成员列表
qq好友列表获取之动态爬虫清洗爬取qq好友列表数据 - 获取qq好友ip、群、群成员列表。我们的好友列表要从 qzone 获取,现在打开 qzone 的链接 https://h5.qzone.qq.com/mqzone/index 并且登陆。
具体步骤:
1、分析qzone请求
2、分析参数来源
3、仿照数据请求
上次写的一个qzone登陆写的不详细这次决定写一个详细分析qzone js 获取好友列表
分析qzone请求
我们的好友列表要从 qzone 获取,现在打开 qzone 的链接 https://h5.qzone.qq.com/mqzone/index 并且登陆。
你可能会说你在逗我,这特么哪里来的qq好友列表
别急,好友列表肯定是有的不然你发表说说怎么@你的好友呢
说到@好友都明白了吧,我们的好友列表接口就从这里开始拦截接口请求。
先把打开我们发说说的那个框框,再把浏览器开启调试模式,清空网络请求拦截列表
现在你应该在发说说的那个界面,点一下说说框下面的 @符号
盯住网络请求那一块,找一下那个像是获取好友列表的,发现一共就6个请求,我一眼就看到了mfriend_list 接口意思很直白啊
qq好友列表已经找到,接下来就是分析参数了,这个过程很痛苦
分析参数来源
首先点我刚刚说到的那一条请求记录 就是这样子的 我对自己的qq号打了码毕竟这个东西获取到可以直接用cookie登陆的
这里可能有人会说,为什么不直接点击拦截列表上面有个可以定位js发出请求的位置,这样找分析请求参数不是更简单吗
这边呢我只能说我之前也找过,但是找不到获取同行qq好友的软件,因为点击过去找到的是封装类的位置。
这边参数呢不多 六个 需要分析的就两个
qzonetoken c2176b5d6f0deff03d0dd0f59f26e51c2b408aa83419d416c737cc1b21d1e913c861ca780ad34ff4293ca5640b69
g_tk:1760587213
res_uin:***
res_type:normal
format:json
timestamp 时间戳
我们现在看一下这个 qzonetoken 使用全局搜索找一下看是不是写在静态页面中的
继续搜索 window.shine0callback
发现都是一个结果。。。。 后面我试着搜索一下html 里面 发现竟然真的有
window.shine0callback = 自执行函数
所以呢 qzonetoken 参数直接用 window.shine0callback 就好了
继续全局搜索 g_tk
这边呢有三个方法获取token
1、userHelper.getPskeyToken()
2、userHelper.getToken()
3、user.getToken()
我们先在控制台执行一下这些方法
发现 user 能执行也和请求的参数对上了,不过我还是想找一下 userHelper 这个东西
先把ajax.js 这个类给弄到本地来 搜索 userHelper
既然写在里面的那copy到控制台就可以执行了。这个不同微信好友列表获取的方式。
开始我把 userHelper copy进去发现少了一个getCookie,再把getCookie 也复制到控制台就好了
这样子执行就能获取到 token 了
res_uin qq号码,我在搜索静态html的时候无意间发现了可以从 FrontPage 对象中获取,当然也可以从 user 对象中获取
res_type 固定normal
format 固定json
timestamp 时间戳拿一下系统时间戳就好。
现在参数都分析完毕,qzone 的接口分析还是蛮简单的,不像某宝网站的程序
仿照数据请求
找到 paresHtml 函数 在这里先切换到默认窗口
def paresHtml(self):
self.driver.switch_to.default_content()
获取 qzonetoken 这边直接执行window.shine0callback 就能获取
qzonetoken = self.driver.execute_script('return window.shine0callback')
获取 g_tk 上面说到user里面可以直接获取,那我们就偷个懒使用 user.getToken()
g_tk = self.driver.execute_script('return user.getToken()')
获取 res_uin 直接从user 里面 getUin()
res_uin = self.driver.execute_script('return user.getUin()')
获取时间戳 由于python 中的time.time()是秒,需要乘个1000
import time
timestamp = time.time() * 1000
拼接url
list = 'https://mobile.qzone.qq.com/friend/mfriend_list?' \
'qzonetoken=%s&g_tk=%s&res_uin=%s&res_type=normal&format=json×tamp=%d' % ( qzonetoken, g_tk, res_uin, timestamp)
本身我想偷懒的直接用 self.driver.get() 直接执行的 后来想想还是算了,没有一点技术含量的东西怎么好意思写呢
最后决定使用js中的XMLHttpRequest 来模仿请求
self.driver.execute_script('window.xhr = new XMLHttpRequest;')
self.driver.execute_script('window.xhr.withCredentials=true;')
self.driver.execute_script(
'window.xhr.open(\'GET\',\'%s\',false)' % list)
self.driver.execute_script('window.xhr.onload = function (e){window.xhrsuccess = window.xhr.responseText}')
self.driver.execute_script('window.xhr.send()')
print(self.driver.execute_script('return window.xhrsuccess'))
请求完成后的结果是这个样子的
下面是请求返回的结果
{
"code":0,
"subcode":0,
"message":"",
"default":0,
"data":{
"gpnames":[//分组列表
{
"gpid":0,//分组id
"gpname":"agp"//分组名称
}
],
"list":[//好友列表
{
"groupid":0,//分组id
"isvip":1,//是否是vip 1 是 vip
"nick":"消费主张", //昵称
"remark":"消费主张",//备注
"searchField":"12315 消费主张 消费主张 xiaofeizhuzhang xfzz xiaofeizhuzhang xfzz",//关键字
"uin":12315,//qq号码
"viplevel":1 //qq等级
}
],
"mayknow":{
"allnum":0,
"list":null,
"page":1
},
"speciallist":null
}
}
最后发一下模仿请求的源码 结合我上一篇文章的源码可以直接执行出结果,也可以获取qq好友ip
import time
def paresHtml(self):
# 切换到默认窗口
self.driver.switch_to.default_content()
# 请求状态
shine0callback = self.driver.execute_script('return window.shine0callback')
# 一定要暂停一下不然 执行user的时候拿不到,因为懒加载
time.sleep(1)
g_tk = self.driver.execute_script('return window.user.getToken()')
uin = self.driver.execute_script('return window.user.getUin()')
timestamp = time.time() * 1000
list = 'https://mobile.qzone.qq.com/friend/mfriend_list?' \
'qzonetoken=%s&g_tk=%s&res_uin=%s&res_type=normal&format=json×tamp=%d' % (
shine0callback, g_tk, uin, timestamp)
# self.load_cookies()
# self.driver.get(list)
self.driver.execute_script('window.xhr = new XMLHttpRequest;')
self.driver.execute_script(
'window.xhr.open(\'GET\',\'%s\',false)' % list)
self.driver.execute_script('window.xhr.onload = function (e){window.xhrsuccess = window.xhr.responseText}')
self.driver.execute_script('window.xhr.send()')
print(self.driver.execute_script('return window.xhrsuccess'))
总结:
1、qzone 里面的接口参数都差不多,总归来讲都能搜索出来
2、qzone 压缩了js提高了分析的难度
3、好友列表模拟请求时记得把cookie带过去否则t不认
4、有时候登陆会登不上,拿到的好友列表数据是请先登录,删掉cookie重试即便就好
更多:qq好友列表获取
上一篇: Android组件化开发
下一篇: 移动开发之手势与双指缩放