第一次写博客,和大家分享一下我在用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# 这里实现微信消息的获取
[email protected]_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()