經過前三篇的教程,相信你們基本上了解了微信開發的基本流程,先判斷用戶傳入數據的類型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一步一步搭建微信公衆平臺(二)----搭建一箇中英互譯的翻譯工具