[python]微信公众号+python+新浪SAE实现实时天气预报功能

本文主要谈谈如何做一个具有天气预报功能的公众号。

话不多说先上图,实现的功能如下图所示:

点击微信右下角的“+”号,分享任意一个位置信息,公众号后台自动回复当地的天气情况。这里的天气预报是用python从中国天气网抓取的雷达数据。有没有更精准的数据源呢,当然有啦,但这不是本文的重点,这里我就不详说了。

用到的工具:新浪SAE + 微信公众平台 + python2.7(新浪SAE目前仅支持2.7版本)

由于本文的重点不是使用python搭建微信公众平台,网上已经有很多不错的教程,为了避免重复造轮子,我在这里贴一个不错的教程,很适合新手入门:

使用python一步一步搭建微信公众平台

在开始之前我们有必要了解一下微信公众平台的开发者文档,查阅可知,微信的消息是以XML(可扩展标记语言)的形式传输的,其中地理位置信息的具体格式是:

相应的参数意义如下:

因此天气预报功能的实现流程为:

在读取经纬度时涉及到一个问题,由于百度地图与谷歌地图采用的是不同协议的坐标,腾讯、高德地图与谷歌地图采用的是同种协议。而微信的经纬度信息是腾讯地图给出的,在网站上查看中国天气网发送的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 = "天气预报:
中国天气网雷达数据(雷达外推数据,仅供参考):"
 94             msg1 += msg
 95             Lmesag += '
'
 96             Lmesag += pretime1
 97             Lmesag += '
'
 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"

彩云天气数据(准确率较高):"
103             #cymsg += cyData['summary']
104             cytemp = u"
温度:"
105             cytemp += str(cyData['temp'])
106             cymsg += cytemp
107             cymsg +=u"
未来1小时天气预报:"
108             cymsg += cyData['summary']
109             Lmesag += cymsg
110             return self.render.reply_text(fromUser,toUser,int(time.time()), Lmesag)
111         else:
112             pass
原文地址:https://www.cnblogs.com/wxj233/p/6084143.html