微软小冰接入itchat实现微信自动回复
- 本文简介
- 先上效果图!
- 一、集成微软小冰制作聊天机器人
- 原理
- 代码
- 监听好友信息
- 监听小冰信息
- 二、定时发送消息推送与自动回复同时实现
- 原理
- 代码
- 完整代码
- 加点花的代码
- 结语
本文简介
最近研究了一下基于python实现的itchat模块,这是一个基于微信网页版接口的微信开源库,通过itchat模块,可以很简单的实现微信的自动回复,在本文之前,网络上也已经有了非常多优秀详实的介绍教程,在仔细学习之后,我也决定写一篇,作为对这个 好玩的模块的学习记录。
通过本文,你可以实现:一、集成微软小冰制作聊天机器人,二、定时发送消息推送与自动回复同时实现
先上效果图!
一、集成微软小冰制作聊天机器人
原理
获取用户发送的信息并将其转发给微软小冰,监听小冰的回复,再将其转发给用户。(这是一种全新的思路,没有使用图灵或者小i的api接口,第一是因为图灵的认证非常麻烦,第二是因为其智能程度远不及小冰。)
代码
监听好友信息
@itchat.msg_register(itchat.content.TEXT, isFriendChat=True)#itchat.content.TEXT表明只监听文字信息, isFriendChat=True表明只监听好友信息
def reply_msg(msg):print(msg['User']['NickName'])#msg['User']['NickName']为好友的微信昵称global people#此处定义的全局变量非常关键,它是将好友的信息传回小冰的关键people=msg['FromUserName']#将全局变量定义为好友的ID,注意这个ID不是昵称print(msg['Content'])#将好友发来的信息打印出来mps = itchat.search_mps(name='小冰')#搜索小冰if len(mps) > 0:print(mps[0]['NickName'])itchat.send_msg(msg['Content'], toUserName=mps[0]['UserName'])#给小冰发消息
监听小冰信息
@itchat.msg_register(itchat.content.TEXT, isMpChat=True)#isMpChat=True表明只监听公众号信息,注意小冰是个公众号
def reply_msg(msg)print(msg['Content'])#将小冰的消息显示出来print(people)itchat.send_msg(msg['Content'], people)#将这个消息发送给原来的那个人
二、定时发送消息推送与自动回复同时实现
原理
多进程的实现,用keeprun进程来保持自动回复,用keepsend来进行定时发送。其中keepsend通过匹配当时时间是否在一个时间段内,之前尝试匹配固定时间点没有成功,可能是网络的原因。在自动回复方面为了实现订阅效果,还使用了sqlite数据库来记录好友的订阅请求。
代码
def AddUser(user):cx = sqlite3.connect("G:/wx.db")cu=cx.cursor()rr="insert into user( name) values ("+"'"+ user+"'"+")"cu.execute(rr)print(rr)cx.commit()cx.close()def keeprun():itchat.run()def keepsend():d_time = datetime.datetime.strptime(str(datetime.datetime.now().date())+'7:00:00', '%Y-%m-%d%H:%M:%S')d_time1 = datetime.datetime.strptime(str(datetime.datetime.now().date())+'7:00:10', '%Y-%m-%d%H:%M:%S')while(1==1): nowTime = datetime.datetime.now()if(nowTime > d_time and nowTime<d_time1):send_msg()#需要定时发送的信息 time.sleep(10)#睡眠的原因是为了不造成多次发送threads = []
t1 = threading.Thread(target=keeprun)
threads.append(t1)
t2 = threading.Thread(target=keepsend)
threads.append(t2)
完整代码
```python
import itchat
from itchat.content import *
import time
import threading@itchat.msg_register(itchat.content.TEXT, isMpChat=True)
def reply_msg(msg):print(msg['Content']) # 将小冰的消息显示出来print(people)itchat.send_msg(msg['Content'], people) # 将这个消息发送给原来的那个人@itchat.msg_register(itchat.content.TEXT, isFriendChat=True)
def reply_msg(msg):print(msg['User']['NickName'])global peoplepeople = msg['FromUserName']print(msg['Content'])mps = itchat.search_mps(name='小冰')if len(mps) > 0:print(mps[0]['NickName'])itchat.send_msg(msg['Content'], toUserName=mps[0]['UserName']) # 给小冰发消息if __name__ == '__main__':itchat.auto_login(hotReload=True, enableCmdQR=True)itchat.run()
加点花的代码
import itchat
import sqlite3
from apscheduler.schedulers.blocking import BlockingScheduler
import time
import datetime
from itchat.content import *
import time
import threading
import urllib3, json, urllib
import re,io
import jieba
from wordcloud import WordCloud
from wordcloud import ImageColorGenerator
import imageio
from scipy.misc import imread, imshow, imsave
import scipy
import matplotlib.pyplot as plt
import requests as rq
@itchat.msg_register(itchat.content.TEXT, isMpChat=True)
def reply_msg(msg):if msg['Content'] == u'今日新闻':itchat.send_msg(msg['User']['NickName'] + "您好:您的今日新闻已订阅成功,系统将在每天7点钟为您推送前一日热点新闻,如需退订,请回复TD!", msg['FromUserName'])print(msg['User']['NickName'])AddUser(msg['User']['NickName'])if msg['Content'] == u'今日黄历':itchat.send_msg(msg['User']['NickName'] + get_huangli(), msg['FromUserName'])print(msg['User']['NickName'])AddUser(msg['User']['NickName'])if msg['Content'] == u'今日头条':itchat.send_msg(msg['User']['NickName'] +"今日头条:"+ get_news(), msg['FromUserName'])print(msg['User']['NickName'])AddUser(msg['User']['NickName'])if msg['Content'] == u'词云':my_friends()my_friends_sex(my_friends())my_friends_style(my_friends())drow_sex(my_friends_sex(my_friends()))wordart()itchat.send_image('G://2.png', msg['FromUserName'])else:print(msg['Content'])#将小冰的消息显示出来print(people)itchat.send_msg(msg['Content'], people)#将这个消息发送给原来的那个人@itchat.msg_register(itchat.content.TEXT, isFriendChat=True)
def reply_msg(msg):if msg['Content'] == u'今日新闻':itchat.send_msg(msg['User']['NickName'] + "您好:您的今日新闻已订阅成功,系统将在每天7点钟为您推送前一日热点新闻,如需退订,请回复TD!", msg['FromUserName'])print(msg['User']['NickName'])AddUser(msg['User']['NickName'])if msg['Content'] == u'今日黄历':itchat.send_msg(msg['User']['NickName'] + get_huangli(), msg['FromUserName'])print(msg['User']['NickName'])AddUser(msg['User']['NickName'])if msg['Content'] == u'今日头条':itchat.send_msg(msg['User']['NickName'] +"今日头条:"+ get_news(), msg['FromUserName'])print(msg['User']['NickName'])AddUser(msg['User']['NickName'])if msg['Content'] == u'词云':my_friends()my_friends_sex(my_friends())my_friends_style(my_friends())drow_sex(my_friends_sex(my_friends()))wordart()#itchat.send_msg("我是一个机器人!", msg['FromUserName'])#itchat.send_image("G://词云.png", msg['FromUserName'])itchat.send_image('G://2.png', msg['FromUserName'])else:print(msg['User']['NickName'])global peoplepeople=msg['FromUserName']print(msg['Content'])mps = itchat.search_mps(name='小冰')if len(mps) > 0:print(mps[0]['NickName'])itchat.send_msg(msg['Content'], toUserName=mps[0]['UserName'])#给小冰发消息def AddUser(user):cx = sqlite3.connect("G:/wx.db")cu=cx.cursor()rr="insert into user( name) values ("+"'"+ user+"'"+")"cu.execute(rr)print(rr)cx.commit()cx.close()def get_iciba_everyday():#金山词霸每日一句url = 'http://open.iciba.com/dsapi/'r = requests.get(url)return json.loads(r.text)def send_msg():#定时发送消息# 1、获取新闻data = {}data["appkey"] = "自己申请api"data["channel"] = "头条" #新闻频道(头条,财经,体育,娱乐,军事,教育,科技,NBA,股票,星座,女性,健康,育儿)url_values = urllib.parse.urlencode(data)url = "https://api.jisuapi.com/news/get" + "?" + url_valuesrequest = urllib.request.Request(url)result = urllib.request.urlopen(request)jsonarr = json.loads(result.read())result = jsonarr["result"] i=0con=""con2=""con3=""con4=""for val in result["list"]:content1= ''.join(val['title'])str1=content1con=con+"\n"+str1#con是新闻url = 'http://open.iciba.com/dsapi/'r = urllib.request.Request(url)result = urllib.request.urlopen(r)content = json.loads(result.read())con2= '\n每日一句:\n'+content['content'] +'\n'+content['note']con3=get_huangli()con="今日关注\n"+con+"\n"+con2+"\n"+con3cx = sqlite3.connect("G:/wx.db")cu=cx.cursor()cu = cx.execute("select name from user")for (row,) in cu: #循环输出结果print(row)#print(row.split(' ', 1 )) # 以空格为分隔符,分隔成两个user_info = itchat.search_friends(name=row)if len(user_info) > 0:user_name = user_info[0]['UserName']itchat.send_msg(con, toUserName=user_name)def get_huangli():#黄历接口data = {}data["appkey"] = "自己申请api"data["year"] =datetime.datetime.now().strftime('%Y')#现在 data["month"] = datetime.datetime.now().strftime('%m')#现在data["day"] =datetime.datetime.now().strftime('%d')#现在 url_values = urllib.parse.urlencode(data)url = "https://api.jisuapi.com/huangli/date" + "?" + url_valuesrequest = urllib.request.Request(url) result = urllib.request.urlopen(request)jsonarr = json.loads(result.read()) result = jsonarr["result"]content1='天干地支:' + ','.join(result['suici'])content2='今日应当注意的生肖:' + result["chong"]content3='宜:' + ','.join(result['yi'])content4='忌:' + ','.join(result['ji'])return '今日黄历:'+content1+'\n'+content2+'\n'+content3+'\n'+content4
def get_news():# 1、获取新闻 data = {}data["appkey"] = "自己申请api"data["channel"] = "头条" #新闻频道(头条,财经,体育,娱乐,军事,教育,科技,NBA,股票,星座,女性,健康,育儿)url_values = urllib.parse.urlencode(data)url = "https://api.jisuapi.com/news/get" + "?" + url_valuesrequest = urllib.request.Request(url)result = urllib.request.urlopen(request)jsonarr = json.loads(result.read()) result = jsonarr["result"] #print(result["channel"],result["num"])i=0con=""for val in result["list"]:content1= ''.join(val['title'])str1=content1con=con+"\n"+str1 #str[i]='\n'+'今日关注:'+content1+'\n'#time.sleep(3) return(con) def get_bots(message):#小i机器人data = {}data["appkey"] = "自己申请api"data["question"] = message url_values = urllib.parse.urlencode(data)url = "https://api.jisuapi.com/iqa/query" + "?" + url_values request = urllib.request.Request(url)result = urllib.request.urlopen(request)jsonarr = json.loads(result.read()) result = jsonarr["result"]print(result["type"],result["content"])return(str(result["content"]))#return(result)#for row in result["relquestion"]:#print(row)#return(row)def get_bot2(message):#图灵机器人print("得到消息")info = message# 图灵API接口api_url = 'http://openapi.tuling123.com/openapi/api/v2'# 接口请求数据data = {"reqType": 0,"perception": {"inputText": {"text": str(info)}},"userInfo": {"apiKey": "自己申请api","userId": "123"}}headers = {'Content-Type': 'application/json','Host': 'openapi.tuling123.com','User-Agent': 'Mozilla/5.0 (Wi`ndows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3486.0 ''Safari/537.36 '}# 请求接口result = rq.post(api_url, headers=headers, json=data).json()print(result['results'][0]['values']['text'])return(str(result['results'][0]['values']['text']))#####用于得到好友的状态签名词云及好友男女分布
def my_friends():#二维码登陆 #获取好友信息friends = itchat.get_friends(update=True)return friends
def my_friends_sex(friends): #创建一个字典用于存放好友性别信息friends_sex = dict()#定义好友性别信息字典的key,分别为男性,女性,其他male = "男性"female = "女性"other = "其他"#遍历列表中每一个好友的信息, for i in friends[1:]:sex = i["Sex"]if sex == 1:#字典操作,找到key并为其的值加1friends_sex[male] = friends_sex.get(male,0) + 1elif sex == 2:friends_sex[female] = friends_sex.get(female,0) + 1elif sex == 0 :friends_sex[other] = friends_sex.get(other,0) + 1#打印好友性别信息的字典#print (friends_sex)#好友总数,从第二个开始是因为第一个好友是自己totle = len(friends[1:])proportion = [float(friends_sex[male])/totle*100,float(friends_sex[female])/totle*100,float(friends_sex[other])/totle*100]print ("男性好友:%.2f%% " % (proportion[0]) +'\n' +"女性好友:%.2f%% " % (proportion[1]) +'\n' +"其他:%.2f%% " % (proportion[2]))return friends_sex
def my_friends_style(friends):#创建列表用于存放个性签名style = []for i in range(len(friends)):#每一个好友的信息存放在列表中的字典里,此处获取到i = friends[i]#得到每个字典的个性签名的key,即Signature#strip去除字符串首位的空格,replace去掉英文Signature = i['Signature'].strip().replace('span','').replace('class','').replace('emoji','')#通过正则表达式将签名中的特殊符号去掉,re.sub则相当于字符串操作中的replacerep = re.compile('1f\d+\w*|[<>/=]')Signature=rep.sub('',Signature)#放入列表style.append(Signature)#join() 方法用于将序列中的元素以指定的字符连接生成一个新的字符串。#此处将所有签名去除特殊符号和英文之后,拼接在一起text = ''.join(style)#将输出保存到文件,并用结巴来分词with io.open('G://text.txt','a',encoding = 'utf-8') as f:wordlist = jieba.cut(text,cut_all=False)word_space_split = ' '.join(wordlist)f.write(word_space_split)def drow_sex(friends_sex):#获取饼状图的标签和大小labels = []sizes = []for key in friends_sex:labels.append(key)sizes.append(friends_sex[key])#每块图的颜色,数量不足时会循环使用colors = ['red', 'yellow', 'blue']#每一块离中心的距离explode = (0.1,0,0)#autopct='%1.2f%%'百分数保留两位小数点;shadow=True,加阴影使图像更立体#startangle起始角度,默认为0°,一般设置为90比较好看plt.pie(sizes,explode=explode,labels=labels,colors=colors,autopct='%1.2f%%',shadow=True,startangle=90)#设置图像的xy轴一致plt.axis('equal')#显示颜色和标签对应关系plt.legend()#添加title,中文有乱码是个坑,不过我找到填平的办法了plt.suptitle("微信好友性别统计图")#保存到本地,因为show之后会创建空白图层,所以必须在show之前保存plt.savefig('F:\好友性别饼状图.png')plt.show()
def wordart():back_color =imread('G://1.png')wc = WordCloud(background_color='white', #背景色max_words=1000,mask=back_color, #以该参数值绘制词云max_font_size=100, font_path="C:/Windows/Fonts//STFANGSO.ttf", #设置字体类型,主要为了解决中文乱码问题random_state=42, #为每一词返回一个PIL颜色)#打开词源文件text = open("G://text.txt",encoding='utf-8').read()#wc.generate(text)#基于彩色图像生成相应颜色image_colosr = ImageColorGenerator(back_color)#显示图片plt.imshow(wc)#关闭坐标轴plt.axis("off")#保存图片wc.to_file("G://2.png")def keeprun():itchat.run()def keepsend():d_time = datetime.datetime.strptime(str(datetime.datetime.now().date())+'7:00:00', '%Y-%m-%d%H:%M:%S')d_time1 = datetime.datetime.strptime(str(datetime.datetime.now().date())+'7:00:10', '%Y-%m-%d%H:%M:%S')while(1==1): nowTime = datetime.datetime.now()if(nowTime > d_time and nowTime<d_time1):send_msg() time.sleep(10)
threads = []
t1 = threading.Thread(target=keeprun)
threads.append(t1)
t2 = threading.Thread(target=keepsend)
threads.append(t2)
if __name__ == '__main__': itchat.auto_login(hotReload=True, enableCmdQR=True) for t in threads:t.setDaemon(True)t.start()
结语
本文参考了
https://blog.csdn.net/coder_pig/article/details/81357810,
https://blog.csdn.net/woniu_001/article/details/80558514
在此表示感谢。
感谢您花时间浏览本文,本文是我的第一篇作品,必然有许多错误之处,也希望您可以将发现的问题反馈给我!
突然发现itchat已经不让使用了,遗憾。在寻找其他可以替代的产品。