侯体宗的博客
  • 首页
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

python微信公众号之关键词自动回复

Python  /  管理员 发布于 7年前   185

最近忙国赛的一个项目,我得做一个微信公众号。功能就是调数据并回复给用户,需要用户发送给公众号一个关键词,通过关键词自动回复消息。

这时就是查询微信公众平台文档了,地址如下: 文档

按照它的入门指南,我基本上了解了用户给公众号发送消息的一个机制,并且一旦给公众号发送消息,在开发者后台,会收到公众平台发送的一个xml,所以通过编写Python脚本进行xml的解析与自动发送功能。

如果用户给公众号发送一段text消息,比如“hello”,那么后台就会收到一个xml为:

<xml><ToUserName><![CDATA[公众号]]></ToUserName><FromUserName><![CDATA[粉丝号]]></FromUserName><CreateTime>1460541339</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[hello]]></Content></xml>

注意这里面有一些标记对于我们开发者来说是非常有用的:ToUserName,FromUserName,MsgType,Content
所以我们只要知道了这些信息,我们就能做到自动回复的功能。

我们发现这个MsgType 为 ‘text'。而微信中的MsgType有“text”(文本)、“image”(图像)、“voice”(语音)、“video”(视频)、“shortvideo”(短视频)、“location”(位置)、“link”(链接)、“event”(事件)

首先我们写一个main.py文件

main.py

# -*- coding: utf-8 -*-# filename: main.pyimport webfrom handle import Handleurls = ( '/wx', 'Handle',)if __name__ == '__main__': app = web.application(urls, globals()) app.run()

然后写一个receive.py,作为接受用户发送过来的数据,并解析xml,返回数据的脚本。

receive.py

import xml.etree.ElementTree as ETdef 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').textclass 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').textclass 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').textclass 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').textclass EventMsg(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换了一下而已,内容自己定。

<xml><ToUserName><![CDATA[粉丝号]]></ToUserName><FromUserName><![CDATA[公众号]]></FromUserName><CreateTime>1460541339</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[test]]></Content></xml>

reply.py

import timeclass 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 webimport replyimport receiveimport JsonDataimport xml.dom.minidomclass 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" %('环境数据如下:','设备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 = "欢迎关注,您好!雨燕城市环境小助手微信公众号:发送 获取数据,公众号会自动发送当前环境数据(目前为调试数据,不是真实数据).将要调试GPS,根据手机定位位置与设备位置相关联,取最近距离的设备所获取到的数据并进行返回."      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

注:代码贴了目前写的所有功能,接收关键字并自动返回数据;关注后自动回复欢迎文字;发送定位获得GPS信息。

那么我怎么样使用微信公众号去调取服务器上的数据呢,因为有了数据的json文件,我们就可以使用Python脚本进行json的解析,然后将数据在content中体现出来就可以了。

Json文件解析

import typesimport urllib.requestimport jsondef 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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


  • 上一条:
    Python使用Pickle库实现读写序列操作示例
    下一条:
    python 读取.csv文件数据到数组(矩阵)的实例讲解
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在windows10中升级go版本至1.24后LiteIDE的Ctrl+左击无法跳转问题解决方案(0个评论)
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(95个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客