最近想在微信上面实现天气查询,分两个步骤:

1.被动回复:输入天气、xx天气获取天气情况

2.主动推送:每天定时推送天气(针对24小时内产生交互的人)

目前已经实现第一个步骤,如下:

现将实现此功能环节、步骤等整理如下:

前置条件:

1.申请微信订阅号

2.申请百度应用引擎(BAE python环境)

技术知识:

1.python

2.Django

其他知识:

1.HTTP协议

2.JSON

3.WechatPy(Python 微信 SDK)

实现思路:

用户上行文字消息 【XX天气】=>订阅号=>微信客户端=>微信后台=>推送到微信开发者接口=>BAE=>Django(Python)=>WechatPy=>文字解析=>百度天气API

=>协议JSON=>生成文章描述XML=>微信后台=>微信客户端 【页面显示】

实现代码:

百度天气查询【输入地市】:

http://api.map.baidu.com/telematics/v3/weather?location=%s&output=json&ak=YOURAK

  1. #! /usr/bin/env python
  2. # coding=utf-8
  3.  
  4. import requests
  5. import json
  6.  
  7. class _cityWeather():
  8.  
  9. #key
  10. appkey='7ed5edfdb07013922a47bd2fbf194d3d'
  11. #url
  12. appurl='http://api.map.baidu.com/telematics/v3/weather?location=%s&output=json&ak=7ed5edfdb07013922a47bd2fbf194d3d'
  13.  
  14. def __init__(self):
  15. pass
  16.  
  17. def getcitynamebyip(self,ip):
  18.  
  19. pass
  20.  
  21. def getcityweather(self,cityname='合肥'):
  22. requrl=self.appurl % (cityname,)
  23. r = requests.get(requrl)
  24. return r.text
  25.  
  26. cityweather = _cityWeather()
  27.  
  28. if __name__ =="__main__":
  29.  
  30. print cityweather.getcityweather('合肥')

Django :

路由【url.py】:

  1. from django.conf.urls import patterns, include, url
  2.  
  3. import weixinviews
  4. import robot
  5.  
  6. urlpatterns = patterns('',
  7.  
  8. # url(r'^$', weixinviews.handleRequest),
  9. url(r'^$', robot.weixin),
  10.  
  11. )

对接微信&消息分流【robot.py】:

  1. # -*- coding: utf-8 -*-
  2.  
  3. from django.http import HttpResponse
  4. from django.template import RequestContext, Template
  5. from django.views.decorators.csrf import csrf_exempt
  6. from django.utils.encoding import smart_str, smart_unicode
  7.  
  8. from wechatpy import parse_message, create_reply
  9. from wechatpy.utils import check_signature
  10. from wechatpy.exceptions import InvalidSignatureException
  11. from wechatpy.replies import BaseReply
  12.  
  13. import reply_text
  14. import reply_event
  15.  
  16. TOKEN = 'YOURTOKEN' # 注意要与微信公众帐号平台上填写一致
  17.  
  18. @csrf_exempt
  19. def weixin(request):
  20. if request.method == 'GET':
  21. signature = request.GET.get('signature', '')
  22. timestamp = request.GET.get('timestamp', '')
  23. nonce = request.GET.get('nonce', '')
  24. echo_str = request.GET.get('echostr', '')
  25. try:
  26. check_signature(TOKEN, signature, timestamp, nonce)
  27. except InvalidSignatureException:
  28. echo_str = 'error'
  29. response = HttpResponse(echo_str, content_type="text/plain")
  30. return response
  31. else:
  32. reply=None
  33. msg = parse_message(request.body)
  34. if msg.type == 'text':
  35. reply = reply_text.doreply(msg)
  36. elif msg.type=='event':
  37. reply = reply_event.doreply(msg)
  38. else:
  39. pass
  40.  
  41. if not reply or not isinstance(reply, BaseReply):
  42. reply = create_reply('暂不支持文本消息外的其他操作...\r\n回复:xx天气 查询地市天气情况', msg)
  43.  
  44. response = HttpResponse(reply.render() , content_type="application/xml")
  45. return response

文字消息应答【reply_text.py】:

  1. # -*- coding: utf-8 -*-
  2.  
  3. from wechatpy import parse_message, create_reply
  4. from wechatpy.replies import TextReply, ArticlesReply
  5. from wechatpy.utils import check_signature
  6. from wechatpy.exceptions import InvalidSignatureException
  7.  
  8. from webcore.weatherservices import cityweather
  9. from isay9685.models import CityWeahter
  10. import json
  11. import time
  12. from datetime import datetime
  13.  
  14. def doreply(msg):
  15. reply = None
  16.  
  17. try:
  18.  
  19. if msg.content[-2:] == u'天气':
  20. if(len(msg.content) == 2):
  21. cityname = '合肥'
  22. else:
  23. cityname = msg.content[:-2]
  24. reply = replyWeather(cityname, msg)
  25. else:
  26. reply = create_reply(repr(msg), msg)
  27.  
  28. except Exception as e:
  29. print 'error:', e
  30.  
  31. return reply
  32.  
  33. def replyWeather(cityname, msg):
  34.  
  35. reply = None
  36.  
  37. dateid = time.strftime("%Y%m%d")
  38. timeid = time.strftime("%H")
  39.  
  40. cWeahter = CityWeahter.objects.filter(dateid=dateid, timeid=timeid, cityname=cityname)
  41. if cWeahter:
  42. weatherstr = cWeahter[0].wheather
  43. else:
  44. weatherstr = cityweather.getcityweather(cityname)
  45. cw = CityWeahter(dateid=dateid, timeid=timeid, cityname=cityname, wheather=weatherstr, createtime=datetime.now())
  46. cw.save()
  47.  
  48. # weatherstr = '''{"error":0,"status":"success","date":"2015-06-15","results":[{"currentCity":"合肥","pm25":"126","index":[{"title":"穿衣","zs":"热","tipt":"穿衣指数","des":"天气热,建议着短裙、短裤、短薄外套、T恤等夏季服装。"},{"title":"洗车","zs":"不宜","tipt":"洗车指数","des":"不宜洗车,未来24小时内有雨,如果在此期间洗车,雨水和路上的泥水可能会再次弄脏您的爱车。"},{"title":"旅游","zs":"适宜","tipt":"旅游指数","des":"温度适宜,又有较弱降水和微风作伴,会给您的旅行带来意想不到的景象,适宜旅游,可不要错过机会呦!"},{"title":"感冒","zs":"较易发","tipt":"感冒指数","des":"相对今天出现了较大幅度降温,较易发生感冒,体质较弱的朋友请注意适当防护。"},{"title":"运动","zs":"较不宜","tipt":"运动指数","des":"有降水,推荐您在室内进行健身休闲运动;若坚持户外运动,须注意携带雨具并注意避雨防滑。"},{"title":"紫外线强度","zs":"弱","tipt":"紫外线强度指数","des":"紫外线强度较弱,建议出门前涂擦SPF在12-15之间、PA+的防晒护肤品。"}],"weather_data":[{"date":"周一 06月15日 (实时:27℃)","dayPictureUrl":"http://api.map.baidu.com/images/weather/day/xiaoyu.png","nightPictureUrl":"http://api.map.baidu.com/images/weather/night/zhongyu.png","weather":"小雨转中雨","wind":"南风微风","temperature":"28 ~ 22℃"},{"date":"周二","dayPictureUrl":"http://api.map.baidu.com/images/weather/day/dayu.png","nightPictureUrl":"http://api.map.baidu.com/images/weather/night/xiaoyu.png","weather":"大雨转小雨","wind":"北风微风","temperature":"26 ~ 21℃"},{"date":"周三","dayPictureUrl":"http://api.map.baidu.com/images/weather/day/xiaoyu.png","nightPictureUrl":"http://api.map.baidu.com/images/weather/night/yin.png","weather":"小雨转阴","wind":"北风微风","temperature":"24 ~ 20℃"},{"date":"周四","dayPictureUrl":"http://api.map.baidu.com/images/weather/day/duoyun.png","nightPictureUrl":"http://api.map.baidu.com/images/weather/night/duoyun.png","weather":"多云","wind":"东北风3-4级","temperature":"28 ~ 20℃"}]}]} '''
  49. weatherjson = json.loads(weatherstr)
  50.  
  51. if weatherjson and weatherjson.get('error') == 0:
  52. date = weatherjson.get('date')
  53. result = weatherjson.get('results')[0]
  54.  
  55. currentCity = result.get('currentCity')
  56. pm25 = result.get('pm25')
  57.  
  58. wheathernowdatas = result.get('weather_data')[0]
  59.  
  60. weathermsg = repr(wheathernowdatas)
  61.  
  62. reply = ArticlesReply(message=msg)
  63.  
  64. # simply use dict as article
  65. reply.add_article({
  66. 'title': wheathernowdatas.get('date'),
  67. })
  68. reply.add_article({
  69. 'title':
  70. u'%s %s %s' % (wheathernowdatas.get('weather') , wheathernowdatas.get('temperature') , wheathernowdatas.get('wind')) \
  71. + '\r\n'\
  72. + '\r\n'\
  73. + currentCity + u' PM2.5: ' + pm25 ,
  74. 'url': 'http://isay9685.duapp.com'
  75. })
  76. reply.add_article({
  77. 'title': u'白天',
  78. 'image': wheathernowdatas.get('dayPictureUrl'),
  79. })
  80. reply.add_article({
  81. 'title': u'晚上',
  82. 'image': wheathernowdatas.get('nightPictureUrl'),
  83. })
  84.  
  85. return reply

事件消息应答【reply_event.py】:

  1. # -*- coding: utf-8 -*-
  2.  
  3. from wechatpy import parse_message, create_reply
  4. from wechatpy.replies import TextReply, ArticlesReply
  5. from wechatpy.utils import check_signature
  6. from wechatpy.exceptions import InvalidSignatureException
  7.  
  8. from webcore.weatherservices import cityweather
  9. from isay9685.models import CityWeahter
  10. import json
  11. import time
  12. from datetime import datetime
  13.  
  14. def doreply(msg):
  15. reply = None
  16.  
  17. try:
  18.  
  19. if msg.event == 'subscribe':
  20. reply = replySubscribe(msg)
  21. else:
  22. reply = create_reply(repr(msg), msg)
  23.  
  24. except Exception as e:
  25. print 'error:', e
  26. reply = None
  27.  
  28. return reply
  29.  
  30. def replySubscribe(msg):
  31.  
  32. reply = TextReply(content='欢迎关注RYHAN的微信订阅号,回复XX天气即可查询天气情况。\r\n 如:合肥天气', message=msg)
  33. return reply

BAE【requirements.txt】

  1. django==1.5.2
  2. MySQL-python==1.2.4
  3. requests==2.8.1
  4. #pycrypto==2.6.1
  5. PyCrypto
  6. #cryptography==0.8.2
  7. wechatpy

测试微信号:

BAE+Python+Django+Wechatpy+Baidu weather api +微信订阅号 = 实现微信查询天气的更多相关文章

  1. CabloyJS的微信API对接模块:当前支持微信公众号和微信小程序

    Cabloy-微信是什么 Cabloy-微信是基于CabloyJS全栈业务开发框架开发的微信接口模块,当前整合了微信公众号和微信小程序的接口,达到开箱即用的使用效果.在Cabloy-微信的基础上,可以 ...

  2. 微信订阅号里实现oauth授权登录,并获取用户信息 (完整篇)

    摘要 这段时间一直有人问我,订阅号实现的oauth授权登录的问题,之前写的比较简单,很多人不明白.众所周知,微信公众号分订阅号.服务号.企业号:每个号的用途不一样,接口开放程度也不一样.微信还有个扯淡 ...

  3. 微信公众号支付|微信H5支付|微信扫码支付|小程序支付|APP微信支付解决方案总结

    最近负责的一些项目开发,都用到了微信支付(微信公众号支付.微信H5支付.微信扫码支付.APP微信支付).在开发的过程中,在调试支付的过程中,或多或少都遇到了一些问题,今天总结下,分享,留存. 先说注意 ...

  4. C#版微信公众号支付|微信H5支付|微信扫码支付问题汇总及解决方案总结

    最近负责的一些项目开发,都用到了微信支付(微信公众号支付.微信H5支付.微信扫码支付).在开发的过程中,在调试支付的过程中,或多或少都遇到了一些问题,今天总结下,分享,留存.代码在文章结尾处,有需要的 ...

  5. JAVA版开源微信管家—JeeWx捷微3.2版本发布,支持微信公众号,微信企业号,支付窗、小程序

    JeeWx捷微3.2微信企业号升级版本发布^_^ JeeWx捷微V3.2——多触点管理平台(支持微信公众号,微信企业号,支付窗.小程序)   JeeWx捷微V3.2.0版本引入了更多新特性,支持微信公 ...

  6. 微信公众号开发--微信JS-SDK分享到朋友圈和分享给朋友

    之前写过一篇使用微信JS-SDK来实现扫一扫功能的博客 微信公众号开发–微信JS-SDK扫一扫功能 在该博客里介绍了微信JS-SDK的基本用法,其中包括以下几个步骤 还详细介绍了通过config接口注 ...

  7. [ios] 微信订阅号: ios博文精选

    晚上下班后时间充裕,平时要么看电视剧,要么玩游戏 感觉浪费时间.  最后决定自己也搞一个微信订阅号分享技术方面的东西,也提升自己. 如果大家也是一样情况,欢迎大家关注我的订阅号. 微信订阅号: ios ...

  8. JeeWx捷微3.1小程序版本发布,支持微信公众号,微信企业号,支付窗——JAVA版开源微信管家

    支持小程序,JeeWx捷微3.1小程序版本发布^_^ JeeWx捷微V3.1——多触点小程序版本管理平台(支持微信公众号,微信企业号,支付窗)   JeeWx捷微V3.1.0版本紧跟微信小程序更新,在 ...

  9. JAVA版开源微信管家—JeeWx捷微3.1小程序版本发布,支持微信公众号,微信企业号,支付窗

    支持小程序,JeeWx捷微3.1小程序版本发布^_^ JeeWx捷微V3.1--多触点小程序版本管理平台(支持微信公众号,微信企业号,支付窗) JeeWx捷微V3.1.0版本紧跟微信小程序更新,在原有 ...

随机推荐

  1. 5、Semantic-UI之基础按钮样式

    5.1 基础按钮样式   在Semantic-UI中定义了很多的按钮样式,可以通过class="ui button"来指定,也可以在class中指定颜色. 示例:定义基础按钮样式 ...

  2. PyCharm创建普通项目配置支持jinja2语法

    打开项目的根目录的.idea文件夹中项目名.iml文件(隐藏文件) 打开这个iml文件,在component标签的同级,添加如下代码: <component name="Templat ...

  3. BOLT.NET 学习笔记(一) 开篇 用.net winform 快速开发 炫酷的界面

    BOLT.NET 学习笔记(一) 开篇 用.net winform 快速开发 炫酷的界面 bolt 基本介绍 Bolt界面引擎是迅雷公司从2009年开始开发的第四代界面库.迅雷7是首个采用该引擎成功开 ...

  4. vue的props 属性类似于bug的东西

    /* * @Author: shs * @Date: 2019-04-19 17:48:39 * @Last Modified by: shs * @Last Modified time: 2019- ...

  5. SQLite Mysql 模糊查找(like)

    select UserId,UserName,Name,Sex,Birthday,Height,Weight,Role from xqhit_Users where UserName like &qu ...

  6. 5个Shell脚本编程入门练习例子

    例子一:绘制特殊图形 复制代码代码如下: #!/bin/bash MAX_NO=0 echo -n "Enter Number between (5 to 9) : " read ...

  7. Spring Cloud使用总结

    本文来自网易云社区,转载务必请注明出处. Spring Cloud 是spring团队推出的基于SpringBoot的分布式微服务框架,为开发者提供了在分布式系统(如配置管理.服务发现.断路器.智能路 ...

  8. windows测试登陆

    测试工具我使用2种(Medusa和hydra): 第一种:Medusa支持端口登录但是不支持rdp协议,意思就是可以验证密码是否正确,新用户不会创建家目录: 使用方法: medusa -M smbnt ...

  9. php-fpm.conf 解析

    以下内容转自:http://www.4wei.cn/archives/1002061 约定几个目录/usr/local/php/sbin/php-fpm/usr/local/php/etc/php-f ...

  10. leecode刷题(13) -- 字符串中的第一个唯一字符

    leecode刷题(13) -- 字符串中的第一个唯一字符 字符串中的第一个唯一字符 描述: 给定一个字符串,找到它的第一个不重复的字符,并返回它的索引.如果不存在,则返回 -1. 案例: s = & ...