1. 利用 Python 读取 QQ 消息
目录
- QQ机器人基础知识
- 前期配置
- QQ机器人实现代码
- 本次作业
1. QQ机器人基础知识
本教程使用 QQ 机器人的实现基于 NoneBot,而 NoneBot 有以下几点基本信息需要你了解即可:
- NoneBot 是一个基于 酷Q 的 Python 异步 QQ 机器人框架
- 酷Q实现了一个“无头QQ客户端”(无头就是,没有正常操作的 Windows(窗口)所有操作通过代码或命令行实现)
- 所有事件(收到消息、通知等)会通过传送给 酷Q 的HTTP API 插件
- https://nonebot.cqp.moe/guide/(NoneBot 文档,可以自行了解)
- NoneBot 仅支持Python 3.6.1+
- 仅限 Windows 系统,Mac 系统需安装虚拟机。(个人了解到的)
2. 前期配置
2.1 安装 NoneBot 使用如下命令:
pip3 install nonebot
运行结果:
clela@黄家宝 C:\Users\clela\Desktop
$ pip install nonebot
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
省略中间大部分信息
Installing collected packages: toml, priority, typing-extensions, hypercorn, aiofiles, Quart, hstspreload, rfc3986, sniffio, httpx, aiocqhttp, aiocache, nonebot
Running setup.py install for hstspreload ... done
Running setup.py install for aiocqhttp ... done
Running setup.py install for nonebot ... done
Successfully installed Quart-0.11.3 aiocache-0.11.1 aiocqhttp-1.2.3 aiofiles-0.4.0 hstspreload-2020.3.12 httpx-0.12.0 hypercorn-0.9.2 nonebot-1.4.2 priority-1.3.0 rfc3986-1.3.2 sniffio-1.1.0 toml-0.10.0 typing-extensions-3.7.4.1
如果像上面的一样,则安装成功。NoneBot 安装完了我们来安装 酷Q 。
2.2 安装 酷Q
Download_Link:https://cqp.cc/b/news
进入页面之后,我们能看见如下页面:
上面有三个版本,我们主要来看前两个版本,一个是 酷Q Air 5.15 ~ 轻盈,梦想,新生 ~,另一个是 酷Q Pro 5.15 这里我们使用 免费 般的酷Q Air,如果你需要更多功能自行选择 Pro 付费版本。
我点击 酷Q Air 之后,见到如下界面:
下载 酷Q Air 图灵版 或 小 i 版都可以,这里我选择下载图灵版本。我们下载完成之后,去安装一下插件。
悦创小提示:
版本区别:
图灵版 = 酷Q Air + 图灵机器人应用(官网)
小i版 = 酷Q Air + 小i机器人应用(官网)
2.3 安装 coolq-http-api
有以下几种下载方法:
方法一(推荐):
- 关注公众号:AI悦创,后台回复 QQ 机器人
- 把
io.github.richardchien.coolqhttpapi.cpk
放到 酷Q Air 的 App 文件夹里面 - **注意:**如果是从我从公众号下载的,解压完成之后。后面几步直接跳过,直接看第三步。
方法二:
- https://github.com/richardchien/coolq-http-api/releases
- 下载 io.github.richardchien.coolqhttpapi.cpk
- 放到 酷Q Air 的 app 文件夹里面
悦创提示:
注意如果 酷Q 启动时报错说插件加载失败,或者系统弹窗提示缺少 DLL 文件,请 参考:https://cqhttp.cc/docs/4.12/#/
上面 2.2 与 2.3 我们下载了所需要的 酷Q Air 图灵版和 coolq-http-api,接下来我带大家安装一下:
- 解压我们下载的 酷Q Air 压缩包,放到你自己的项目目录下。
- 将
io.github.richardchien.coolqhttpapi.cpk
放到 酷Q Air 的 app 文件夹里面
最终效果图:
3. QQ机器人实现代码
首先,在我们编写代码之前我们先运行 CQA.exe ,接下来按它的提示操作即可。
如果出现自动更新,让它更新即可:
勾选同意条款,然后点击确认:
点击确认即可:
登陆你的 QQ 号,悦创提醒你使用小号操作!
如果,需要验证,则自行验证:
登陆之后,会有一个悬浮框并且在工具栏会有图标。
注意:
我们一定要在任务栏该程序图标右键:应用 >>> 应用管理 >>> 启用 HTTP API,你如果不启用,光放插件时没有效果的。
全部选择允许即可,之后你会看见如下内容:
上面操作完了,我们就可以退出这个 酷Q 了。
3.1 配置 HTTP API
在 data/app/io.github.richardchien.coolqhttpapi/config/
下可以看到一个以你登录QQ号命名 的.json文件
打开该文件然后找到下面三个配置项
- ws_reverse_api_url
- ws_reverse_event_url
- use_ws_reverse
修改为如下内容:
"ws_reverse_api_url": "ws://127.0.0.1:8080/ws/api/",
"ws_reverse_event_url": "ws://127.0.0.1:8080/ws/event/",
"ws_reverse_reconnect_interval": 3000,
"ws_reverse_reconnect_on_code_1000": true,
"use_ws_reverse": true,
记得保存哦!
3.2 编写一个主启动程序
保存为 main.py,先载入内置的插件测试效果:
"""
project = 'Code', file_name = 'main', author = 'AI悦创'
time = '2020/3/16 0:01', product_name = PyCharm
# code is far away from bugs with the god animal protecting
I love animals. They taste delicious.
"""
import nonebot
if __name__ == '__main__':
nonebot.init()
nonebot.load_builtin_plugins()
nonebot.run(host='127.0.0.1', port=8080)
运行该文件并启动 酷Q 机器人,Python 程序确保已启动。
悦创提醒:
先运行 酷Q 并启动 Http API 然后再运行 Python 代码。
如果显示连接成功,就表明二则应该已经连接上了。
3.3 尝试一下给机器人账号发指令
用另一个账号给你登录的机器人账号发一条指令:/echo 你好,世界 机器人会给你回复一段相同的话
/echo 你好,悦创。
如果上面成功了,就表明你的机器人时成功的。接下来我们继续配置一下我们的项目。
3.4 配置我们的项目结构
新建一个 config.py
文件,放在和 main.py
同一个位置。
"""
project = 'Code', file_name = 'config.py', author = 'AI悦创'
time = '2020/3/16 0:18', product_name = PyCharm
# code is far away from bugs with the god animal protecting
I love animals. They taste delicious.
"""
from nonebot.default_config import *
SUPERUSERS = {123123123}
创建一个 MyBot 文件夹,在里面创建一个 plugins 文件夹 在里面创建一个 bot.py 文件
├── MyBot
│└── plugins
│ └── bot.py
├── main.py
└── config.py
3.4.1 修改 main.py 文件
加载我们的插件,尝试运行:
"""
project = 'Code', file_name = 'main', author = 'AI悦创'
time = '2020/3/16 0:01', product_name = PyCharm
# code is far away from bugs with the god animal protecting
I love animals. They taste delicious.
"""
import nonebot
import config
from os import path
if __name__ == '__main__':
nonebot.init(config) # 初始化
# 加载我们自己的插件
nonebot.load_plugins(
path.join(path.dirname(__file__), 'MyBot', 'plugins'),
'MyBot.plugins'
)
nonebot.run(host='127.0.0.1', port=8080)
加载我们的插件,尝试运行:
clela@黄家宝 C:\Code\pycharm_daima\交流群直播代码\QQ 机器人
$ Python main.py
ujson module not found, using json
msgpack not installed, MsgPackSerializer unavailable
[2020-03-16 00:35:49,645 nonebot] INFO: Succeeded to import "MyBot.plugins.bot"
[2020-03-16 00:35:49,646 nonebot] INFO: Running on 127.0.0.1:8080
Running on http://127.0.0.1:8080 (CTRL + C to quit)
[2020-03-16 00:35:49,657 nonebot] INFO: Scheduler started
[2020-03-16 00:35:49,664] Running on 127.0.0.1:8080 over http (CTRL + C to quit)
[2020-03-16 00:35:49,728] 127.0.0.1:58360 GET /ws/api/ 1.1 101 - 7978
[2020-03-16 00:35:49,735] 127.0.0.1:58361 GET /ws/event/ 1.1 101 - 4981
[2020-03-16 00:35:49,738] INFO in __init__: received event: meta_event.lifecycle.connect
[2020-03-16 00:36:02,679] ASGI Framework Lifespan error, shutdown without Lifespan support
从上面可以看见:Succeeded to import "MyBot.plugins.bot"
表示我们的插件成功导入,页正常运行。
3.4.2 修改 bot.py
找到我们在 plugins
文件夹中的 bot.py
文件,加入以下内容 :
"""
project = 'Code', file_name = 'bot.py', author = 'AI悦创'
time = '2020/3/16 0:30', product_name = PyCharm
# code is far away from bugs with the god animal protecting
I love animals. They taste delicious.
"""
import nonebot
bot = nonebot.get_bot()
@bot.on_message('private')
async def _(ctx):
print(ctx)
当你修改完你的程序,你可以使用 QQ 私聊消息,你将会在控制台看到有内容输出:
{'font': 6889288, 'message': [{'type': 'text', 'data': {'text': '你好,我是悦创'}}], 'message_id': 28, 'message_type': 'private', 'post_type':
'message', 'raw_message': '你好,我是悦创', 'self_id': 1423120581, 'sen
der': {'age': 1, 'nickname': 'AI悦创', 'sex': 'male', 'user_id': 1432803776},
'sub_type': 'friend', 'time': 1584317165, 'user_id': 1432803669}
我们可以看到这几点:
- raw_message:消息内容
- user_id:给你发私聊 消息的 QQ 号
那这时候有同学会问了,那群聊消息该如何处理呢?改成 group 就是群聊消息处理:
import nonebot
bot = nonebot.get_bot()
@bot.on_message('group') # 如果收到一条群聊的信息时,进入函数里面处理。
async def _(ctx):
print(ctx)
群聊消息将会看到有内容输出:
{'anonymous': None, 'font': 6889000, 'group_id': 813167307, 'message': [{'type': 'text', 'data': {'text': '测试用例'}}], 'message_id': 32, 'message_
type': 'group', 'post_type': 'message', 'raw_message': '测试用例', 'self_id':
1432803990, 'sender': {'age': 1, 'area': '法国', 'card': '', 'level': '潜水',
'nickname': 'AI悦创', 'role': 'owner', 'sex': 'male', 'title': '', 'user_id':
1432803990}, 'sub_type': 'normal', 'time': 1584318928, 'user_id': 1432803990}
- group_id:群聊号
- user_id:发消息的 QQ 号
- raw_message:具体的消息内容
当然,如果你不想创建群,你可以加入我的 QQ 群进行测试,QQ 群号:813167307,不知道同学有没有发现,我们得到的结果其实就相当于一个 Python 中的数据类型 字典(dictionary)可以直接用的。
3.5 处理加群消息
"""
project = 'Code', file_name = 'bot.py', author = 'AI悦创'
time = '2020/3/16 0:30', product_name = PyCharm
# code is far away from bugs with the god animal protecting
I love animals. They taste delicious.
"""
from nonebot import on_request, RequestSession
# 将函数注册为群请求处理器
@on_request('group')
async def _(session: RequestSession):
# 判断验证信息是否符合要求
if session.ctx['comment'] == 'aiyc':
# 验证信息正确,同意入群
await session.approve()
return
# 验证信息错误,拒绝入群
await session.reject('请说暗号')
3.5.1 接收新人入群消息
from nonebot import on_notice, NoticeSession
# 将函数注册为:群成员增加通知处理器
@on_notice('group_increase')
async def _(session: NoticeSession):
print('有新人来了')
4. 本次作业
编写一个Python程序,要求
-
读取QQ消息
-
将聊天内容储存到Excel表格中
-
根据不同人/群聊来创建不同的sheet,一个sheet对应一个人/群聊
2. 利用 Python 发送 QQ 消息
目录
- 发送消息
- 本次作业
1. 发送消息
1.1 发送私聊消息
bot.send_private_msg(user_id=对方QQ, message=具体消息)
@bot.on_message('private') # 如果收到一条私聊的信息时,进入函数里面处理。
# 实现在我们收到一条私聊消息的时候,它到底有哪些内容在里面呢?
async def _(ctx):
msg = ctx['raw_message']
user_id = ctx['user_id']
# bot.send_private_msg(user_id=对方的 QQ, message=对方具体的消息) 你在别的地方也是可以使用的
await bot.send_private_msg(user_id = user_id, message = msg)
print(ctx)
1.2 发送群聊消息
bot.send_group_msg(group_id=群号, message=具体消息)
@bot.on_message('group') # 如果收到一条群聊的信息时,进入函数里面处理。
async def _(ctx):
user_id = ctx['user_id']
# if user_id == 指定 QQ 号:
if user_id == ctx['user_id']:
group_id = ctx['group_id']
await bot.send_group_msg(group_id = group_id, message = "说的对")
1.3 欢迎新成员
对于有session的,可以直接session.send()
@on_notice('group_increase')
# 带类型的参数
async def _(session: NoticeSession):
await session.send("欢迎新朋友~")
1.4 发布群公告
bot._send_group_notice(group_id=群号, title=群公告标题, content=群公告内容)
注意_send_group_notice最开头有一个下划线
1.5 群组设置某人禁言
bot.set_group_ban(group_id=群号, user_id=QQ号, duration=秒为单位的禁言时间)
@bot.on_message('group') # 如果收到一条群聊的信息时,进入函数里面处理。
async def _(ctx):
user_id = ctx['user_id']
# if user_id == 指定 QQ 号:
if user_id == ctx['user_id']:
group_id = ctx['group_id']
await bot.send_group_msg(group_id = group_id, message = "说的对")
msg = ctx['raw_message']
if '傻瓜' == msg:
group_id = ctx['group_id']
user_id = ctx['user_id']
await bot.send_group_msg(group_id=group_id, message=f"{msg}你不良言行,已经被禁言!")
await bot.set_group_ban(group_id = group_id, user_id = user_id, duration = 15*60)
1.6 群组踢人
bot.set_group_kick(group_id=群号, user_id=要踢的人QQ号, reject_add_request=是否不允许再加群)
@bot.on_message('group') # 如果收到一条群聊的信息时,进入函数里面处理。
async def _(ctx):
user_id = ctx['user_id']
msg = ctx['raw_message']
# if user_id == 指定 QQ 号:
group_id = ctx['group_id']
if user_id == ctx['user_id']:
await bot.send_group_msg(group_id = group_id, message = "说的对")
if msg == '傻瓜':
await bot.send_group_msg(group_id=group_id, message=f"{msg}你不良言行,已经被禁言!")
await bot.set_group_ban(group_id = group_id, user_id = user_id, duration = 15*60)
if msg == '退群':
await bot.set_group_kick(group_id = group_id, user_id = user_id, reject_add_request = True)
2. 本次作业
定时群发公告机器人,编写一个Python程序,要求
-
程序启动后从 group_notice.json 文件中读取要群发的群号及群公告 内容
-
按照指定时间定时发送(比如每周一三五下午三点)
悦创提示:如需要完整代码,关注公众号:AI悦创,后台回复: QQ机器人