第一次写博客,和大家分享一下我在用itchat开发图灵机器人中遇到的若干坑。由于是新手小白,所以踩到了颇多基础的坑,希望各位前辈在博客中发现低级错误,切勿鄙夷,还望斧正。

事情起源于前几天看到CSDN公众号发的一篇文章《如何用30行代码实现微信自动回复机器人》,文中介绍了如何使用itchat配合图灵机器人实现微信自动回复机器人,我对照着微信教程在Python中安装了itchat,这部分一般不会出啥错,有兴趣的就照常规方法安装就行。之后我继续照着教程把代码拷贝了一份,再之后去图灵机器人的官网注册了账号创建了机器人,关于这部分都没遇到啥坑。坑人的地方到了,运行的时候无法实现自动回复,只能回复默认回复。代码如下:

1import requests
 2import itchat
 3
 4KEY = \'8edce3ce905a4c1dbb965e6b35c3834d\'
 5
 6def get_response(msg):
 7    # 这里实现与图灵机器人的交互
 8    # 构造了要发送给服务器的数据
 9    apiUrl = \'http://www.tuling123.com/openapi/api\'
10    data = {
11        \'key\' : KEY,
12      \'info\' : msg,
13      \'userid\' : \'wechat-robot\',
14    }
15    try:
16        r = requests.post(apiUrl, data=data).json()
17        # 字典的get方法在字典没有\'text\'值的时候会返回None而不会抛出异常
18        return r.get(\'text\')
19    # 为了防止服务器没有正常响应导致程序异常退出,这里用try-except捕获了异常
20    # 如果服务器没能正常交互(返回非json或无法连接),那么就会进入下面的return
21    except:
22        # 将会返回一个None
23        return
24
25# 这里实现微信消息的获取
26@itchat.msg_register(itchat.content.TEXT)
27def tuling_reply(msg):
28    # 为了保证在图灵Key出现问题的时候仍旧可以回复,这里设置一个默认回复
29    defaultReply = \'I received: \' + msg[\'Text\']
30    # 如果图灵Key出现问题,那么reply将会是None
31    reply = get_response(msg[\'Text\'])
32    # a or b的意思是,如果a有内容,那么返回a,否则返回b
33    # 有内容一般就是指非空或者非None,你可以用`if a: print(\'True\')`来测试
34    return reply or defaultReply
35
36# 为了让实验过程更加方便(修改程序不用多次扫码),我们使用热启动
37itchat.auto_login(hotReload=True)
38itchat.run()
\"\"

以上代码运行只会返回defaultReply,说明程序接受到了监听的消息,考虑是图灵机器人API接口的问题,查看了官网的文档,接口长这样:

{
	\"reqType\":0,
    \"perception\": {
        \"inputText\": {
            \"text\": \"附近的酒店\"
        },
        \"inputImage\": {
            \"url\": \"imageUrl\"
        },
        \"selfInfo\": {
            \"location\": {
                \"city\": \"北京\",
                \"province\": \"北京\",
                \"street\": \"信息路\"
            }
        }
    },
    \"userInfo\": {
        \"apiKey\": \"\",
        \"userId\": \"\"
    }
}
\"\"

和教程上简单的接口实现完全不同,复杂了不止一个档次,对于接口有兴趣的朋友请移步API V2.0接入文档,在百度上一番搜索后才知道教程上的接口是第一版本,现在官网提供的是第二版本,这个就有点坑了。照着官网文档上的接口实现了一下,程序还是不能运行。再次进行BUG的排查,进入图灵机器人后台查看日志,后台显示已经收到程序发送的信息,并且返回消息。那就是在接收返回消息到把消息发送给微信的代码出问题了。确定了问题接下来就一步步排查,先测试是否接受到了后台返回的消息。再次网上搜索,发现有人遇到相似问题,原因是json数据需要使用json.dumps()解析,插入代码后依旧不能运行,继续排查,测试代码如下:

# -*- coding: utf-8 -*-
\"\"\"
Created on Mon Dec 10 14:10:01 2018

@author: Loye
\"\"\"

import requests
import json

def get_response(msg):
    apiUrl=\'http://www.tuling123.com/openapi/api/v2\'
    data= {
         \"reqType\":0,
         \"perception\": {
            \"inputText\": {
                \"text\": msg
            },
             \"selfInfo\": {
                 \"location\": {
                 \"city\": \"北京\",
                 \"province\": \"北京\",
                 \"street\": \"信息路\"
                  }
              }
        },
        \"userInfo\":{
            \"apiKey\":\"5c680f292ff4399862e206a32ee\",
            \"userId\": \"7458\"
            }
    }
    try:
        dat=json.dumps(data)
        req=requests.post(apiUrl,data=dat).json()
        print(req[\'results\'][0][\'values\'][\'text\'])
        nReq=str(req[\'results\'][0][\'values\'][\'text\'])
#        print(\'1\')
#        dicm=json.loads(req)
#        str=dicm[\'results\'][0][\'values\'][\'text\']
#        print(str)
        return nReq
    except:
        return
    
if __name__==\'__main__\':
#    get_response(\'想要个萌萌哒女朋友\')
    nReq=get_response(\'单身狗,好难过\')
    print(nReq)
\"\"

一番操作之后数据终于能传出来了,但运行调整好的程序,还是没能达到理想的效果。继续排除问题,现在就比较明确了,问题在itchat的部分。最后解决了问题,但不知道问题出在哪。itchat部分的测试代码如下

import itchat

def get_response(msg):
        if(msg[\'Text\']==\"1\"):
          return \'hehe\'
        else:
          return \'lala\'

@itchat.msg_register(itchat.content.TEXT)
def tuling_reply(msg):
#    defaultReply=\'I received:\'+msg[\'Text\']
    liAn=get_response(msg)
    itchat.send(\'%s: %s\' % (msg[\'Type\'], msg[\'Text\']), msg[\'FromUserName\'])
#    return reply or defaultReply
    return liAn or \'666\'

itchat.auto_login(hotReload=True)
itchat.run()
\"\"

代码使用官方文档上的测试代码改编,但是在运行时还是没反应,至今没搞懂,希望有大神赐教。

最后没使用return,使用msg.user.send()来传递返回值。目前还只能达到聊天功能,看到图灵机器人上有斗图功能,但目前没发现文档可以参考,以后技术进步再写吧。最后附上完整代码:

# -*- coding: utf-8 -*-
\"\"\"
Created on Mon Dec 10 10:47:52 2018

@author: Loye
\"\"\"

import requests
import itchat
import json

#    注册监听微信文本消息,微信自带表情也行,有文本传入,运行方法执行功能
@itchat.msg_register(itchat.content.TEXT)
def tuling_reply(msg):
#    defaultReply=\'I received:\'+msg[\'Text\']
    liAn=get_response(msg)
#    return reply or defaultReply
    msg.user.send(liAn)
    
#    从微信接受消息,传递给后台图灵机器人,接收后台发回的消息,处理后返回
def get_response(msg):
    apiUrl=\'http://www.tuling123.com/openapi/api/v2\'
    data= {
         \"reqType\":0,
         \"perception\": {
            \"inputText\": {
                \"text\": msg[\'Text\']
            },
             \"inputImage\": {
                  \"url\": \"imageUrl\"
                   },
             \"selfInfo\": {
                 \"location\": {
                 \"city\": \"北京\",
                 \"province\": \"北京\",
                 \"street\": \"信息路\"
                  }
              }
        },
        \"userInfo\":{
            \"apiKey\":\"5c680f292ff43998627e206a732ee\",
            \"userId\": \"7458\"
            }
    }
    try:
        dat=json.dumps(data)
        req=requests.post(apiUrl,data=dat).json()
        lian=str(req[\'results\'][0][\'values\'][\'text\'])
#        json.loads(str)
        return lian
    except:
        return
    
itchat.auto_login()
itchat.run()
\"\"
收藏 打印