引言
众所周知python有一个功能十分强大的库— — itchat。本篇文章将用Python实现微信的接受消息,防撤回等功能,这些功能的实现离不开itchat的运用。
itchat基本介绍
1.如何登陆微信
首先安装itchat库。
import itchat
itchat.login()
运行后,手机微信扫描二维码即可登陆。
注意:出于安全考虑,腾讯封停了网页版微信API,新注册的微信账号可能无法登陆微信网页版。此时安装itchat-uos版本即可。
这里需要注意一个问题,每次运行程序都要扫描二维码登录,这样未免太麻烦,有没有办法只扫描一次,以后就自动登录了呢?这当然是可以的。
import itchat
itchat.auto_login(hotReload=True)
运行程序,扫码登录之后会在项目路径下创建一个itchat.pkl文件,该文件用于存储登录的状态,所以不要动它,如果你想换一个微信账号登录,就要先把这个文件删除,因为该文件记录的是上一个微信的登陆状态,删除之后即可切换账号登录。
注意:这种方式只能保证你在短时间内无需重复登录,时间长了,还是需要重新扫码登录的。
2.获取好友列表
用itchat模块提供的API获取好友列表。
import itchat
itchat.auto_login(hotReload=True)
friends = itchat.get_friends()
print(friends)
使用get_friends()函数即可获取到好友列表的所有好友信息,包括昵称、备注名、地址、个性签名、性别等等。
UserName,这是用户的唯一标识,相当于身份证号码,你的每个好友都会有这样一个标识,每个好友之间肯定都是不一样的;然后是NickName,这是好友的昵称;HeadImgUrl是好友的头像地址;RemarkName是你对好友的备注;Province是省份等等,这里不一一介绍。
3.如何发送消息给好友
import itchat
itchat.auto_login(hotReload=True)
friends = itchat.get_friends()
name = '你对好友的备注'
for i in friends:
if '你对好友的备注' == i['RemarkName']:
itchat.send('想要发送的消息内容', toUserName=i['UserName'])
break
这样,就可以指定发送给任意好友,通过好友的备注在好友列表中进行检索,找到的话,就获取该好友的UserName,然后发送消息,也可以通过好友的昵称(NickName)查找。
4.装饰器
itchat模块还有很多功能,这里就不作过多讲解了,关于装饰器,一时半会儿讲不清楚,这里只是简单介绍一下,装饰器的作用就是用于拓展原来函数功能的一种函数,目的是在不改变原函数名(或类名)的情况下,给函数增加新的功能。
程序源代码
随便调试了一小会儿,目前没发现bug,后续如果找到bug会再修改。
import itchat
from itchat.content import *
import os
import time
from playsound import playsound
import xml.dom.minidom
temp = 'E:/python/微信脚本/消息' + '/' + '撤回的消息'
new_temp = 'E:/python/微信脚本/消息' + '/' + '聊天记录'
tp = r'E:/python/微信脚本/消息/撤回的消息'
ntp = r'E:/python/微信脚本/消息/聊天记录'
dict = {}
@itchat.msg_register([TEXT, PICTURE, FRIENDS, CARD, MAP, SHARING, RECORDING, ATTACHMENT, VIDEO])
def resever_info(msg):
global dict
info = msg['Text']
msgId = msg['MsgId']
info_type = msg['Type']
name = msg['FileName']
fromUser = itchat.search_friends(userName=msg['FromUserName'])['RemarkName']
ticks = msg['CreateTime']
time_local = time.localtime(ticks)
dt = time.strftime("%Y-%m-%d %H:%M:%S", time_local)
dict[msgId] = {"info": info, "info_type": info_type, "name": name, "fromUser": fromUser, "dt": dt}
msg_type = dict[msgId]['info_type']
if msg_type == 'Text':
text_info = dict[msgId]['info']
fromUser = dict[msgId]['fromUser']
dt = dict[msgId]['dt']
print('时间:' + dt + '\n' + fromUser + ':' + text_info)
elif msg_type == 'Picture':
picture_info = dict[msgId]['info']
fromUser = dict[msgId]['fromUser']
dt = dict[msgId]['dt']
info_name = dict[msgId]['name']
picture_info(new_temp + '/' + info_name)
print('时间:' + dt + '\n' + fromUser + ':' + '<图片>')
elif msg_type == 'Recording':
recording_info = dict[msgId]['info']
info_name = dict[msgId]['name']
fromUser = dict[msgId]['fromUser']
dt = dict[msgId]['dt']
recording_info(new_temp + '/' + info_name)
playsound(new_temp + '/' + info_name)
print('时间:' + dt + '\n' + fromUser + ':' + '<语音>')
@itchat.msg_register(NOTE)
def note_info(msg):
content = msg['Content']
doc = xml.dom.minidom.parseString(content)
result = doc.getElementsByTagName("msgid")
msgId = result[0].childNodes[0].nodeValue
msg_type = dict[msgId]['info_type']
if '撤回了一条消息' in msg['Text']:
if msg_type == 'Recording':
recording_info = dict[msgId]['info']
info_name = dict[msgId]['name']
fromUser = dict[msgId]['fromUser']
dt = dict[msgId]['dt']
recording_info(temp + '/' + info_name)
send_msg = '发送人:' + fromUser + '\n' + '发送时间:' + dt + '\n' + '撤回了一条语音'
itchat.send(send_msg, 'filehelper')
itchat.send_file(temp + '/' + info_name, 'filehelper')
del dict[msgId]
print(fromUser + " 撤回了一条消息")
elif msg_type == 'Text':
text_info = dict[msgId]['info']
fromUser = dict[msgId]['fromUser']
dt = dict[msgId]['dt']
send_msg = '发送人:' + fromUser + '\n' + '发送时间:' + dt + '\n' + '撤回内容:' + text_info
itchat.send(send_msg, 'filehelper')
del dict[msgId]
print(fromUser + " 撤回了一条消息")
elif msg_type == 'Picture':
picture_info = dict[msgId]['info']
fromUser = dict[msgId]['fromUser']
dt = dict[msgId]['dt']
info_name = dict[msgId]['name']
picture_info(temp + '/' + info_name)
send_msg = '发送人:' + fromUser + '\n' + '发送时间:' + dt + '\n' + '撤回了一张图片'
itchat.send(send_msg, 'filehelper')
itchat.send_file(temp + '/' + info_name, 'filehelper')
del dict[msgId]
print(fromUser + " 撤回了一条消息")
def clear_cache(path):
ls = os.listdir(path)
for i in ls:
c_path = os.path.join(path, i)
if os.path.isdir(c_path):
clear_cache(c_path)
else:
os.remove(c_path)
if __name__ == '__main__':
if not os.path.exists(temp):
os.mkdir(temp)
if not os.path.exists(new_temp):
os.mkdir(new_temp)
clear_cache(tp)
clear_cache(ntp)
itchat.auto_login()
itchat.run()
有了这个程序就可以编敲代码边看微信消息,非常适合像我这样懒得切出去看微信消息的懒狗(手动滑稽)。
对于文本消息:直接在控制台打印输出。
对于图片消息:储存在对应位置,可点开查看。
对于语音消息:调用playsound库,使语音消息自动播放。
对于已撤回消息:储存在撤回的消息目录里,并通过文件传输助手发送到手机上,可以直接查看。
为防止聊天文件占用磁盘太多,设置了清除文件夹内容的函数,每次登录微信前会清除文件夹里之前的聊天记录文件。
之前程序写的比较匆忙,想让收到的图片自动在pycharm的sciview上绘制出来,初步设想是用matplotlib库,png文件下测试没问题,但遇到jpg和gif文件时就会报错,需要将文件转换成png文件,参考网上的代码有了一些想法,写了一点点但bug有点多,容我改改,完善后再发出来。