今天終於要開始我們的實作拉~
這次要做的是未來 36 小時天氣預測資料
會利用到中央氣象局的API資料
小叮嚀
本機測試可以用 ngrok 做臨時的 wenhook
也要記得到 LINE Official Account Manager 修改 webhook 連結喔!
我們現在有中央氣象局的 API,現在只需要使用 Python 內的 requests 套件
我們要先到中央氣象局 開放資料平台辦一個帳號
接下來到會員資訊 - API授權碼 取得我們的 Token
接下來直接對 API 提供的連結 GET ,就可以拿到我們的資料了
可以參考中央氣象局的API資料
我們可以寫一個 get
的 function 去獲取資料
import requests
def get(city):
token = 'YourToken' //這裡記得換成剛剛生成的 Token
url = 'https://opendata.cwb.gov.tw/api/v1/rest/datastore/F-C0032-001?Authorization=' + token + '&format=JSON&locationName=' + str(city)
Data = requests.get(url)
print(Data.text)
我們可以先以 臺北市
為例,看看接收到的文字內容
{
"success": "true",
"result": {
"resource_id": "F-C0032-001",
"fields": [
{...}
]
},
"records": {
"datasetDescription": "三十六小時天氣預報",
"location": [
{
"locationName": "臺北市",
"weatherElement": [
{
"elementName": "Wx",
"time": [
{
"startTime": "2020-09-26 18:00:00",
"endTime": "2020-09-27 06:00:00",
"parameter": {
"parameterName": "陰陣雨",
"parameterValue": "14"
}
},
{...}
]
},
{
"elementName": "PoP",
"time": [
{
"startTime": "2020-09-26 18:00:00",
"endTime": "2020-09-27 06:00:00",
"parameter": {
"parameterName": "80",
"parameterUnit": "百分比"
}
},
{...}
]
},
{
"elementName": "MinT",
"time": [
{
"startTime": "2020-09-26 18:00:00",
"endTime": "2020-09-27 06:00:00",
"parameter": {
"parameterName": "21",
"parameterUnit": "C"
}
},
{...}
]
},
{
"elementName": "CI",
"time": [
{
"startTime": "2020-09-26 18:00:00",
"endTime": "2020-09-27 06:00:00",
"parameter": {
"parameterName": "舒適"
}
},
{...}
]
},
{
"elementName": "MaxT",
"time": [
{
"startTime": "2020-09-26 18:00:00",
"endTime": "2020-09-27 06:00:00",
"parameter": {
"parameterName": "23",
"parameterUnit": "C"
}
},
{...}
]
}
]
}
]
}
}
注意一下裡面的幾個參數
資料內都是以 12 小時為一個區間
另外可以發現到,我們拿到的資料會是字串型態的 JSON
可以利用 Python 的 JSON 套件將字串轉換成 dict ,方便未來存取
現在我們有資料了,之前曾經提到在開發 LINE BOT 時,很重要的是 輸入 與 輸出 的概念
我們要先決定好輸入與輸出的格式
我們希望用戶輸入 天氣 {縣市}
來要求獲取天氣資料
其中 {縣市}
要替換成縣市的名稱
例如要查詢臺北市 天氣 臺北市
因為台灣的縣市名稱有 台
和 臺
的不同,我們直接統一將使用者輸入的台改寫成大寫的臺
針對上面我們有的資料,我希望只輸出:
而輸出的格式會是以 Carousel 的型態輸出
且每一個 column 都代表一個 12 小時的區間
下方有個按鈕導向中央氣象局的網站
像是這樣子
好的~目前稍微規劃好了,我們先來處理輸入吧~
if(message[:2] == '天氣'):
city = message[3:]
city = city.replace('台','臺')
# 使用者輸入的內容並非符合格式
if(not (city in cities)):
line_bot_api.reply_message(reply_token,TextSendMessage(text="查詢格式為: 天氣 縣市"))
else:
# 處理輸出
現在來整理一下資料吧~
我希望我可以將資料分成 3 個部分,分別表示每 12 個小時的一個區間
稍微改寫一下前面的 get function 來處理吧~
def get(city):
token = 'YourToken'
url = 'https://opendata.cwb.gov.tw/api/v1/rest/datastore/F-C0032-001?Authorization=' + token + '&format=JSON&locationName=' + str(city)
Data = requests.get(url)
Data = (json.loads(Data.text,encoding='utf-8'))['records']['location'][0]['weatherElement']
res = [[] , [] , []]
for j in range(3):
for i in Data:
res[j].append(i['time'][j])
return res
['records']['location'][0]['weatherElement']
res
改寫成一個有3格的 list ,而每一格裡面都包含一個時間區段的 dict最後就剩下輸出了
我們主要關注在 title
和 text
上
注意到
title
最多 40 字text
最多 60 字
title
格式為: 月-日 時:分 ~ 月-日 時:分
text
格式為: 天氣狀況 {}\n溫度 {} ~ {} °C\n降雨機率 {}
最終的輸出 code
res = get(city)
line_bot_api.reply_message(reply_token, TemplateSendMessage(
alt_text = city + '未來 36 小時天氣預測',
template = CarouselTemplate(
columns = [
CarouselColumn(
thumbnail_image_url = 'https://i.imgur.com/Ex3Opfo.png',
title = '{} ~ {}'.format(res[0][0]['startTime'][5:-3],res[0][0]['endTime'][5:-3]),
text = '天氣狀況 {}\n溫度 {} ~ {} °C\n降雨機率 {}'.format(data[0]['parameter']['parameterName'],data[2]['parameter']['parameterName'],data[4]['parameter']['parameterName'],data[1]['parameter']['parameterName']),
actions = [
URIAction(
label = '詳細內容',
uri = 'https://www.cwb.gov.tw/V8/C/W/County/index.html'
)
]
)for data in res
]
)
))
完整的程式碼可以參考今日練習 Github 連結
經過這次的練習,大概可以學到
不過這一個版本中還有很多可以改進的部分
像是對於使用者而言,每次查詢還需要輸入文字是很麻煩的
在下一篇我們會提到改良的方式
實際上到這邊,各位都有能力自己做出一個 LINE BOT
各式的訊息 接收/傳送 都已經在前面完整說明過
大概最後遇到的幾乎都不會是 LINE BOT API 的使用問題ww
大概最頭痛的會是資料處理的部分
透過這次實作應該也能發現到我們花了不少時間在處理資料
另外,這次也強調將特定的功能另外拉出來寫成一個 function
這在未來對於開發專案是很有幫助的
先在 main 裡面寫好邏輯,預先設定該函數回傳的內容
這樣一來在寫程式上會輕鬆需多,一次只需要注意一件事即可
接下來極有可能會是每天都帶實作
這真的有點可怕QQ
希望各位客官如果任何想法或是建議
例如希望我嘗試做做看什麼功能w
都歡迎在下面留言喔~
中央氣象局 - 開放資料平台
中央氣象局 - 預報XML產品預報因子欄位中文說明表
中央氣象局 API線上說明文件
程式前沿