经过前三篇的教程,相信你们基本上了解了微信开发的基本流程,先判断用户传入数据的类型MsgType,而后再获取用户输入的内容content,再对content进行处理,再返回给用户python
如今咱们来加点料,在完成了前三篇的基础上,咱们把小黄鸡的自动回复功能整合到咱们的微信中,咱们最终实现的目的是这样的,当用户输入xhj指令后,进行和小黄鸡的对话中,这时候用户每输入的内容都将传给小黄鸡,而后小黄鸡进行回复,咱们获得小黄鸡的回复内容后再返回给用户。mysql
主要的问题,好比当用户输入“你好”,由于微信以前有翻译功能,那么咱们的微信是如何判断你想要发送的是和小黄鸡的对话仍是想要翻译“你好”这个单词?web
解决这个问题就须要咱们此次教程中所要用到的memcache,咱们使用memcache来记录一个状态,好比mc.set(‘xhj’,' true’),那么当用户发送“你好”时,程序先从memcache中获取一个’xhj’ 这个key的值,若是是true 那么说明用户发送“你好”是为了和小黄鸡对话,当memcache中没有’xhj’ 这个key的时候,说明用户是想要翻译“你好”这个单词算法
这样问题看似就能够解决了,可是会有另一个问题,当有两个用户同时发送“你好”时,A用户想要和小黄鸡对话,B用户想要翻译“你好”,那么此时,当memcache中有xhj且值为true,那么两我的获得的回复将都会是小黄鸡的回复,当没有xhj的key时,两个用户将都会获得“你好”这个词的翻译。sql
这样看,问题彷佛又更复杂了,其实解决起来只要将memcache中的key设置为惟一,就是说A用户对应一个key,B用户对应另一个key,那么问题就获得了解决,程序收到A用户的消息后,会在memcache中获取A用户的key,B用户获取B用户的key,这样就作到的相互不影响的效果,而要作到惟一,用户的fromUser值就是独一无二的,因此咱们在memcache中能够这样设计key mc.set(fromUser+’_xhj’,'xhj’)json
1. 小黄鸡有对外的接口,可是是收费的,咱们屌丝就只能用另外的方法,使用抓包来看下数据的调用api
能够看出,它的返回值是一个json格式的,response为小黄鸡返回的话,另外查看Params,还有一个ft=0.0这么个参数,一开始我都没有注意到,网上的别的帖子也没有提到它,因此一开始我一直调用不成功,写一个函数来调用小黄鸡,获得返回值缓存
def xiaohuangji(ask): ask = ask.encode('UTF-8') enask = urllib2.quote(ask) baseurl = r'http://www.simsimi.com/func/req?msg=' url = baseurl+enask+'&lc=ch&ft=0.0' resp = urllib2.urlopen(url) reson = json.loads(resp.read()) return reson
2. 使用memcache时先要在头上引入import pylibmc微信
使用memcache以前要先在SAE上启用memcachecookie
根据自已的须要输入容量,这个应用比较小,5M就足够了
pylibmc的基本操做也很简单
2.1初始化一个memcache
mc = pylibmc.Client()Python代码
2.2添加key
mc.set(key,value)
2.3查找key
mc.get(key)
3.4删除key
mc.delete(key)
有了上面的memcache操做,那么就能实现小黄鸡的操做了
# -*- coding: utf-8 -*- import hashlib import web import lxml import time import os import urllib2,json,urllib from lxml import etree import pylibmc import random class WeixinInterface: def __init__(self): self.app_root = os.path.dirname(__file__) self.templates_root = os.path.join(self.app_root, 'templates') self.render = web.template.render(self.templates_root) def GET(self): #获取输入参数 data = web.input() signature=data.signature timestamp=data.timestamp nonce=data.nonce echostr=data.echostr #本身的token token="你的token" #字典序排序 list=[token,timestamp,nonce] list.sort() sha1=hashlib.sha1() map(sha1.update,list) hashcode=sha1.hexdigest() #sha1加密算法 #若是是来自微信的请求,则回复echostr if hashcode == signature: #print "true" return echostr #return '欢迎光临' def POST(self): str_xml = web.data() xml = etree.fromstring(str_xml) #xml = urllib.unquote(xml) mstype=xml.find("MsgType").text fromUser=xml.find("FromUserName").text toUser=xml.find("ToUserName").text mc = pylibmc.Client() #初始化一个memcache实例用来保存用户的操做 #下面建立一个欢迎消息,经过判断Event类型 if mstype == "event": mscontent = xml.find("Event").text if mscontent == "subscribe": replayText = u'''欢迎关注本微信,这个微信是本人业余爱好所创建,也是想一边学习Python一边玩的东西, 如今尚未什么功能,只是弄了个翻译与豆瓣图书查询的小工具,大家有什么好的文章也欢迎反馈给我,我会不按期的分享给你们,输入help查看操做指令''' return self.render.reply_text(fromUser,toUser,int(time.time()),replayText) if mscontent == "unsubscribe": replayText = u'我如今功能还很简单,知道知足不了您的需求,可是我会慢慢改进,欢迎您之后再来' return self.render.reply_text(fromUser,toUser,int(time.time()),replayText) if mstype == 'text': content=xml.find("Content").text if content.lower() == 'bye': mc.delete(fromUser+'_xhj') return self.render.reply_text(fromUser,toUser,int(time.time()),u'您已经跳出了和小黄鸡的交谈中,输入help来显示操做指令') if content.lower() == 'xhj': mc.set(fromUser+'_xhj','xhj') return self.render.reply_text(fromUser,toUser,int(time.time()),u'您已经进入与小黄鸡的交谈中,请尽情的蹂躏它吧!输入bye跳出与小黄鸡的交谈') if content.lower() == 'm': musicList = [ [r'http://bcs.duapp.com/yangyanxingblog3/music/destiny.mp3','Destiny',u'献给个人宝贝晶晶'], [r'http://bcs.duapp.com/yangyanxingblog3/music/5days.mp3','5 Days',u'献给个人宝贝晶晶'], [r'http://bcs.duapp.com/yangyanxingblog3/music/Far%20Away%20%28Album%20Version%29.mp3','Far Away (Album Version)',u'献给个人宝贝晶晶'], [r'http://bcs.duapp.com/yangyanxingblog3/music/%E5%B0%91%E5%B9%B4%E6%B8%B8.mp3',u'少年游',u'献给个人宝贝晶晶'], [r'http://bcs.duapp.com/yangyanxingblog3/music/%E8%8F%8A.mp3',u'菊--关喆',u'献给个人宝贝晶晶'], [r'http://bcs.duapp.com/yangyanxingblog3/music/%E7%A6%BB%E4%B8%8D%E5%BC%80%E4%BD%A0.mp3',u'离不开你',u'献给个人宝贝晶晶'], [r'http://bcs.duapp.com/yangyanxingblog3/music/%E9%99%8C%E7%94%9F%E4%BA%BA.mp3',u'陌生人',u'献给个人宝贝晶晶'], [r'http://bcs.duapp.com/yangyanxingblog3/music/%E8%8A%B1%E5%AE%B9%E7%98%A6.mp3',u'花容瘦',u'献给个人宝贝晶晶'], [r'http://bcs.duapp.com/yangyanxingblog3/music/%E4%B9%98%E5%AE%A2.mp3',u'乘客',u'献给个人宝贝晶晶'], [r'http://bcs.duapp.com/yangyanxingblog3/music/If%20My%20Heart%20Was%20A%20House.mp3',u'If My Heart Was A House',u'献给个人宝贝晶晶'], [r'http://bcs.duapp.com/yangyanxingblog3/music/Hello%20Seattle%EF%BC%88Remix%E7%89%88%EF%BC%89.mp3',u'Hello Seattle(Remix版',u'献给个人宝贝晶晶'], [r'http://bcs.duapp.com/yangyanxingblog3/music/Everybody%20Hurts.mp3',u'Everybody Hurts',u'献给个人宝贝晶晶'] ] music = random.choice(musicList) musicurl = music[0] musictitle = music[1] musicdes =music[2] return self.render.reply_music(fromUser,toUser,int(time.time()),musictitle,musicdes,musicurl) #读取memcache中的缓存数据 mcxhj = mc.get(fromUser+'_xhj') if mcxhj =='xhj': res = xiaohuangji(content) reply_text = res['response'] if u'微信' in reply_text: reply_text = u"小黄鸡脑壳出问题了,请换个问题吧~" #这里小黄鸡会有广告,我索性就全给屏蔽了 return self.render.reply_text(fromUser,toUser,int(time.time()),reply_text) if content == 'help': replayText = u'''1.输入中文或者英文返回对应的英中翻译 2.输入m随机听一首音乐 3.输入xhj进入调戏小黄鸡模式''' return self.render.reply_text(fromUser,toUser,int(time.time()),replayText) elif type(content).__name__ == "unicode": content = content.encode('UTF-8') Nword = youdao(content) return self.render.fanyi(fromUser,toUser,int(time.time()),Nword) def youdao(word): qword = urllib2.quote(word) baseurl = r'http://fanyi.youdao.com/openapi.do?keyfrom=yyxweixintranslate&key=1581042900&type=data&doctype=json&version=1.1&q=' url = baseurl+qword resp = urllib2.urlopen(url) fanyi = json.loads(resp.read()) if fanyi['errorCode'] == 0: if 'basic' in fanyi.keys(): trans = u'%s:\n%s\n%s\n网络释义:\n%s'%(fanyi['query'],''.join(fanyi['translation']),' '.join(fanyi['basic']['explains']),'\n'.join(fanyi['web'][0]['value'])) return trans else: trans = u'%s:\n基本翻译:%s\n'%(fanyi['query'],''.join(fanyi['translation'])) return trans elif fanyi['errorCode'] == 20: return u'对不起,要翻译的文本过长' elif fanyi['errorCode'] == 30: return u'对不起,没法进行有效的翻译' elif fanyi['errorCode'] == 40: return u'对不起,不支持的语言类型' else: return u'对不起,您输入的单词%s没法翻译,请检查拼写'% word def xiaohuangji(ask): ask = ask.encode('UTF-8') enask = urllib2.quote(ask) baseurl = r'http://www.simsimi.com/func/req?msg=' url = baseurl+enask+'&lc=ch&ft=0.0' resp = urllib2.urlopen(url) reson = json.loads(resp.read()) return reson
最终的效果以下
查看效果请扫描添加如下微信公众帐号,有什么好的想法创意请输入“fk 内容”发送给我
4月8日更新,下面评论中有网友指出小黄鸡更改的地址,并须要cookies才能够,感谢@416548283
因而改了下代码
if mcxhj =='xhj': res = xiaohuangji(content) reply_text = res['sentence_resp'] if u'微信' in reply_text or u'微 信' in reply_text: reply_text = u"小黄鸡脑壳出问题了,请换个问题吧~" return self.render.reply_text(fromUser,toUser,int(time.time()),reply_text)
def xiaohuangji(ask): ask = ask.encode('UTF-8') enask = urllib2.quote(ask) send_headers = { 'Cookie':'Filtering=0.0; Filtering=0.0; isFirst=1; isFirst=1; simsimi_uid=50840753; simsimi_uid=50840753; teach_btn_url=talk; teach_btn_url=talk; sid=s%3AzwUdofEDCGbrhxyE0sxhKEkF.1wDJhD%2BASBfDiZdvI%2F16VvgTJO7xJb3ZZYT8yLIHVxw; selected_nc=zh; selected_nc=zh; menuType=web; menuType=web; __utma=119922954.2139724797.1396516513.1396516513.1396703679.3; __utmc=119922954; __utmz=119922954.1396516513.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)' } baseurl = r'http://www.simsimi.com/func/reqN?lc=zh&ft=0.0&req=' url = baseurl+enask req = urllib2.Request(url,headers=send_headers) resp = urllib2.urlopen(req) reson = json.loads(resp.read()) return reson
回顾以前的文章
使用python一步一步搭建微信公众平台(一)----基本的验证与鹦鹉学舌功能
使用python一步一步搭建微信公众平台(二)----搭建一个中英互译的翻译工具