Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
35 lines (22 sloc) 4.66 KB
title tags categories date
QQBot
Python
QQ
作品
网络
2015-10-13 16:27:52 -0700

好久没更新了,羞愧羞愧……写一下最近一直在搞的QQBot项目。

QQBot项目的目标是制作出QQ聊天库(虽然叫机器人,但目的只是制作有特定功能的机器人,并不含人工智能),也就是让程序能够收发QQ聊天消息。我很早以前就有过这个设想,但是直到前一段时间才真的见到了一个QQ机器人(科大魔方协会QQ群中的wca查询机器人),大呼“好棒”的同时终于下定决心动工。

首先,QQ这款软件有许多平台上的各种版本,使用着不同的网络传输数据的方式(“接口”),要在其中选择合适的一种,将我自己的程序伪装成相应的QQ客户端。简单划分的话,QQ的版本分为PC、手机、Web(曾经叫WebQQ,现在升级为SmartQQ)和3GQQ。PC和手机都是使用较为底层的协议来通信的,需要建立UDP或TCP连接,并且处理各种腾讯自己定义的数据包格式(需要在电脑上运行抓包软件来获取数据包,直接获取到的都是人类不可读的加密二进制数据,需要人工理解它的格式和编码方式)。而Web和3GQQ都是基于HTTP协议,HTTP之上是明文、人类可读的简单数据(加密靠SSL在HTTP的下层实现),比较容易处理,因此被选中作为我将要研究的版本。

要做机器人,首先要能让机器人登录上QQ。QQ登录一般就是提供号码和密码来验证,但有可能需要再输入一个验证码。如今一种新的方法是使用已经登录的手机扫描二维码来登录,这个方法的好处是不仅绝大多数情况下(我还没遇到过反例)不需要输入验证码,而且不需要把自己的账号和密码写进程序里,极大的提高了安全性。所以我选择了能够使用二维码登录的SmartQQ来研究。

好吧,另一个原因是,3GQQ不是HTML的,比较难搞,数据包截取的过程中出了一些问题,于是我可耻地失败了。

SmartQQ也蛮复杂的,所以我看了看几个主要过程(登录、获取好友列表及好友详细信息、检查是否有新消息、接收消息、发送消息)的逻辑流程后就打开了GitHub,搜索“SmartQQ”,fork了一个看起来不错的项目来用,并且装作自己是独立搞出了一个SmartQQ库。(稍后详细解释)

我的程序是Python2的,最初在自己的笔记本上运行了一段时间。之后我得知,科大有自己的云服务平台,并且每个学生都可以免费申请云主机,便迁移到了平台上运行。给自己的账号绑定的机器人在测试了一段时间后,由于不知道该让它干什么……现在已经关闭了。但为一个群专门制作的另一个功能性机器人效果很好,运行稳定。这些天的这个发展,群成员团结一致,同心同德,机器人的智商已经取得了很大的进步。

现在对于SmartQQ的一些流程总结如下,给想要做同样开发的人一些参考:

进行二维码登录流程,需要先获取一个appid(似乎永远是一个固定值?或许是SmartQQ这个接口所拥有的),然后到一个固定的地址获取二维码(jpg文件),唯一的变量是随本请求所返回的cookie。接下来带着这个cookie到另一个固定的地址轮询扫码状态,常见的结果为未扫描(再次询问)、已失效(重新下载)、已扫描(再次询问)或已登录(会获得一个较长的返回值,可以提取出QQ号码、昵称等信息,以及最重要的一些身份标识串)。最初我以为appid是不同的,用来标识身份的,所以让程序打印出二维码的地址,然后手动下载二维码。这样会导致程序在轮询状态阶段未发送cookie而遭遇403错误。

接下来可以请求好友列表、群列表,查询具体的好友/群信息,这些的接口都很简单,略过不提。

SmartQQ的一个坏处就是需要不断轮询,也就是每隔一会发送一个poll请求来查询最新接收到的消息。据我目前的了解,要实现“有新消息时收到通知”,也就是推送,似乎必须使用标准的QQ协议。每次poll到的消息是一个列表,其中一个需要注意的问题就是QQ系统使用“uid”作为用户/群的唯一标识,和QQ号/群号不同。如果需要换算,调用一个接口即可。

另外,SmartQQ会被认为是电脑登录,可以和手机并存,但是我还没发现它加载历史消息的接口,因此目前不知道该如何读取到自己的账号通过手机所发送的消息。这似乎不会在poll时产生一个消息提醒。

You can’t perform that action at this time.