微信第三方库简单运用ItChat

javascript

浏览数:987

2019-1-7


ItChat

#-*-encoding:utf-8-*-
import itchat
#from itchat.content import TEXT
from itchat.content import *
import sys
import time
import re
import os
import matplotlib,matplotlib.pyplot as plt

import random
import wordcloud
from PIL import Image
import math
import jieba
# pip3 install pandas  pandas 为数据分析工具,类似数据库中的表
# pip3 install numpy

import json
import urllib.request
#图灵机器人
def reply_tuling(info):
    api_url = "http://openapi.tuling123.com/openapi/api/v2"
    req = {
        "perception":
        {
            "inputText":
            {
                "text": info
            },

            # "selfInfo":
            # {
            #     "location":
            #     {
            #         "city": "",
            #         "province": "",
            #         "street": ""
            #     }
            # }
        },

        "userInfo":
        {
            "apiKey": "788189184d8b42408555a1d0ed770b41",
            "userId": "358485"
        }
    }
    # 将字典格式的req编码为utf8
    req = json.dumps(req).encode('utf8')
    http_post = urllib.request.Request(api_url, data=req, headers={'content-type': 'application/json'})
    response = urllib.request.urlopen(http_post)
    response_str = response.read().decode('utf8')
    # print(response_str)
    response_dic = json.loads(response_str)

    intent_code = response_dic['intent']['code']
    if 4003 == intent_code:
        return '我要休息了,下次再聊'  #使用次数到达了1000
    else:
        results_text = response_dic['results'][0]['values']['text']
        print(results_text)
        return results_text
msg_information = {}
face_bug=None  #针对表情包的内容
#消息接收
@itchat.msg_register([TEXT, PICTURE, FRIENDS, CARD, MAP, SHARING, RECORDING, ATTACHMENT, VIDEO],isFriendChat=True, isGroupChat=True, isMpChat=True)
def handle_receive_msg(msg):
    global face_bug

    if msg == None :
        return
    msg_time_rec = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())   #接受消息的时间
    msg_from = itchat.search_friends(userName=msg['FromUserName'])#['NickName']   #在好友列表中查询发送信息的好友昵称
    msg_time=''
    msg_id = 0
    msg_content = None      #储存信息的内容
    msg_share_url = None    #储存分享的链接,比如分享的文章和音乐
    print(msg)
    if 'MsgId' in msg:
        msg_id = msg['MsgId']  # 每条信息的id
    if 'CreateTime' in msg:
        msg_time = msg['CreateTime']  # 信息发送的时间
    if 'ActualNickName' in msg:
        print(msg['ActualNickName'])
    else:
        pass
    if 'User' in msg :
        test = msg['User']
        if 'RemarkName' in test and test['RemarkName']:
            print(test['RemarkName'])
        elif 'NickName' in test:
            print(test['NickName'])
    else:
        pass

    if msg['Type'] == 'Text' or msg['Type'] == 'Friends':     #如果发送的消息是文本或者好友推荐
        if 'newsapp' != msg['FromUserName']:
            msg_content = msg['Text']
            if '图灵' in msg_content: #机器人对话功能
                testContent = msg_content[2:]
                print(testContent)
                replyTest = reply_tuling(testContent)
                if msg['ToUserName']=='filehelper':
                    itchat.send(replyTest,'filehelper')
                else:
                    return replyTest
            elif '好友性别分析' in msg_content:
                friendlist = get_friends_weixin()
                statistic_friends_sex(friendlist)
            elif '好友头像拼接' in msg_content:
                friendlist = get_friends_weixin()
                picture_friend(friendlist)
            elif '好友个性签名词云生成'in msg_content:
                getSignature()
            elif '爬取朋友友圈'in msg_content:
                pass
            elif '开启摄像头' in msg_content:
                pass
    #如果发送的消息是附件、视屏、图片、语音
    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 msg_content
    elif msg['Type'] == 'Card':    #如果消息是推荐的名片
        msg_content = msg['RecommendInfo']['NickName'] + '的名片'    #内容就是推荐人的昵称和性别
        if msg['RecommendInfo']['Sex'] == 1:
            msg_content += '性别为男'
        else:
            msg_content += '性别为女'

        print(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
    elif msg['Type'] == 'Sharing':     #如果消息为分享的音乐或者文章,详细的内容为文章的标题或者是分享的名字
        msg_content = msg['Text']
        msg_share_url = msg['Url']       #记录分享的url
        print(msg_share_url)
    face_bug=msg_content

##将信息存储在字典中,每一个msg_id对应一条信息
    msg_information.update(
        {
            msg_id: {
                "msg_from": msg_from, "msg_time": msg_time, "msg_time_rec": msg_time_rec,
                "msg_type": msg["Type"],
                "msg_content": msg_content, "msg_share_url": msg_share_url
            }
        }
    )

##这个是用于监听是否有消息撤回
@itchat.msg_register(NOTE, isFriendChat=True, isGroupChat=True, isMpChat=True)
def information(msg):
    #这里如果这里的msg['Content']中包含消息撤回和id,就执行下面的语句
    #print(msg)
    if msg['MsgType'] == 1000:
        if 'User' in msg and msg['Content'] == '收到红包,请在手机上查看':
            test = msg['User']
            mssseageInfo = ''
            if 'RemarkName' in test and test['RemarkName']:
                mssseageInfo = test['RemarkName']
            else:
                mssseageInfo = (test['NickName'])
            itchat.send('%s 给你发了个红包,请注意查收。'% mssseageInfo,'filehelper')
    else:
        pass

    if '撤回了一条消息' in msg['Content']:
        old_msg_id = re.search("\<msgid\>(.*?)\<\/msgid\>", msg['Content']).group(1)   #在返回的content查找撤回的消息的id
        old_msg = msg_information.get(old_msg_id)    #得到消息
        print(old_msg)
        if old_msg == None:
            return
        else:
            pass
        if len(old_msg_id)<11:  #如果发送的是表情包
            itchat.send_file(face_bug,toUserName='filehelper')
        else:  #发送撤回的提示给文件助手
            msg_body ='撤回消息为: '+ old_msg['msg_content']
            #如果是分享的文件被撤回了,那么就将分享的url加在msg_body中发送给文件助手
            if old_msg['msg_type'] == "Sharing":
                msg_body += "\n就是这个链接➣ " + old_msg.get('msg_share_url')

            # 将撤回消息发送到文件助手
            itchat.send_msg(msg_body, toUserName='filehelper')
            # 有文件的话也要将文件发送回去
            if old_msg["msg_type"] == "Picture" \
                    or old_msg["msg_type"] == "Recording" \
                    or old_msg["msg_type"] == "Video" \
                    or old_msg["msg_type"] == "Attachment":
                file = '@fil@%s' % (old_msg['msg_content'])
                itchat.send(msg=file, toUserName='filehelper')
                os.remove(old_msg['msg_content'])
            # 删除字典旧消息
            msg_information.pop(old_msg_id)
#微信好友分析
def get_friends_weixin():
    friends = itchat.get_friends(update=True)[0:]
    #statistic_friends_sex(friends)
    return friends

#统计好友性别
def statistic_friends_sex(friends_dict):
    result=[0,0,0]
    for friend in friends_dict[1:]:
        sex = friend['Sex'] # 1 男   2女
        if sex == 1:
            result[0] += 1
        elif sex == 2:
            result[1] += 1
        else:
            result[2] += 1
    sex_pie_chart(result)
    #return result
#好友头像拼接
def picture_friend(friends_dict):
    for count, f in enumerate(friends_dict):
        # 根据userName获取头像
        img = itchat.get_head_img(userName=f["UserName"])
        imgFile = open("img/" + str(count) + ".jpg", "wb")
        imgFile.write(img)
        imgFile.close()
    createImg()
def sex_pie_chart(sex_num):
    """
    该函数功能为实现画出性别统计的饼图
    :param sex_num: 统计好的性别数据, [#male, #female, #unknown]
    """
    # 指定默认字体
    matplotlib.rcParams['font.sans-serif'] = ['SimHei']
    matplotlib.rcParams['font.family'] = 'sans-serif'

    # 解决负号'-'显示为方块的问题
    matplotlib.rcParams['axes.unicode_minus'] = False

    labels = ['男', '女', '不明']
    colors = ['green', 'pink', 'yellow']
    plt.pie(sex_num, colors=colors, labels=labels, autopct='%1.1f%%', pctdistance=0.8)
    plt.title('微信好友性别情况', bbox={'facecolor': '0.8', 'pad': 5})
    plt.savefig("sex.png")
    itchat.send_image("sex.png", toUserName='filehelper')
    #plt.show()
#好友图像拼接
def createImg():
    x = 0
    y = 0
    imgs = os.listdir("img")
    random.shuffle(imgs)
    # 创建640*640的图片用于填充各小图片
    newImg = Image.new('RGBA', (640, 640))
    # 以640*640来拼接图片,math.sqrt()开平方根计算每张小图片的宽高,
    width = int(math.sqrt(640 * 640 / len(imgs)))
    # 每行图片数
    numLine = int(640 / width)

    for i in imgs:
        img = Image.open("img/" + i)
        # 缩小图片
        img = img.resize((width, width), Image.ANTIALIAS)
        # 拼接图片,一行排满,换行拼接
        newImg.paste(img, (x * width, y * width))
        x += 1
        if x >= numLine:
            x = 0
            y += 1

    newImg.save("all.png")
    itchat.send_image("all.png", toUserName='filehelper')

#个性签名
def getSignature():
    #itchat.login()
    friends = itchat.get_friends(update=True)
    file = open('sign.txt', 'a', encoding='utf-8')
    for f in friends:
        signature = f["Signature"].strip().replace("emoji", "").replace("span", "").replace("class", "")
        # 正则匹配
        rec = re.compile("1f\d+\w*|[<>/=]")
        signature = rec.sub("", signature)
        file.write(signature + "\n")

    file.close()
    create_word_cloud('sign.txt')

# 生成词云图
def create_word_cloud(filename):
    # 读取文件内容
    # f = open("{}.txt".format(filename), encoding='utf-8')
    # text = f.read()
    text = open(filename,'r',encoding='utf-8').read()
    # 注释部分采用结巴分词
    # wordlist = jieba.cut(text, cut_all=True)
    # wl = " ".join(wordlist)

    # 设置词云
    wc = wordcloud.WordCloud(
            # 设置背景颜色
            background_color="white",
            # 设置最大显示的词云数
            max_words=2000,
            # 这种字体都在电脑字体中,window在C:\Windows\Fonts\下,mac下可选/System/Library/Fonts/PingFang.ttc 字体
            font_path='C:\\Windows\\Fonts\\simfang.ttf',
            height=500,
            width=500,
            # 设置字体最大值
            max_font_size=60,
            # 设置有多少种随机生成状态,即有多少种配色方案
            random_state=30,
    )
    # myword = wc.generate(wl)
    myword = wc.generate(text)  # 生成词云 如果用结巴分词的话,使用wl 取代 text, 生成词云图
    # 展示词云图
    plt.imshow(myword)
    plt.axis("off")
    #plt.show()
    wc.to_file('signature.png')  # 把词云保存下
    itchat.send_image("signature.png", toUserName='filehelper')

itchat.auto_login(hotReload=True)

itchat.run()