1. 引言
Google Apps Script 不但可以操作 Google 自家的各種應用程式,
也可以跟外部系統互動。
意思是我們可以從外面抓資料進來,
也可以把資料傳到別的系統。
只要該系統有提供 API (Application Programming Interface) 即可。
我們今天就來用一個簡單的案例,
看看要怎麼透過 API 從外部把資料抓進來。
這個案例並沒有成功一步到位,
而是跟 ChatGPT 來回討論才達成所要的效果。
我會直接分享我的真實對話紀錄連結,
你可以看到我遇到了哪些問題,
並且如何發問來解決它。
2. 案例背景
YouBike 是我上下班的主要通勤方式,
但常常想借沒得借,想還沒得還。
雖然手機 app 可以即時查看各站點可借還的車數,
但有的時候光有即時資訊是不夠的。
我不但想要知道現況,我還想要預測未來。
因為有的時候其實只要多等一下下,
YouBike 工作人員就會來釋出空位或補車。
沒有人能精準預測未來。
但如果想猜得準,讀點歷史總是有幫助的。
鑑往知來嘛。
要是我們可以把 YouBike 站點的流量數據記錄下來,
就有可供分析的數據了!
3. 實作過程:如何使用 GenAI 產生程式
我跟 ChatGPT 完整的對話紀錄可以直接看這裡:
https://chatgpt.com/share/66ff1c27-2cfc-800e-abd4-da735249197d
以下概述過程。
原本以為可以一次成功
我本來以為在請 ChatGPT 寫程式之前,
我們要自己先查好 YouBike 數據要從哪裡抓並提供給 ChatGPT。
但我發現 ChatGPT 已經有這方面的資料了,
所以我們可以直接這樣問就好:
請幫我用 Google Apps Script 寫一個自動抓取 YouBike 站點數據並記錄在 Google Sheets 的程式
而如果你今天想抓的資料並不像 YouBike 資料這麼廣為人知,
是你們公司的私有系統或是別的 ChatGPT 沒聽過的冷門系統,
你就需要先查一下該系統的 API 說明書,
把說明書提供給 ChatGPT,
再請 ChatGPT 依此文件幫你寫程式。
我把 ChatGPT 產生的程式拿去執行後,
真的成功顯示出各站點的資料了:
慢著……
看起來有點怪怪的,
為什麼即時資訊得到的是2022年10月的資料呢?
上網一查發現,
原來 YouBike API 有改版過,
ChatGPT 給的程式碼用到舊版的了……
新版的改到這裡抓:
https://tcgbusfs.blob.core.windows.net/dotapp/youbike/v2/youbike_immediate.json
更新成 v2 API 版本
我再次向 ChatGPT 詢問
這個 api 好像是舊的,資料只到2022年
請問有新的嗎?
這次 ChatGPT 主動上網搜尋最新資訊了,
然後又改了一版程式碼給我。
我拿來一試發現……
這次 API 也有抓到資料,
但是卻沒有紀錄在 Google Sheets 上。
我診斷後認為是在解析資料時失敗了。
可能是因為 ChatGPT 沒看過該 API 回傳資料的格式長什麼子,
亂猜之下猜錯了。
以正確的方式來解析資料
我又跟 ChatGPT 說:
我發現沒有成功寫入資料,推測是沒有 parse 成功。
這是https://tcgbusfs.blob.core.windows.net/dotapp/youbike/v2/youbike_immediate.json 回傳的資料樣子:
[
{
“sno”: “500101001”,
“sna”: “YouBike2.0_捷運科技大樓站”,
“sarea”: “大安區”,
“mday”: “2024-09-28 18:32:19”,
“ar”: “復興南路二段235號前”,
“sareaen”: “Daan Dist.”,
“snaen”: “YouBike2.0_MRT Technology Bldg. Sta.”,
“aren”: “No.235, Sec. 2, Fuxing S. Rd.”,
“act”: “1”,
“srcUpdateTime”: “2024-09-28 18:32:24”,
“updateTime”: “2024-09-28 18:32:52”,
“infoTime”: “2024-09-28 18:32:19”,
“infoDate”: “2024-09-28”,
“total”: 28,
“available_rent_bikes”: 0,
“latitude”: 25.02605,
“longitude”: 121.5436,
“available_return_bikes”: 27
},
{
“sno”: “500101002”,
“sna”: “YouBike2.0_復興南路二段273號前”,
“sarea”: “大安區”,
“mday”: “2024-09-28 18:28:14”,
“ar”: “復興南路二段273號西側”,
“sareaen”: “Daan Dist.”,
“snaen”: “YouBike2.0_No.273, Sec. 2, Fuxing S. Rd.”,
“aren”: “No.273, Sec. 2, Fuxing S. Rd. (West)”,
“act”: “1”,
“srcUpdateTime”: “2024-09-28 18:32:24”,
“updateTime”: “2024-09-28 18:32:52”,
“infoTime”: “2024-09-28 18:28:14”,
“infoDate”: “2024-09-28”,
“total”: 21,
“available_rent_bikes”: 0,
“latitude”: 25.02565,
“longitude”: 121.54357,
“available_return_bikes”: 21
}]
你可以依此重新修改程式嗎?成功了!
在最後這一版的程式,
終於成功抓到最新的即時資訊了!
包含站點名稱、區域、地址、可借車數量、可還車位數量,甚至連經緯度都有。
4. Google Apps Script 程式碼解說
最終運行成功版的程式碼如下,
細節可略過不看:
function fetchYouBikeData() {
// 設定 YouBike 2.0 API URL(台北市)
var apiUrl = "https://tcgbusfs.blob.core.windows.net/dotapp/youbike/v2/youbike_immediate.json";
try {
// 透過 UrlFetchApp 抓取 API 數據
var response = UrlFetchApp.fetch(apiUrl);
var jsonData = JSON.parse(response.getContentText());
// 取得當前試算表的第一個工作表
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getActiveSheet();
// 清空現有數據,並重設標題
sheet.clear();
var header = [
"站點編號", "站點名稱", "區域", "地址", "可借車數量",
"可還車位數量", "總停車位", "更新時間", "經度", "緯度"
];
sheet.appendRow(header);
// 遍歷所有站點並將數據寫入試算表
jsonData.forEach(function(station) {
var rowData = [
station.sno, // 站點編號
station.sna, // 站點名稱
station.sarea, // 區域
station.ar, // 地址
station.available_rent_bikes, // 可借車數量
station.available_return_bikes, // 可還車位數量
station.total, // 總停車位
station.mday, // 更新時間
station.longitude, // 經度
station.latitude // 緯度
];
// 將每個站點的資料寫入試算表
sheet.appendRow(rowData);
});
Logger.log("YouBike 2.0 站點數據已成功寫入試算表。");
} catch (error) {
Logger.log("錯誤:" + error.message);
}
}
這段程式碼的主要目的是透過 Google Apps Script 抓取台北市 YouBike 2.0 即時數據,並將這些數據記錄到 Google 試算表中。它的運作方式可以分為以下幾個步驟:
設定 API 來源
程式中首先設定了 apiUrl,即用來抓取 YouBike 2.0 站點資料的 API 網址:https://tcgbusfs.blob.core.windows.net/dotapp/youbike/v2/youbike_immediate.json。
該 API 會返回所有台北市 YouBike 2.0 站點的即時狀態數據,例如:站點名稱、站點位置、可借車數量、可停車位數量等。
抓取 API 資料
使用 UrlFetchApp.fetch(apiUrl) 發送 HTTP GET 請求來獲取 API 的回應,並透過 getContentText() 將回應內容轉換為 JSON 格式的文字資料。
之後再使用 JSON.parse() 將文字格式轉為 JavaScript 物件(JSON 解析),使程式能夠操作 API 回傳的資料。
選擇與清空試算表
程式使用 SpreadsheetApp.getActiveSpreadsheet() 取得當前試算表的物件,並選取其第一個工作表。
使用 sheet.clear() 清空該工作表中所有現有資料,確保不會重複紀錄。
寫入標題與資料
首先設定表格的標題列(例如:站點編號、站點名稱、可借車數量等),並使用 sheet.appendRow() 將標題寫入試算表。
之後,遍歷所有的站點資料(透過 jsonData.forEach()),將每個站點的詳細資訊(如編號、名稱、地址、可借車與可停車數量、經緯度等)逐列寫入試算表。
錯誤處理
整個程式碼包裹在 try-catch 區塊內,用於捕捉並記錄可能發生的錯誤。若在抓取 API 或寫入試算表時發生任何錯誤,程式會將錯誤訊息記錄到日誌中,方便調試。
5. 下一步優化
在這篇裡我們已經做到用程式自動抓取 YouBike 即時數據了,
下一篇我們會進一步做兩項改善
- 設定定時執行,每五分鐘就自動抓取一次數據並紀錄下來
- 只針對關注的站點做紀錄,免得資料爆炸多
[…] […]
[…] […]