python微信公眾號之關(guān)鍵詞自動回復(fù)
最近忙國賽的一個項目,我得做一個微信公眾號。功能就是調(diào)數(shù)據(jù)并回復(fù)給用戶,需要用戶發(fā)送給公眾號一個關(guān)鍵詞,通過關(guān)鍵詞自動回復(fù)消息。
這時就是查詢微信公眾平臺文檔了,地址如下: 文檔
按照它的入門指南,我基本上了解了用戶給公眾號發(fā)送消息的一個機(jī)制,并且一旦給公眾號發(fā)送消息,在開發(fā)者后臺,會收到公眾平臺發(fā)送的一個xml,所以通過編寫Python腳本進(jìn)行xml的解析與自動發(fā)送功能。
如果用戶給公眾號發(fā)送一段text消息,比如“hello”,那么后臺就會收到一個xml為:
<xml> <ToUserName><![CDATA[公眾號]]></ToUserName> <FromUserName><![CDATA[粉絲號]]></FromUserName> <CreateTime>1460541339</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[hello]]></Content> </xml>
注意這里面有一些標(biāo)記對于我們開發(fā)者來說是非常有用的:ToUserName,F(xiàn)romUserName,MsgType,Content
所以我們只要知道了這些信息,我們就能做到自動回復(fù)的功能。
我們發(fā)現(xiàn)這個MsgType 為 ‘text'。而微信中的MsgType有“text”(文本)、“image”(圖像)、“voice”(語音)、“video”(視頻)、“shortvideo”(短視頻)、“l(fā)ocation”(位置)、“l(fā)ink”(鏈接)、“event”(事件)
首先我們寫一個main.py文件
main.py
# -*- coding: utf-8 -*- # filename: main.py import web from handle import Handle urls = ( '/wx', 'Handle', ) if __name__ == '__main__': app = web.application(urls, globals()) app.run()
然后寫一個receive.py,作為接受用戶發(fā)送過來的數(shù)據(jù),并解析xml,返回數(shù)據(jù)的腳本。
receive.py
import xml.etree.ElementTree as ET
def parse_xml(web_data):
if len(web_data) == 0:
return None
xmlData = ET.fromstring(web_data)
msg_type = xmlData.find('MsgType').text
if msg_type == 'text':
#print('text')
return TextMsg(xmlData)
elif msg_type == 'image':
return ImageMsg(xmlData)
elif msg_type == 'location':
#print('location')
return LocationMsg(xmlData)
elif msg_type == 'event':
#print('event')
return EventMsg(xmlData)
class Event(object):
def __init__(self, xmlData):
self.ToUserName = xmlData.find('ToUserName').text
self.FromUserName = xmlData.find('FromUserName').text
self.CreateTime = xmlData.find('CreateTime').text
self.MsgType = xmlData.find('MsgType').text
self.Eventkey = xmlData.find('EventKey').text
class Msg(object):
def __init__(self, xmlData):
self.ToUserName = xmlData.find('ToUserName').text
self.FromUserName = xmlData.find('FromUserName').text
self.CreateTime = xmlData.find('CreateTime').text
self.MsgType = xmlData.find('MsgType').text
self.MsgId = xmlData.find('MsgId').text
class TextMsg(Msg):
def __init__(self, xmlData):
Msg.__init__(self, xmlData)
self.Content = xmlData.find('Content').text.encode("utf-8")
class ImageMsg(Msg):
def __init__(self, xmlData):
Msg.__init__(self, xmlData)
self.PicUrl = xmlData.find('PicUrl').text
self.MediaId = xmlData.find('MediaId').text
class LocationMsg(Msg):
def __init__(self, xmlData):
Msg.__init__(self, xmlData)
self.Location_X = xmlData.find('Location_X').text
self.Location_Y = xmlData.find('Location_Y').text
class EventMsg(Msg):
def __init__(self, xmlData):
Event.__init__(self, xmlData)
self.Event = xmlData.find('Event').text
其中,我們使用xml.etree.ElementTree,這是一個簡單而有效的用戶解析和創(chuàng)建XML數(shù)據(jù)的API。而fromstring()就是解析xml的函數(shù),然后通過標(biāo)簽進(jìn)行find(),即可得到標(biāo)記內(nèi)的內(nèi)容。
同時還要寫一個reply.py,作為自動返回數(shù)據(jù)的腳本。
剛才提到了,用戶給公眾號發(fā)送消息,公眾號的后臺會接收到一個xml,那么如果公眾號給用戶發(fā)送消息呢,其實也就是公眾號給用戶發(fā)送一個xml,只是ToUserName,F(xiàn)romUserName換了一下而已,內(nèi)容自己定。
<xml> <ToUserName><![CDATA[粉絲號]]></ToUserName> <FromUserName><![CDATA[公眾號]]></FromUserName> <CreateTime>1460541339</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[test]]></Content> </xml>
reply.py
import time
class Msg(object):
def __init__(self):
pass
def send(self):
return "success"
class TextMsg(Msg):
def __init__(self, toUserName, fromUserName, content):
self.__dict = dict()
self.__dict['ToUserName'] = toUserName
self.__dict['FromUserName'] = fromUserName
self.__dict['CreateTime'] = int(time.time())
self.__dict['Content'] = content
def send(self):
XmlForm = """
<xml>
<ToUserName><![CDATA[{ToUserName}]]></ToUserName>
<FromUserName><![CDATA[{FromUserName}]]></FromUserName>
<CreateTime>{CreateTime}</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[{Content}]]></Content>
</xml>
"""
return XmlForm.format(**self.__dict)
class ImageMsg(Msg):
def __init__(self, toUserName, fromUserName, mediaId):
self.__dict = dict()
self.__dict['ToUserName'] = toUserName
self.__dict['FromUserName'] = fromUserName
self.__dict['CreateTime'] = int(time.time())
self.__dict['MediaId'] = mediaId
def send(self):
XmlForm = """
<xml>
<ToUserName><![CDATA[{ToUserName}]]></ToUserName>
<FromUserName><![CDATA[{FromUserName}]]></FromUserName>
<CreateTime>{CreateTime}</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
<Image>
<MediaId><![CDATA[{MediaId}]]></MediaId>
</Image>
</xml>
"""
return XmlForm.format(**self.__dict)
接著我們要寫一個handle.py,作為對消息進(jìn)行反映處理(自動回復(fù))的腳本。
handle.py
import web
import reply
import receive
import JsonData
import xml.dom.minidom
class Handle(object):
def GET(self):
try:
data = web.input()
if len(data) == 0:
return "hello, this is handle view"
signature = data.signature
timestamp = data.timestamp
nonce = data.nonce
echostr = data.echostr
token = "hello2016"
list = [token, timestamp, nonce]
list.sort()
sha1 = hashlib.sha1()
map(sha1.update, list)
hashcode = sha1.hexdigest()
#print("handle/GET func: hashcode, signature: ", hashcode, signature)
if hashcode == signature:
return echostr
else:
return ""
except Exception as Argument:
return Argument
def POST(self):
try:
webData = web.data()
#print(webData)
recMsg = receive.parse_xml(webData)
#print(recMsg)
if isinstance(recMsg, receive.Msg):
toUser = recMsg.FromUserName
fromUser = recMsg.ToUserName
if recMsg.MsgType == 'text':
try:
a = JsonData.praserJsonFile()
#print(a)
except Exception as Argument:
return Argument
if a['status'] == '1':
content = "No equipment"
else:
if a['data'][0]['weather']=='0':
israin = '7.沒有下雨'
else:
israin = '7.下雨'
#print(israin)
content = "此設(shè)備數(shù)據(jù)如下:\n"+"1.id號為 "+a['data'][0]['id']+"\n"+"2.溫度為 "+a['data'][0]['temp']+"\n"+"3.濕度為 "+a['data'][0]['humidity']+"\n"+"4.PM2.5濃度為 "+a['data'][0]['pm25']+"ug\n"+"5.PM10濃度為 "+a['data'][0]['pm10']+"\n"+"6.光照 "+a['data'][0]['illumination']+"L\n"+israin
#content = "%s\n%s %s\n%s %s\n%s %s\n%s %s\n%s %s\n%s" %('環(huán)境數(shù)據(jù)如下:','設(shè)備id號為',a['data']['id'],'temp is', a['data']['temp'], 'humidity is', a['data']['humidity'],'PM25 is',a['data']['pm25'],'illumination',a['data']['illumination'],israin)
#print(content)
replyMsg = reply.TextMsg(toUser, fromUser, content)
return replyMsg.send()
if recMsg.MsgType == 'image':
mediaId = recMsg.MediaId
replyMsg = reply.ImageMsg(toUser, fromUser, mediaId)
return replyMsg.send()
if recMsg.MsgType == 'location':
location_x = recMsg.Location_X
location_y = recMsg.Location_Y
content = "您所在的位置是在:經(jīng)度為"+location_x+";緯度為:"+location_y
replyMsg = reply.TextMsg(toUser, fromUser, content)
return replyMsg.send()
if recMsg.MsgType == 'event':
#print('yes')
event = recMsg.Event
if event == 'subscribe':
content = "歡迎關(guān)注,您好!雨燕城市環(huán)境小助手微信公眾號:發(fā)送 獲取數(shù)據(jù),公眾號會自動發(fā)送當(dāng)前環(huán)境數(shù)據(jù)(目前為調(diào)試數(shù)據(jù),不是真實數(shù)據(jù)).將要調(diào)試GPS,根據(jù)手機(jī)定位位置與設(shè)備位置相關(guān)聯(lián),取最近距離的設(shè)備所獲取到的數(shù)據(jù)并進(jìn)行返回."
replyMsg = reply.TextMsg(toUser, fromUser, content)
return replyMsg.send()
else:
return reply.Msg().send()
else:
print("not do")
return reply.Msg().send()
except Exception as Argment:
return Argment
注:代碼貼了目前寫的所有功能,接收關(guān)鍵字并自動返回數(shù)據(jù);關(guān)注后自動回復(fù)歡迎文字;發(fā)送定位獲得GPS信息。
那么我怎么樣使用微信公眾號去調(diào)取服務(wù)器上的數(shù)據(jù)呢,因為有了數(shù)據(jù)的json文件,我們就可以使用Python腳本進(jìn)行json的解析,然后將數(shù)據(jù)在content中體現(xiàn)出來就可以了。
Json文件解析
import types import urllib.request import json def praserJsonFile(): url = "http://118.89.244.53:8080/index.php/home/api/present_data" data = urllib.request.urlopen(url).read() value = json.loads(data.decode()) #print(value) #print(value['data']) return value #praserJsonFile()
這個value就是我們解析json出來的一個list
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 10分鐘教你用Python實現(xiàn)微信自動回復(fù)功能
- python實現(xiàn)微信自動回復(fù)功能
- python itchat實現(xiàn)微信自動回復(fù)的示例代碼
- 利用python微信庫itchat實現(xiàn)微信自動回復(fù)功能
- python實現(xiàn)微信小程序自動回復(fù)
- python實現(xiàn)微信機(jī)器人: 登錄微信、消息接收、自動回復(fù)功能
- Python中re.compile函數(shù)的使用方法
- 關(guān)于Python中compile() 函數(shù)簡單實用示例詳解
- Python正則表達(dá)式re.compile()和re.findall()詳解
- Python 正則 re.compile 真的必需嗎
- Python中請不要再用re.compile了
- python內(nèi)置函數(shù)compile(),complex()的使用
相關(guān)文章
TensorFlow教程Softmax邏輯回歸識別手寫數(shù)字MNIST數(shù)據(jù)集
這篇文章主要為大家介紹了python神經(jīng)網(wǎng)絡(luò)的TensorFlow教程基于Softmax邏輯回歸識別手寫數(shù)字的MNIST數(shù)據(jù)集示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-11-11
在Linux上安裝Python的Flask框架和創(chuàng)建第一個app實例的教程
這篇文章主要介紹了在Linux上安裝Python的Flask框架和創(chuàng)建第一個app實例,包括創(chuàng)建一個HTML模版和利用Jinja2模板引擎來做渲染的步驟,需要的朋友可以參考下2015-03-03
利用python在excel里面直接使用sql函數(shù)的方法
今天小編就為大家分享一篇利用python在excel里面直接使用sql函數(shù)的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-02-02
在PyCharm中實現(xiàn)關(guān)閉一個死循環(huán)程序的方法
今天小編就為大家分享一篇在PyCharm中實現(xiàn)關(guān)閉一個死循環(huán)程序的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-11-11
Python?中?Pandas?文件操作和讀取?CSV?參數(shù)詳解
CSV?又稱逗號分隔值文件,是一種簡單的文件格式,以特定的結(jié)構(gòu)來排列表格數(shù)據(jù),這篇文章主要介紹了Python?之?Pandas?文件操作和讀取?CSV?參數(shù)詳解,需要的朋友可以參考下2023-03-03
Python光學(xué)仿真wxpython透鏡演示系統(tǒng)初始化與參數(shù)調(diào)節(jié)
這篇文章主要為大家介紹了Python光學(xué)仿真wxpython透鏡演示系統(tǒng)的初始化與參數(shù)調(diào)節(jié),同樣在學(xué)習(xí)wxpython透鏡演示系統(tǒng)的入門同學(xué)可以借鑒參考下,希望能夠有所幫助2021-10-10
python爬蟲爬取監(jiān)控教務(wù)系統(tǒng)的思路詳解
這篇文章主要介紹了python爬蟲監(jiān)控教務(wù)系統(tǒng),主要實現(xiàn)思路是對已有的成績進(jìn)行處理,變?yōu)閘ist集合,本文通過實例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2020-01-01
Python BentoML構(gòu)建部署和管理機(jī)器學(xué)習(xí)模型技巧掌握
BentoML是一個開源的Python框架,旨在簡化機(jī)器學(xué)習(xí)模型的打包、部署和管理,本文將深入介紹BentoML的功能和用法,提供詳細(xì)的示例代碼和解釋,幫助你更好地理解和應(yīng)用這個強(qiáng)大的工具2024-01-01

