使用Bun 來抓取UBike即時車位Json並且進行顯示 (new javascript runtime)

JLin
7 min readSep 14, 2023

從Ubike API抓取資料

抓json顯示 (台灣公共腳踏車即時資訊API) 有興趣的可以看上一篇介紹Bun,因為得太多,這篇就衍生專門針對Bike來增加囉,由於我本身是寫kotlin為主,javascript其實也是大學時候再寫的,大同小異,但順便當作練習

ubike api json回傳

https://data.tycg.gov.tw/api/v1/rest/datastore/a1b4714b-3b75-4ff8-a8f2-cc377e4eaa0f?format=json

and

const response = await fetch("https://data.tycg.gov.tw/api/v1/rest/datastore/a1b4714b-3b75-4ff8-a8f2-cc377e4eaa0f?format=json", {
method: "GET",
headers: { "Content-Type": "application/json" },
});
const body = await response.json();console.log(body)

這是一個公開的即時UBIKE剩餘車輛資訊,簡單這樣就可以抓取json

抓第一筆

由於他回來是一個json object,裝了一些json array,因此改透過這樣可以抓取第一筆

const response = await fetch("https://data.tycg.gov.tw/api/v1/rest/datastore/a1b4714b-3b75-4ff8-a8f2-cc377e4eaa0f?format=json", {
method: "GET",
headers: { "Content-Type": "application/json" },
});
const body = await response.json();console.log(body['result']['records'][0])

在整理一下,可以判斷’success’,有沒有成功才顯示

async function main() {
const response = await fetch("https://data.tycg.gov.tw/api/v1/rest/datastore/a1b4714b-3b75-4ff8-a8f2-cc377e4eaa0f?format=json", {
method: "GET",
headers: { "Content-Type": "application/json" },
});

const body = await response.json();
const isFail = !body['success']
if(isFail) {
console.log('read failed')
return
}

console.log(body['result']['records'][0])
}
main()

目前印在console,也可以轉而變成一個網站,可以自己試試囉。

抓第一筆詳細參數

如果想要只抓取第一筆,並且抓出名稱與剩餘車輛數量呢

async function main() {
const response = await fetch("https://data.tycg.gov.tw/api/v1/rest/datastore/a1b4714b-3b75-4ff8-a8f2-cc377e4eaa0f?format=json", {
method: "GET",
headers: { "Content-Type": "application/json" },
});

const body = await response.json();
const isFail = !body['success']
if(isFail) {
console.log('read failed')
return
}

const ubikeList = body['result']['records']
const first = ubikeList[0]
const name = first['sna']
const remaind = first['sbi']
const total = first['tot']

console.log(name + "(" + remaind + "/" + total + ")")
}

main()

這樣擷取起來好像比較好看?

當中應過可以用string template,個人懶惰就沒去查了,上面為了要在失敗的時候執行return,就必需將整個流程包進一個main function,執行結果是這樣

中央大學圖書館(33/60)

能把抓到的結果顯示於simple http server嗎?

當然是可以的,不過我下面寫的方式只是demo,實際應該會先顯示網頁,然後在網頁上非同步的方式去更新抓到ubike的結果,否則像這樣網頁載入速度就會取決於ubike api的回傳速度,對於你的網站體驗是非常不好的

可以看到下面這樣執行後,你就會取得一個localhost的服務

async function main() {
const response = await fetch("https://data.tycg.gov.tw/api/v1/rest/datastore/a1b4714b-3b75-4ff8-a8f2-cc377e4eaa0f?format=json", {
method: "GET",
headers: { "Content-Type": "application/json" },
});

const body = await response.json();
const isFail = !body['success']
if(isFail) {
console.log('read failed')
return
}

const ubikeList = body['result']['records']
const first = ubikeList[0]
const name = first['sna']
const remaind = first['sbi']
const total = first['tot']
const text = `${name} ( ${remaind} / ${total})`
console.log(text)

const server = Bun.serve({
port: 3000,
fetch(request) {
return new Response(`Welcome to Bun! ${text}`);
},
});

console.log(`Listening on localhost: ${server.port} ,UBike:${text}`);
}

main()

執行結果會是

透過瀏覽器

如此就可以產生一個網頁並且是透過json抓得的結果來顯示啦,有興趣的就可以自己試試囉

--

--

JLin

JAVA / Android /Kotlin / Kotlin Native 對於Kotlin衍生的JVM等技術 Compose for web / desktop / Ktor Server,或是生成式AI (Gemini/OpenAI)各式應用, 都有小興趣