python微信公众号之关键词自动回复
最近忙国赛的一个项目,我得做一个微信公众号。功能就是调数据并回复给用户,需要用户发送给公众号一个关键词,通过关键词自动回复消息。
这时就是查询微信公众平台文档了,地址如下:文档
按照它的入门指南,我基本上了解了用户给公众号发送消息的一个机制,并且一旦给公众号发送消息,在开发者后台,会收到公众平台发送的一个xml,所以通过编写Python脚本进行xml的解析与自动发送功能。
如果用户给公众号发送一段text消息,比如“hello”,那么后台就会收到一个xml为:
1460541339
注意这里面有一些标记对于我们开发者来说是非常有用的:ToUserName,FromUserName,MsgType,Content
所以我们只要知道了这些信息,我们就能做到自动回复的功能。
我们发现这个MsgType为‘text'。而微信中的MsgType有“text”(文本)、“image”(图像)、“voice”(语音)、“video”(视频)、“shortvideo”(短视频)、“location”(位置)、“link”(链接)、“event”(事件)
首先我们写一个main.py文件
main.py
#-*-coding:utf-8-*- #filename:main.py importweb fromhandleimportHandle urls=( '/wx','Handle', ) if__name__=='__main__': app=web.application(urls,globals()) app.run()
然后写一个receive.py,作为接受用户发送过来的数据,并解析xml,返回数据的脚本。
receive.py
importxml.etree.ElementTreeasET
defparse_xml(web_data):
iflen(web_data)==0:
returnNone
xmlData=ET.fromstring(web_data)
msg_type=xmlData.find('MsgType').text
ifmsg_type=='text':
#print('text')
returnTextMsg(xmlData)
elifmsg_type=='image':
returnImageMsg(xmlData)
elifmsg_type=='location':
#print('location')
returnLocationMsg(xmlData)
elifmsg_type=='event':
#print('event')
returnEventMsg(xmlData)
classEvent(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
classMsg(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
classTextMsg(Msg):
def__init__(self,xmlData):
Msg.__init__(self,xmlData)
self.Content=xmlData.find('Content').text.encode("utf-8")
classImageMsg(Msg):
def__init__(self,xmlData):
Msg.__init__(self,xmlData)
self.PicUrl=xmlData.find('PicUrl').text
self.MediaId=xmlData.find('MediaId').text
classLocationMsg(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
classEventMsg(Msg):
def__init__(self,xmlData):
Event.__init__(self,xmlData)
self.Event=xmlData.find('Event').text
其中,我们使用xml.etree.ElementTree,这是一个简单而有效的用户解析和创建XML数据的API。而fromstring()就是解析xml的函数,然后通过标签进行find(),即可得到标记内的内容。
同时还要写一个reply.py,作为自动返回数据的脚本。
刚才提到了,用户给公众号发送消息,公众号的后台会接收到一个xml,那么如果公众号给用户发送消息呢,其实也就是公众号给用户发送一个xml,只是ToUserName,FromUserName换了一下而已,内容自己定。
1460541339
reply.py
importtime classMsg(object): def__init__(self): pass defsend(self): return"success" classTextMsg(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 defsend(self): XmlForm="""""" returnXmlForm.format(**self.__dict) classImageMsg(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 defsend(self): XmlForm=""" {CreateTime} """ returnXmlForm.format(**self.__dict) {CreateTime}
接着我们要写一个handle.py,作为对消息进行反映处理(自动回复)的脚本。
handle.py
importweb
importreply
importreceive
importJsonData
importxml.dom.minidom
classHandle(object):
defGET(self):
try:
data=web.input()
iflen(data)==0:
return"hello,thisishandleview"
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/GETfunc:hashcode,signature:",hashcode,signature)
ifhashcode==signature:
returnechostr
else:
return""
exceptExceptionasArgument:
returnArgument
defPOST(self):
try:
webData=web.data()
#print(webData)
recMsg=receive.parse_xml(webData)
#print(recMsg)
ifisinstance(recMsg,receive.Msg):
toUser=recMsg.FromUserName
fromUser=recMsg.ToUserName
ifrecMsg.MsgType=='text':
try:
a=JsonData.praserJsonFile()
#print(a)
exceptExceptionasArgument:
returnArgument
ifa['status']=='1':
content="Noequipment"
else:
ifa['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"%('环境数据如下:','设备id号为',a['data']['id'],'tempis',a['data']['temp'],'humidityis',a['data']['humidity'],'PM25is',a['data']['pm25'],'illumination',a['data']['illumination'],israin)
#print(content)
replyMsg=reply.TextMsg(toUser,fromUser,content)
returnreplyMsg.send()
ifrecMsg.MsgType=='image':
mediaId=recMsg.MediaId
replyMsg=reply.ImageMsg(toUser,fromUser,mediaId)
returnreplyMsg.send()
ifrecMsg.MsgType=='location':
location_x=recMsg.Location_X
location_y=recMsg.Location_Y
content="您所在的位置是在:经度为"+location_x+";纬度为:"+location_y
replyMsg=reply.TextMsg(toUser,fromUser,content)
returnreplyMsg.send()
ifrecMsg.MsgType=='event':
#print('yes')
event=recMsg.Event
ifevent=='subscribe':
content="欢迎关注,您好!雨燕城市环境小助手微信公众号:发送获取数据,公众号会自动发送当前环境数据(目前为调试数据,不是真实数据).将要调试GPS,根据手机定位位置与设备位置相关联,取最近距离的设备所获取到的数据并进行返回."
replyMsg=reply.TextMsg(toUser,fromUser,content)
returnreplyMsg.send()
else:
returnreply.Msg().send()
else:
print("notdo")
returnreply.Msg().send()
exceptExceptionasArgment:
returnArgment
注:代码贴了目前写的所有功能,接收关键字并自动返回数据;关注后自动回复欢迎文字;发送定位获得GPS信息。
那么我怎么样使用微信公众号去调取服务器上的数据呢,因为有了数据的json文件,我们就可以使用Python脚本进行json的解析,然后将数据在content中体现出来就可以了。
Json文件解析
importtypes importurllib.request importjson defpraserJsonFile(): 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']) returnvalue #praserJsonFile()
这个value就是我们解析json出来的一个list
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。