CoolFace
Apppublic

cormort/procurement-crawler-py

sourceHugging Faceapache-2.0updated 2h agoView on Hugging Face
0likes
App README

🕷️ 政府採購網 - 雲端多功能工作站

查詢台灣政府電子採購網的標案、批次取得完整公告欄位、匯出 Excel。 資料來源以 g0v 社群維護的 [pcc-api.openfun.app](https://pcc-api.openfun.app) 為主 (不碰官網,因此沒有驗證碼問題),需要時仍可切回官網爬取模式。

四種模式

模式說明
📡 開放資料 API(建議)關鍵字或日期查詢,一次請求取回整頁含預算金額/截止投標等欄位;可再批次取得 86 欄完整資料
🔍 關鍵字搜尋 (官網)直接爬 web.pcc.gov.tw(有驗證碼風險,內建人類節奏延遲與退避)
🔗 網址直爬貼上標案網址逐筆爬取
📂 異步解析上傳已存下來的標案 HTML,用執行緒池批次解析

為什麼這樣改(實測依據)

這一版的重點是減少請求數尊重對方 API 的流量政策,不是把併發開大:

  1. 1.N 次請求 → 1 次searchbytitle 等搜尋端點支援 columns[]。 實測 searchbytitle?query=農田水利署&columns[]=採購資料:預算金額… 一次就回傳 99 筆(含指定詳細欄位)。原本的寫法是「勾幾筆就打幾次 /api/tender」。
  2. 2.API 有速率限制,而且很緊:後端 APILimiter.php 的規則是 10 秒內 >10 次60 秒內 >60 次就回 429。實測連續打 15 次會被擋到幾乎全部 429 (而且會連帶把後續幾十秒的請求一起拖下水)。因此:
  3. 3.客戶端自我限速在 8 次/10 秒、50 次/60 秒(留安全邊際,不靠「被擋再退避」);
  4. 4.被 429 時冷卻 12 秒再重試(12 秒足以讓 10 秒窗口清空,又不會多等一整個長窗口);
  5. 5.支援 Bearer Token(官方文件明載:帶 token 可解除流量限制)—— 需要大量抓取時請自行申請。
  6. 6.86 欄只拿 7 欄/api/tender 一筆回傳 86 個欄位,舊版只映射 7 個,UI 卻寫著 「80+ 完整欄位」。新版「取得完整欄位」會把 86 欄全部攤平進 Excel(並逐筆快取,重跑不重抓)。
  7. 7.官網模式同一次搜尋打兩次:舊版先用 safe_crawl_with_backoff 打一次拿狀態, 轉頭又打第二次拿 HTML —— 等於把觸發驗證碼的機率與等待時間翻倍。新版一次取得 HTML 後直接解析。
  8. 8.Streamlit 每次互動都會重跑整份腳本,舊版因此在每次點擊/換頁都重打一次搜尋 API。 新版對搜尋結果加上 15 分鐘 TTL 快取,同一組條件不會重複打。
  9. 9.錯誤處理:舊版遇到非 JSON 回應會在 resp.json() 丟出 JSONDecodeError —— 那不是 RequestException,不會被 except 接住,整個頁面會直接掛掉。 新版統一包成 ApiError 並在 UI 顯示原因。
  10. 10.部署requirements.txt 全部釘死版本(浮動版本=某天突然建不起來)、 基底映像 python:3.9-slimpython:3.12-slim(3.9 已 EOL)、改成非 root(uid 1000)執行、 COPY . . 改為只複製必要檔案。

實測數字

情境舊版新版
取得 50 筆的預算金額/截止投標50 次 /api/tender(且很快就 429)1 次 搜尋請求(columns[]
連續 15 次 /api/tender幾乎全部 429(實測 2/15 成功)不會發生:客戶端守在 8 次/10 秒
每次點擊畫面的 API 呼叫1 次(無快取)0 次(TTL 15 分鐘)
單筆可用欄位7 欄86 欄
官網搜尋的請求數2 次1 次

使用方式

  1. 1.左側選「📡 開放資料 API」→ 輸入關鍵字 → 🔎 API 搜尋。 列表在同一次請求就帶回預算金額與截止投標,不必再逐筆抓。
  2. 2.需要完整公告內容時,勾選列 → ⚡ 取得完整欄位(86 欄),完成後可下載 Excel (按鈕上會先顯示預估秒數)。
  3. 3.大量查詢建議在左側填入 data.openfun.tw 的 Bearer Token(可解除流量限制); 留空也能用,只是會自我限速。

資料保存

⚠️ HF Space 的容器檔案系統是暫時性的:重新建置或重啟就會清空 crawled_history.txt。 側邊欄的「案號去重資料庫」提供匯出/匯入 CSV,請自行備份重要清單。

開發與測試

bash
python3 -m venv .venv && . .venv/bin/activate
pip install -r requirements.txt

python3 selftest.py        # 離線測試(限速器、429 退避、欄位攤平、錯誤處理、官網解析)
streamlit run app.py

pcc_core.py 放的是網路、限速、欄位處理等純邏輯(不 import streamlit),所以可以直接測試; app.py 只負責 UI 與流程。

資料來源與授權

  • 資料:政府電子採購網(行政院公共工程委員會),API 由 g0v 社群 (openfunltd/pcc.g0v.ronny.tw)維護。 使用時請遵循原始資料來源的著作權聲明;商業利用請走官方資料集或 M2M 授權。
  • 本程式:Apache-2.0。