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

打印 上一主题 下一主题

主题 954|帖子 954|积分 2866

偶然间,看到 GitHub Actions 教程:定时发送天气邮件 - 阮一峰的网络日志 这篇文章,没错,这个正好能打发自己的折腾之心,也能通过代码给生活引入一些变化。
还是在这里简单记录一下实现过程吧。
第一步 获取天气预报出现问题

按照阮一峰的教程走,一开始使用了 wttr 的结果作为数据来源,也在 文档 上研究了很久,最终的结果总是不尽如人意。
最终展现到邮件上的结果如下:

从上面就可以看出一些问题:

  • 展示到邮件中的是一个 HTML 页面,白色的背景使得结果展示不理想
  • 默认返回的结果比较多,根据配置做调整之后返回的结果又比较少,结果不尽如人意
  • 从页面上看返回的都是不太好理解的单位,不能让人一眼就能理解
  • ......
其实还有很多问题,最主要的原因还是其 API 的结果更符合国外的理解,而不适合我用。
第二步 寻找新的数据来源

通过在网上寻找,最终找到了一个 墨迹天气 的 API 作为数据来源,虽然没有找到出处,但是暂时还可用。
其返回的结果是一个 JSON 对象,可根据自己的需求去组装。下面是返回的示例:
  1. {
  2.     "code": 0,
  3.     "msg": "操作成功",
  4.     "data": {
  5.         "total": 7,
  6.         "sourceName": "墨迹天气",
  7.         "list": [
  8.             {
  9.                 "city": "广州",
  10.                 "lastUpdateTime": "2022-10-13 08:55:08",
  11.                 "date": "2022-10-13",
  12.                 "weather": "晴",
  13.                 "temp": 20.0,
  14.                 "humidity": "35%",
  15.                 "wind": "东北风3级",
  16.                 "pm25": 29.0,
  17.                 "pm10": 43.0,
  18.                 "low": 20.0,
  19.                 "high": 30.0,
  20.                 "airData": "43",
  21.                 "airQuality": "优",
  22.                 "dateLong": 1665590400000,
  23.                 "weatherType": 0,
  24.                 "windLevel": 3,
  25.                 "province": "广东"
  26.             },
  27.             {
  28.                 "city": "广州",
  29.                 "lastUpdateTime": "2022-10-13 08:00:00",
  30.                 "date": "2022-10-14",
  31.                 "weather": "晴",
  32.                 "humidity": "未知",
  33.                 "wind": "微风",
  34.                 "pm25": 0.0,
  35.                 "low": 21.0,
  36.                 "high": 30.0,
  37.                 "airData": "80",
  38.                 "airQuality": "良",
  39.                 "dateLong": 1665676800000,
  40.                 "weatherType": 0,
  41.                 "windLevel": 1,
  42.                 "province": "广东"
  43.             },
  44.             {
  45.                 "city": "广州",
  46.                 "lastUpdateTime": "2022-10-13 08:00:00",
  47.                 "date": "2022-10-15",
  48.                 "weather": "晴",
  49.                 "humidity": "未知",
  50.                 "wind": "北风",
  51.                 "pm25": 0.0,
  52.                 "low": 21.0,
  53.                 "high": 31.0,
  54.                 "airData": "80",
  55.                 "airQuality": "良",
  56.                 "dateLong": 1665763200000,
  57.                 "weatherType": 0,
  58.                 "windLevel": 3,
  59.                 "province": "广东"
  60.             },
  61.             {
  62.                 "city": "广州",
  63.                 "lastUpdateTime": "2022-10-13 08:00:00",
  64.                 "date": "2022-10-16",
  65.                 "weather": "多云",
  66.                 "humidity": "未知",
  67.                 "wind": "北风",
  68.                 "pm25": 0.0,
  69.                 "low": 22.0,
  70.                 "high": 32.0,
  71.                 "airData": "70",
  72.                 "airQuality": "良",
  73.                 "dateLong": 1665849600000,
  74.                 "weatherType": 1,
  75.                 "windLevel": 4,
  76.                 "province": "广东"
  77.             }
  78.         ],
  79.         "logoUrl": "http://iflycar.hfdn.openstorage.cn/xfypicture/dev/logo/moji.png"
  80.     }
  81. }
复制代码
根据上述的返回结果,简单组装了一个自己想要的结果:
  1. 位置:广东-广州  今天:2022-10-11
  2. 当前:15.0°C  最低:15.0°C  最高:26.0°C
  3. 空气质量:优  湿度:29%
  4. 风向:东北风4级  PM2.5:17.0
  5. 位置:广西-桂林  今天:2022-10-11
  6. 当前:11.0°C  最低:11.0°C  最高:25.0°C
  7. 空气质量:优  湿度:30%
  8. 风向:北风5级  PM2.5:23.0
复制代码
实际上是非常简陋的,但却也暂时够用了,后续有相关的需求再加内容上去。
第三步 通过脚本简化

解决了数据来源和展示文本之后,其实已经是解决了需求端的问题,然后来到程序员的实现端。
现在,我们先将需求做拆解,落实到程序上应该有以下工作要做:

  • 通过 API 获取到数据来源,组装成推送的文本格式
  • 定时触发,可以通过 Github Action 白嫖
  • 发送邮件,可以通过 QQ 邮箱白嫖
上述工作中的第一步,我最终是选择使用 Python 对其脚本化,代码如下:
  1. import sys
  2. import requests
  3. def generate_weather_text(weather: dict) -> str:
  4.     ret = [
  5.         f'位置:{weather.get("province")}-{weather.get("city")}  今天:{weather.get("date")}',
  6.         f'当前:{weather.get("temp")}°C  最低:{weather.get("low")}°C  最高:{weather.get("high")}°C',
  7.         f'空气质量:{weather.get("airQuality")}  湿度:{weather.get("humidity")}',
  8.         f'风向:{weather.get("wind")}  PM2.5:{weather.get("pm25")}',
  9.     ]
  10.     return '\n'.join(ret)
  11. def get_weather(city: str) -> dict:
  12.     url = 'http://autodev.openspeech.cn/csp/api/v2.1/weather'
  13.     params = {
  14.         'openId': 'aiuicus',
  15.         'clientType': 'android',
  16.         'sign': 'android',
  17.         'city': city,
  18.     }
  19.     res = requests.get(url, params=params).json()
  20.     return res['data']['list'][0]
  21. def get_weather_text(city: str) -> str:
  22.     weather = get_weather(city)
  23.     return generate_weather_text(weather)
  24. if __name__ == '__main__':
  25.     if len(sys.argv) >= 2:
  26.         ret = [get_weather_text(_) for _ in sys.argv[1:]]
  27.         print('\n\n'.join(ret))
  28.     else:
  29.         print('请求参数错误')
复制代码
第四步 配置 Github Action

Github Action 的配置文件趋同于阮一峰的教程,下面是这个配置文件的一些解释。
定时触发
  1. name: "天气预报"
  2. on:
  3.   push:
  4.   schedule:
  5.     # 需要减 8 个小时
  6.     - cron: "0 23 * * *"
复制代码
这里比较好理解,name 是名称,on 是触发的时机,push 是我们提交代码到 Github 时触发,schedule 是定时触发,需要注意的时候,定时触发的时间需要减掉 8 个小时,其遵循国际标准时间而不是北京时间。
运行流程
  1. runs-on: ubuntu-latest
  2. steps:
  3.   - name: "切换代码"
  4.     uses: actions/checkout@v3
复制代码
进入到 jobs 运行流程中,runs-on 指定运行环境是最新的 Ubuntu 即可,actions/checkout@v3 用作从代码仓库获取代码。
获取时间
  1. - name: "获取时间"
  2.   run: echo "WEATHER_REPORT_DATE=$(TZ=':Asia/Shanghai' date '+%Y-%m-%d %T')" >> $GITHUB_ENV
复制代码
直接通过 Linux 命令获取当前时间,然后转换成北京时间,这个时间主要是用于后续写入到邮件的标题当中。
在这里,通过 echo "{environment_variable_name}={value}" >> $GITHUB_ENV 的方式写入环境变量,在后续的步骤中都可以访问到这个环境变量。
执行脚本
  1. - uses: actions/setup-python@v4
  2.   with:
  3.     python-version: "3.10"
  4. - run: pip install -r requirements.txt
  5. - name: "获取天气结果"
  6.   run: 'echo "$(python open_api/weather.py 广州 桂林)" > output.txt'
复制代码
这里有两个步骤,一个是指定 Python 的运行环境并且安装好相关的依赖,第二个是执行 Python 的脚本获取结果。
在这里,为了方便将脚本的执行结果给到后续的步骤,选择将执行结果写入到一个文件当中。当然,选择怎样的方式主要看自己。
发送邮件
  1. - name: "发送邮件"
  2.   uses: dawidd6/action-send-mail@v3
  3.   with:
  4.     server_address: smtp.qq.com
  5.     server_port: 465
  6.     username: ${{ secrets.SENDER_USER }}
  7.     password: ${{ secrets.SENDER_PASSWORD }}
  8.     subject: 天气预报 - ${{env.WEATHER_REPORT_DATE}}
  9.     from: GitHub Actions
  10.     to: fatedeity@qq.com
  11.     body: file://output.txt
复制代码
按照阮一峰的脚本,使用 Send email · Actions 发送邮件,和其不同的就是相关的配置。
当然,也可以通过将发送邮件直接写入到 Python 脚本当中,它们各有自己的优势。
使用 GIthub Action 发送邮件更易懂,只需要填写配置即可,也可以将脚本和发送邮件解耦。
使用 Python 发送邮件可以省下 Github Action 的步骤,直接通过脚本一步到位,耦合就比较高。
总结

通过这一次的尝试,使用 Github Action 实现了自动化及定时,也是为以后实现自己的自动化做铺垫。本篇文章的源码可以通过 GitHub - fatedeity/weather-action 访问。
生命在于折腾,看似无用的一次尝试,希望能给自己带来美好的未来。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

东湖之滨

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表