[python]微信公衆號+python+新浪SAE實現實時天氣預報功能

本文主要談談如何作一個具備天氣預報功能的公衆號。html

話很少說先上圖,實現的功能以下圖所示:python

點擊微信右下角的「+」號,分享任意一個位置信息,公衆號後臺自動回覆當地的天氣狀況。這裏的天氣預報是用python從中國天氣網抓取的雷達數據。有沒有更精準的數據源呢,固然有啦,但這不是本文的重點,這裏我就不詳說了。web

 

用到的工具:新浪SAE + 微信公衆平臺 + python2.7(新浪SAE目前僅支持2.7版本)算法

 

因爲本文的重點不是使用python搭建微信公衆平臺,網上已經有不少不錯的教程,爲了不重複造輪子,我在這裏貼一個不錯的教程,很適合新手入門:chrome

使用python一步一步搭建微信公衆平臺json

 

在開始以前咱們有必要了解一下微信公衆平臺的開發者文檔,查閱可知,微信的消息是以XML(可擴展標記語言)的形式傳輸的,其中地理位置信息的具體格式是:api

 

相應的參數意義以下:瀏覽器

 

所以天氣預報功能的實現流程爲:服務器

 

 

在讀取經緯度時涉及到一個問題,因爲百度地圖與谷歌地圖採用的是不一樣協議的座標,騰訊、高德地圖與谷歌地圖採用的是同種協議。而微信的經緯度信息是騰訊地圖給出的,在網站上查看中國天氣網發送的url請求可知,中國天氣網採用的是百度地圖,所以在查詢以前須要對經緯度信息作一次轉換。具體的轉換方式請查看:微信

百度經緯度和谷歌經緯度轉換

 

如何根據經緯度查詢當地天氣信息?

1.用chrome瀏覽器進入中國天氣網臨近預報頁面

 

2.按F12打開控制檯,點擊地圖上任意一個點

 

3.查看Network,發現有一條萌萌噠url

 

4.點擊url查看請求和響應信息,發現響應的是一段Json信息,猜測多是天氣信息;

 

5.打開該url,發現一段萌萌噠數據

紅色部分就是咱們想要的東西了

 

6.接下來要作的就是利用Python抓取這段數據了,因爲這段數據並非嚴格的Json數據(多是爲了防爬蟲而採起的簡單措施吧),因此須要先截取出Json部分。不過相對仍是比較簡單的。

 

下面就直接上代碼啦,此處默認讀者已經會使用web.py搭建微信公衆號了。代碼裏面有彩蛋請自行查閱~這裏不方便宣傳,由於偷偷用了人家的url…

 

  1 # -*- coding: utf-8 -*-
  2 import hashlib
  3 import web
  4 import lxml
  5 import time
  6 import os
  7 import urllib2,json
  8 import urllib
  9 import re
 10 import random
 11 import hashlib
 12 import cookielib
 13 import requests
 14 import math
 15 import re
 16 import sys
 17 reload(sys)
 18 sys.setdefaultencoding('utf8')
 19 from bs4 import BeautifulSoup
 20 from urllib import urlencode
 21 from lxml import etree
 22 from smtplib import SMTP_SSL
 23 from email.header import Header
 24 from email.mime.text import MIMEText
 25 
 26 #session = requests.Session()
 27 #s.config['keep_alivesession = requests.Session()
 28 class WeixinInterface:
 29 
 30     def __init__(self):
 31         self.app_root = os.path.dirname(__file__)
 32         self.templates_root = os.path.join(self.app_root, 'templates')
 33         self.render = web.template.render(self.templates_root)
 34 
 35     def GET(self):
 36         #獲取輸入參數
 37         data = web.input()
 38         signature=data.signature
 39         timestamp=data.timestamp
 40         nonce=data.nonce
 41         echostr = data.echostr
 42         #本身的token
 43         token="" #這裏改寫你在微信公衆平臺裏輸入的token
 44         #字典序排序
 45         list=[token,timestamp,nonce]
 46         list.sort()
 47         sha1=hashlib.sha1()
 48         map(sha1.update,list)
 49         hashcode=sha1.hexdigest()
 50         #sha1加密算法
 51 
 52         #若是是來自微信的請求,則回覆echostr
 53         if hashcode == signature:
 54             return echostr
 55 
 56     def POST(self): 
 57         str_xml = web.data() #得到post來的數據 
 58         xml = etree.fromstring(str_xml)#進行XML解析 
 59         msgType=xml.find("MsgType").text
 60         fromUser=xml.find("FromUserName").text 
 61         toUser=xml.find("ToUserName").text 
 62         if msgType == 'location':
 63             wdu = xml.find("Location_X").text
 64             wdu = float(wdu)
 65             
 66             jdu = xml.find("Location_Y").text
 67             jdu = float(jdu)
 68             #轉換爲百度標準
 69             x_pi = 3.14159265358979324 * 3000.0 / 180.0
 70             x = jdu
 71             y = wdu
 72             z = math.sqrt(x * x + y * y) + 0.00002 * math.sin(y * x_pi)
 73             theta = math.atan2(y, x) + 0.000003 * math.cos(x * x_pi)
 74             jdu = z * math.cos(theta) + 0.0065
 75             wdu = z * math.sin(theta) + 0.006
 76             wdu = str(wdu)
 77             jdu = str(jdu)
 78             Lmesag = u"您的位置:"
 79             Lmesag += xml.find("Label").text
 80             myres = requests.get('http://d3.weather.com.cn/webgis_rain_new/webgis/ele?lat='+ wdu + '&lon='+ jdu + '&callback=fc5m&_=1470809429568')
 81             if myres.status_code != 200:
 82                 if myres.status_code == 500:
 83                     status_error = u"服務器未響應,請稍後再試~"
 84                     return self.render.reply_text(fromUser,toUser,int(time.time()), status_error)
 85             myres.encoding = 'utf-8'
 86             text = myres.text
 87             text = text[9:-2]
 88             data = json.loads(text)
 89             pretime = data['time']
 90             msg = data['msg']
 91             pretime1 = u"查詢時間:"
 92             pretime1 += pretime
 93             msg1 = "天氣預報:\n中國天氣網雷達數據(雷達外推數據,僅供參考):"
 94             msg1 += msg
 95             Lmesag += '\n'
 96             Lmesag += pretime1
 97             Lmesag += '\n'
 98             Lmesag += msg1
 99             cyres = requests.get('http://www.caiyunapp.com/fcgi-bin/v1/api.py?lonlat=' + jdu + ',' + wdu + '&format=json&product=minutes_prec&token=96Ly7wgKGq6FhllM&random=0.8600497214532319')
100             cyres.encoding = "utf-8"
101             cyData = json.loads(cyres.text)
102             cymsg = u"\n\n彩雲天氣數據(準確率較高):"
103             #cymsg += cyData['summary']
104             cytemp = u"\n溫度:"
105             cytemp += str(cyData['temp'])
106             cymsg += cytemp
107             cymsg +=u"\n將來1小時天氣預報:"
108             cymsg += cyData['summary']
109             Lmesag += cymsg
110             return self.render.reply_text(fromUser,toUser,int(time.time()), Lmesag)
111         else:
112             pass
相關文章
相關標籤/搜索