WeixinAuto(Windows 微信自动化)
基于 UIAutomation 的微信 PC 端自动化工具,用来:
- 打开 / 切换聊天窗口
- 发送文本消息 / 文件消息
- 监听指定群 / 会话的新消息
- 批量监听多个群,并统一处理消息
⚠️ 仅支持 Windows + 新版微信(
weixin.exe),并且需要保持微信登录状态。本项目核心类已全面增加 Type Hints (类型注解),在 PyCharm 等 IDE 中具有极佳的代码补全体验。
环境要求
- Windows 10 | 11
- Python 3.10+(建议)
- PC 微信客户端 4.1 版本以上(
weixin.exe)
安装
外部用户直接通过 pip 安装(包名 weixinautox4):
pip install weixinautox4
源码开发环境则安装依赖:
pip install -r requirements.txt
核心类概览
主要对外只需要关心一个类:Wechat
from weixinauto.wechat import Wechat
核心能力:
send_message(target: str, text: str):给指定的 target 目标发送文本消息send_file(target: str, file_path: str):给指定的 target 目标发送文件add_listen_chat(title: str, on_new: Callable, ...):监听单个会话(回调模式)add_listens(titles: Iterable[str], ...)+start_listen()+get_listen_message():批量监听多个群(轮询模式)stop_listen(title: Optional[str] = None):停止监听
注:底层方法已封装针对微信状态的安全保护,未激活时调用将自发拦截并输出结构化警告日志。
1. 激活与初始化示例
首次运行必须要激活才能实例化对象工作:
from weixinauto import Wechat
from weixinauto.logger import get_logger
logger = get_logger(__name__)
wx = Wechat()
# 填入您的激活码
ok, update_info = wx.activate("LIC-XGFD8TF3-QTKIZ8Q5")
if ok:
logger.info("核心已就绪,微信驱动激活成功!")
else:
logger.error("激活失败!")
说明:
- 一台电脑一个授权码,授权码有效期为 1 年:
- 联系
wx:agentaibot获得授权码 - 每个授权码一年 300 元
- 联系
2. 发送消息与发送文件示例
向指定群 / 好友发送文本 / 文件:
from weixinauto.wechat import Wechat
import time
wx = Wechat()
wx.activate("LIC-XGFD8TF3-QTKIZ8Q5") # 确保已激活
# 1. 发送文本消息
ok_msg = wx.send_message(
target="工作群",
text="大家好,我是自动化助手~"
)
print("文本发送结果:", ok_msg)
time.sleep(1)
# 2. 发送文件或图片
ok_file = wx.send_file(
target="工作群",
file_path=r"E:\1.jpg"
)
print("文件发送结果:", ok_file)
说明:
- 内部会自动执行:
- 激活并前置微信主窗口。
- 在搜索框搜索目标并精准进入聊天窗口。
- 将文本或文件填入/粘贴到输入框后执行发送。
- 方法全自动检测微信是否可用,若未就绪会打印标准
logger级别警告。
3. 单个窗口监听(精准对答模式)
3.1 回调函数标准签名
由于我们添加了严格的类型提示,你可以直接复制以下推荐签名来享受 IDE 补全:
from weixinauto.infra.uia.message import ChatMessage
from typing import Callable
def on_new_msg(group: str, msg: ChatMessage, reply: Callable[[str, str], bool]):
"""
group: 当前消息所属群 / 会话标题
msg: 包含发送人、时间戳、类型的消息对象
reply: 便捷的当前窗口回复函数
"""
pass
ChatMessage 常用属性:
msg.text→ 文本内容(去掉尾部空白)msg.mtype→ 消息类型(纯文本/图片等)msg.is_self→ 是否为自己发的消息(用于防回声死循环)msg.sender→ 发送者昵称(若开启获取功能)
3.2 示例:自动回复指定口令
import time
from weixinauto.wechat import Wechat
from weixinauto.infra.uia.message import ChatMessage
from typing import Callable
def on_new(group: str, msg: ChatMessage, reply: Callable[[str, str], bool]):
print(f"[{group}] 收到来自【{msg.sender}】的新消息:{msg.text}")
# 简单示例:别人说“1”,我回“收到1” (防回声检测:必须排除是自己发的消息)
if msg.text == "1" and not msg.is_self:
# 这里的 reply 直接绑定了当前窗口的发送函数
reply("收到1")
def main():
wx = Wechat()
wx.activate("...")
# 挂载监听,不需要获取对方昵称时建议 need_nickname=False
ok = wx.add_listen_chat(
title="工作群",
on_new=on_new,
interval_sec=0.18,
need_nickname=False,
auto_save_image=False # 若需存图改为 True
)
if ok:
print("开始监听:工作群")
try:
while True:
time.sleep(1.0)
except KeyboardInterrupt:
wx.stop_listen("工作群")
if __name__ == "__main__":
main()
4. 批量监听多个群(轮询模式)
如果你需要作为“监控中心”同时监听数十个群落,轮询拉取是最稳健的方式:
import time
from weixinauto.wechat import Wechat
def main():
wx = Wechat()
wx.activate("...")
# 需要监听的群列表
groups = ["工作群", "测试群A", "测试群B"]
# 1) 批量挂载监听
wx.add_listens(
titles=groups,
need_nickname=True, # 如果要收集发件人名字
poll_sec=0.15,
auto_save_image=True # 文件如需下载也开启对应的配置
)
# 2) 驱动跑起来
wx.start_listen()
print(f"已启动批量监听,目标池:{groups}")
try:
while True:
# 3) 按需自定间隔获取最近产生的所有未读信息
all_msgs = wx.get_listen_messages(clear=True)
if all_msgs:
for chat_wnd, msgs in all_msgs.items():
group_name = chat_wnd.title
for msg in msgs:
print(f"[{group_name}] {msg.sender}: {msg.text}")
# 可以直接从 wnd_obj 回复
if msg.text == "查表" and not msg.is_self:
chat_wnd.reply("表格生成中...")
time.sleep(0.5)
except KeyboardInterrupt:
wx.stop_listen()
if __name__ == "__main__":
main()
5. 全局未读红点监听(无视被折叠的群)
当有群聊或人在后台给你发消息(即使被折叠在消息列表),只要微信左侧边栏产生小红点,我们就可以进行全局抽取并回复。此模式非常适合做全局的默认接待机器人。
import time
from typing import List, Callable
from weixinauto.wechat import Wechat
from weixinauto.infra.uia.message import ChatMessage
def on_global_new(msgs: List[ChatMessage], reply: Callable[[ChatMessage, str], None]) -> None:
print(f"\\n================ 本轮收到 {len(msgs)} 条全局未读消息 =================")
for m in msgs:
print(f"[{m.group}] -> {m.sender} -> {m.text}")
# 遇到特定词语触发全局回复(利用传入的 reply 函数和 msg 对象本身定位)
if m.text == "在吗":
ok = reply(m, "您好,系统自动接待中,请留言。")
print(f"回复 {m.group} 结果: {ok}")
def main():
wx = Wechat()
wx.activate("...")
# 挂载全局监听
ok = wx.get_new_message(
on_new=on_global_new,
interval_sec=5.0, # 每 5 秒扫描一次红点
need_nickname=True, # 若要获取陌生人昵称
auto_save_image=False,
auto_save_file=False
)
if ok:
print("✅ 已启动【全局未读消息监听】。")
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
wx.stop_new_message_listen()
if __name__ == "__main__":
main()
6. 防自言自语(回声抑制机制)
为避免机器人发出消息后误将其识别为新到达指令从而死循环,内部集成了双保险:
- 缓存令牌校验:在
chat_wnd.reply或主动发送消息时,立刻缓存文本或文件的 HASH 令牌。 - 侦听过滤:监听到包含自发 HASH 的新节点时,直接抛弃不触发业务 callback。
开发者守则:
编写业务流时,依然建议加上 if not msg.is_self 作为终端护城河判定以保持逻辑严谨。
7. 其他运维管理
- 停止特定监听:
wx.stop_listen("业务群A")
- 全局停止:
wx.stop_listen()
- 全局退出清理:
wx.shutdown()
注意事项:
- 必须保持微信前台可见可用,本版本深度依赖原生 Windows UI Automation。
- 批量监听且
need_nickname=True会模拟点击头像卡片弹出进行解析,在对前台鼠标干扰极度敏感或非专用副机的场景请慎用该参数(配置为False即可无感挂机)。
8. 系统整体说明与限制(高频并发场景必读)
本自动化基于 UI 树元素的物理抓取,针对高频消息环境存在以下客观限制,请开发者在业务架构中做好容错:
- 多媒体处理抢占
- 接收到图片/文件消息时,若开启了自动保存,系统会先触发 UI 菜单级操作去下载。
- 文件下载完成后,通过回调赋予
msg.file_path。也可以通过自定义路径保存。
- 高频突发消息遗漏 (丢消息风险)
- 在执行诸如图片下载、点击头像获取昵称等前台焦点操作时,若瞬间(20~50毫秒内)群内爆发出第二条、第三条高速刷屏消息,后续消息可能在本次轮询周期内被 UI 树直接冲掉(覆盖)。
- 现状:当前版本暂时未实现高并发的深度队列缓冲处理。在极端高速刷屏的抢答或监控场景下,大概率会发生信息遗漏,这属于 UI 自动化方案的物理极限。业务层请不要对 100% 毫无漏接的消息流做绝对强依赖。
Metadata
Release files for weixinautox4 2.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| weixinautox4-2.4.0-cp311-cp311-win_amd64.whl | CPython 3.11 | CPython 3.11 | Windows x86-64 | Details |
Release files / weixinautox4-2.4.0-cp311-cp311-win_amd64.whl
| Download URL | weixinautox4-2.4.0-cp311-cp311-win_amd64.whl |
|---|---|
| Size | 1.6 MB |
| Tags | CPython 3.11 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
dfa6542b0b62c9e7204d6b1e03e7f3a5c0df254d06021e9731bb485bf3670b29
|
|
BLAKE2b-256 checksum How to use checksums |
870df988e70507f662ff1c488c7307f651435f2388e27daaac94ea0ae45a6fa8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.8
|