前言

最近在公司和同事一起处理问题的时候,发现他的 QQ 群消息提醒,QQ 群的名字很熟悉,于是我回到自己工位看了下自己的 QQ,发现我们在一个技术群里面。这就很尴尬了,之前没少在这群里吹牛,都被我同事静静的看着。

我看了下,我有近 100 个 QQ 群,为了避免以后有类似的尴尬,我想到能不能写一个工具来查询这些群里面有哪些是我的好友。

QQ 登录授权

要获取相关数据,肯定是要先登录授权的。找到了 QQ 群的官方网站 https://qun.qq.com/,打开开发者工具-网络,然后再进行登录进行网络请求查看。

发现不少参数是通过计算后得到的,而且登录时大概率是会遇到验证码的。

考虑到这类工具的特点,所以首选直接通过 WebBrowserhttps://qun.qq.com/打开,手动登录后,再去获取相关 cookies 等数据信息即可。

但今天稍微改变下,还是通过WebBrowserhttps://qun.qq.com/打开,不过WebBrowser是完全隐藏不可见的。

我们自己搞一个界面,把输入的账号密码传递给 WebBrowser,再进行登录操作,如果遇到验证码,再把验证码传递回来,在自己的界面输入后再给到 WebBrowser 完成登录。

最终的登录界面如下:

获取相关数据

通过一段时间的探索,在 QQ 官方网站里面,找到了相关接口:

获取好友列表和群列表

1
var url = $"http://user.qzone.qq.com/p/r/cgi-bin/tfriend/friend_show_qqfriends.cgi?uin={Account}&follow_flag=0&groupface_flag=1&fupdate=1&g_tk={Gtk}&callbackFun=GetGroupAndFriends";

获取一个群的群成员

1
var url = $"http://qun.qzone.qq.com/cgi-bin/get_group_member?uin={Account}&groupid={groupId}&g_tk={Gtk}&callbackFun=GetGroupMember";

上面的 Gtk 的生成方式参考代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public int GetGtk(List<Cookie> cookies)
{
int gtk = 0;
foreach (var item in cookies)
{
if (item.Name == "skey")
{
int hash = 5381;
string str = item.Value;
for (int i = 0, len = str.Length; i < len; ++i)
{
hash += (hash << 5) + str.ElementAt(i);
}
gtk = hash & 0x7fffffff;
}
}
return gtk;
}

因为一次只能获取到一个群里的成员,需要调用很多次接口,所以再加了一个加载界面:

数据展示

使用的 echarts 简单的展示出来,鼠标放在圆点上会显示出好友名称或 QQ 群名。

仔细看了上面的数据,得到以下一些数据:

  • 有几个朋友从小学、初中到高中都在一个班级上学。
  • 还有一位朋友甚至还是同一所大学,虽然交流的很少。
  • 还有一位网友,从多个.NET 技术群到多个前端技术群都有他。
  • 最关键的来了,查出 3 名现在公司的同事在不同的技术群里。于是我给这几个技术群的群名备注了下,完美解决了问题。