Python 实现微信好友撤回消息查看功能
一、环境准备
使用 Python 解决微信相关问题,首先需要安装相应的第三方库。本方案基于 itchat 库进行开发。
- 确保已安装 Python 环境(建议版本 3.x)。
- 在终端或命令行中执行以下命令安装依赖:
pip install itchat
安装完成后,系统会提示 Successfully installed itchat...,表示安装成功。
二、微信登录机制
安装完库后,调用 itchat.login() 即可尝试登录。直接使用网页版接口可能会遇到腾讯的安全限制,控制台可能提示'由于安全原因,此微信号不能使用网页版微信'。
若遇到此类问题,通常是因为网页版 API 被限制。此时可尝试以下解决方案:
- 检查网络环境是否稳定。
- 使用支持 Windows/Mac 客户端桥接的方式登录。
- 确保账号未在其他设备异常登录。
确保登录成功后,才能进行后续的消息监听操作。
三、消息发送测试
登录成功后,可先测试发送消息功能,验证连接是否正常。
- 使用
itchat.search_friends()查找好友列表。 - 通过
send()方法向指定用户发送文本消息。
示例代码逻辑如下:
friends = itchat.search_friends()
if friends:
itchat.send('Hello', userName=friends[0]['UserName'])
四、消息监听机制
接下来需要监听好友发送的消息。使用 @itchat.msg_register() 装饰器注册消息回调函数。
该装饰器允许我们定义一个函数,当收到特定类型的消息时自动触发。我们需要捕获文本、图片、语音等多种类型,以便后续处理撤回逻辑。
五、消息存储逻辑
为了处理撤回消息,我们需要在消息被撤回前将其内容暂存。定义一个全局字典 dict_msg,以消息唯一标识 MsgId 为键,消息详情为值。
每条消息的 MsgId 是唯一的,这为我们后续匹配撤回通知提供了关键索引。
六、多类型消息处理
除了文本,还需处理图片、语音等类型。通过 itchat.msg_register([TEXT, PICTURE, RECORDING, ...]) 覆盖多种消息类型。
在回调函数中,提取消息的关键信息:
Text: 消息内容(文本或文件路径)。MsgId: 消息唯一 ID。Type: 消息类型(TEXT, PICTURE 等)。FileName: 文件名(针对附件类消息)。FromUserName: 发送者 ID。CreateTime: 发送时间。
七、文件存储与目录管理
图片和语音需要保存到本地。使用 os.mkdir() 创建存储目录,并在接收消息时调用保存函数。
建议将撤回的消息统一保存在一个独立的文件夹中,例如 /tmp/itchat_recalled。程序启动时检查目录是否存在,不存在则自动创建。
八、撤回消息识别原理
微信撤回消息时会触发系统 NOTE 类型消息。通过判断 msg['Text'] 是否包含'撤回了一条消息',并结合 msg['Content'] 中的 XML 数据解析出原消息 ID。
XML 结构通常包含 <msgid> 标签,其值即为原始消息的 MsgId。通过比对之前存储的字典,即可找到对应的消息内容。
九、完整代码实现
以下是完整的程序代码,整合了上述所有步骤。请根据实际运行环境调整文件路径。
import itchat
from itchat.content import *
import os
import time
import xml.dom.minidom
# 保存撤回消息的文件目录
temp = '/tmp/itchat_recalled'
if not os.path.exists(temp):
os.mkdir(temp)
itchat.auto_login(True)
dict_msg = {}
@itchat.msg_register([TEXT, PICTURE, FRIENDS, CARD, MAP, SHARING, RECORDING, ATTACHMENT, VIDEO])
def resever_info(msg):
global dict_msg
info = msg.get('Text', '')
msgId = msg['MsgId']
info_type = msg['Type']
name = msg.get('FileName', '')
# 获取发送者昵称
try:
fromUser = itchat.search_friends(userName=msg['FromUserName'])['NickName']
except:
fromUser = 'Unknown'
ticks = msg['CreateTime']
dt = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(ticks))
dict_msg[msgId] = {
"info": info,
"info_type": info_type,
"name": name,
"fromUser": fromUser,
"dt": dt
}
@itchat.msg_register(NOTE)
def note_info(msg):
if '撤回了一条消息' in msg['Text']:
content = msg['Content']
doc = xml.dom.minidom.parseString(content)
result = doc.getElementsByTagName("msgid")
if result:
msgId = result[0].childNodes[0].nodeValue
if msgId in dict_msg:
item = dict_msg[msgId]
msg_type = item['info_type']
fromUser = item['fromUser']
dt = item['dt']
if msg_type == 'Recording':
recording_info = item['info']
info_name = item['name']
print(f"保存语音:{info_name}")
send_msg = f'【发送人】{fromUser}\n发送时间:{dt}\n撤回了一条语音'
itchat.send(send_msg, 'filehelper')
elif msg_type == 'Text':
text_info = item['info']
send_msg = f'【发送人】{fromUser}\n发送时间:{dt}\n撤回内容:{text_info}'
itchat.send(send_msg, 'filehelper')
print("保存文本")
elif msg_type == 'Picture':
picture_info = item['info']
info_name = item['name']
print(f"保存图片:{info_name}")
send_msg = f'【发送人】{fromUser}\n发送时间:{dt}\n撤回了一张图片'
itchat.send(send_msg, 'filehelper')
del dict_msg[msgId]
itchat.run()
十、使用说明与注意事项
1. 运行方式
将代码保存为 .py 文件,在终端运行 python your_script.py。首次运行会弹出二维码,使用手机微信扫码登录。
2. 隐私与安全
- 本工具仅用于个人学习研究,请勿用于非法用途。
- 登录过程中请确保账号安全,避免在非信任设备上长期保持登录状态。
- 撤回消息功能依赖于消息接收速度,若消息发送与撤回间隔极短,可能无法及时缓存。
3. 常见问题
- 无法登录:检查网络连接,或尝试更换网络环境。
- 消息未保存:检查
temp目录权限,确保程序有写入权限。 - XML 解析失败:部分旧版本微信可能格式不同,需适配解析逻辑。
通过上述配置,程序即可在后台持续运行,实时记录并转发好友撤回的消息至文件助手,实现消息留存功能。

