序言
准备事情
剖析(x0)

剖析(x1)
剖析(x2)
剖析(x3)
代码
结语
序言
本人所有文章内容、源码,除官方企业外,禁止个人转载,感激合营。
....太多培训机构拿我的文章源码去讲公开课了,还有很多培训机构的招生员拿我源码自己编个小故事直接便是一篇文章(但凡这种都是一大堆废话+源码,毫无剖析逻辑)。
大家好,我叫善念。有大概一周没有来更新博文了,一个缘故原由是反响并不理想,第二个缘故原由则是每篇文章都是现写的,花费的韶光并不少。
实在我并不是非常想更新这篇文章,这样子会造成很多人利用我的办法,给大家带来一些生活上的小困扰,可是很多人又很想学,我只想说:技能无罪。
在这里至心感谢一贯在支持我的那几个粉丝,感激你们的持续关注点赞。
准备事情
利用到的模块
from selenium import webdriverimport jsonimport requestsimport execjsimport jsonpath
模块的安装
紧张利用到这五个模块,个中json为内置模块,其它均为第三方模块。安装办法如下所示:
pip install seleniumpip install requestspip install PyExecjspip install jsonpath
插件的安装
关于selenium这个模块,咱们来重点先容一下:
Selenium是一个用于Web运用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。
如果不能够理解我就讲点口语,如果你是web开拓职员,开拓好了几百个网站,那么如果你认为的去一个个的测试BUG,是不是很摧残浪费蹂躏韶光?而selenium这个框架便是用来仿照人去自动化操控浏览器的,那么是不是就节约了很多韶光呢。
既然selenium能够操控浏览器,那么它们之间必须要有一个桥梁,总不能无中生有吧?
那么操控的浏览器格局不一样,中间的桥梁也是不一样的。比如我更喜好用chrome浏览器,那么咱们须要下载一个selenium与Chrome的桥梁——Chromedriver插件
下载地址
下载与你当前谷歌浏览器版本最附近的Chromedriver
那么像我的话,下载
即可。
Windows系统需下载32位,其它的自己看着办。点进去下载win32即可。
那么如何让Python与selenium连接起来呢,这里咱们须要配置一个环境变量,便是把Python与selenium处于同一个目录:
到此为止,咱们的环境就搭建好了。
剖析(x0)
进入咱们的目标网站:目标网站
点击登录后点击群管理:
再点击成员管理,进入咱们的数据页面:
在这个页面可以看到有很多的群,我们随便点击一个就可以看到当群的成员数据:
可以看到咱们的群的号码实在就在当前网页的url中....不难想到它的url便是随咱们的群的号码变革的。
以此群为例,咱们看下网页源代码中是否包含咱们的数据,直接搜一下自己的号码即可,由于我自己是肯定在群当中的嘛:
emmm什么都没有,再去网页元素中看一下吧:
网页元素中是有的,一个tr标签保存了一个成员信息。不过我群里九百多个人,为什么右边的进度条这么粗....
解释什么?异步加载咯,常常说到得瀑布流,当我们拉动下滑条的时候才会刷新出更多得成员数据
明显看得到吧,当我们拉动下滑条后,元素中的元素变多了,那个进度条变短了。
剖析(x1)
那么就可以总结出来思路了,便是当我们用selenium仿照人打开一个浏览器,然后我们登录、点开群管理、找到须要采集的群点击(或者直接进入到当前群的url也是可行的)、末了便是拉动下滑条然后用selenium从网页元素上爬取数据咯。
该当不难明得吧,这实在便是我们刚才认为做的一个事情。我只是用selenium代替我们人去仿照这个事情再做一遍。
而我反复强调过:selenium的速率太慢太慢,只管即便不要去利用它!
那么怎么办?抓包呗,网页源代码中没有数据,而下拉滑动条后网页元素中涌现了该数据,不便是解释当我们拉动下滑条就实行了一些JavaScript脚本或者一些接口从而产生了数据?
数据也是不可能无中生有的,总有个来源,咱们监听下做事器与客服真个一个互换过程:
刷新当前网页抓包后,可以看到咱们抓的包当中天生了0-20便是21条数据,然后再看看这个包须要的参数:
是一个post要求,然后参数的话...gc貌似便是群的号码,然后st为0、end为20啥的估计便是说0-20统共21条数据吧,bkn......大头菜,明显不是一个韶光戳,按道理是JavaScript加密。
我们再拉动点滑动条往下面拉,再抓一个包看看有没有什么参数发生变革:
果真0-20便是代表一个数据的排序,比如我第一个包是0-20是前面的21条数据,那么第二个包当然便是21-41了。
果真,第三个包也是按21的步差来的,而sort为零不变,bkn也不变。
剖析(x2)
走吧,开始去剖析咱们的bkn是如何天生的:
上次有人问我,这个玩意该怎么搜...我这里见告你们了,先点一下那三个点,然后点击search:
可以看到就一个JS文件中包含bkn,切实其实完美了,事情变得越来越大略。
请不要碰着JavaScript加密就闹心,静下心来好好看看
o.data.bkn
o字典里面的data里面的bkn便是个嵌套而已,也便是解释bkn属于o字典里面的一个键,然后它居然赋值给了一个函数function,把稳看结尾用了一个()啥意思?
把把函数赋值给一个变量bkn,然后调用该函数。解释什么?bkn就为函数中return的值呀......是不是很大略?看不懂多看几遍。
函数里面的话便是个循环咯,当条件不知足时就一贯加,直到条件知足为止。看不懂可以去学学基本的JavaScript语法,不学也问题不大,咱们直接抠JavaScript代码也行。
for (var e = $.cookie("skey"), t = 5381, n = 0, o = e.length; n < o; ++n) t += (t << 5) + e.charAt(n).charCodeAt(); return 2147483647 & t
e为cookie中"skey"键所对应的值,o为e这个字符串的长度,n起始值为0.....居然都是已知数据,压根没有变量,那么咱们看看skey对应的值是啥:
彷佛问题是已经办理了吧,那么咱们来测试一下:
看下与咱们的post参数是否相同:
emmmmm,大功告成啦!
剖析(x3)
总结下思路:
1.利用selenium打开浏览器然后登录
2.获取cookies保存(后期用来解密bkn的)
3.解密JavaScript
4.发送post要求想要采集的群号
代码
JS代码:
function GetBkn(e) {for (t = 5381, n = 0, o = e.length; n < o; ++n) t += (t << 5) + e.charAt(n).charCodeAt();return 2147483647 & t}
Python代码:
#!/usr/bin/python3# -- coding: utf-8 --# @Time : 2019/6/02 21:44# @Author : 善念# @File : demo12.py# @Software: PyCharmfrom selenium import webdriver# from time import sleepimport jsonimport requestsimport execjsimport jsonpath# import sysdef get_cookies(): driver = webdriver.Chrome() driver.get('https://qun.qq.com/manage.html#click') driver.find_element_by_xpath('//[@id="headerInfo"]/p[1]/a').click() # sleep(5) input('上岸后请按Enter') cookie_list = driver.get_cookies() cookie = {} for i in cookie_list: cookie[i["name"]] = i["value"] with open("cookies.txt", "w") as f: f.write(json.dumps(cookie)) f = open("cookies.txt") # 字符串转字典 cookies = json.loads(f.read()) f.close() driver.close() return cookiesdef get_bkn(cookies): e = cookies['skey'] with open("gtk.js", encoding='utf-8') as f: jsData = f.read() js_text = execjs.compile(jsData) bkn = js_text.call('GetBkn', e) return bkndef get_data(bkn, cookies): headers = { 'origin': 'https://qun.qq.com', 'referer': 'https://qun.qq.com/member.html', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'same-origin', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.29 Safari/537.36', 'x-requested-with': 'XMLHttpRequest', } qq_group = input('请输入你要查询的QQ群号码:') offset = 21 max_num = [] for index, i in enumerate(range(0, 5000, offset)): data = { 'gc': qq_group, 'st': i, 'end': 20 + offsetindex, 'sort': '0', 'bkn': bkn, } req = requests.post('https://qun.qq.com/cgi-bin/qun_mgr/search_group_members', headers=headers, data=data, cookies=cookies).json() qq_numbers = jsonpath.jsonpath(req, '$..uin',) qq_names = jsonpath.jsonpath(req, '$..nick',) try: max_num.append(len(qq_numbers)) for QQ_number, QQ_name in zip(qq_numbers, qq_names): with open(qq_group+'.txt', 'a', encoding='utf-8')as f: f.write(str(QQ_number)+'@qq.com'+'\n') print('共得到成员数:%d' % sum(max_num)) except TypeError: exit()def go(): cookies = get_cookies() bkn = get_bkn(cookies) get_data(bkn, cookies)if __name__ == '__main__': go()
结语
当你毫无保留地信赖一个人,终极只会有两个结果,不是生命中的那个人,便是生命中的一堂课。
① 2000多本Python电子书(主流和经典的书本该当都有了)
② Python标准库资料(最全中文版)
③ 项目源码(四五十个有趣且经典的练手项目及源码)
④ Python根本入门、爬虫、web开拓、大数据剖析方面的视频(适宜小白学习)
⑤ Python学习路线图(告别不入流的学习)
私信
原创不易,再次感激大家~