| name | pyweixin-rpa |
| description | 基于pywinauto实现的Windows微信UI自动化工具,支持消息收发、文件传输、 朋友圈操作和通讯录管理。当用户提及微信、WeChat、pyweixin、发消息、 朋友圈或Windows微信RPA时使用。 ⚠️平台限制:本工具仅支持Windows系统。若当前环境非Windows, 请立即中止操作并告知用户。 |
pyweixin RPA
Overview
Python 微信 RPA 工具,基于 pywinauto 实现,纯 UI 自动化,无 Hook 注入。
核心原则:所有方法均为静态方法,无需实例化类。
仅支持 Windows 平台。如果运行环境不是 Windows,则应输出:
This tool requires Windows. Aborting.
Resources
- scripts/requirements.txt — 依赖清单
- scripts/check_requirements.py — 依赖检查脚本
- scripts/check_visibility.py — 微信 UI 可见性检查脚本
- scripts/check_running_state.py — 微信运行状态检查脚本
- references/Weixin4.0.md — 微信 4.0+ UI 树可见性说明
- scripts/pyweixin/ — 微信 4.0+ 自动化源码
- references/api_reference.md — 方法签名速查(推荐优先阅读)
Check Requirements
首次调用该 Skill 时需要在仓库根目录(即 skills/pyweixin-rpa/)使用系统 Python 运行以下命令。注意:只有在当前系统中首次运行该 Skill 时才需要执行此步骤,后续不再需要。
python scripts/check_requirements.py
- 输出结果:JSON 对象
{"missing_package": list}
- 如果脚本退出码非零、输出无法解析为 JSON、或缺少
missing_package 键,则视为缺少依赖。
- 如果输出可解析且返回的 JSON 字符串中
missing_package 键对应的列表为空,则视为不缺少相关依赖。
处理:
- 如果缺少相关依赖,输出:
缺乏相关依赖,正在安装相关依赖,并在仓库根目录使用系统 Python 运行:
pip install -r scripts/requirements.txt
- 如果不缺少相关依赖,可以继续进行其他操作。
Check Visibility
该 Skill 每次被调用时都需要经过这一阶段。在仓库根目录使用系统 Python 运行:
python scripts/check_visibility.py
- 输出结果:JSON 对象
{"visibility": bool}
- 如果脚本退出码非零、输出无法解析为 JSON、或缺少
visibility 键,则 visibility 视为 False。
- 如果
visibility == False,继续运行:
python scripts/check_running_state.py
- 输出结果:JSON 对象
{"is_running": bool}
- 如果
is_running == false,输出:微信未启动,请自行启动并登录后再尝试进行相关自动化操作!
- 如果
is_running == true,告知用户微信 UI 树不可见,无法执行自动化操作。在控制台输出一份中文摘要:
- 3-5 条要点
- 最多 150 字
- 来源:
references/Weixin4.0.md
- 如果
visibility == True,可以继续进行其他操作。
Import List
| 模块 | 类 | 说明 |
|---|
WeChatAuto | Messages | 消息发送、拉取、导出会话、导出聊天记录 |
| Files | 文件发送、保存、导出 |
| Call | 语音/视频通话 |
| Contacts | 联系人、群聊、公众号信息获取 |
| FriendSettings | 好友管理(备注、标签、拉黑、删除等) |
| Monitor | 消息监听 |
| Moments | 朋友圈操作 |
| Settings | 微信设置 |
| AutoReply | 自动回复 |
| Collections | 收藏操作 |
WeChatTools | Tools | 微信路径查询、状态检测、消息解析 |
| Navigator | 打开微信内部一切可以打开的窗口 |
WinSettings | SystemSettings | Windows 系统操作(剪贴板、输入法等) |
utils | | 扫描新消息 scan_for_new_messages |
from pyweixin import AutoReply, Collections, Call, Contacts, Files, FriendSettings, Messages, Moments, Monitor, Settings
from pyweixin import Tools, Navigator
from pyweixin import SystemSettings
from pyweixin.Config import GlobalConfig
Scripting Guidelines
原则一:导入前务必 sys.path.insert(0, 'scripts')
scripts/pyweixin/ 是本工具的本地源码目录。如果你的 Python 环境中安装了同名的第三方 pyweixin pip 包,from pyweixin import Messages 会优先加载 pip 包而非本地模块,导致报错(如 AttributeError: type object 'Messages' has no attribute 'dump_chat_history')。
import sys
sys.path.insert(0, 'scripts')
from pyweixin import Messages, Files
注意: scripts/check_visibility.py 等检查脚本内部已处理路径,直接运行不受影响。仅在编写自定义脚本时需要关注。
原则二:dump_chat_history 返回 list[dict],不要解包为两个变量
messages, times = Messages.dump_chat_history(friend='xxx', number=5)
result = Messages.dump_chat_history(friend='xxx', number=5, close_weixin=False)
for msg in result:
print(msg['消息发送人'], msg['消息内容'])
原则三:返回值以 API Reference 为准,无需探针
references/api_reference.md 中每个方法都已标注准确的返回类型和结构,这些标注直接从源码提取。
result = Messages.dump_chat_history(friend='xxx', number=5, close_weixin=False)
for msg in result:
print(msg.get('消息内容'))
例外: 如果你修改了源码或使用了源码中未覆盖的方法,才需要探针验证。日常使用以文档为准。
原则四:已拉取的数据不要重复拉取
如果已经调用了一次 dump_chat_history(或其他拉取方法)拿到了数据,后续的处理步骤(如生成报告、分析、转发)应该接收现有数据,而不是再调一次拉取方法。
result = Messages.dump_chat_history(friend='xxx', number=200, close_weixin=False)
result = Messages.dump_chat_history(friend='xxx', number=200, close_weixin=False)
report = build_report(result)
send(report)
如果确实需要自包含的独立脚本(比如一次性工具),可以在脚本内部加一个已拉取检查,或者用全局配置控制只拉一次。
经验: 每条 dump_chat_history 调用 = 一次聊天窗口滚动操作。跑两次就是两次滚动操作,纯属浪费。拿到 list[dict] 后你想怎么处理都行,不需要重新拉。
💡 只读消息用 pull_messages,别用 dump_chat_history: pull_messages 只拉取已有聊天区域内的消息记录,不滚动窗口,比 dump_chat_history 轻量得多。验证、检查最新消息、确认发送结果,都应该用 pull_messages。需要翻历史记录时(消息数量超过当前可视区域),才用 dump_chat_history。
Send Messages
在发送消息时,注意消息中是否有文件(如图片、视频等):
- 如果发送的内容只是文本字符串,使用
Messages 内的 send 操作即可。
- 如果消息中包含文件,使用
Files 内的 send 操作,且 with_messages 参数设置为 True。
Handle Exception
在自动化过程中,scripts/pyweixin 内代码可能引发的异常分为以下类别。对于所有异常,不要自动重试,直接结束相关自动化任务,是否重试由用户本人决定。
异常分类与处理
| 异常 | 来源 | 原因 | 处理方式 |
|---|
ComError | pywin32 | 自动化窗口中 top_window 被手动关闭 | 出现该异常后不要重试,直接结束相关自动化任务,返回:本次自动化操作中顶部窗口被意外关闭,自动化任务终止。 |
ElementNotFoundError | pywinauto | 源码中某一处控件未在微信相关窗口中定位到 | 出现该异常后不要重试,直接结束相关自动化任务。总结异常信息,将未定位到的 UI 控件具体位置返回(scripts/pyweixin/Uielements.py),并建议用户使用 inspect.exe 等工具查看未定位到的控件信息,将信息反馈后修改定位逻辑。 |
TimeoutError | pywinauto | 控件未定位到,且可能使用了 pywinauto 的 wait 机制 | 出现该异常后不要重试,直接结束相关自动化任务。处理逻辑与 ElementNotFoundError 一致。 |
NotStartError | pyweixin | 微信未启动 | 提示用户启动并登录微信后重试。 |
NotLoginError | pyweixin | 微信未登录 | 提示用户登录微信后重试。 |
NotFoundError | pyweixin | 无法识别微信主界面(常见于无障碍未开启) | 建议开启 Windows 讲述人等无障碍服务后重试。 |
NoSuchFriendError | pyweixin | 好友/群聊备注不存在 | 核对备注名后重试。 |
NotFriendError | pyweixin | 非正常好友或群聊,无法打开目标界面 | 确认目标是否为有效好友/群聊。 |
关于 MousePos 坐标异常
如果异常的源代码中涉及到了 MousePos 类,导致本次异常的原因大概率是点击坐标有偏差,未弹出期望窗口或控件。出现该异常后可以尝试在 scripts/pyweixin/Uielements.py 的 MousePos 类中直接修改点击坐标。
涉及 MousePos 的方法:
| 位置 | 具体坐标 |
|---|
WeChatTools.py\class Navigator\open_my_profile | MousePos(weixin_button).AvatarPos |
WeChatTools.py\class Tools\select_chatList | MousePos(selected[0]).ChatListSelectPos |
WeChatTools.py\class Tools\select_chatHistoryList | MousePos(selected[0]).ChatHistorySelectPos |
WeChatAuto.py\class Moments\post_notes | MousePos(container).MoreButtonPos |
WeChatAuto.py\class Moments\like_posts | MousePos(content_listitem).PostImagePos |
WeChatAuto.py\class Moments\like_posts | MousePos(content_listitem).EllipsisPos |
WeChatAuto.py\class Moments\dump_recent_posts | MousePos(content_listitem).PostNamePos |
WeChatAuto.py\class Moments\dump_friend_posts | MousePos(content_listitem).PostDetailVideoPos |
WeChatAuto.py\class Moments\dump_friend_posts | MousePos(content_listitem).PostDetailVideoMousePos |
WeChatAuto.py\class Moments\dump_friend_posts | MousePos(content_listitem).PostDetailImagePos |
WeChatAuto.py\class Moments\dump_friend_posts | MousePos(content_listitem).PostDetailImageMousePos |
WeChatAuto.py\class Messages\send_audios_to_friend | MousePos(send_audio_button).AudioButtonPos |
WeChatAuto.py\class Messages\send_audios_to_friend | MousePos(main_window).MainWindowPos |
WeChatAuto.py\class Messages\message_chain | MousePos(AddContentText).SolitairePos |
WeChatAuto.py\class Messages\search_chat_history | MousePos(next_item).SearchChatPos |
WeChatAuto.py\class Collections\collect_offAcc_articles | MousePos(offAcc_window).CardLinkPos |
WeChatAuto.py\class Collections\cardLink_to_url | MousePos(offAcc_window).CardLinkPos |
Scheduled Tasks:用外部调度器触发脚本,不要在代码里写定时逻辑
如果需要「在某个时间点自动给好友发消息」之类的定时操作,不要在 Python 脚本里写 time.sleep、schedule 库或任何自身定时逻辑。而是:
- 写一个纯干活脚本(只做一件事,不含时间判断)。
- 用外部调度器触发(系统任务计划程序、CI 调度、AI 助手的 cron 能力等)。
正确做法
写脚本:(只干活)
import sys
sys.path.insert(0, 'scripts')
from pyweixin import Messages
Messages.send_messages_to_friend(
friend='文件传输助手',
messages=['你好,这是定时消息'],
close_weixin=False
)
用外部调度器触发: 系统计划任务、CI 平台的 cron 表达式,或 AI 助手的定时能力在指定时间执行该脚本。
❌ 不要这样做
import time
time.sleep(120)
Messages.send_messages_to_friend(...)
import schedule
schedule.every().day.at("09:51").do(send_msg)
为什么?
- 脚本只负责干活,时间控制完全解耦,脚本可以被随时手动执行、调试。
- 调度器(无论是计划任务、CI 还是 AI 助手)已经具备成熟的定时能力,无需在脚本中重复造轮子。
- 纯干活脚本 = 可测试、可复用、可手动执行。
Execution
Check Visibility 阶段没有任何问题后,便可以在 Windows 环境下运行相关自动化操作。通过阅读 references/api_reference.md 来获取各方法的完整签名、参数说明来生成对应的 Python 脚本。