python微信机器人

这个微信的包和聊天机器人都是我先发现的,不过在梦里做得比较快,程序的也很好。这些都是基于这个电池做的。只可惜这个类型基于hook的访问微信的方法都会被报毒且杀掉(因为原理和病毒式一样的)。所以建议添加白名单。后面又因为未知原因无法使用这个包了。

学会使用API是效率的提升,尤其是当可以白嫖的时候。

我和在梦里一样,都使用了思知的AI小思。她的API调用极其简单直接get就行,可以去官网的文档上看看使用方法,而且她是免费的(不知道比图灵机器人好多少)。在python程序中使用基本的requests操作就可以与她对话了。(好像不太聪明的样子)那么现在要做的就是简单地把他们连起来。

做到这一步时,发现原来的的电池由于未知原因无法使用,于是转战另一个。它的用法稍微没那么直观,但逻辑更加清晰,功能更加强大,也不需要易语言的程序当病毒。简单地修改修改我的程序就可以了。注意:它只支持微信版本2.8.0.133。

一个简单的程序示例:

from PyWeChatSpy import WeChatSpy

def parser(data):
    print(data)

if __name__ == '__main__':
    spy = WeChatSpy(parser=parser, download_image=True)
    spy.run()

分析一下data的格式就知道了。如下

https://github.com/veikai/PyWeChatSpy

{"type":1,"wxid":"","nickname":"","wechatid":"","profilephoto_url":"","phone_num":""} >当前登录微信账号基本信息
{"type":2,"wxid":"","nickname":"","wechat_id":"",...} >联系人详情
{"type":5,"data":[{"self":0,"msg_type":1,"wxid1":"","wxid2":"","head":"","content":""}]} >微信消息self类型说明: * 1 消息由当前登录账号发出 * 0 消息由他人发出
msg_type类型说明: * 1 文本消息 * 37 好友请求消息 * 好友请求消息为xml结构体,其中fromusername为请求方wxid,encryptusername为v1字段,ticket为v2字段,content为请求内容 * 10000 联系人变动消息
head说明:当消息来自群聊时,head为包括被at人列表(atuserlist)、群人数(membercount)的xml结构体
{"type":200} >心跳
{"type":303} >微信登出



send_text(wxid, content, at_wxid="") >发送文本消息
send_image(wxid, image_path) >发送图片消息消息
query_contact_details(wxid) >查询联系人详情

下一步计划是识别表情包的文字以回复。

我想这里面接入百度智能云的API做到文字识别以交给小思回答。本身调用API是一件简单的事。但是微信的保存的图片是加密过的.dat文件。(充分地体现出来了微信的一些缺点。)于是,我找到了一个可以破解加密的网站,但这个就没有API供我们调用了,于是我用的是其他地方的python版

其实我现在用的电池是会自动解密并下载微信图片的,所以解密这一步也免了。现在需要解析出来表情包xml如下。

{'type': 5, 'data': [{'self': 0, 'msg_type': 47, 'wxid1': '256****@chatroom', 'wxid2': 'wxid_dq*****3fp8h22', 'head': '<msgsource>\n\t<silence>1</silence>\n\t<membercount>41</membercount>\n</msgsource>\n', 'content': '<msg><emoji fromusername = "wxid_dqaa1k*****" tousername = "256242*****@chatroom" type="1" idbuffer="media:0_0" md5="cc447c875cc1227ef01e5661dd21a157" len = "34850" productid="" androidmd5="cc447c875cc1227ef01e5661dd21a157" androidlen="34850" s60v3md5 = "cc447c875cc1227ef01e5661dd21a157" s60v3len="34850" s60v5md5 = "cc447c875cc1227ef01e5661dd21a157" s60v5len="34850" cdnurl = "http://emoji.qpic.cn/wx_emoji/GadFzur4lQJ4fSQkTAweicN5QtCUd4KQxGdjD9kgdIDf7XaTNK6leEddm2gfxXIR5/" designerid = "" thumburl = "" encrypturl = "http://emoji.qpic.cn/wx_emoji/GadFzur4lQJ4fSQkTAweicN5QtCUd4KQxGdjD9kgdIDdzHyqib20iaaOEM52oZk9MyT/" aeskey= "adc5de6b7dd4a3d24af358749a3875d9" externurl = "http://emoji.qpic.cn/wx_emoji/GadFzur4lQJ4fSQkTAweicN5QtCUd4KQxGdjD9kgdIDfY4adc6I0iahMsBEibUbsgGE/" externmd5 = "df21382a83ba18ebe9769f277f65770f" width= "167" height= "198" tpurl= "" tpauthkey= "" attachedtext= "" attachedtextcolor= "" lensid= "" ></emoji> </msg>'}], 'client_port': 3871}

其中的cndurl就可以直接得到表情包的图片。

然后我无奈地发现这个库不支持发送表情包或者任何gif格式的图片,所以就放弃了斗图机器人的想法。

之后也没有多少更新了。把代码贴在这里吧:

# -*- coding: UTF-8 -*-

from PyWeChatSpy import WeChatSpy

import BotAPIs
import pinyin2hanzi
import BaiduAPIs
import ConvertImg
import Faces

import random
import re

def parser(data):
    global variables

    if data['type'] == 5:
        print(data)
        for i in data['data']:

            wxid1 = i['wxid1']

            if wxid1[-9:-1] == '@chatroo':
                # 判断是否为群聊
                try:
                    atid = i['wxid2']
                except KeyError:
                    atid = ''
            else:
                atid = ''

            try:
                content = i['content']
            except KeyError:
                #是图片,百度API文字识别
                try:
                    path = i['image_path']
                    res = BaiduAPIs.general_OCR(path)
                    results = []
                    if not res['words_result_num'] ==0:
                        for x in res['words_result']:
                            results.append(x['words'])
                        content = ",".join(results)
                        print(content)
                        spy.send_text(wxid=wxid1, content=content, at_wxid=atid)
                except:
                    continue

            is_master = wxid1 == 'wxid_21axs6tdxnqm22' or atid == 'wxid_21axs6tdxnqm22'   # 是我

            if re.match('<msg><emoji ', content):
                try:
                    if variables['Bot'][wxid1] == 'Doutu':
                        Faces.get_face(variables['faces'])
                        spy.send_image(wxid1, r'C:\Users\zhong\Pictures\face.jpg')
                    else:
                        try:
                            # 表情包,先分析网址
                            span = re.search('cdnurl = ', content, flags=0).span()
                            cdnurl = content[span[1]:]
                            indi = re.match('".*" designerid', cdnurl).span()
                            cdnurl = cdnurl[indi[0] + 1: indi[1] - 12]
                            url = ConvertImg.convert_image_url(cdnurl, 'jpeg')
                            res = BaiduAPIs.webimage_OCR(url)
                            results = []
                            if not res['words_result_num'] == 0 or res['error_code']:
                                for x in res['words_result']:
                                    results.append(x['words'])
                                content = ",".join(results)
                                print(content)
                                spy.send_text(wxid=wxid1, content=content, at_wxid=atid)
                            else:
                                Faces.get_face(variables['faces'])
                                spy.send_image(wxid1, r'C:\Users\zhong\Pictures\face.jpg')
                        except:
                            Faces.get_face(variables['faces'])
                            spy.send_image(wxid1, r'C:\Users\zhong\Pictures\face.jpg')
                except:
                    pass

            print(variables)

            try:
                if variables['run'][wxid1] == 1:
                    # 启动状态

                    if i['self'] == 1:
                        # 自己的消息
                        continue

                    if content[0] == "#":
                        continue

                    # 命令处理
                    if content == "111":
                        spy.send_text(wxid=wxid1, content='response from new bot', at_wxid=atid)
                        spy.send_image(wxid=wxid1, image_path=r'C:\Users\zhong\Pictures\face.jpg')


                    elif content == "收工":
                        variables['run'][wxid1] = 0
                        spy.send_text(wxid=wxid1, content="机器人已关闭", at_wxid=atid)

                    elif content == "召唤乡村熊":
                        variables['Bot'][wxid1] = random.choice(('Xiaosi', 'Qingyun'))
                        spy.send_text(wxid=wxid1, content="HI!", at_wxid=atid)

                    elif content == "乡村熊再见" and variables['Bot'][wxid1] == 'Xiaosi':
                        variables['Bot'][wxid1] = ''
                        spy.send_text(wxid=wxid1, content="再见!", at_wxid=atid)

                    elif content == "斗图":
                        variables['Bot'][wxid1] = 'Doutu'

                    elif content[0] == "%":
                        try:
                            sen = content[1:]
                            pinlist = sen.split(' ')
                            content = pinyin2hanzi.pinyin2hanzi(pinlist)
                            spy.send_text(wxid=wxid1, content=content, at_wxid=atid)
                        except:
                            spy.send_text(wxid=wxid1, content="没识别出来呢", at_wxid=atid)

                    else:
                        if variables['Bot'][wxid1] == 'Xiaosi':
                            # 调用思科
                            if "乡村熊" in content:
                                content.replace("乡村熊", "小思")
                            res = BotAPIs.requestXiaosi(content, userid=atid)
                            if res['message'] == 'success':
                                results = res['data']['info']['text']
                                results.replace("小思", "乡村熊")
                                spy.send_text(wxid=wxid1, content=results, at_wxid=atid)
                            else:
                                spy.send_text(wxid=wxid1, content="乡村熊暂时不在", at_wxid=atid)

                        elif variables['Bot'][wxid1] == 'Qingyun':
                            # 调用青云
                            if "乡村熊" in content:
                                content.replace("乡村熊", "菲菲")
                            res = BotAPIs.requestQingyun(content)
                            if res['result'] == 0:
                                results = res['content']
                                results.replace("菲菲", "乡村熊")
                                spy.send_text(wxid=wxid1, content=results, at_wxid=atid)
                            else:
                                spy.send_text(wxid=wxid1, content="乡村熊暂时不在", at_wxid=atid)



                else:
                    # 待机状态
                    if i['content'] == "开工":
                        variables['run'][wxid1] = 1
                        spy.send_text(wxid=wxid1, content="机器人已开启", at_wxid=atid)

            except KeyError:
                variables['run'][wxid1] = 1

            except:
                pass

    elif data['type'] == 303:
        print("微信登出")


if __name__ == '__main__':
    variables = {'run': {},
                 'Bot': {},
                 'faces': Faces.get_face_list()
                 }
    spy = WeChatSpy(parser=parser, download_image=True)
    spy.run()

其中有几个我自己写的模块都是调用API的,不要也罢。

关于 “python微信机器人” 的 2 个意见

发表评论

电子邮件地址不会被公开。 必填项已用*标注