# 9. Browser Control 瀏覽器控制

### 9.1 架構總覽

```
Telegram Agent 發出瀏覽器指令
        │
        ▼
┌──────────────────────────────────────────────┐
│          OpenClaw Gateway (port 18789)        │
│  browser.request → 轉發給 Node Host          │
└──────────────┬───────────────────────────────┘
               │ WebSocket
┌──────────────▼───────────────────────────────┐
│          OpenClaw Node Host                   │
│  systemd user: openclaw-node.service          │
│  browser relay：接收 Gateway 指令             │
│  caps: browser, system                        │
└──────────────┬───────────────────────────────┘
               │ CDP (Chrome DevTools Protocol)
┌──────────────▼───────────────────────────────┐
│          Playwright Chromium (port 18801)      │
│  systemd user: playwright-chrome.service      │
│  binary: ~/.cache/ms-playwright/chromium-1208 │
│  user-data: ~/.openclaw/browser/playwright-data│
│  DISPLAY=:99 (Xvfb)                          │
└───────────────────────────────────────────────┘
```

### 9.2 服務組成

| 服務 | systemd unit | 功能 | 環境要求 |
|------|-------------|------|---------|
| Node Host | `openclaw-node.service` | Gateway <-> Chrome relay | `DISPLAY=:99` |
| Playwright Chrome | `playwright-chrome.service` | Chromium 實例，CDP port 18801 | `DISPLAY=:99` |

### 9.3 Browser Profile

| Profile 名稱 | Driver | Port | 用途 | 狀態 |
|-------------|--------|------|------|------|
| `cdp-direct` | openclaw (CDP) | 18801 | **預設**（CLI 使用），直連 Playwright Chromium | 使用中 |
| `chrome` | openclaw (CDP) | 18801 | **覆寫為 CDP**，Agent 透過 Node Host 操控時固定走此 profile | 使用中 |
| `openclaw` | openclaw (CDP) | 18801 | **覆寫為 CDP**（原為 Gateway 內建 port 18800，會嘗試啟動 snap Chromium 而失敗） | 使用中 |

設定位置：`~/.openclaw/openclaw.json` → `browser.defaultProfile: "cdp-direct"`

> **踩坑 1**：`defaultProfile` 只影響 CLI 指令。Agent 透過 Node Host 操控瀏覽器時**固定走 `chrome` profile**，因此必須在 `browser.profiles` 中覆寫 `chrome` 的 `cdpUrl` 指向 Playwright CDP（port 18801），否則會走 extension relay 模式而報錯。
>
> **踩坑 2**：v2026.3.7 內建 `openclaw` profile（port 18800），Gateway 會嘗試用 detectedPath（`/usr/bin/chromium-browser`，snap 版）啟動瀏覽器。snap Chromium 會剝掉 CDP 參數導致永遠啟動失敗，agent tool call 15 秒後 timeout。**修復**：在 `browser.profiles` 覆寫 `openclaw` profile，讓它也指向 Playwright CDP（port 18801）。

### 9.4 常用指令

```bash
# 狀態查看
openclaw browser status                    # 查看預設 profile 狀態
openclaw browser profiles                  # 列出所有 profile
openclaw nodes status                      # Node Host 連線狀態

# 分頁操作
openclaw browser tabs                      # 列出分頁
openclaw browser open <url>                # 開新分頁
openclaw browser navigate <url>            # 當前分頁導航
openclaw browser focus <tab-id>            # 切換分頁
openclaw browser close <tab-id>            # 關閉分頁

# 截圖與快照
openclaw browser screenshot                # 截圖
openclaw browser screenshot --full-page    # 完整頁面截圖
openclaw browser snapshot                  # AI 可讀的頁面快照（預設 ai 格式）
openclaw browser snapshot --format aria    # Accessibility tree 格式

# 互動操作
openclaw browser click <ref>               # 點擊元素
openclaw browser type <ref> "text"         # 輸入文字
openclaw browser press Enter               # 按鍵
openclaw browser hover <ref>               # 滑鼠 hover
openclaw browser fill --fields '[...]'     # 表單填寫

# 其他
openclaw browser pdf                       # 存成 PDF
openclaw browser console --level error     # 查看 console 錯誤
openclaw browser evaluate --fn '...'       # 執行 JavaScript
```

### 9.5 安裝步驟（從零開始）

```bash
# 1. 確保 Xvfb 在運行（DISPLAY=:99）
pgrep -la Xvfb

# 2. 安裝 Playwright 瀏覽器（如未安裝）
npx playwright install chromium

# 3. 安裝 OpenClaw Node service
openclaw node install
# 手動加入 DISPLAY=:99 到 service 檔案
# ~/.config/systemd/user/openclaw-node.service → Environment=DISPLAY=:99

# 4. 確保 gateway.env 也有 DISPLAY=:99
echo 'DISPLAY=:99' >> ~/.config/openclaw/gateway.env

# 5. 啟動 Node service 並配對
systemctl --user daemon-reload
systemctl --user enable --now openclaw-node.service
# 等待 Node 連上 Gateway 後出現 pending device
openclaw devices list          # 查看 pending request
openclaw devices approve <id>  # 核准配對

# 6. 建立 Playwright Chrome service
# 見 ~/.config/systemd/user/playwright-chrome.service
systemctl --user enable --now playwright-chrome.service

# 7. 建立 cdp-direct browser profile
openclaw browser create-profile --name cdp-direct --cdp-url http://127.0.0.1:18801 --driver openclaw

# 8. 設為預設 profile，並覆寫 chrome + openclaw profile
# 在 openclaw.json 的 browser 區塊：
#   "defaultProfile": "cdp-direct"
#   "profiles": {
#     "cdp-direct": { "cdpUrl": "http://127.0.0.1:18801", "color": "#00AAFF" },
#     "chrome":     { "cdpUrl": "http://127.0.0.1:18801", "color": "#00AA00" },
#     "openclaw":   { "cdpUrl": "http://127.0.0.1:18801", "color": "#FF4500" }
#   }
# chrome profile 必須覆寫，Agent 透過 Node Host 固定走此 profile
# openclaw profile 必須覆寫，否則 Gateway 嘗試用 snap Chromium 啟動而 timeout

# 9. 重啟 Gateway
systemctl --user restart openclaw-gateway

# 10. 驗證
openclaw browser status
openclaw browser navigate https://example.com
openclaw browser screenshot
```

### 9.6 已知問題

| 問題 | 原因 | 修復 |
|------|------|------|
| Snap Chromium 不支援 `--load-extension` / `--remote-debugging-port` | snap 沙箱會剝掉安全相關旗標 | 改用 Playwright Chromium（非 snap，直接二進位） |
| Node service `pairing required` | 首次連線需經 Gateway 核准 | `openclaw devices approve <id>` |
| Browser start timeout | Node/Gateway 缺少 `DISPLAY` 環境變數 | 在 service 和 gateway.env 加 `DISPLAY=:99`；Gateway service 本身也需要 `Environment=DISPLAY=:99` |
| `openclaw browser start --browser-profile chrome` 需要點擴充套件 | `chrome` profile 使用 extension relay 模式 | 改用 `cdp-direct` profile（CDP 直連，不需擴充套件） |
| Port 18800 被 Gateway 佔用 | `openclaw` profile 預設使用 18800 | 自訂 port 使用 18801 |
| Agent 操控瀏覽器仍報 extension relay 錯誤 | `defaultProfile` 只影響 CLI，Agent 透過 Node Host 固定走 `chrome` profile | 在 `openclaw.json` 的 `browser.profiles` 覆寫 `chrome` 的 `cdpUrl` 指向 Playwright CDP port 18801 |
| Agent browser tool timeout（v2026.3.7，2026-03-11） | 內建 `openclaw` profile 嘗試用 snap Chromium 啟動（detectedPath: `/usr/bin/chromium-browser`），snap 會剝掉 `--remote-debugging-port` 導致 CDP 永遠無法建立 | 在 `browser.profiles` 覆寫 `openclaw` profile 的 `cdpUrl` 指向 Playwright CDP port 18801；同時確認 Gateway service 有 `Environment=DISPLAY=:99` |
