iT邦幫忙

2026 iThome 鐵人賽

DAY 2
0
自我挑戰組

30 天養大一個開源專案:baodao-skill 從零開始系列 第 2

【Day 2】想查颱風警報卻被官網擋在門外,我找到了免金鑰的 NCDR CAP

  • 分享至 

  • xImage
  •  

昨天 Day 1,我把五個「不用 API 金鑰」的台灣生活查詢技能丟上了 GitHub:發票對獎、YouBike、垃圾車、天氣。晚上躺在床上越想越不對:現在是九月,正是颱風季,我的天氣技能居然只會說「明天會下雨」,不會說「氣象署發布了海上颱風警報」。

不行,這個一定要補。

第一道牆:CWA 官網不讓我進

最直覺的想法是:中央氣象署官網 www.cwa.gov.tw 上明明就有警特報列表,直接讀它的頁面不就好了?

我 curl 下去,得到的是乾脆俐落的 HTTP 403。換了 User-Agent 假裝自己是瀏覽器,還是 403。看起來 CWA 官網有 Bot 防護,從資料中心的 IP 過去一律被擋。這很合理,人家的網站是給人看的,不是給程式讀的。

至於 CWA 的開放資料 API(opendata.cwa.gov.tw),警特報資料集當然有,但要 API 金鑰。我們 repo 裡的 cwa-weather 技能就是走這條路,運作得很好。可是 baodao-skill 的初衷是「裝了就能用」,我希望連警報都有免金鑰的備援方案。

挖到寶:NCDR 的 CAP 公開 Feed

查資料的時候我注意到一個單位:國家災害防救科技中心(NCDR)。他們是台灣災害示警的交換中心,氣象署、水利署這些機關發布的警報,都會以 CAP(Common Alerting Protocol)格式彙整到這裡。而且他們把 CAP 訊息做成了公開的 Atom feed:

https://alerts.ncdr.nat.gov.tw/RssAtomFeed.ashx?AlertType=5

最後面那個數字是災害類型代碼。官方頁面上沒有一張完整的對照表,所以我就一個一個試(實測日期:2026-09-09):

AlertType 內容
1-4 回傳「存取檔案有誤」,不存在
5 颱風
6 地震
7 海嘯
8 淹水
9 土石流及大規模崩塌
10 降雨
11 河川高水位

颱風、地震、海嘯,最想查的三個全中。不用金鑰、不用登入,curl 就打得到。

第一個坑:429 教你做人

我興高采烈地寫了個迴圈,想一次把七種類型都抓下來:

for t in 5 6 7 8 9 10 11; do
  curl -s "https://alerts.ncdr.nat.gov.tw/RssAtomFeed.ashx?AlertType=$t" > "cap_$t.xml"
done

結果前五個還正常,後面開始噴 HTTP 429 Too Many Requests。原來 NCDR 有速率限制,試了幾次之後確認:連續請求之間至少要隔 3 秒。所以正確的寫法是:

for t in 5 6 7 8 9 10 11; do
  curl -s "https://alerts.ncdr.nat.gov.tw/RssAtomFeed.ashx?AlertType=$t" > "cap_$t.xml"
  sleep 3
done

把這段踩雷過程寫進 SKILL.md 的「錯誤與失敗時的處理」,下一個人(或下一個 AI)就不用再被 429 打一次臉。

第二個坑:「有資料」不等於「現在有效」

CAP 的 Atom feed 裡,每一則警報長這樣(節錄):

<entry>
  <title>海上颱風警報</title>
  <updated>2026-09-08T20:30:00+08:00</updated>
  <summary>...</summary>
  <cap:expires>2026-09-09T20:30:00+08:00</cap:expires>
</entry>

注意最後那個 cap:expires。NCDR 的 feed 會留著已經過期的警報一段時間,如果你只看「feed 裡有海上颱風警報」就跟使用者說「現在發布颱風警报了」,那可能是在播報三天前的舊聞。正確流程是:取出每一則 entry,比對 updated 和 cap:expires,過期的就不報、或明講「這則警報已解除」。

順便一提:feed 內容是 UTF-8 中文,終端機直接看沒問題;但 XML 解析建議用 xmllint 或程式語言的 XML parser,不要用正規表示式硬拆,CAP 的命名空間會讓你哭。

三個來源怎麼分工

改完之後,taiwan-weather 技能的世界觀變清楚了,我把它整理成一張表放進 SKILL.md:

需求 用哪個 要不要金鑰
現在天氣、未來預報 Open-Meteo 不用
官方預報、鄉鎮級預報 CWA opendata API 要(免費申請)
颱風/地震/海嘯等災害警報 NCDR CAP feed 不用

Open-Meteo 管「天氣怎麼樣」,NCDR 管「有沒有出事」,CWA API 管「官方怎麼說」。三個加起來,免金鑰的部分已經能應付大多數日常問題。

今天的成果

taiwan-weather 從「只會查天氣」升級成「會查天氣也會查災害警報」,cwa-weather 也補了一段:沒有金鑰的時候,警特報請轉用 NCDR CAP。全部實測過才敢寫進去,這是這個 repo 的鐵則。

明天來聊另一個升級:YouBike 查詢是怎麼從雙北長到四個城市的。每個縣市的開放資料格式都不一樣,那才叫刺激。


上一篇
【Day 1】開賽宣言:為什麼我要用 30 天,從零養大一個開源專案
下一篇
【Day 3】四個城市、四種格式,然後我找到了「一統江湖」的那支 JSON
系列文
30 天養大一個開源專案:baodao-skill 從零開始3
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言