# 策展 · X (Twitter) 🔥

> 作者：derek (@derekmeegan) · 平台：X (Twitter) · 日期：2026-05-15

> 原始來源：https://x.com/derekmeegan/status/2054694139397361842

## 中文摘要

將網站轉換為 結構化 API

@derekmeegan 推出「browser-to-api」技能，利用 /browser-trace 捕捉的瀏覽器追蹤資料，離線處理 CDP 請求/回應事件，模板化 URL、推斷 JSON 結構，並輸出 OpenAPI 3.1 文件與可讀報告。此工具針對無文件或第三方網站 API，展示如 Codex 單次提示即可生成完整 OpenTable API 客戶端，強調重播驅動的 API 發現流程。

**安裝方式**  
使用單一指令加入技能：  
```
$ npx skills add https://github.com/browserbase/skills --skill browser-to-api
```

**技能核心功能**  
- 輸入：browser-trace 產生的 `.o11y/<run>/cdp/network/{requests,responses}.jsonl` 檔案桶。  
- 輸出：`.o11y/<run>/api-spec/` 資料夾，包含 `index.html`（視覺報告）、`openapi.yaml`、`client.mjs`（無依賴 fetch 客戶端）等。  
- 純離線後處理，不捕捉流量；需先執行 browser-trace 捕捉資料。  
- 適用情境：  
  - 使用者需為第三方或無文件網站生成 OpenAPI 文件。  
  - 從 browser-trace 執行中提取端點與結構描述。  
  - 建置針對無規範網站的客戶端/SDK。  
  - 生成涵蓋報告，顯示需擴展流程以拓寬規範。

**兩步驟工作流程**  
1. 使用 browser-trace 捕捉（建議搭配 `browse network on` 擷取主體）：  
   ```
   # 本地範例（詳見 browser-trace SKILL.md 的 Browserbase 變體）
   browse env local
   browse open about:blank
   TARGET="$(browse status --json | jq -r .wsUrl)"

   node ../browser-trace/scripts/start-capture.mjs "$TARGET" my-site
   browse network on                                    # 捕捉請求/回應主體
   browse open https://example.com
   # ...執行欲涵蓋的任意流程...

   # 在關閉捕捉前快照主體目錄（臨時目錄為會話共享，略過此步會混入未來捕捉）
   cp -r "$(browse network path | jq -r .path)" .o11y/my-site/cdp/network/bodies/
   browse network off

   node ../browser-trace/scripts/stop-capture.mjs my-site
   node ../browser-trace/scripts/bisect-cdp.mjs my-site
   ```  
   注意：`browse network on` 為選用但強烈建議，無此步驟則無回應主體結構描述（CDP 火管不嵌入主體）；啟用後，透過 CDP `requestId` 合併請求/回應主體。

2. 生成規範：  
   ```
   node scripts/discover.mjs --run .o11y/my-site
   ```  
   輸出檔案：  
   - `.o11y/my-site/api-spec/index.html`（開啟此檔案）  
   - `.o11y/my-site/api-spec/client.mjs`  
   - `.o11y/my-site/api-spec/openapi.yaml`  
   - `.o11y/my-site/api-spec/openapi.json`  
   - `.o11y/my-site/api-spec/report.md`  
   - `.o11y/my-site/api-spec/confidence.json`  
   - `.o11y/my-site/api-spec/samples/*.json`  
   - `.o11y/my-site/api-spec/intermediate/*.jsonl`  
   `discover.mjs` 自動偵測 `<run>/cdp/network/bodies/`；若使用外部主體路徑，明確傳入 `--bodies <path>`。

3. 開啟 HTML 報告：  
   ```
   open .o11y/my-site/api-spec/index.html
   ```  
   報告為自包含 HTML（無需伺服器），以展開卡片顯示每個操作，包括變數、客戶端用法、請求/回應範例及 `client.mjs` 片段，此為主要交付物，務必開啟檢視。

**CLI 旗標**  
| 旗標 | 必要 | 意義 |  
|------|------|------|  
| `--run <path>` | 是 | browser-trace 執行目錄路徑 |  
| `--out <path>` | 否 | 輸出目錄；預設 `<run>/api-spec/` |  
| `--bodies <path>` | 否 | `browse network` 捕捉目錄（自動偵測 `<run>/cdp/network/bodies/`） |  
| `--include <regex>` | 否 | 僅包含符合 regex 的 URL（可重複） |  
| `--exclude <regex>` | 否 | 排除符合 regex 的 URL（可重複，外加預設） |  
| `--origins <list>` | 否 | 逗號分隔來源允許清單（如 `api.example.com,example.com`） |  
| `--format <yaml\|json\|both>` | 否 | 輸出格式，預設 both |  
| `--title <string>` | 否 | OpenAPI `info.title`，預設從主要來源衍生 |  
| `--redact <list>` | 否 | 額外標頭/JSON 鍵隱匿（逗號分隔） |  
| `--min-samples <n>` | 否 | 每端點最小樣本數，預設 1 |  
| `--stage <name>` | 否 | 僅執行單階段：load、filter、normalize、infer、emit |

**輸出結構**  
```
<run>/api-spec/
├── index.html                視覺報告 — 開啟此檔案（自包含，無需伺服器）
├── client.mjs                無依賴 fetch 客戶端，每操作具類型函式
├── openapi.yaml              機器可讀規範
├── openapi.json              鏡像
├── report.md                 Markdown 摘要 + curl 範例
├── confidence.json           每端點信心度 + 標準化旗標
├── samples/                  隱匿請求/回應範例
│   └── <method>__<path-hash>.json
└── intermediate/             管線副產品（配對/過濾/端點 jsonl）
```

**捕捉來源比較**  
兩個互補來源：  

| 來源 | 提供 | 限制 |  
|------|------|------|  
| `browse cdp`（browser-trace 使用） | 請求 method/URL/headers/postData、回應 status/headers/mimeType、完整事件計時 | 不嵌入回應主體，需 `Network.getResponseBody` 拉取（火管未執行） |  
| `browse network on`（獨立指令） | 磁碟上請求主體與回應主體，按 CDP `requestId` 鍵值 | 捕捉目錄為 `browse` 會話共享；下次 `browse network on` 前快照 |  

`discover.mjs` 若傳 `--bodies <path>` 或置於 `<run>/cdp/network/bodies/`（自動偵測），則按 `requestId` 合併主體。主體存在時變化：  
- ✅ 路徑模板化、查詢參數結構、狀態碼、內容類型 — 兩者相同。  
- ✅ 請求主體結構 — CDP `postData` 足夠，主體目錄為非必要。  
- ✅ 回應主體結構 — 從真實樣本完整推斷；無主體僅得 `{ description, content: <mimeType> }` 骨架。報告標記無回應主體樣本的端點。

**自動雜訊過濾**  
標準化階段自動分類並捨棄基礎設施雜訊，通常淘汰 60-80% 捕捉流量：  
- 追蹤/分析 — 包含 `/track`、`/pixel`、`/beacon`、`/impression`、`/pageview`、`/dag/v*` 的路徑。  
- Bot 防禦 — Akamai（`/akam/`）、指紋酬載（`sensor_data`）、混淆多段路徑。  
- 會話管線 — `/session`、`/authenticate/start`、Cookie 同意、A/B 實驗端點。  
- HTML 頁面渲染 — 回傳 `text/html` 的 GET 請求（渲染頁面，非 API）。  
使用 `--include` 可救回誤判。

**GraphQL / 多工端點分解**  
單一端點（如 `/dapi/fe/gql`）若以不同 `operationName` 呼叫，自動拆分為獨立邏輯操作，每個擁有：  
- OpenAPI 路徑條目（如 `/dapi/fe/gql [Autocomplete]`）。  
- 僅從該操作樣本推斷的請求/回應結構。  
- 報告中的 curl 範例與變數表。  
偵測依賴主體欄位（`operationName`、`method`、`action`）與查詢參數（`opname`、`op`），涵蓋 GraphQL（APQ 與內嵌）、JSON-RPC 及類似分派模式。

**限制與現實考量**  
- 涵蓋範圍受捕捉流程限制，未執行的端點不會出現，技能無法證明完整性。  
- 結構描述為歸納式，非合約式；伺服器欄位可能為選用，即便所有樣本皆含。  
- 認證僅觀察不規範化，記錄於 `x-observed-auth` 擴充，但不主張安全方案。  
- 路徑模板化為啟發式，按段偵測數字/UUID/hex/slug 模式；歧義 URL 於 `confidence.json` 標記。  
- 隱匿為盡力而為，預設涵蓋常見憑證，但應用特定秘密可能漏網；使用 `--redact` 處理自訂標頭/鍵值。

**最佳實務**  
- 驅動欲文件化的流程，browser-trace 越豐富，規範越詳盡。  
- 雜訊網站使用 `--origins` 限制，如行銷頁觸發數十分析主機，僅限關心 API 來源。  
- 先檢視 `report.md`，含每個操作的 curl 就緒範例與回應樣本。  
- 欲僅納入高信心端點，將 `--min-samples` 設為 2+，捨棄長尾。  
- 回應主體結構關鍵時，搭配 `browse network on`；單獨 CDP 火管僅有請求主體。  
管線內部與檔案格式參考見 `REFERENCE.md`。

此技能建基於 [browserbase/skills/browser-to-api](https://www.skills.sh/browserbase/skills/browser-to-api)，展示將網站行為轉為結構化 API 的強大潛力，但強調需手動驅動流程與後續驗證，忠實反映其離線、觀察導向的本質，而非萬能解方。

## 標籤

Skills, 開源專案, 爬蟲, Browserbase, Codex
