python微信公眾號之關鍵詞自動回復
最近忙國賽的一個項目,我得做一個微信公眾號。功能就是調數據并回復給用戶,需要用戶發(fā)送給公眾號一個關鍵詞,通過關鍵詞自動回復消息。
這時就是查詢微信公眾平臺文檔了,地址如下: 文檔
按照它的入門指南,我基本上了解了用戶給公眾號發(fā)送消息的一個機制,并且一旦給公眾號發(fā)送消息,在開發(fā)者后臺,會收到公眾平臺發(fā)送的一個xml,所以通過編寫Python腳本進行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>
注意這里面有一些標記對于我們開發(fā)者來說是非常有用的:ToUserName,F(xiàn)romUserName,MsgType,Content
所以我們只要知道了這些信息,我們就能做到自動回復的功能。
我們發(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ā)送過來的數據,并解析xml,返回數據的腳本。
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數據的API。而fromstring()就是解析xml的函數,然后通過標簽進行find(),即可得到標記內的內容。
同時還要寫一個reply.py,作為自動返回數據的腳本。
剛才提到了,用戶給公眾號發(fā)送消息,公眾號的后臺會接收到一個xml,那么如果公眾號給用戶發(fā)送消息呢,其實也就是公眾號給用戶發(fā)送一個xml,只是ToUserName,F(xiàn)romUserName換了一下而已,內容自己定。
<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,作為對消息進行反映處理(自動回復)的腳本。
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 = "此設備數據如下:\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)境數據如下:','設備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 = "您所在的位置是在:經度為"+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 = "歡迎關注,您好!雨燕城市環(huán)境小助手微信公眾號:發(fā)送 獲取數據,公眾號會自動發(fā)送當前環(huán)境數據(目前為調試數據,不是真實數據).將要調試GPS,根據手機定位位置與設備位置相關聯(liá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
注:代碼貼了目前寫的所有功能,接收關鍵字并自動返回數據;關注后自動回復歡迎文字;發(fā)送定位獲得GPS信息。
那么我怎么樣使用微信公眾號去調取服務器上的數據呢,因為有了數據的json文件,我們就可以使用Python腳本進行json的解析,然后將數據在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
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- 10分鐘教你用Python實現(xiàn)微信自動回復功能
- python實現(xiàn)微信自動回復功能
- python itchat實現(xiàn)微信自動回復的示例代碼
- 利用python微信庫itchat實現(xiàn)微信自動回復功能
- python實現(xiàn)微信小程序自動回復
- python實現(xiàn)微信機器人: 登錄微信、消息接收、自動回復功能
- Python中re.compile函數的使用方法
- 關于Python中compile() 函數簡單實用示例詳解
- Python正則表達式re.compile()和re.findall()詳解
- Python 正則 re.compile 真的必需嗎
- Python中請不要再用re.compile了
- python內置函數compile(),complex()的使用
相關文章
Ubuntu下使用python讀取doc和docx文檔的內容方法
今天小編就為大家分享一篇Ubuntu下使用python讀取doc和docx文檔的內容方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-05-05

