Feature #179
進行中新增座標比對驗證機制(自動偵測 Booking.com 地名誤解)與價格區間過濾
100%
概述
h1. 問題背景
Google Places Autocomplete 回傳的地名格式(如 Salò, Province of Brescia, Italy)傳給 Booking.com 的 ss= 參數時,Booking.com 可能將其解讀為完全不同的城市(例如搜到 Brescia 或 Turin 的飯店,偏差超過 200km)。先前的 workaround
是直接將所有搜尋轉為座標模式,但這會失去 Booking.com 文字搜尋的語意優勢(如城市範圍、熱門排序等)。
h1. 解決方案:座標比對驗證
採用「先信任文字搜尋,載入後自動驗證」的策略:
- app.py 將 Google Places 座標(search_lat / search_lng)作為驗證用參數傳入,destination 恢復為原始文字
- scraper.py 在 SSR 頁面載入後,從 HTML 提取所有飯店座標的中位數
- 計算中位數與 Google 座標的 Haversine 大圓距離
-
50km:判定為地名誤解,自動切換為座標搜尋(latitude/longitude URL 參數),並記錄 WARNING
- ≤ 50km:驗證通過,繼續使用文字搜尋,記錄 INFO
門檻值 50km 根據測試數據選定(正確搜尋 < 1km,錯誤搜尋 > 200km),可 100% 區分。
h1. 附帶功能:價格區間過濾
- UI 新增「啟用價格區間」toggle 與滑桿(0–50,000)
- 利用 GraphQL 已回傳的價格欄位,在爬取詳細頁面前進行早期淘汰
- 減少不必要的詳細頁請求,提升整體效率
影響範圍
┌────────────┬──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 檔案 │ 修改內容 │
├────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ scraper.py │ 新增 google_lat/google_lng 參數、_haversine_km()、_extract_ssr_location_median()、載入後座標驗證邏輯 │
├────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ main.py │ 傳遞 search_lat/search_lng 給 scraper、新增價格區間早期淘汰邏輯 │
├────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ app.py │ 撤銷座標 workaround、改傳 Google 座標作驗證用、新增價格區間 UI │
└────────────┴──────────────────────────────────────────────────────────────────────────────────────────────────────┘
驗證方式
- 搜尋 Salò, Province of Brescia, Italy → log 應顯示「偵測到地名誤解(偏差 ~231km),切換為座標搜尋」,結果為 Salò 附近飯店
- 搜尋 Venice, Metropolitan City of Venice, Italy → log 應顯示「地名驗證通過(偏差 < 5km)」,繼續文字搜尋
- 地圖點選座標模式 → _is_coordinate() 判定後直接走座標路線,跳過驗證
- 價格區間過濾 → 開啟 toggle 後,log 顯示被淘汰的飯店與價格
沒有任何資料可供顯示