适用于 Yunzai 的 QQ 空间自动点赞插件。插件通过 Playwright 扫码登录 QQ 空间,保存多账号登录状态,并由本地 Python 服务持续拉取好友动态、跳过已点赞内容后自动点赞。
主要面向 Miao-Yunzai v3;源码中提供了 TRSS-Yunzai 的插件基类路径兼容处理,实际可用性仍取决于所使用的 Yunzai 版本和 QQ 协议端。
Important
自动化访问和点赞可能触发 QQ 风控,也可能受到平台接口变更影响。请仅操作本人或已获得明确授权的账号,自行控制频率并承担使用风险。严禁将本项目用于骚扰、刷量或其他违法违规用途。
- 扫码登录 QQ 空间,无需手动填写 Cookie
- 支持多个 QQ 账号同时运行,每个账号使用独立工作线程
- 自动抓取空间动态,只对明确识别为“未点赞”的内容执行点赞
- 白天和夜间使用不同的轮询、点赞间隔,并加入随机等待
- 支持请求重试、异常退避、账号熔断和 Python 服务崩溃自启
- 支持持久暂停、恢复和确认删除账号;暂停状态在重启后仍然有效
- 查询单账号或全部账号的运行状态、成功率和最近错误
- 支持 Dry Run,只解析动态而不点赞
- 可向指定运维群发送登录、下线和线程状态通知
- Python API 仅监听
127.0.0.1,首次启动自动生成独立鉴权密钥 - 默认仅主人可以添加账号,支持群白名单、私聊二维码及扫码账号一致性校验
- 登录结果采用短轮询,不会长期占用 Python Web 服务线程
- Miao-Yunzai v3,或兼容其插件 API 的 Yunzai 分支
- Node.js 运行环境由 Yunzai 提供
- Python 3.10 或更高版本
- Python 依赖:
requests、beautifulsoup4、Flask、waitress、playwright - Playwright Chromium 浏览器
将整个插件目录放入 Yunzai 的 plugins 目录,确保文件结构如下:
Yunzai/
├─ lib/
└─ plugins/
└─ Yunzai-MZ-plugin/
├─ mz_qzone.js
├─ mz_qzone_server.py
├─ requirements.txt
└─ configs/
└─ mz_qzone_config.json
不要只复制 mz_qzone.js,Python 服务和 configs 目录也需要保留。
Windows:
python -m pip install -r requirements.txt
python -m playwright install --no-shell chromiumLinux:
python3 -m pip install -r requirements.txt
python3 -m playwright install --with-deps --no-shell chromium插件会从 Yunzai 进程的 PATH 中查找 python、python3 或 Windows 下的 py。如果 Yunzai 由 PM2、systemd、Docker 或虚拟环境运行,请确保依赖和 Chromium 安装在该服务实际使用的 Python 环境及系统用户下。
Playwright 更新后可能需要重新执行浏览器安装命令,详见 Playwright Python 浏览器安装文档。
编辑 configs/mz_qzone_config.json,至少完成以下操作:
- 保持
auth_key为空,让插件首次启动时自动生成configs/.auth_key。 - 默认
allow_user_login=false,只有主人能够添加账号;如需开放,请同时配置allowed_group_ids。 - 将
notify_group_id改为自己的运维群号,并按需开启通知开关。 - 按账号数量和风控情况调整轮询与点赞间隔。
配置在服务启动时读取,修改后需要重启 Yunzai 才会生效。
按当前部署方式重启 Yunzai,然后发送:
#mz登录
默认情况下,群聊发起登录后二维码会私聊发送。请先添加机器人好友,并在配置的登录超时时间内使用指令指定的 QQ 扫码;扫码账号不一致时登录会被拒绝。
指令无需主动 @ 机器人;如果协议端或 Yunzai 本身配置了必须 @,则以其配置为准。
| 指令 | 权限 | 说明 |
|---|---|---|
#mz帮助 |
所有人 | 查看插件帮助 |
#mz登录 |
主人;或配置允许的用户 | 为自己的 QQ 扫码登录并启动任务 |
#mz登录 <QQ> |
主人 | 代指定账号发起登录,也支持 @某人 |
#mz结束登录 |
主人;或配置允许的用户 | 结束自己的当前登录流程,并清除本次二维码冷却 |
#mz结束登录 <QQ> |
主人 | 结束指定账号的登录流程,也支持 @某人 |
#mz状态 |
所有人 | 查询自己的运行状态 |
#mz状态 <QQ> |
主人 | 查询指定账号状态,也支持 @某人 |
#mz状态 all / #mz状态 全部 |
主人 | 查询所有已保存账号的状态汇总 |
#mz下线 |
所有人 | 持久暂停自己的点赞任务 |
#mz下线 <QQ> |
主人 | 持久暂停指定账号,也支持 @某人 |
#mz下线 all / #mz下线 全部 |
主人 | 持久暂停全部已保存账号 |
#mz恢复 |
所有人 | 恢复自己的已暂停账号 |
#mz恢复 <QQ> |
主人 | 恢复指定账号,也支持 @某人 |
#mz恢复 all / #mz恢复 全部 |
主人 | 恢复全部 Cookie 仍有效的账号 |
#mz删除账号 确认 |
所有人 | 停止自己的任务并删除本地登录凭据 |
#mz删除账号 <QQ> 确认 |
主人 | 删除指定账号的本地登录凭据 |
#mz测试 [QQ] |
主人 | 抓取一次动态并输出预览,不执行点赞 |
非主人不能操作其他人的 QQ。默认不允许非主人添加账号;开启 allow_user_login 后,普通用户登录仍受以下限制:
- 同一群每分钟最多发起 3 次登录请求。
- 同一 QQ 两次获取二维码之间默认间隔 60 秒。
- 同一 QQ 同时只能存在一个登录流程。
- 全局并发登录默认最多 2 个,已保存账号默认最多 10 个。
Note
#mz下线会将账号持久标记为暂停,重启后不会自动恢复;使用 #mz恢复重新启动。只有带“确认”的 #mz删除账号会删除本地 Cookie 文件。
配置文件:configs/mz_qzone_config.json
| 配置项 | 默认值 | 说明 |
|---|---|---|
port |
38888 |
Node.js 与 Python 服务通信端口,仅监听本机;冲突时只尝试后续端口,不会结束占用进程 |
auth_key |
"" |
兼容旧版手动密钥;留空时使用自动生成且被 Git 忽略的 configs/.auth_key |
http_retry_count |
3 |
请求 QQ 空间接口时的重试次数 |
http_timeout |
10 |
Python 请求超时,单位为秒 |
node_api_timeout_ms |
8000 |
Node.js 调用 Python API 的超时,单位为毫秒 |
node_api_retry |
2 |
Node.js 调用 Python API 的重试次数 |
max_restart_count |
5 |
滚动时间窗口内允许的 Python 服务自动重启次数 |
restart_window_seconds |
600 |
统计 Python 服务崩溃次数的滚动窗口秒数 |
stable_uptime_reset_seconds |
300 |
服务稳定运行达到该时长后清空旧崩溃记录 |
round_sleep_error |
15 |
单账号任务异常后的退避时间,单位为秒 |
circuit_break_threshold |
3 |
连续异常达到该次数后熔断账号线程 |
empty_round_degraded_threshold |
15 |
连续抓取不到动态达到该轮数后进入降级状态并降低频率,不会仅凭空结果判定 Cookie 失效 |
| 配置项 | 默认值 | 说明 |
|---|---|---|
like_sleep_min |
1.5 |
白天两次点赞之间的最小随机等待秒数 |
like_sleep_max |
3.5 |
白天两次点赞之间的最大随机等待秒数 |
round_sleep_normal |
5 |
白天每轮动态抓取之间的等待秒数 |
night_mode_start_hour |
0 |
夜间慢速模式开始小时,按服务器本地时间计算 |
night_mode_end_hour |
7 |
夜间慢速模式结束小时;与开始小时相同表示关闭夜间模式 |
like_sleep_min_night |
3.0 |
夜间两次点赞之间的最小随机等待秒数 |
like_sleep_max_night |
6.5 |
夜间两次点赞之间的最大随机等待秒数 |
round_sleep_night |
18 |
夜间每轮动态抓取之间的等待秒数 |
dry_run |
false |
设为 true 后,常驻任务只解析动态,不实际点赞 |
| 配置项 | 默认值 | 说明 |
|---|---|---|
qrcode_cooldown_seconds |
60 |
非主人为同一 QQ 重复获取二维码的冷却时间 |
login_timeout_seconds |
120 |
扫码登录有效时间,单位为秒 |
login_poll_interval_ms |
1000 |
Node.js 查询登录结果的轮询间隔,单位为毫秒 |
allow_user_login |
false |
是否允许非主人添加自己的账号 |
allowed_group_ids |
[] |
非空时,仅允许列表中的群发起普通用户登录 |
login_qr_private |
true |
群聊发起登录时是否只通过私聊发送二维码 |
max_accounts |
10 |
最多保存的账号数量 |
max_concurrent_logins |
2 |
全局最多同时存在的扫码登录流程数 |
notify_group_id |
0 |
接收运行通知的群号;0 表示未配置 |
notify_on_login |
false |
登录成功时发送群通知 |
notify_on_stop |
false |
执行下线时发送群通知 |
notify_on_thread_event |
false |
线程启动、恢复、停止、Cookie 失效或熔断时发送群通知 |
端口冲突时插件只在本次运行中尝试后续端口,并通过环境变量同步给 Python 服务,不会杀死占用端口的其他进程,也不会把临时端口写回公开配置。
扫码成功后,插件会将每个账号保存到:
configs/<QQ号>.json
这些文件包含 QQ 空间 Cookie、p_skey 等登录凭据。Cookie 在文件中只是 Base64 编码,并未加密,任何能读取文件的人都可能还原凭据。
- 不要把
configs/<QQ号>.json上传到 GitHub、网盘、群文件或发送给他人。 - 备份、迁移和日志排查时,不要公开账号 JSON 的内容。
- 建议限制插件目录的访问权限;Linux 下插件会尝试将账号文件权限设为
600。 - 如果凭据已经泄露,请立即在 QQ 安全中心处理登录状态,并重新扫码生成凭据。
- 发布本项目时,只应保留
configs/mz_qzone_config.json,所有纯数字命名的 JSON 都应排除。
仓库自带的 .gitignore 已排除账号 JSON、configs/.auth_key、临时文件和环境变量文件。运行时鉴权密钥同样是敏感数据,不应公开。
Yunzai 指令
│
▼
mz_qzone.js ──本机鉴权 HTTP──▶ mz_qzone_server.py
│
┌────────────┴────────────┐
▼ ▼
Playwright 扫码登录 requests 拉取/点赞
│ │
└────────────┬────────────┘
▼
configs/<QQ>.json
插件启动时由 Node.js 拉起独立的 Python 文件,健康检查通过后才解锁指令。Python 服务异常退出时会在滚动窗口内指数退避重启;Yunzai 退出时会尝试同步停止 Python 子进程。
安装依赖后可运行:
python -m unittest discover -s tests -v测试覆盖账号数据编码和原子写入、暂停及删除、登录状态即时返回、API 鉴权、路径穿越防护,以及不会杀死端口占用进程或覆盖 Python 源文件。
确认依赖安装到了插件实际调用的 Python:
python -c "import requests, bs4, flask, waitress, playwright; print('ok')"Linux 环境如果使用的是 python3,请将命令中的 python 替换为 python3。
在运行 Yunzai 的同一系统用户和 Python 环境下重新安装 Chromium:
python -m playwright install --no-shell chromiumLinux 缺少系统库时执行:
python3 -m playwright install --with-deps --no-shell chromium检查 Yunzai 日志中的 [mz-qzone][STDERR]、Python 依赖错误和端口占用。port 应使用仅供本插件占用的本机端口;修改配置后重启 Yunzai。
重新执行 #mz登录。新的扫码登录会覆盖账号凭据并重新启动对应线程。连续空动态现在只会进入“降级运行”,只有接口明确表现为登录失效时才会禁用账号。
默认 login_qr_private=true。请先添加机器人好友并确认协议端支持主动私聊;若协议端不支持,可在确认群聊环境可信后将其设为 false。
不会。Python 服务现在是唯一源码,Node.js 只负责启动它,不再保留或写入内嵌副本。
本项目仅供学习、研究和个人自动化使用。QQ 空间页面结构、接口、登录策略及风控规则均可能随时变化,插件不保证长期可用。因使用本项目导致的账号限制、数据泄露、服务异常或其他损失,由使用者自行承担。