详解用python自制微信机器人,定时发送天气预报
0引言
前段时间找到了一个免费的天气预报API,费了好段时间把这个API解析并组装成自己想用的格式了,就想着如何实现每天发送天气信息给自己。最近无意中发现了wxpy库,用它来做再合适不过了。以下是wxpy库的简介:
wxpy基于itchat,使用了Web微信的通讯协议,通过大量接口优化提升了模块的易用性,并进行丰富的功能扩展。实现了微信登录、收发消息、搜索好友、数据统计、微信公众号、微信好友、微信群基本信息获取等功能。
废话不多说,代码写起来。
1环境
操作系统:Windows/Linux
Python版本:3.7.2
2代码实现
我们要实现用Python来发微信,发送的内容是每天最新的天气信息。很明显我们需要完成两部分的准备,先来看看获取天气信息这部分内容。
2.0准备工作
本文我们用到的第三方库有requests、wxpyy,若环境还没有,按如下方式进行安装即可。
pipinstallwxpy
pipinstallrequests
2.1获取天气信息
这里我使用的API的请求链接如下:
http://t.weather.sojson.com/api/weather/city/city_code
请求方式是GET方法,使用时注意更换为自己城市对应的city_code,除此之外不用带任何参数。
请求是restfull风格,city_code为9位数字,如下示例:
{ "_id":58, "id":59, "pid":3, "city_code":"101230201", "city_name":"厦门" }
大家可以从_city.json文件中获取各个城市对应的编号。该文件我已经放在Github本文章对应的目录下了,大家可自行查询使用。
#weatherAPI的URL,此处的城市编号,参看_city.json url='http://t.weather.sojson.com/api/weather/city/101010200' header={ 'User-Agent':'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/73.0.3683.75Safari/537.36' } #请求WeatherAPI并拿到服务器返回的数据 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"HaveaNiceDay!") #每隔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效果展示
这是我清晨收到的微信消息截图,看上去还不错。没白忙活