BAE+Python+Django+Wechatpy+Baidu weather api +微信訂閱號 = 實現微信查詢天氣

 

最近想在微信上面實現天氣查詢,分兩個步驟:python

1.被動回覆:輸入天氣、xx天氣獲取天氣狀況web

2.主動推送:天天定時推送天氣(針對24小時內產生交互的人)django

 

目前已經實現第一個步驟,以下:json

 

現將實現此功能環節、步驟等整理以下:api

 

前置條件:微信

1.申請微信訂閱號微信開發

2.申請百度應用引擎(BAE python環境)app

 

技術知識:ide

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('暫不支持文本消息外的其餘操做...\r\n回覆: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              + '\r\n'\
75              + '\r\n'\
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天氣便可查詢天氣狀況。\r\n 如:合肥天氣', 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

 

 

測試微信號:

相關文章
相關標籤/搜索