初级PHP工程师决战千人QQ群成员信息获取

PHP,网站动态编程语言。

有一天,你入职了一家很大的公司,人事很快就把你拉入公司千人QQ工作群。上级给你布置了一项任务,他想要知道群里所有人QQ号、昵称和部门的关系。

oh,导出EXCEL员工QQ号信息表,我懂,这很简单。于是你打开QQ群,开始对着群成员列表疯狂复制粘贴进EXCEL,当你复制了几百个的时候,发现这群特么1000多人,还有一半没做完...woc,好像有几个人昵称复制错了Orz

作为一名初级工程师,键盘上Ctrl+c、v就要被你按烂了,你的怨念值在上升。你想到了尝试网上各种导出QQ群成员信息工具。于是找啊找,终于找到了那么一两个,可惜公司内网限制下载,好不容易下载安装,一打开还被提示植入病毒,公司电脑不敢瞎搞,只有老实复制粘贴吧!

旁边工位的老程序员老牛实在看不下去了,这很不Professional。喂,那个小白啊,你来在我这登下你的QQ,8分钟后桌面冒出个7.47MB的excel.xlsx文件,小白激动的打开,哇靠——几万条QQ信息,竟然是全公司全集团的所有人的QQ号啊,超乎想象。

小白:老牛我——爱—你

老牛:滚,不搞基

数天后...

教教我嘛,经过小白多日的软磨硬泡,外带非要请吃饭一周,老牛终于答应教小白了——那个,你就当有腾讯高级工程师给你写好了数据接口,现在需要你来对接,用程序登录授权,访问接口拿到数据,这样能理解了吧。我呢尽力给你讲详细点,但可能你是听不懂的,明白一点是一点。实在看不懂就分享给别人虐吧,请吃饭就不用了

出师—程序的诞生➳

①发现

对于你加入的任何一个QQ群(即使不是群主或管理员),你都可以看到其他成员的基础信息。例如:

看到这个页面,初级工程师想到的第一方案是让程序访问这个页面,获取页面HTML字符串,进行文档结构解析。经过进一步的操作分析,我们采用更好的方案——页面中成员信息就是AJAX异步加载的,前后端分离、接口。继续刷新当前页面,通过火狐浏览器F12可查看信息

随着页面下拉,浏览器AJAX异步发出数据请求,以st为起点,end为终止,每次获取20条数据。

[下拉刷新查看数据-gif]

太棒了,这里的数据就是通过访问接口获取的,不需要从页面HTML解析数据。也就是说我们只要模拟浏览器访问,通过接口就可以获取到JSON类型的数据。思路就是这样,但其实还有很多琐碎的工作需要完成和理解。

(针对本文的简要名词解释)

接口:访问一个页面URL地址,例如xxx.com/api/get_member ,页面返回一段字符串,这段字符串以(参数:值)的JSON格式呈现,返回数据。

②获取请求头

我们通过人工安全登录让浏览器就获得Cookie,程序将直接使用,通过火狐浏览器F12监控页面XHR,提取出请求头,Cookie也在其中。这样程序就可以像人工打开浏览器登录该页面一样,通过Cookie验证身份请求数据。

[获取请求头信息-gif]

完整的请求头信息参考:

注意POST之后的地址是需要根据接口不同变化的,另外一些参数我们在程序中是不需要使用的,

在PHP实际的程序中用到的:

以上信息表示:发起请求是64位win10系统的Firefox浏览器,我们设置将其中Cookie设置为参数$Cookie(键值对字符串),其他信息可以认为是固定的(首行POST地址实际是根据接口变化的)。所以只要获得登录后的Cookie,就能用程序模拟浏览器发出请求并且具有访问接口的权限。

请求头的部分已经完成了,通过F12浏览器开发者工具,也可以看到XHR传递到不同接口的参数,下面将详细说明。

③接口分析

现在我们需要分析上面JSON字段的含义,我们只用到其中两个接口,都需要Cookie,通过手动操作QQ登录后授权带参访问它,获得正确的JSON数据。

经过对字段的分析,在数据库中设计两个表qqGroup、qqMember来对接以上数据,我们尽可能保持字段命名的一致性。COMMENT注释中说明了字段的含义,后面的一些字段是为了方便查阅数据自定义追加的,用空行隔开了。

④程序实现思路

首先通过人为手动安全登录QQ,获取bkn和Cookie。其次,我们st设置为0,end直接设置为4000一次获取所有接口数据(虽然不够完美但省去每次20条分页循环),然后需要制定一个QQ群测试一下配置是否有效,然后就可以正式行动。有n个群,就需要反复修改n次QQ群号码。不,继续用程序获取所在QQ群列表,以这个列表为基础数据,循环去请求所有群内成员信息。

⑤程序清单

set.php中:

mycurl.php中:

已知异常返回JSON说明:

到这里所有的编程知识都交给你了。

喝口100ml的纯净水,需要休息好一会。

到这里我也是身感疲惫的,知识点和细节说明非常消耗元气。传道受业解惑,确实任重而道远。专心写文档比程序还难,尤其是程序之后的,想象完成后的神清气爽、如沐春风,为了信仰必须继续,可能吸引到同行小伙伴。中途休一天。

进击—数据会说话➳

⑥数据测试

我们发现最终的成员信息是少于每个群基本信息求和的,上面就相差了1670条。这个结果其实是意料之中的。对于一个真实成员4581人的群,理论只能查阅其中4000人的信息:

在成员管理界面,滚动条拉倒底恰好是4000,不再变化。

是接口设计如此吗?

所以对于一个超过4000人的群,理论上依靠接口仅能获取其中4000条信息,那我们来实际测试下一个4581人的群:

为什么会有事3971,接下来尝试几组参数

根据分析,将目光投向第二组测试数据

st=3972 到 end= 4000 ,应该获取28条,实际只有26,缺少2条。

难道是插入出了问题?我们观察到页面

其实我们的数据库和表字符集一开始已经是utf8mb4,网络上说了一大堆的修改,从MySQL配置my.ini到数据库再到改到表字符集。对于我们这个项目,其实只用改动插入类中设置的字符集即可。因为储存字符集已经是utf8mb4,所以只用传递也设置为utf8mb4就能正常插入。

那些缺失的数量都是由于名字含有特殊符号或表情导致的插入错误,满满的4000,这下圆满了。

至于怎么获取另外的581人,答复为接口设计如此。个人猜测可能开发版本较早,没有想到后来还有超过4000人的QQ群。对于4000人以上的群,部分成员管理从名单溢出,不知道这算不算BUG。另一方面,日常中很少会进到那个管理页面,在QQ群成员面板都可以进行大部分操作,所以完美改进的必要性似乎也很低。

⑦查询SQL

⑧总结

通过对页面的分析,我们知道QQ成员管理是前后端分离开发模式下的产品。前端发起请求,后端响应请求返回JSON数据,页面通过下拉刷新的方式加载数据。我们利用手动登录,拷贝Cookie和相关浏览器信息,让程序模拟浏览器请求数据,最终将公开可见的数据信息,依靠程序能够自动获取。

在这个过程中的很多工作,都是在做黑盒测试,因为我们对接口参数请求规则一无所知,是一个反复尝试求证的过程。另外呢程序其实还有不少需要改进的地方,一个是数据库批量插入,针对单条记录的插入在批量执行时存在重复操作;还有一个是程序是半自动的执行的,需要更加智能化自动获取Cookie的操作。那么,剩下的无尽的探索和发现就由你尽情发挥。have fun

以上。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180406G1AFQ600?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券