zoukankan      html  css  js  c++  java
  • BAE+Python+Django+Wechatpy+Baidu weather api +微信订阅号 = 实现微信查询天气

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

    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 
     8 class _cityWeather():
     9     
    10     #key
    11     appkey='7ed5edfdb07013922a47bd2fbf194d3d'
    12     #url
    13     appurl='http://api.map.baidu.com/telematics/v3/weather?location=%s&output=json&ak=7ed5edfdb07013922a47bd2fbf194d3d'
    14     
    15     def __init__(self):
    16         pass
    17     
    18     def getcitynamebyip(self,ip):
    19         
    20         pass
    21     
    22     def getcityweather(self,cityname='合肥'):
    23         requrl=self.appurl % (cityname,)
    24         r =  requests.get(requrl)
    25         return r.text
    26         
    27 cityweather = _cityWeather()    
    28     
    29     
    30 if __name__ =="__main__":
    31     
    32     
    33     print cityweather.getcityweather('合肥')
    34 
    35     
    36     
    37     
    38     
    39     
    40     
    41     
    42     
    View Code

    Django :

    路由【url.py】:

    from django.conf.urls import patterns, include, url
    
    import weixinviews
    import robot
    
    urlpatterns = patterns('',
       
    #     url(r'^$', weixinviews.handleRequest),
        url(r'^$', robot.weixin),
      
    )
    View Code

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

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

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

     1 # -*- coding: utf-8 -*-
     2 
     3 
     4 from wechatpy import parse_message, create_reply  
     5 from wechatpy.replies import TextReply, ArticlesReply
     6 from wechatpy.utils import check_signature  
     7 from wechatpy.exceptions import InvalidSignatureException
     8 
     9 from webcore.weatherservices import cityweather
    10 from isay9685.models import CityWeahter
    11 import json
    12 import time
    13 from datetime import datetime
    14 
    15 
    16 
    17 def doreply(msg):    
    18     reply = None
    19     
    20     try:
    21         
    22         if msg.content[-2:] == u'天气':
    23             if(len(msg.content) == 2):
    24                 cityname = '合肥'
    25             else:
    26                 cityname = msg.content[:-2]
    27             reply = replyWeather(cityname, msg)
    28         else:
    29             reply = create_reply(repr(msg), msg)
    30         
    31     except Exception as e:
    32         print 'error:', e
    33         
    34     return reply
    35         
    36 def replyWeather(cityname, msg):
    37     
    38     reply = None
    39     
    40     dateid = time.strftime("%Y%m%d")
    41     timeid = time.strftime("%H")
    42     
    43     cWeahter = CityWeahter.objects.filter(dateid=dateid, timeid=timeid, cityname=cityname)
    44     if cWeahter:
    45         weatherstr = cWeahter[0].wheather
    46     else:
    47         weatherstr = cityweather.getcityweather(cityname)
    48         cw = CityWeahter(dateid=dateid, timeid=timeid, cityname=cityname, wheather=weatherstr, createtime=datetime.now())
    49         cw.save()
    50        
    51     # 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℃"}]}]} '''
    52     weatherjson = json.loads(weatherstr)
    53     
    54     if weatherjson and weatherjson.get('error') == 0:
    55         date = weatherjson.get('date')
    56         result = weatherjson.get('results')[0]
    57         
    58         currentCity = result.get('currentCity')
    59         pm25 = result.get('pm25')
    60         
    61         wheathernowdatas = result.get('weather_data')[0]
    62         
    63         weathermsg = repr(wheathernowdatas)
    64         
    65         reply = ArticlesReply(message=msg)
    66         
    67         # simply use dict as article
    68         reply.add_article({
    69             'title': wheathernowdatas.get('date'),
    70         })
    71         reply.add_article({
    72             'title':
    73              u'%s %s %s' % (wheathernowdatas.get('weather') , wheathernowdatas.get('temperature') , wheathernowdatas.get('wind')) 
    74              + '
    '
    75              + '
    '
    76              + currentCity + u' PM2.5: ' + pm25  ,
    77             'url': 'http://isay9685.duapp.com'
    78         })   
    79         reply.add_article({
    80             'title':  u'白天',
    81             'image': wheathernowdatas.get('dayPictureUrl'),
    82         })    
    83         reply.add_article({
    84             'title':  u'晚上',
    85             'image': wheathernowdatas.get('nightPictureUrl'),
    86         })
    87         
    88           
    89     return reply
    90 
    91     
    View Code

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

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

    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
    View Code

    测试微信号:

  • 相关阅读:
    浅谈localStorage和sessionStorage的相关用法
    v-for中:key的作用总结
    textarea的placeholder无效问题解决
    6月10日
    6月9日
    6月8日
    6月7日
    6月6日
    10月5日
    6月4日
  • 原文地址:https://www.cnblogs.com/ryhan/p/5011962.html
Copyright © 2011-2022 走看看