偶然間,看到 GitHub Actions 教程:定時發送天氣郵件 - 阮一峰的網路日志 這篇文章,沒錯,這個正好能打發自己的折騰之心,也能通過代碼給生活引入一些變化,
還是在這里簡單記錄一下實作程序吧,
第一步 獲取天氣預報出現問題
按照阮一峰的教程走,一開始使用了 wttr 的結果作為資料來源,也在 檔案 上研究了很久,最終的結果總是不盡如人意,
最終展現到郵件上的結果如下:

從上面就可以看出一些問題:
- 展示到郵件中的是一個 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"
}
}
根據上述的回傳結果,簡單組裝了一個自己想要的結果:
位置:廣東-廣州 今天: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 sys
import requests
def 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 Action
Github Action 的組態檔趨同于阮一峰的教程,下面是這個組態檔的一些解釋,
定時觸發
name: "天氣預報"
on:
push:
schedule:
# 需要減 8 個小時
- cron: "0 23 * * *"
這里比較好理解,name 是名稱,on 是觸發的時機,push 是我們提交代碼到 Github 時觸發,schedule 是定時觸發,需要注意的時候,定時觸發的時間需要減掉 8 個小時,其遵循國際標準時間而不是北京時間,
運行流程
runs-on: ubuntu-latest
steps:
- name: "切換代碼"
uses: actions/checkout@v3
進入到 jobs 運行流程中,runs-on 指定運行環境是最新的 Ubuntu 即可,actions/checkout@v3 用作從代碼倉庫獲取代碼,
獲取時間
- name: "獲取時間"
run: echo "WEATHER_REPORT_DATE=$(TZ=':Asia/Shanghai' date '+%Y-%m-%d %T')" >> $GITHUB_ENV
直接通過 Linux 命令獲取當前時間,然后轉換成北京時間,這個時間主要是用于后續寫入到郵件的標題當中,
在這里,通過 echo "{environment_variable_name}={value}" >> $GITHUB_ENV 的方式寫入環境變數,在后續的步驟中都可以訪問到這個環境變數,
執行腳本
- uses: actions/setup-python@v4
with:
python-version: "3.10"
- run: pip install -r requirements.txt
- name: "獲取天氣結果"
run: 'echo "$(python open_api/weather.py 廣州 桂林)" > output.txt'
這里有兩個步驟,一個是指定 Python 的運行環境并且安裝好相關的依賴,第二個是執行 Python 的腳本獲取結果,
在這里,為了方便將腳本的執行結果給到后續的步驟,選擇將執行結果寫入到一個檔案當中,當然,選擇怎樣的方式主要看自己,
發送郵件
- name: "發送郵件"
uses: dawidd6/action-send-mail@v3
with:
server_address: smtp.qq.com
server_port: 465
username: ${{ secrets.SENDER_USER }}
password: ${{ secrets.SENDER_PASSWORD }}
subject: 天氣預報 - ${{env.WEATHER_REPORT_DATE}}
from: GitHub Actions
to: [email protected]
body: file://output.txt
按照阮一峰的腳本,使用 Send email · Actions 發送郵件,和其不同的就是相關的配置,
當然,也可以通過將發送郵件直接寫入到 Python 腳本當中,它們各有自己的優勢,
使用 GIthub Action 發送郵件更易懂,只需要填寫配置即可,也可以將腳本和發送郵件解耦,
使用 Python 發送郵件可以省下 Github Action 的步驟,直接通過腳本一步到位,耦合就比較高,
總結
通過這一次的嘗試,使用 Github Action 實作了自動化及定時,也是為以后實作自己的自動化做鋪墊,本篇文章的原始碼可以通過 GitHub - fatedeity/weather-action 訪問,
生命在于折騰,看似無用的一次嘗試,希望能給自己帶來美好的未來,
首發于翔仔的個人博客,點擊查看更多,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/518742.html
標籤:其他
