python 基于itchat详解微信防撤回程序
2018-12-04 01:19
549 查看
itchat学习笔记请见另一文章
文章目录
- 0. 选题背景
- 1. 发现问题
- 2. 提炼问题
- 3. 解决方案
- 4. 分析设计
- 4.0 准备
- 问题4.1 : 如何用程序登录自己的微信账号?
- 问题4.2 : 如何用程序获取账号接收到的消息
- 问题4.3 : 如何识别接收到的消息的不同类别,并作出不同的处理
- 问题4.4 : 如何实时保存接收到的消息
- 问题4.5 : 如何检测到其他用户的”撤回“指令
- 问题4.6 : 如何根据“撤回”指令在保存下来的消息中找到被撤回的消息内容
- 问题4.7 : 如何在微信中显示撤回的不同类型的内容
- 5.-1 结构
- 5.0 库引用
- 5.1 全局变量设置
- 5.2 登录
- 5.3 处理接收到的信息
- 5.4 分类处理
- 5.5 更新存储变量的字典
- 5.6 监测是否有消息撤回若有,找回消息
- 5.7 分类处理 && 5.8 显示消息
- 5.9 弹出该消息并run
0. 选题背景
- 随着聊天软件的逐渐进步,不知什么时候开始,微信以及QQ都已经提供了消息撤回的功能,提供撤回功能的目的呢,无非就是以下几点:打错字了;发完消息后悔了;调皮了一下却不想让更多的人(或某个人)看到(更多的出现在群组里)。
1. 发现问题
- 但是人类的好奇心是无法满足的,越是撤回的消息,就越是想要看到,尤其是以下情况:你的朋友(说不定是心上人哦~)撤回了发来的消息,然而你错过了、你的群组里有人撤回了消息,后面是一群人的惊呼,然而你错过了。
- 怎么可以这样!!!这时候,你(我)就需要一款能够查看撤回消息的神兵利器了!怎么办?当然是求助python了!
2. 提炼问题
- 要解决WeChat防撤回的功能,主要有以下几个问题有待解决。
- 如何用程序登录自己的微信账号
- 如何用程序获取账号接收到的消息
- 如何识别接收到的消息的不同类别,并作出不同的处理
- 如何实时保存接收到的消息
- 如何检测到其他用户的“撤回”指令
- 如何根据“撤回”指令在保存下来的消息中检索到被撤回的消息内容
- 如何在微信中显示撤回的不同类型的内容
3. 解决方案
- 通过查询了解到,python有一个名为itchat的第三方库,专门为WeChat所写
- ++itchat is an open source api for WeChat, a commonly-used Chinese social networking app.
Accessing your personal wechat account through itchat in python has never been easier.++
++itchat是微信的开源API,微信是一种常用的中文社交网络应用程序。通过python中的itchat访问您的个人微信帐户变得前所未有的如此简单。++ - 上面的一段话是PyPI对itchat库的介绍,而我们微信防撤回系统的实现也是基于itchat库的。
- 方法:通过itchat库实现个人微信的登录、消息获取以及分类处理、撤回消息指令的识别以及撤回消息的寻找、撤回内容在wechat上的显示。
4. 分析设计
4.0 准备
- 本部分是对各个问题关键点进行的分析设计,主要是各个问题需要用什么样的知识点、什么样的函数来完成,具体步骤以及完整代码请见下面“5. 代码实现”部分
- 在对WeChat开始“骚”操作之前,首先我们要有一定的知识储备,我首先对itchat库进行了初步的学习,学习笔记参见附件。
问题4.1 : 如何用程序登录自己的微信账号?
#通过此函数实现账号登录 itchat.login()
问题4.2 : 如何用程序获取账号接收到的消息
问题4.3 : 如何识别接收到的消息的不同类别,并作出不同的处理
# 对消息进行注册使用下面的语句 @itchat.msg_register([a,b,c]) # 以下实现了对不同类别a,b,c的分类以及处理处理 def handleRMsg(msg): # balabala
问题4.4 : 如何实时保存接收到的消息
# 创建一个全局变量字典,用来保存消息相关信息 msg_info = {} # 在对消息处理之后将信息储存到msg_info中 msg_info.update( { msg_id: { "": "": "": "": } } )
问题4.5 : 如何检测到其他用户的”撤回“指令
if '撤回了一条消息' in msg['Content']:
问题4.6 : 如何根据“撤回”指令在保存下来的消息中找到被撤回的消息内容
# 用正则表达式查找message id recall_msg_id = re.search("\<msgid\>(.*?)\<\/msgid\>", msg['Content']).group(1) # 在存储的信息中根据message id查找消息 recall_msg = msg_info.get(recall_msg_id)
问题4.7 : 如何在微信中显示撤回的不同类型的内容
# 将消息发送到文件传输助手以便查看 itchat.send_msg(msg_prime, toUserName='filehelper')
5. 代码实现
5.-1 结构
- 我们首先清晰一下程序的大致结构
- 库引用
- 全局变量设置
- 登录
- 处理接收到的信息
- 分类处理
- 更新存储变量的字典
- 监测是否有消息撤回若有,找回消息
- 分类处理
- 显示消息
- 弹出该消息并run
5.0 库引用
- 本次将会用到以下几个函数库,其中,itchat.content以此方式引用更利于代码的美观以及简洁。
import re import time import itchat import platform from itchat.content import *
5.1 全局变量设置
- emmmmm说是全局变量设置,但事实上用到的全局变量就只有一个存储消息相关信息的字典~(@^_^@)~
# 用来存储消息相关信息的字典 msg_info = {}
5.2 登录
# 调用platform库判断操作系统,以便接下来的登录操作 # 登录函数如下,该函数执行过后用户可通过扫描二维码登录网页版微信 if platform.platform()[:7] == 'Windows': itchat.login(enableCmdQR=False) else: itchat.login(enableCmdQR=True)
5.3 处理接收到的信息
# 注册,分别对应文本,图片,好友申请,名片,地图信息,分享,语音,附件,视频 # isFriendChat对应朋友会话,isMpChat对应公众号会话,另isGroupChat对应群组会话 @itchat.msg_register([TEXT, PICTURE, FRIENDS, CARD, MAP, SHARING, RECORDING, ATTACHMENT, VIDEO], isFriendChat=True, isMpChat=True) def handleRMsg(msg): # 获取接收消息的时间并将时间字符串格式化 msg_time_receive = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) # 获取发信人信息 try: # 通过'FromUserName'寻找到一个字典并取其'NickName'赋值给msg_from msg_from = itchat.search_friends(userName=msg['FromUserName'])['NickName'] except: # 如果非正常,则是WeChat官方声明 msg_from = 'WeChat Official Accounts' # 获取发信时间 msg_time_send = msg['CreateTime'] # 获取信息ID msg_id = msg['MsgId'] # 消息内容置空 msg_content = None # link置空 msg_link = None
5.4 分类处理
# 文本或者好友推荐 if msg['Type'] == 'Text' or msg['Type'] == 'Friends': msg_content = msg['Text'] print('[Text/Friends]: %s' % msg_content) # 附件/视频/图片/语音 elif msg['Type'] == 'Attachment' or msg['Type'] == "Video" or msg['Type'] == 'Picture' or msg['Type'] == 'Recording': msg_content = msg['FileName'] msg['Text'](str(msg_content)) print('[Attachment/Video/Picture/Recording]: %s' % msg_content) # 推荐名片 elif msg['Type'] == 'Card': msg_content = msg['RecommendInfo']['NickName'] + '的推荐名片,' if msg['RecommendInfo']['Sex'] == 1: msg_content += '性别男。' else: msg_content += '性别女。' print('[Card]: %s' % msg_content) # 位置信息 elif msg['Type'] == 'Map': x, y, location = re.search("<location x=\"(.*?)\" y=\"(.*?)\".*label=\"(.*?)\".*", msg['OriContent']).group(1, 2, 3) if location is None: msg_content = r"纬度:" + x.__str__() + ", 经度:" + y.__str__() else: msg_content = r"" + location print('[Map]: %s' % msg_content) # 分享的音乐/文章 elif msg['Type'] == 'Sharing': msg_content = msg['Text'] msg_link = msg['Url'] print('[Sharing]: %s' % msg_content)
5.5 更新存储变量的字典
# 更新 msg_info.update( { msg_id: { "msg_from": msg_from, "msg_time_send": msg_time_send, "msg_time_receive": msg_time_receive, "msg_type": msg["Type"], "msg_content": msg_content, "msg_link": msg_link } } )
5.6 监测是否有消息撤回若有,找回消息
# 再次注册NOTE即通知类型 @itchat.msg_register(NOTE, isFriendChat=True, isGroupChat=True, isMpChat=True) def monitor(msg): if '撤回了一条消息' in msg['Content']:# 此处\<msgid\>(.*?)\<\/msgid\>的原因是,如果将msg['Content']打印出来,会在其中得到含有\<msgid\> \<\/msgid\>的一段信息 # 而(.*?)则是正则表达式,用于匹配其中的任意字符串 # 同时,group(1)表示从第一个左括号处开始匹配 recall_msg_id = re.search("\<msgid\>(.*?)\<\/msgid\>", msg['Content']).group(1) recall_msg = msg_info.get(recall_msg_id) print('[Recall]: %s' % recall_msg)
5.7 分类处理 && 5.8 显示消息
# 分类并处理 msg_prime = '---' + recall_msg.get('msg_from') + '撤回了一条消息---\n' \ '消息类型:' + recall_msg.get('msg_type') + '\n' \ '时间:' + recall_msg.get('msg_time_receive') + '\n' \ '内容:' + recall_msg.get('msg_content') if recall_msg['msg_type'] == 'Sharing': msg_prime += '\n链接:' + recall_msg.get('msg_link') # 向文件助手发送消息 itchat.send_msg(msg_prime, toUserName='filehelper') if recall_msg['msg_type'] == 'Attachment' or recall_msg['msg_type'] == "Video" or recall_msg['msg_type'] == 'Picture' or recall_msg['msg_type'] == 'Recording': file = '@fil@%s' % (recall_msg['msg_content']) itchat.send(msg=file, toUserName='filehelper')
5.9 弹出该消息并run
# 弹出并run msg_info.pop(recall_msg_id) itchat.run()
6. 完整代码
import re import time import itchat import platform from itchat.content import *# 用来存储消息相关信息的字典 msg_info = {}# 调用platform库判断操作系统,以便接下来的登录操作 # 登录函数如下,该函数执行过后用户可通过扫描二维码登录网页版微信 if platform.platform()[:7] == 'Windows': itchat.login(enableCmdQR=False) else: itchat.login(enableCmdQR=True)# 注册,分别对应文本,图片,好友申请,名片,地图信息,分享,语音,附件,视频 # isFriendChat对应朋友会话,isMpChat对应公众号会话,另isGroupChat对应群组会话 @itchat.msg_register([TEXT, PICTURE, FRIENDS, CARD, MAP, SHARING, RECORDING, ATTACHMENT, VIDEO], isFriendChat=True, isMpChat=True) def handleRMsg(msg): # 获取接收消息的时间并将时间字符串格式化 msg_time_receive = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) # 获取发信人信息 try: # 通过'FromUserName'寻找到一个字典并取其'NickName'赋值给msg_from msg_from = itchat.search_friends(userName=msg['FromUserName'])['NickName'] except: # 如果非正常,则是WeChat官方声明 msg_from = 'WeChat Official Accounts' # 获取发信时间 msg_time_send = msg['CreateTime'] # 获取信息ID msg_id = msg['MsgId'] # 消息内容置空 msg_content = None # link置空 msg_link = None# 文本或者好友推荐 if msg['Type'] == 'Text' or msg['Type'] == 'Friends': msg_content = msg['Text'] print('[Text/Friends]: %s' % msg_content) # 附件/视频/图片/语音 elif msg['Type'] == 'Attachment' or msg['Type'] == "Video" or msg['Type'] == 'Picture' or msg['Type'] == 'Recording': msg_content = msg['FileName'] msg['Text'](str(msg_content)) print('[Attachment/Video/Picture/Recording]: %s' % msg_content) # 推荐名片 elif msg['Type'] == 'Card': msg_content = msg['RecommendInfo']['NickName'] + '的推荐名片,' if msg['RecommendInfo']['Sex'] == 1: msg_content += '性别男。' else: msg_content += '性别女。' print('[Card]: %s' % msg_content) # 位置信息 elif msg['Type'] == 'Map': x, y, location = re.search("<location x=\"(.*?)\" y=\"(.*?)\".*label=\"(.*?)\".*", msg['OriContent']).group(1, 2, 3) if location is None: msg_content = r"纬度:" + x.__str__() + ", 经度:" + y.__str__() else: msg_content = r"" + location print('[Map]: %s' % msg_content) # 分享的音乐/文章 elif msg['Type'] == 'Sharing': msg_content = msg['Text'] msg_link = msg['Url'] print('[Sharing]: %s' % msg_content)msg_info.update( { msg_id: { "msg_from": msg_from, "msg_time_send": msg_time_send, "msg_time_receive": msg_time_receive, "msg_type": msg["Type"], "msg_content": msg_content, "msg_link": msg_link } } ) # 再次注册NOTE即通知类型 @itchat.msg_register(NOTE, isFriendChat=True, isGroupChat=True, isMpChat=True) def monitor(msg): if '撤回了一条消息' in msg['Content']:# 此处\<msgid\>(.*?)\<\/msgid\>的原因是,如果将msg['Content']打印出来,会在其中得到含有\<msgid\> \<\/msgid\>的一段信息 # 而(.*?)则是正则表达式,用于匹配其中的任意字符串 # 同时,group(1)表示从第一个左括号处开始匹配 recall_msg_id = re.search("\<msgid\>(.*?)\<\/msgid\>", msg['Content']).group(1) recall_msg = msg_info.get(recall_msg_id) print('[Recall]: %s' % recall_msg) msg_prime = '---' + recall_msg.get('msg_from') + '撤回了一条消息---\n' \ '消息类型:' + recall_msg.get('msg_type') + '\n' \ '时间:' + recall_msg.get( 'msg_time_receive') + '\n' \ '内容:' + recall_msg.get('msg_content') if recall_msg['msg_type'] == 'Sharing': msg_prime += '\n链接:' + recall_msg.get('msg_link') # 向文件助手发送消息 itchat.send_msg(msg_prime, toUserName='filehelper') if recall_msg['msg_type'] == 'Attachment' or recall_msg['msg_type'] == "Video" or recall_msg[ 'msg_type'] == 'Picture' or recall_msg['msg_type'] == 'Recording': file = '@fil@%s' % (recall_msg['msg_content']) itchat.send(msg=file, toUserName='filehelper') msg_info.pop(recall_msg_id) itchat.run()
相关文章推荐
- Python微信库:itchat的用法详解
- 使用Python微信库itchat获得好友和群组已撤回的消息
- Python微信好友信息意义及取值分析(基于itchat)
- Python itchat模块在微信上的各种小应用
- Python之itchat生成微信头像拼接问题
- 安装python itchat 模块 用python发微信消息
- 微信小程序支付过程详解,基于node.js的后台
- Python itchat模块在微信上的各种小应用
- 有了 itchat, python 调用微信个人号从未如此简单(新增 py3 支持)
- python实现微信接口(itchat)
- Python—itchat小程序之——景点信息获取
- Python利用itchat对微信中好友数据实现简单分析的方法
- Python实现微信好友签名词云的构建(itchat、jieba、wordcloud)
- python使用itchat发送微信消息提醒
- Python微信库: itchat
- 在python中使用itchat发送微信消息
- python实现微信接口(itchat)详细介绍
- Python学习-Itchat微信API
- 在python中使用itchat发送微信消息
- python实现微信接口(itchat)