250 lines
18 KiB
Markdown
250 lines
18 KiB
Markdown
# Browse.sh Crawler Playbook
|
||
|
||
> Scope: MOMO / PChome 動態頁診斷、selector 探勘、XHR/network trace。正式價格資料仍以既有 Python crawler、PChome API 與資料庫閉環為準。
|
||
|
||
## 評估結論
|
||
|
||
- `browse.sh` 是 Browserbase 提供的 browser CLI,主打 open web catalog、browser primitives、debugging、cloud sessions 與 network/console tail。
|
||
- 官方安裝入口為 `npm install -g browse`,CLI 名稱是 `browse`。
|
||
- 對本專案最有價值的地方不是取代爬蟲,而是當 MOMO/PChome HTML 或前端 XHR 改版時,快速看 selector、console、network 與可重放 skill。
|
||
- 本機目前 Node 16 因 `icu4c` 動態庫缺失無法啟動,不能在本機直接安裝或執行 `browse`。導入方式先採 optional wrapper,不影響 production scheduler。
|
||
|
||
## 使用邊界
|
||
|
||
- 只允許做 read-only 診斷,不登入、不下單、不加入購物車、不寫第三方狀態。
|
||
- 不把 `browse` 放進排程主路徑;若未來要排程化,需另開 ADR 與 feature flag。
|
||
- 不把 `browse` 輸出直接寫成正式價格;所有正式比價仍需經 `services/pchome_crawler.py`、`services/momo_crawler.py`、`services/marketplace_product_matcher.py` 與 `competitor_match_attempts` 診斷。
|
||
- Cloud sessions 可能需要 Browserbase 帳號與憑證;憑證不可寫入 repo。
|
||
|
||
## 本地檢查
|
||
|
||
```bash
|
||
python scripts/tools/browse_sh_probe.py
|
||
```
|
||
|
||
可用時會輸出 `available=true` 與版本;不可用時會輸出原因。若 `browse` 不在 PATH,可用:
|
||
|
||
```bash
|
||
BROWSE_SH_CLI=/path/to/browse python scripts/tools/browse_sh_probe.py
|
||
```
|
||
|
||
## 診斷流程
|
||
|
||
1. 先用既有 crawler/API 重現問題,保存失敗 SKU、搜尋詞、候選網址與 matcher diagnostics。
|
||
2. 使用 `browse` 開同一頁,查看搜尋結果 DOM、network 與 console。
|
||
3. 若找到穩定 XHR/API,優先回補到 Python crawler;若只能走 DOM,才更新 selector。
|
||
4. 新增或更新單元測試,至少覆蓋搜尋詞、候選解析與 matcher hard veto。
|
||
5. 只在測試通過後部署 app/scheduler/bot;不得重建或重啟 `momo-db`。
|
||
|
||
## 常用命令
|
||
|
||
```bash
|
||
python scripts/tools/browse_sh_probe.py -- --version
|
||
python scripts/tools/browse_sh_probe.py -- skills list
|
||
python scripts/tools/browse_sh_probe.py -- open "https://24h.pchome.com.tw/"
|
||
python scripts/tools/browse_sh_probe.py -- network --tail
|
||
python scripts/tools/browse_sh_probe.py -- screenshot
|
||
```
|
||
|
||
## MOMO/PChome 導入策略
|
||
|
||
- PChome:目前已有搜尋 API 與商品 API,`browse` 只用於確認 API 參數、分頁行為、前端是否切新 endpoint。
|
||
- MOMO:若既有 BeautifulSoup selector 失效,先用 `browse` 找出前端實際 XHR;找到 API 時優先改成 structured API parser。
|
||
- Matcher:`browse` 只提供候選證據;是否為同款仍由 `marketplace_product_matcher.score_marketplace_match()` 決定。
|
||
|
||
## PixelRAG-style 視覺證據 fallback
|
||
|
||
2026-07-09 評估 PixelRAG 後,結論是「可導入,而且不應只限 MOMO/PChome」。PixelRAG 的核心價值是把渲染後頁面截圖切成 tiles,讓 AI 讀到 HTML parser 可能丟失的視覺結構;本專案第一階段採用這個視覺證據思路,擴充成多電商 public marketplace visual evidence layer,不直接拉外部 runtime、不用外部 embedding API、不把像素結果寫入正式價格表。
|
||
|
||
導入順序:
|
||
|
||
1. 既有 PChome API / MOMO structured parser 先跑;若 parser 結果為空、價格欄位缺失、規格/組合資訊疑似只存在渲染畫面,才啟動視覺證據 fallback。
|
||
2. Phase 1 只輸出 screenshot/tile manifest:URL、platform、crawler、parse failure、viewport、tile coordinates、artifact path、evidence intent。
|
||
3. Phase 2 用 manifest 收集 replay samples,對照 `marketplace_product_matcher` 與 `competitor_match_attempts` 的診斷結果,評估是否提高身份證據覆蓋率。
|
||
4. Phase 3 才評估 Ollama-first multimodal embedding;未完成 GCP-A → GCP-B → 111 視覺 embedding 驗證前,不做自動像素檢索。
|
||
5. Phase 4 若需要索引,優先設計 pgvector-compatible evidence metadata;FAISS 只能先當本地研究/ADR 候選,不直接進 production。
|
||
6. Phase 5 才談 crawler fusion;正式 `competitor_prices` / `competitor_price_history` 寫入仍需 matcher replay/canary 證據。
|
||
|
||
多電商優先順序:
|
||
|
||
| Priority | Platform | PixelRAG 用途 | 邊界 |
|
||
|---|---|---|---|
|
||
| P0 | MOMO / PChome | 既有 structured crawler 失敗時自動產生 visual manifest queue | 正式價格仍以既有 parser/API/matcher 為準 |
|
||
| P1 | Shopee Taiwan / Coupang Taiwan | 抓公共搜尋頁商品卡、促銷 badge、店家/配送/評分視覺證據 | 不登入、不碰購物車、不繞過 anti-bot |
|
||
| P2 | Yahoo Shopping / ETMall | 補促銷券、快速到貨、活動價格等視覺訊號 | 先做 controlled probe,再決定 parser |
|
||
| P3 | friDay / Rakuten Taiwan | 先建立 probe profile 與 search manifest | URL pattern 需 runtime receipt 驗證後再排程 |
|
||
|
||
已支援的 platform code:
|
||
|
||
```text
|
||
momo
|
||
pchome
|
||
shopee_tw
|
||
coupang_tw
|
||
yahoo_shopping_tw
|
||
etmall_tw
|
||
friday_tw
|
||
rakuten_tw
|
||
```
|
||
|
||
自動觸發:
|
||
|
||
- `PChomeCrawler.fetch_region_page` 找不到商品 ID 時會 queue PixelRAG manifest。
|
||
- `PChomeCrawler.fetch_product_details` API 回傳但無可解析商品時會 queue 商品頁 manifest。
|
||
- `PChomeCrawler.search_products` 搜尋無商品 ID 或 request error 時會 queue 公開搜尋頁 manifest。
|
||
- queue 預設路徑:正式 app 容器 `/app/data/ai_automation/pixelrag_manifest_queue`,本機為 `runtime_artifacts/pixelrag_manifest_queue`。
|
||
- queue 只寫 artifact,不寫 DB、不寫正式價格、不讀 secret;capture worker 後續消費 manifest 產生 screenshot/tile receipt。
|
||
|
||
機器可讀評估:
|
||
|
||
```bash
|
||
python scripts/ops/report_pixelrag_crawler_integration.py
|
||
python scripts/ops/report_pixelrag_crawler_integration.py --platform momo
|
||
python scripts/ops/report_pixelrag_crawler_integration.py --ecommerce-expansion-plan
|
||
python scripts/ops/report_pixelrag_application_portfolio.py
|
||
python scripts/ops/report_pixelrag_application_portfolio.py --area commerce
|
||
python scripts/ops/report_pixelrag_crawler_integration.py --platform shopee_tw --marketplace-keyword "防曬乳"
|
||
python scripts/ops/report_pixelrag_crawler_integration.py --platform coupang_tw --marketplace-keyword "iphone"
|
||
python scripts/ops/report_pixelrag_crawler_integration.py --capability ollama_multimodal_ready --capability pgvector_visual_ready
|
||
python scripts/ops/report_pixelrag_crawler_integration.py \
|
||
--platform momo \
|
||
--manifest-url "https://m.momoshop.com.tw/search.momo?searchKeyword=test" \
|
||
--crawler MomoCrawler.search_products \
|
||
--trigger-reason parser_empty \
|
||
--page-size page=1440x1900 \
|
||
--tile-size tile=512x512
|
||
```
|
||
|
||
登入後 API 回讀:
|
||
|
||
```text
|
||
/api/ai-automation/pixelrag-crawler-integration?platform=momo
|
||
/api/ai-automation/pixelrag-crawler-integration?expansion_plan=true
|
||
/api/ai-automation/pixelrag-application-portfolio
|
||
/api/ai-automation/pixelrag-application-portfolio?area=commerce
|
||
/api/ai-automation/pixelrag-crawler-integration?platform=shopee_tw&marketplace_keyword=%E9%98%B2%E6%9B%AC%E4%B9%B3
|
||
/api/ai-automation/pixelrag-crawler-integration?platform=coupang_tw&marketplace_keyword=iphone
|
||
/api/ai-automation/pixelrag-crawler-integration?platform=pchome&manifest_url=https://24h.pchome.com.tw/prod/TEST-000000001&crawler=PChomeCrawler.search_products&trigger_reason=parser_empty
|
||
/api/ai-automation/pixelrag-visual-evidence-readback?platform=pchome&manifest_id=4a93e95e5afb414bc8c3
|
||
/api/ai-automation/pixelrag-rag-candidate-replay?platform=shopee_tw&platform=coupang_tw
|
||
```
|
||
|
||
視覺證據 capture worker:
|
||
|
||
```bash
|
||
python3 scripts/ops/report_pixelrag_crawler_integration.py \
|
||
--platform momo \
|
||
--manifest-url "https://m.momoshop.com.tw/search.momo?searchKeyword=test" \
|
||
--crawler MomoCrawler.search_products \
|
||
--trigger-reason parser_empty \
|
||
--page-size page=1440x1900 \
|
||
--tile-size tile=512x512 \
|
||
> /tmp/pixelrag_manifest.json
|
||
|
||
node scripts/ops/capture_pixelrag_visual_evidence.js \
|
||
--manifest-file /tmp/pixelrag_manifest.json \
|
||
--output-dir runtime_artifacts/pixelrag_visual_evidence \
|
||
--dry-run
|
||
|
||
node scripts/ops/capture_pixelrag_visual_evidence.js \
|
||
--manifest-file /tmp/pixelrag_manifest.json \
|
||
--output-dir runtime_artifacts/pixelrag_visual_evidence
|
||
|
||
# Production host can use the Python Playwright worker when Node modules are not installed.
|
||
python3 scripts/ops/capture_pixelrag_visual_evidence.py \
|
||
--manifest-file /tmp/pixelrag_manifest.json \
|
||
--output-dir runtime_artifacts/pixelrag_visual_evidence \
|
||
--max-tiles 12
|
||
```
|
||
|
||
capture 成功後,receipt 會落在:
|
||
|
||
```text
|
||
runtime_artifacts/pixelrag_visual_evidence/<platform>/<manifest_id>/capture_receipt.json
|
||
```
|
||
|
||
API readback 只讀 receipt 和檔案存在狀態,不重新抓外站、不寫資料庫。
|
||
正式 app 容器內的 readback 預設讀 `/app/data/ai_automation/pixelrag_visual_evidence`;host worker 若直接在 188 執行,預設仍可用 `runtime_artifacts/pixelrag_visual_evidence`,需要給 API 回讀時再同步到容器掛載的 `data/ai_automation`。
|
||
|
||
RAG candidate replay:
|
||
|
||
```bash
|
||
python scripts/ops/report_pixelrag_rag_candidate_replay.py
|
||
python scripts/ops/report_pixelrag_rag_candidate_replay.py --platform shopee_tw --platform coupang_tw
|
||
```
|
||
|
||
此 replay 只把 receipt 轉成內部 RAG candidate preview;eligible receipt 仍需 OCR/VLM replay、identity matcher replay、PromotionGate 與 embedding signature guard,blocked / 403 / captcha / access denied receipt 只能進 platform probe 或 structured API 策略,不得當成商品資料。
|
||
|
||
OCR/VLM replay contract:
|
||
|
||
```bash
|
||
python scripts/ops/report_pixelrag_ocr_vlm_replay.py
|
||
python scripts/ops/report_pixelrag_ocr_vlm_replay.py --platform shopee_tw --platform coupang_tw
|
||
```
|
||
|
||
此 contract 只把 saved tiles、欄位 schema、輸出 schema、confidence/evidence 規則與 Ollama-first worker 下一步打包;目前不執行 OCR/VLM、不呼叫模型、不寫 RAG、不寫 `ai_insights`、不寫正式價格表。ready receipt 進 `run_ollama_first_vlm_replay_worker`,blocked / 403 / captcha / access denied receipt 進 platform probe 或 structured API 策略。
|
||
|
||
Ollama-first VLM replay worker:
|
||
|
||
```bash
|
||
python scripts/ops/report_pixelrag_vlm_route_readiness.py
|
||
python scripts/ops/report_pixelrag_vlm_route_readiness.py --model minicpm-v:latest --include-models
|
||
python scripts/ops/run_pixelrag_vlm_replay_worker.py
|
||
python scripts/ops/run_pixelrag_vlm_replay_worker.py --platform shopee_tw --platform coupang_tw
|
||
python scripts/ops/run_pixelrag_vlm_replay_worker.py --platform shopee_tw --execute --write-receipt --limit 1
|
||
python scripts/ops/report_pixelrag_platform_probe.py --platform shopee_tw --platform coupang_tw
|
||
python scripts/ops/run_pixelrag_platform_probe_worker.py --platform shopee_tw --platform coupang_tw
|
||
python scripts/ops/run_pixelrag_platform_probe_worker.py --platform shopee_tw --execute --write-receipt --limit 1
|
||
python scripts/ops/run_pixelrag_platform_probe_worker.py --platform coupang_tw --execute --write-receipt --limit 1
|
||
python scripts/ops/run_pixelrag_source_contract_replay_worker.py --platform shopee_tw --platform coupang_tw
|
||
python scripts/ops/run_pixelrag_source_contract_replay_worker.py --platform coupang_tw --execute --write-receipt --limit 1
|
||
python scripts/ops/run_pixelrag_marketplace_source_contract_adapter_preflight.py --platform shopee_tw --platform coupang_tw
|
||
python scripts/ops/run_pixelrag_marketplace_source_contract_adapter_preflight.py --platform coupang_tw --execute --write-receipt --limit 1
|
||
python scripts/ops/run_pixelrag_marketplace_source_contract_adapter_dry_run.py --platform shopee_tw --platform coupang_tw
|
||
python scripts/ops/run_pixelrag_marketplace_source_contract_adapter_dry_run.py --platform coupang_tw --execute --write-receipt --limit 1
|
||
python scripts/ops/run_pixelrag_marketplace_identity_matcher_replay.py --platform shopee_tw --platform coupang_tw
|
||
python scripts/ops/run_pixelrag_marketplace_identity_matcher_replay.py --platform coupang_tw --execute --write-receipt --limit 1
|
||
python scripts/ops/run_pixelrag_marketplace_promotion_gate_replay.py --platform shopee_tw --platform coupang_tw
|
||
python scripts/ops/run_pixelrag_marketplace_promotion_gate_replay.py --platform coupang_tw --execute --write-receipt --limit 1
|
||
python scripts/ops/run_pixelrag_marketplace_embedding_signature_guard_replay.py --platform shopee_tw --platform coupang_tw
|
||
python scripts/ops/run_pixelrag_marketplace_embedding_signature_guard_replay.py --platform coupang_tw --execute --write-receipt --limit 1
|
||
python scripts/ops/run_pixelrag_marketplace_candidate_knowledge_replay.py --platform shopee_tw --platform coupang_tw
|
||
python scripts/ops/run_pixelrag_marketplace_candidate_knowledge_replay.py --platform coupang_tw --execute --write-receipt --limit 1
|
||
```
|
||
|
||
API readback: `/api/ai-automation/pixelrag-vlm-route-readiness` 與 `/api/ai-automation/pixelrag-vlm-replay-worker?platform=shopee_tw`。worker 預設為 dry-run,不呼叫模型、不寫 artifact;`execute=true&write_receipt=true` 才呼叫 Ollama VLM 並寫 artifact receipt。execute 前會自動讀 approved Ollama `/api/tags` 選擇已安裝候選模型;若完全沒有候選,會寫 `model_route_not_ready` artifact receipt,不盲打 generate。即使 execute,結果仍只是 candidate evidence;不得直接寫 `ai_insights`、正式價格表或競品價格歷史,且 missing confidence/evidence 會留在 replay / probe lane。
|
||
|
||
Platform probe worker API readback: `/api/ai-automation/pixelrag-platform-probe-worker?platform=shopee_tw`。worker 預設為 dry-run,不抓外站、不寫 artifact;`execute=true&write_receipt=true` 才對 Shopee language / traffic / generic landing 執行 public empty-context capture,或對 Coupang 403 / access denied 寫 structured-source/backoff receipt。capture 成功後仍回到 RAG candidate replay,不得直接寫 `ai_insights`、正式價格表或競品價格歷史。
|
||
|
||
Source-contract replay worker API readback: `/api/ai-automation/pixelrag-source-contract-replay-worker?platform=coupang_tw`。worker 預設為 dry-run,不抓外站、不呼叫模型、不寫 artifact;`execute=true&write_receipt=true` 才把 platform probe worker 的 `source_contract_fallback` receipt 轉成 source-contract replay artifact。artifact 仍只是候選合約證據,不得直接寫 `ai_insights`、正式價格表或競品價格歷史。
|
||
|
||
Marketplace adapter preflight API readback: `/api/ai-automation/pixelrag-marketplace-source-contract-adapter-preflight?platform=coupang_tw`。preflight 預設為 dry-run,不抓外站、不呼叫模型、不寫 artifact;`execute=true&write_receipt=true` 才把 source-contract replay receipt 轉成 adapter preflight artifact。artifact 只證明 adapter dry-run 條件齊備,不得直接寫 `ai_insights`、正式價格表或競品價格歷史。
|
||
|
||
Marketplace adapter dry-run API readback: `/api/ai-automation/pixelrag-marketplace-source-contract-adapter-dry-run?platform=coupang_tw`。dry-run 預設只讀 adapter preflight receipts 並建立 deterministic field contracts;`execute=true&write_receipt=true` 只寫 adapter dry-run artifact receipt,不抓外站、不呼叫模型、不寫 DB、不寫 `ai_insights`、不寫正式價格表。dry-run artifact 下一步只能進 identity matcher replay 與 PromotionGate,不得直接變成價格資料。
|
||
|
||
Marketplace identity matcher replay API readback: `/api/ai-automation/pixelrag-marketplace-identity-matcher-replay?platform=coupang_tw`。identity matcher replay 預設只讀 adapter dry-run receipts 並建立 deterministic identity candidate contracts;`execute=true&write_receipt=true` 只寫 identity matcher artifact receipt,不抓外站、不呼叫模型、不寫 DB、不寫 `ai_insights`、不寫正式價格表。identity receipt 下一步只能進 PromotionGate replay,不得直接變成價格資料。
|
||
|
||
Marketplace PromotionGate replay API readback: `/api/ai-automation/pixelrag-marketplace-promotion-gate-replay?platform=coupang_tw`。PromotionGate replay 預設只讀 identity matcher receipts 並建立 deterministic promotion candidate contracts;`execute=true&write_receipt=true` 只寫 PromotionGate artifact receipt,不抓外站、不呼叫模型、不寫 DB、不寫 `ai_insights`、不寫正式價格表。PromotionGate receipt 下一步只能進 embedding signature guard replay,不得直接變成價格資料。
|
||
|
||
Marketplace embedding signature guard replay API readback: `/api/ai-automation/pixelrag-marketplace-embedding-signature-guard-replay?platform=coupang_tw`。embedding signature guard replay 預設只讀 PromotionGate receipts 並建立 deterministic signature guard contracts;`execute=true&write_receipt=true` 只寫 embedding signature guard artifact receipt,不產生 embedding、不抓外站、不呼叫模型、不寫 DB、不寫 `ai_insights`、不寫正式價格表。signature guard receipt 下一步只能進 candidate knowledge replay,不得直接變成價格資料。
|
||
|
||
Marketplace candidate knowledge replay API readback: `/api/ai-automation/pixelrag-marketplace-candidate-knowledge-replay?platform=coupang_tw`。candidate knowledge replay 預設只讀 embedding signature guard receipts 並建立 deterministic internal RAG candidate preview contracts;`execute=true&write_receipt=true` 只寫 candidate knowledge artifact receipt,不產生 embedding、不抓外站、不呼叫模型、不寫 DB、不寫 `ai_insights`、不寫正式價格表。candidate knowledge receipt 下一步只能進 internal RAG candidate canary,不得直接變成正式知識庫或價格資料。
|
||
|
||
Application portfolio:
|
||
|
||
```bash
|
||
python scripts/ops/report_pixelrag_application_portfolio.py
|
||
python scripts/ops/report_pixelrag_application_portfolio.py --area commerce
|
||
python scripts/ops/report_pixelrag_application_portfolio.py --area rag --include-forbidden
|
||
```
|
||
|
||
此 portfolio 把 PixelRAG 可整合範圍正式分成 commerce、RAG、UX、ops、marketing、governance lanes。每個 lane 都必須有 priority、status、可整合對象、use cases、next machine action 與 no-write 邊界;forbidden lane 明確拒絕 login-only、cart、checkout、private coupon、session 與 anti-bot bypass。
|
||
|
||
安全邊界:
|
||
|
||
- read-only;不登入、不下單、不加入購物車、不寫第三方狀態。
|
||
- 不從像素結果直接寫正式價格或同款判斷,只寫 artifact / review diagnostics。
|
||
- 不使用 GitHub runtime 依賴;不讀 secrets / sessions / cookies。
|
||
- 不呼叫 hosted embedding / VLM API;如需 embedding,必須走 Ollama-first 並保留成本/品質 benchmark。
|
||
- 若穩定 XHR/API 可取得同樣資訊,仍優先回補 structured parser,不把視覺 fallback 變成主路徑。
|