微软小冰接入itchat实现微信自动回复

微软小冰接入itchat实现微信自动回复

  • 本文简介
    • 先上效果图!
    • 一、集成微软小冰制作聊天机器人
    • 原理
    • 代码
      • 监听好友信息
      • 监听小冰信息
    • 二、定时发送消息推送与自动回复同时实现
    • 原理
    • 代码
    • 完整代码
    • 结语

本文简介

最近研究了一下基于python实现的itchat模块,这是一个基于微信网页版接口的微信开源库,通过itchat模块,可以很简单的实现微信的自动回复,在本文之前,网络上也已经有了非常多优秀详实的介绍教程,在仔细学习之后,我也决定写一篇,作为对这个 好玩的模块的学习记录。
通过本文,你可以实现:一、集成微软小冰制作聊天机器人,二、定时发送消息推送与自动回复同时实现

先上效果图!

微软小冰接入itchat实现微信自动回复_第1张图片微软小冰接入itchat实现微信自动回复_第2张图片

一、集成微软小冰制作聊天机器人

原理

获取用户发送的信息并将其转发给微软小冰,监听小冰的回复,再将其转发给用户。(这是一种全新的思路,没有使用图灵或者小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

完整代码


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 people
        people=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_values
    request = urllib.request.Request(url)
    result = urllib.request.urlopen(request)
    jsonarr = json.loads(result.read())
    result = jsonarr["result"] 
    i=0
    con=""
    con2=""
    con3=""
    con4=""
    for val in result["list"]:
        content1= ''.join(val['title'])
        str1=content1
        con=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"+con3
    cx = 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_values
    request = 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_values
    request = urllib.request.Request(url)
    result = urllib.request.urlopen(request)
    jsonarr = json.loads(result.read()) 
    result = jsonarr["result"] 
    #print(result["channel"],result["num"])
    i=0
    con=""
    for val in result["list"]:
        content1= ''.join(val['title'])
        str1=content1
        con=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并为其的值加1
            friends_sex[male] = friends_sex.get(male,0) + 1
        elif sex == 2:
            friends_sex[female] = friends_sex.get(female,0) + 1
        elif 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则相当于字符串操作中的replace
        rep = 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

结语

本文参考了
https://blog.csdn.net/coder_pig/article/details/81357810,
https://blog.csdn.net/woniu_001/article/details/80558514
在此表示感谢。

感谢您花时间浏览本文,本文是我的第一篇作品,必然有许多错误之处,也希望您可以将发现的问题反馈给我!

你可能感兴趣的:(python)