iT邦幫忙

2026 iThome 鐵人賽

DAY 3
0
自我挑戰組

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

【Day 3】四個城市、四種格式,然後我找到了「一統江湖」的那支 JSON

  • 分享至 

  • xImage
  •  

昨天預告過了:今天來講 YouBike 查詢怎麼從雙北長到四個城市。本來以為是「多接兩個 API」的小事,結果變成這次升級裡踩最多坑的一個——而且坑踩完之後,隔天又來了一個大反轉。

理想很豐滿:YouBike 不是全台統一嗎?

YouBike 2.0 的站點即時資料,理論上各縣市政府都會透過開放資料平台釋出。所以擴充計畫聽起來很簡單:找到各縣市的 feed,寫進 SKILL.md,收工。

實際上每個城市各自為政。收錄的四個來源長這樣(實測日期:2026-09-09):

城市 來源 站數
台北市 tcgbusfs.blob.core.windows.net 約 1,800 站
新北市 data.ntpc.gov.tw JSON API 約 1,600 站
台中市 newdatacenter.taichung.gov.tw 約 1,800 站
桃園市 opendata.tycg.gov.tw 約 700 站

同一個 YouBike,四套 endpoint、四套欄位命名。台北用 available_rent_bikes,新北用 sbi_quantity,台中和桃園用 sbi。回傳型別也不統一:台北給數字,其他三市給字串。連更新時間格式都有三種:台北是 "YYYY-MM-DD HH:MM:SS",新北是 "YYYYMMDDTHHMMSS",台中和桃園是 "YYYYMMDDHHMMSS"。這些差異最後全部整理成對照表放進 SKILL.md,查詢的人(或 AI)不用每個城市重新猜一次。

第一個坑:桃園只有 20 個站?

接桃園的時候,curl 回來的 JSON 我數了一下:20 站。桃園好歹一百多萬人,YouBike 只有 20 站?怎麼想都不對。

仔細看才發現,桃園的 API 預設只回 20 筆,要加上 limit 參數才會給全量:

curl -s "https://opendata.tycg.gov.tw/api/v1/dataset.api_access?rid=08274d61-edbe-419d-8fcc-7a643831283d&format=json&limit=2000"

帶了 limit=2000 之後,七百多站整整齊齊地出現。如果當初只看回傳「有資料」就收工,這個 skill 就會永遠以為桃園只有 20 站。這也是為什麼 repo 的鐵則是「實測過才收錄」:不只要確認打得通,還要確認數量合理。

第二個坑:電輔車數量藏在字串裡

電輔車(YouBike 2.0E)篩選是這次的重點之一。新北很佛心,直接給 eyb_quantity 欄位。台中和桃園就把電輔車數量塞在一個叫 sbi_detail 的欄位裡,而且兩市格式還不一樣:台中是逗號分隔字串("5,1"=一般車 5、電輔車 1),桃園是 JSON 字串({"yb2":5,"eyb":1}),要再 parse 一次。

台中那個 "5,1" 的順序,官方文件沒寫清楚。我的驗證方式很土法煉鋼:找一個 sbi(總可借)等於 6 的站,它的 sbi_detail 是 "5,1",5+1=6 對得起來,再挑幾個站交叉比對才確認順序。文件沒寫的東西,就用資料自己證明。

第三個坑:連站名都不老實

你以為欄位對齊就沒事了?站名還有「台」跟「臺」的問題。台北市的資料裡,一百多個站用「臺」,其他用「台」;新北也混著用。使用者打「台大」搜尋,結果站名是「臺大」,就直接查無此站。最後在查詢範例裡加了正規化指引:搜尋前先把「臺」換成「台」(jq 的 gsub("臺";"台")),或兩個寫法都試。

還有台北和新北的邊界問題:很多站蓋在兩市交界,住永和的人最近的站可能在台北市的 feed 裡。所以查「附近站點」時,兩個城市的資料要合起來算距離,不能各查各的。

大反轉:原來有一支全國統一的 feed

四個城市接完,我本來已經接受「YouBike 資料就是碎的」這個事實。結果隔天整理程式碼的時候發現:YouBike 官方網站自己用的一支 JSON,一次給全台灣的即時資料:

https://apis.youbike.com.tw/json/station-yb2.json

14 個縣市、九千五百多個站,欄位統一:available_spaces、empty_spaces、status,連 available_spaces_detail 都直接拆好 {"yb1","yb2","eyb"}。昨天還在頭痛的電輔車篩選,這支 feed 直接內建。

但這裡要冷靜:這支 feed 是 YouBike 公司網站自己用的,不是政府開放資料平台,沒有正式文件,隨時可能改格式或關掉。所以最後的架構是雙軌:查全台(包含昨天忍痛放棄的高雄)用這支統一 feed,各縣市的政府開放資料當備援。repo 的規矩沒變——沒驗證過的不收,驗證過的也要講清楚它的風險。

順帶一提,台北市政府的 feed 裡沒有電輔車欄位,所以「台北市+電輔車」這個組合,以前只能說不支援,現在可以導到統一 feed 查。

寫完之後的加固

功能接完,回頭把文件和 CI 也補強了一輪:站數從硬寫的數字改成「約幾站+實測日期」(桃園一天之內就從 702 漂到 703),health-check 腳本除了看 HTTP status,還開始解析回傳的 JSON、檢查站數有沒有低於門檻(專抓「HTTP 200 但其實是錯誤頁」的沉默失敗),CHANGELOG 記上每一筆改動的理由。

今天的成果

youbike-realtime 從「雙北限定」長成「全台 14 縣市」:統一 feed 當主力、四市政府開放資料當備援、電輔車可單獨篩選、暫停營運的站如實回報、台臺異體字有解。昨天寫「高雄忍痛排除」的我,今天被一支 JSON 拯救了。

明天換垃圾車出場:taipei-garbage 是怎麼改名成 taiwan-garbage 的,新北市的兩萬六千多筆清運點又是怎麼分頁抓完的。


上一篇
【Day 2】想查颱風警報卻被官網擋在門外,我找到了免金鑰的 NCDR CAP
系列文
30 天養大一個開源專案:baodao-skill 從零開始3
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言