通过 Github Action 实现定时推送天气预报

偶然间,看到 GitHub Actions 教程:定时发送天气邮件 - 阮一峰的网络日志 这篇文章,没错,这个正好能打发自己的折腾之心,也能通过代码给生活引入一些变化 。
还是在这里简单记录一下实现过程吧 。
第一步 获取天气预报出现问题按照阮一峰的教程走,一开始使用了 wttr 的结果作为数据来源,也在 文档 上研究了很久,最终的结果总是不尽如人意 。
最终展现到邮件上的结果如下:

通过 Github Action 实现定时推送天气预报

文章插图
从上面就可以看出一些问题:
  • 展示到邮件中的是一个 HTML 页面 , 白色的背景使得结果展示不理想
  • 默认返回的结果比较多,根据配置做调整之后返回的结果又比较少,结果不尽如人意
  • 从页面上看返回的都是不太好理解的单位,不能让人一眼就能理解
  • ......
其实还有很多问题,最主要的原因还是其 API 的结果更符合国外的理解 , 而不适合我用 。
第二步 寻找新的数据来源通过在网上寻找,最终找到了一个 墨迹天气 的 API 作为数据来源,虽然没有找到出处,但是暂时还可用 。
其返回的结果是一个 JSON 对象,可根据自己的需求去组装 。下面是返回的示例:
{"code": 0,"msg": "操作成功","data": {"total": 7,"sourceName": "墨迹天气","list": [{"city": "广州","lastUpdateTime": "2022-10-13 08:55:08","date": "2022-10-13","weather": "晴","temp": 20.0,"humidity": "35%","wind": "东北风3级","pm25": 29.0,"pm10": 43.0,"low": 20.0,"high": 30.0,"airData": "43","airQuality": "优","dateLong": 1665590400000,"weatherType": 0,"windLevel": 3,"province": "广东"},{"city": "广州","lastUpdateTime": "2022-10-13 08:00:00","date": "2022-10-14","weather": "晴","humidity": "未知","wind": "微风","pm25": 0.0,"low": 21.0,"high": 30.0,"airData": "80","airQuality": "良","dateLong": 1665676800000,"weatherType": 0,"windLevel": 1,"province": "广东"},{"city": "广州","lastUpdateTime": "2022-10-13 08:00:00","date": "2022-10-15","weather": "晴","humidity": "未知","wind": "北风","pm25": 0.0,"low": 21.0,"high": 31.0,"airData": "80","airQuality": "良","dateLong": 1665763200000,"weatherType": 0,"windLevel": 3,"province": "广东"},{"city": "广州","lastUpdateTime": "2022-10-13 08:00:00","date": "2022-10-16","weather": "多云","humidity": "未知","wind": "北风","pm25": 0.0,"low": 22.0,"high": 32.0,"airData": "70","airQuality": "良","dateLong": 1665849600000,"weatherType": 1,"windLevel": 4,"province": "广东"}],"logoUrl": "http://iflycar.hfdn.openstorage.cn/xfypicture/dev/logo/moji.png"}}根据上述的返回结果,简单组装了一个自己想要的结果:
【通过 Github Action 实现定时推送天气预报】位置:广东-广州今天:2022-10-11当前:15.0°C最低:15.0°C最高:26.0°C空气质量:优湿度:29%风向:东北风4级PM2.5:17.0位置:广西-桂林今天:2022-10-11当前:11.0°C最低:11.0°C最高:25.0°C空气质量:优湿度:30%风向:北风5级PM2.5:23.0实际上是非常简陋的,但却也暂时够用了,后续有相关的需求再加内容上去 。
第三步 通过脚本简化解决了数据来源和展示文本之后,其实已经是解决了需求端的问题,然后来到程序员的实现端 。
现在,我们先将需求做拆解,落实到程序上应该有以下工作要做:
  • 通过 API 获取到数据来源 , 组装成推送的文本格式
  • 定时触发,可以通过 Github Action 白嫖
  • 发送邮件 , 可以通过 QQ 邮箱白嫖
上述工作中的第一步,我最终是选择使用 Python 对其脚本化 , 代码如下:
import sysimport requestsdef generate_weather_text(weather: dict) -> str:ret = [f'位置:{weather.get("province")}-{weather.get("city")}今天:{weather.get("date")}',f'当前:{weather.get("temp")}°C最低:{weather.get("low")}°C最高:{weather.get("high")}°C',f'空气质量:{weather.get("airQuality")}湿度:{weather.get("humidity")}',f'风向:{weather.get("wind")}PM2.5:{weather.get("pm25")}',]return '\n'.join(ret)def get_weather(city: str) -> dict:url = 'http://autodev.openspeech.cn/csp/api/v2.1/weather'params = {'openId': 'aiuicus','clientType': 'android','sign': 'android','city': city,}res = requests.get(url, params=params).json()return res['data']['list'][0]def get_weather_text(city: str) -> str:weather = get_weather(city)return generate_weather_text(weather)if __name__ == '__main__':if len(sys.argv) >= 2:ret = [get_weather_text(_) for _ in sys.argv[1:]]print('\n\n'.join(ret))else:print('请求参数错误')第四步 配置 Github ActionGithub Action 的配置文件趋同于阮一峰的教程,下面是这个配置文件的一些解释 。

推荐阅读