使用 pywinauto UI 自动化技术实现 Windows 电脑版微信的自动化操作(消息、文件、朋友圈、联系人)。当用户提及微信、WeChat、pyweixin、发消息、朋友圈或 W 时使用。
Python 微信 RPA 工具,基于 pywinauto 实现, 纯 UI 自动化,无 Hook 注入。
核心原则:所有方法均为静态方法,无需实例化类。
仅支持 Windows 平台。如果运行环境不是 Windows,则应输出:
This tool requires Windows. Aborting.
首次调用该 Skill 时需要在仓库根目录(即 skills/pyweixin-rpa/)使用系统 Python 运行以下命令。注意:只有在当前系统中 首次 运行该 Skill 时才需要执行此步骤,后续不再需要。
bash
python scripts/check_requirements.py
{"missing_package": list}missing_package 键,则视为缺少依赖。missing_package 键对应的列表为空,则视为不缺少相关依赖。处理:
缺乏相关依赖,正在安装相关依赖,并在仓库根目录使用系统 Python 运行:bash
pip install -r scripts/requirements.txt
该 Skill 每次被调用时都需要经过这一阶段。在仓库根目录使用系统 Python 运行:
bash
python scripts/check_visibility.py
{"visibility": bool}visibility 键,则 visibility 视为 False。visibility == False,继续运行:bash
python scripts/check_running_state.py
输出结果:JSON 对象 {"is_running": bool}
如果 is_running == false,输出: 微信未启动,请自行启动并登录后再尝试进行相关自动化操作!
如果 is_running == true,告知用户微信 UI 树不可见,无法执行自动化操作。在控制台输出一份中文摘要:
references/Weixin4.0.mdvisibility == True,可以继续进行其他操作。模块类说明WeChatAuto``Messages消息发送、拉取、导出会话、导出聊天记录Files文件发送、保存、导出Call语音/视频通话Contacts联系人、群聊、公众号信息获取FriendSettings好友管理(备注、标签、拉黑、删除等)Monitor消息监听Moments朋友圈操作Settings微信设置AutoReply自动回复Collections收藏操作WeChatTools``Tools微信路径查询、状态检测、消息解析Navigator打开微信内部一切可以打开的窗口WinSettings``SystemSettingsWindows 系统操作(剪贴板、输入法等)utils扫描新消息 scan_for_new_messagespython
# 所有可用类的具体导入方式(需要先 sys.path.insert)
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
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')。
python
import sys
sys.path.insert(0, 'scripts')
from pyweixin import Messages, Files # 现在会加载本地模块
注意:
scripts/check_visibility.py等检查脚本内部已处理路径,直接运行不受影响。仅在编写自定义脚本时需要关注。
dump_chat_history 返回 list[dict],不要解包为两个变量#python
# ❌ 错误:返回值是 list[dict],不是 tuple
messages, times = Messages.dump_chat_history(friend='xxx', number=5)
# ✅ 正确:直接拿 dict 列表
result = Messages.dump_chat_history(friend='xxx', number=5, close_weixin=False)
for msg in result:
print(msg['消息发送人'], msg['消息内容'])
references/api_reference.md 中每个方法都已标注准确的返回类型和结构,这些标注直接从源码提取。
python
# ✅ 正确:查文档比跑探针更可靠
# api_reference.md 中:
# Messages.dump_chat_history(...) -> list[dict]
# 每个 dict 键: '消息发送人', '消息内容', '消息类型', '消息发送时间'
result = Messages.dump_chat_history(friend='xxx', number=5, close_weixin=False)
for msg in result:
print(msg.get('消息内容')) # 直接使用,无需 type() 探测
例外: 如果你修改了源码或使用了源码中未覆盖的方法,才需要探针验证。日常使用以文档为准。
如果已经调用了一次 dump_chat_history(或其他拉取方法)拿到了数据,后续的处理步骤(如生成报告、分析、转发)应该 接收现有数据,而不是再调一次拉取方法。
python
# ❌ 错误:拉取 + 报告各拉一次 = 两次 UI 自动化操作
result = Messages.dump_chat_history(friend='xxx', number=200, close_weixin=False)
# ... 然后又在一个新脚本里调了一次 dump_chat_history ...
# ✅ 正确:只拉一次,把结果传给下游
result = Messages.dump_chat_history(friend='xxx', number=200, close_weixin=False)
report = build_report(result) # 复用数据,不再调用 dump_chat_history
send(report)
如果确实需要自包含的独立脚本(比如一次性工具),可以在脚本内部加一个 已拉取检查,或者用全局配置控制只拉一次。
经验: 每条
dump_chat_history调用 = 一次聊天窗口滚动操作。跑两次就是两次滚动操作,纯属浪费。拿到list[dict]后你想怎么处理都行,不需要重新拉。
💡 只读消息用
pull_messages,别用dump_chat_history:pull_messages只拉取已有聊天区域内的消息记录,不滚动窗口,比dump_chat_history轻量得多。验证、检查最新消息、确认发送结果,都应该用pull_messages。需要翻历史记录时(消息数量超过当前可视区域),才用dump_chat_history。
在发送消息时,注意消息中是否有文件(如图片、视频等):
Messages 内的 send 操作即可。Files 内的 send 操作,且 with_messages 参数设置为 True。在自动化过程中, scripts/pyweixin 内代码可能引发的异常分为以下类别。对于所有异常, 不要自动重试,直接结束相关自动化任务,是否重试由用户本人决定。
异常来源原因处理方式ComErrorpywin32自动化窗口中 top_window 被手动关闭出现该异常后不要重试,直接结束相关自动化任务,返回: 本次自动化操作中顶部窗口被意外关闭,自动化任务终止。``ElementNotFoundErrorpywinauto源码中某一处控件未在微信相关窗口中定位到出现该异常后不要重试,直接结束相关自动化任务。总结异常信息,将未定位到的 UI 控件具体位置返回( scripts/pyweixin/Uielements.py),并建议用户使用 inspect.exe 等工具查看未定位到的控件信息,将信息反馈后修改定位逻辑。TimeoutErrorpywinauto控件未定位到,且可能使用了 pywinauto 的 wait 机制出现该异常后不要重试,直接结束相关自动化任务。处理逻辑与 ElementNotFoundError 一致。NotStartErrorpyweixin微信未启动提示用户启动并登录微信后重试。NotLoginErrorpyweixin微信未登录提示用户登录微信后重试。NotFoundErrorpyweixin无法识别微信主界面(常见于无障碍未开启)建议开启 Windows 讲述人等无障碍服务后重试。NoSuchFriendErrorpyweixin好友/群聊备注不存在核对备注名后重试。NotFriendErrorpyweixin非正常好友或群聊,无法打开目标界面确认目标是否为有效好友/群聊。
如果异常的源代码中涉及到了 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
如果需要「在某个时间点自动给好友发消息」之类的定时操作, 不要 在 Python 脚本里写 time.sleep、 schedule 库或任何自身定时逻辑。而是:
systemEvent 在主 session 执行。Step 1:写脚本(只干活)
python
import sys
sys.path.insert(0, 'scripts')
from pyweixin import Messages
Messages.send_messages_to_friend(
friend='文件传输助手',
messages=['你好,这是定时消息'],
close_weixin=False
)
Step 2:设 cron 任务(用 OpenClaw 的定时能力触发)
bash
# 在 OpenClaw 中创建定时任务
# 09:51 时触发主 session 执行脚本
对应的 cron 参数:
字段值说明schedule``{"kind": "at", "at": "2026-06-02T09:51:00+08:00"}触发时间payload.kind``systemEvent在主 session 中注入事件payload.text``执行脚本:python scripts/cron_send_msg.py告诉 agent 做什么sessionTarget``main在主 session 执行(能看到上下文)delivery不设不需要回传
python
# 错误:在脚本里自己控制时间
import time
time.sleep(120) # ❌ 脚本挂起,阻塞
Messages.send_messages_to_friend(...)
python
# 错误:用 external scheduler 轮询
import schedule # ❌ 引入额外依赖
schedule.every().day.at("09:51").do(send_msg)
at(一次性)、 every(间隔)、 cron(cron 表达式)三种模式。sessionTarget="main" 让主 session 收到定时事件后直接 exec 脚本,不需要 isolated session 去猜上下文。Check Visibility 阶段没有任何问题后,便可以在 Windows 环境下运行相关自动化操作。通过阅读 references/api_reference.md 来获取各方法的完整签名、参数说明来生成对应的 Python 脚本。