[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
相关文章
相关标签/搜索