這是什麼
Art-Tracking 把散在各館官網和 IG 的台北展覽資訊抓在一起,用我自己的方式呈現。首頁是 搜尋加上幾個可以疊加的快捷 chip(7 天內結束、離我 2 km、追蹤場館、新、免費),卡片上 標著展出中、剩幾天;另外有甘特圖時間軸看哪一檔快結束,以及每個場館自己的頁面。
網站放在登入後面,只有我自己看得到——上面有我去過哪裡、給幾分、寫了什麼筆記。
為什麼做
美術館的資訊好找,麻煩的是畫廊和替代空間的小型個展。第一版用程式爬蟲抓,畫廊網頁一 改版就斷,修爬蟲的時間比看展還多,最後整個關掉。第二版動工前先想清楚要做什麼、不做 什麼:只做台北但畫廊要收,地圖和推薦系統先砍掉,舊資料全部重來。
怎麼用
對一檔展的狀態拆成三個各自獨立的軸:展期(未開展/展出中/已結束,由日期算出來, 不存)、我的意圖(愛心或跳過,可以改變主意)、造訪(去過是事實,同一檔可以去 兩次)。「有愛心、已結束、沒去過」的交集就是錯過的展,不需要另外標。
首頁像 Inbox 但不逼我表態:依愛心/未標示/跳過分三段,新展只用一個「新」標記提示。 排序是多層的,快到期和離我近的排第一層,愛心在第二層,剩三天的展不會被壓在下面。
技術重點
抓資料交給 agent,不再寫爬蟲:Claude Code 的 skill 每週讀各館頁面、整理成 JSON 送進 API。要抓哪些來源存在資料庫裡,每一列帶一段給 agent 看的自然語言指示,在網頁上就能改。 agent 的權限只到產出 JSON,去重、寫入、抓海報、歸檔全部是 Worker 端的確定性程式碼。
整個站是單一個 Cloudflare Worker:同一支 Worker 同時服務靜態檔和 Hono API,資料在 D1 (Drizzle),海報在 R2,前後端共用同一份 zod schema 與狀態計算。登入交給 Cloudflare Access,Worker 端再驗一次 JWT,設定不完整就直接拒絕,寧可鎖死也不要意外公開。路由測試 用 Vitest 的 workers pool 真的跑在 workerd 裡。
設計取捨
來源壞了要看得到:連續失敗兩次首頁亮警示,四次自動暫停;agent 自己找到新網址時不直接 改,標成待確認等我按一下。代價是每次抓取要花 token,但一週跑一次,可以接受。
