0 引言
前段时间找到了一个免费的天气预报 API,费了好段时间把这个 API 解析并组装成自己想用的格式了,就想着如何实现每天发送天气信息给自己。最近无意中发现了 wxpy 库,用它来做再合适不过了。以下是 wxpy 库的简介:
wxpy 基于 itchat,使用了 Web 微信的通讯协议,通过大量接口优化提升了模块的易用性,并进行丰富的功能扩展。实现了微信登录、收发消息、搜索好友、数据统计、微信公众号、微信好友、微信群基本信息获取等功能。
废话不多说,代码写起来。
1 环境
操作系统:Windows / Linux
Python 版本:3.7.2
2 代码实现
我们要实现用 Python 来发微信,发送的内容是每天最新的天气信息。很明显我们需要完成两部分的准备,先来看看获取天气信息这部分内容。
2.0 准备工作
本文我们用到的第三方库有 requests、wxpyy,若环境还没有,按如下方式进行安装即可。
pip install wxpy
pip install requests
2.1 获取天气信息
这里我使用的 API 的请求链接如下:
http://t.weather.sojson.com/a…
请求方式是 GET 方法,使用时注意更换为自己城市对应的 city_code,除此之外不用带任何参数。
请求是 restfull 风格,city_code 为 9 位数字,如下示例:
{
“_id”: 58,
“id”: 59,
“pid”: 3,
“city_code”: “101230201”,
“city_name”: “ 厦门 ”
}
大家可以从_city.json 文件中获取各个城市对应的编号。该文件我已经放在 Github 本文章对应的目录下了,大家可自行查询使用。
# weather API 的 URL,此处的城市编号,参看_city.json
url = ‘http://t.weather.sojson.com/api/weather/city/101010200’
header = {
‘User-Agent’: ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36’
}
# 请求 Weather API 并拿到服务器返回的数据
rep = requests.get(url, headers = header)
rep.encoding = “utf-8″
result = ”
weather = rep.tex
这个 API 接口的返回值内容很多,以下仅展示返回的部分信息。实际使用中仅用到三块内容,首先是城市信息。
“cityInfo”: {
“city”: “ 海淀区 ”, // 请求城市
“cityId”: “101010200”, // 城市 ID
“parent”: “ 北京市 ”, // 上级,一般是省份
“updateTime”: “09:02” // 天气更新时间
}
其次是,该城市当前天气的空气相关指数。
“data”: {
“shidu”: “32%”, // 湿度
“pm25”: 35.0, //pm2.5
“pm10”: 97.0, //pm10
“quality”: “ 良 ”, // 空气质量
“wendu”: “7”, // 温度
“ganmao”: “ 极少数敏感人群应减少户外活动 ”, // 感冒提醒(指数)
}
第三部分,该城市当前天气的温度风力等另外一些指数。
“forecast”: [// 今天 + 未来 14 天
{
“date”: “16”, // 日期
“sunrise”: “06: 28”,
“high”: “ 高温 20.0℃”,
“low”: “ 低温 2.0℃”,
“sunset”: “18: 21”,
“aqi”: 48.0,
“ymd”: “2019-03-16”, // 年月日
“week”: “ 星期六 ”,
“fx”: “ 西北风 ”, // 风向
“fl”: “3- 4 级 ”, // 风力
“type”: “ 晴 ”,
“notice”: “ 愿你拥有比阳光明媚的心情 ”
}
]
注:这个 API 接口返回值完整的示例,请见 Github 中本文章目录下的 weather.json 文件。
拿到返回值之后,需要解析,并转换组装成我们想要的格式。
# 解析服务器返回的数据,具体可参考 weather.json 文件
index_cityInfo = weather.find(“cityInfo”)
index_cityId = weather.find(“cityId”)
index_shidu = weather.find(“shidu”)
index_pm25 = weather.find(“pm25”)
index_pm10 = weather.find(“pm10”)
index_quality = weather.find(“quality”)
index_wendu = weather.find(“wendu”)
index_ganmao = weather.find(“ganmao”)
index_forecast = weather.find(“forecast”)
index_ymd = weather.find(“ymd”, index_forecast)
index_week = weather.find(“week”, index_forecast)
index_sunset = weather.find(“sunset”, index_forecast)
index_high = weather.find(“high”, index_forecast)
index_low = weather.find(“low”, index_forecast)
index_fx = weather.find(“fx”, index_forecast)
index_fl = weather.find(“fl”, index_forecast)
index_aqi = weather.find(“aqi”, index_forecast)
index_type = weather.find(“type”, index_forecast)
index_notice = weather.find(“notice”, index_forecast)
这是我最终想达到的效果如下:
# 今日天气预报
# 年月日 + 星期 + 所在地城市
# 天气类型 + 风向 + 风力
# 温度范围(最低温度~ 最高温度)
# 污染指数:PM2.5/PM10/AQI
# 空气质量
# 当前温度 + 空气湿度
# Notice 信息
转换化具体代码就是这样子的:
result = ‘ 今日天气预报 ’ + ‘\n’ \
+ weather[index_ymd + 6:index_week – 3] + ” ” \
+ weather[index_week + 7:index_fx – 3] + ” ” \
+ weather[index_cityInfo + 19:index_cityId – 3] + ‘\n’ \
+ “ 天气: ” + weather[index_type + 7:index_notice – 3] + ” ” \
+ weather[index_fx + 5:index_fl – 3] \
+ weather[index_fl + 5:index_type – 3] + ‘\n’ \
+ “ 温度范围:” + weather[index_low + 9:index_sunset – 3] + ” ~” \
+ weather[index_high + 10:index_low – 3] + ‘\n’ \
+ “ 污染指数: PM2.5:” + weather[index_pm25 + 6:index_pm10 – 1] + “” \
+ “PM10:” + weather[index_pm10 + 6:index_quality – 1] + ” ” \
+ “AQI:” + weather[index_aqi + 5:index_ymd – 2] + ‘\n’ \
+ “ 空气质量:” + weather[index_quality + 10:index_wendu – 3] + ‘\n’ \
+ “ 当前温度:” + weather[index_wendu + 8:index_ganmao – 3] + ” ” \
+ “ 空气湿度:” + weather[index_shidu + 8:index_pm25 – 3] + ‘\n’ \
+ weather[index_notice + 9:weather.find(‘}’, index_notice) – 1]
这样我们的第一步,获取天气信息就完成了。接下来就是登录微信定时发送消息了。
2.2 登录微信定时发送消息
首先要登录微信,一行代码就搞定了。这里实际上是扫二维码登录了一个 Web 版的微信。
# 初始化机器人,扫码登陆微信,适用于 Windows 系统
bot = Bot()
# Linux 系统,执行登陆请调用下面的这句
bot = Bot(console_qr=2, cache_path=”botoo.pkl”)
然后我们需要定义一个发送消息的函数,将获取并解析好的天气信息发送给指定微信好友。
# 调用 get_weather 函数
GW = get_weather()
# 填入你朋友的微信昵称,注意这里不是备注,也不是微信帐号
my_friend = bot.friends().search(u’ 一个昵称 ’)[0]
# 发送微信消息
my_friend.send(u” 早上好 Y(^o^)Y,这里是今日份的天气信息请查收!”)
my_friend.send(GW)
my_friend.send(u”Have a Nice Day!”)
# 每隔 86400 秒(1 天),发送 1 次
t = Timer(86400, auto_send)
t.start()
接下来,你可以使用 try…except… 语句来实现在消息失败时发出告警:
try:
”’ 此处为发送消息的代码,即上一段内容 ”’
except:
# 你的微信昵称,注意这里不是备注,也不是微信帐号
my_friend = bot.friends().search(‘& 娴敲棋子 &’)[0]
my_friend.send(u” 报告老板,今日份的信息发送失败了!”)
最后运行主函数,调用发送消息的函数即可。
# 调用函数进行消息发送
auto_send()
3 效果展示
这是我清晨收到的微信消息截图,看上去还不错。没白忙活????
4 后记
我把这个脚本丢在了我的树莓上,挂在后台一直运行,简直完美。
这里仅是实现一个最简单的定时发送,后续考虑如何实现多个时间点的定时发送,还准备加上早间新闻资讯以及火车放票信息等内容。
关注公众号「Python 专栏」,后台回复:zsxq05,获取本文全套代码!