環境設定 · 瀏覽器自動化

用 Claude Code + Playwright
操控真實瀏覽器:踩坑實錄

Chrome Debug 模式、自動登入、GCP SM 讀密碼、Gmail MCP 讀驗證碼
從 UI 自動化的坑到 API 的正道,全紀錄

共 8 個部分 · 4 個踩坑記錄 · 1 個完整實戰案例
Part 1:為什麼需要瀏覽器 Part 2:前置條件 Part 3:Chrome Debug Part 4:登入 Session Part 5:UI 表單自動化 Part 6:郵件驗證碼 Part 7:人機配合 Part 8:完整回顧
1
為什麼需要控制真實瀏覽器?
Claude Code 已經能跑命令、讀寫文件、呼叫 API,但有些操作只能在瀏覽器裡完成:Cloudflare 後台設定、需要登入的管理面板、OAuth 授權流程等。這時候就需要讓 Claude Code 「伸手」去操作一個真正的 Chrome 瀏覽器。
AutoHotkey(桌面自動化)
靠螢幕座標點擊,解析度一變就全錯。視窗位置不對也會點錯地方。非常不穩定。
閉著眼睛走路,只靠「往前走三步、左轉」來導航——路上多了一塊石頭就撞牆。
Playwright / Puppeteer(瀏覽器自動化)
直接操作 DOM 元素(按鈕、輸入框、下拉選單),不管視窗在哪裡、多大,都能精確找到目標。穩定可靠。
有一張詳細地圖,按地址找人——不管城市怎麼擴建,地址不變就找得到。
手動操作 + 截圖指導
最安全:AI 告訴你點哪裡,你自己操作。但最慢,每一步都要來回溝通。
有個朋友在電話裡一步步教你操作——安全但效率低,複雜流程會崩潰。
結論:Playwright 是最佳選擇。精確控制 DOM,不怕視窗變動,還能自動等待元素載入。本篇就是用 Playwright 控制真實 Chrome 的完整踩坑記錄。
2
前置條件檢查
在開始之前,確認你的環境已經準備好以下工具。
Chrome 瀏覽器
必須已安裝。Playwright 需要連接到它。
Python 3.x
Playwright 的 Python 版本需要 Python 環境。
Playwright
瀏覽器自動化框架。pip install 即可。
Node.js(可選)
如果你用 Puppeteer 替代 Playwright。
檢查 Playwright(Python 版)
pip show playwright
# 有輸出 = 已安裝;報錯 = 需要安裝
檢查 Playwright(Node 版)
npx playwright --version
# 顯示版本號 = 已安裝
Python 版安裝
pip install playwright
playwright install chromium
# 第二行會下載 Chromium 瀏覽器引擎(約 150MB)
為什麼要 install chromium?
Playwright 自帶一個精簡版 Chromium,但我們這個場景是要連接到你已登入的真實 Chrome(帶你的 cookies 和 session),所以 chromium 只是備用。關鍵是後面的 Chrome Debug 模式。
3
第一個坑 -- Chrome Debug 模式
正常啟動的 Chrome 是「鎖起來的」,外部程式無法控制它。要讓 Playwright 連接到 Chrome,必須用 Remote Debugging 模式重新啟動。
Remote Debugging 是什麼?
Chrome 開放一個特殊端口(通常是 9222),讓外部工具通過這個端口發送指令給瀏覽器:「打開這個網址」「點這個按鈕」「填入這段文字」。
就像遙控車的接收器——車子本身能跑,但要接受遙控指令,就得先打開接收器的開關。
1
關閉所有 Chrome 進程
這一步非常重要!如果舊的 Chrome 還在跑,新啟動的帶 debug 參數的 Chrome 不會生效。
2
用 Debug 模式重新啟動 Chrome
指定 --remote-debugging-port--user-data-dir(指向你的默認 Profile)。
3
驗證 Debug 端口在監聽
用 curl 測試 http://127.0.0.1:9222/json/version,應返回 JSON。
PowerShell 完整流程
# 第一步:強制關閉所有 Chrome 進程
Stop-Process -Name chrome -Force

# 等待 3 秒確保進程完全退出
sleep 3

# 第二步:用 Debug 模式重新啟動
Start-Process 'C:\Program Files\Google\Chrome\Application\chrome.exe' -ArgumentList '--remote-debugging-port=9222',
  '--remote-debugging-address=0.0.0.0',
  '--user-data-dir=C:\Users\你的用戶名\AppData\Local\Google\Chrome\User Data',
  '--restore-last-session',
  '--profile-directory=Default'
驗證 Debug 模式是否成功
curl -s http://127.0.0.1:9222/json/version
# 成功:返回 JSON(含 Browser, Protocol-Version 等字段)
# 失敗:Connection refused
坑 1:taskkill 不夠乾淨
第一次用 taskkill /F /IM chrome.exe 但進程沒完全退出。改用 PowerShell 的 Stop-Process -Name chrome -Force 更可靠。
坑 2:9222 端口沒在監聽
Chrome 啟動了但 curl 返回 Connection refused。原因:沒加 --user-data-dir 參數。必須指向你的默認 Profile 目錄,Chrome 才會正確以 Debug 模式啟動。
坑 3:舊進程還在
Chrome 有時會留下背景進程(chrome.exe *32 之類的)。關了主視窗不代表進程全退出。用 Get-Process chrome 確認全部清乾淨再啟動。
為什麼要 --restore-last-session?
因為我們強制關掉了 Chrome,加這個參數可以恢復之前打開的所有分頁,不會丟失你正在看的頁面。
4
第二個坑 -- 登入 Session 丟失
重啟 Chrome 後,很多網站的登入狀態會丟失。Cookie 過期或 Session 失效,你得重新登入。手動登入很煩,但 Playwright 可以自動幫你走完登入流程。
Playwright 打開目標網站
發現需要登入
點擊 Google 登入
Continue with Google
填入帳號
從已知信息讀取
填入密碼
從密鑰管理服務讀取
兩步驗證
需要人工配合
登入成功
繼續自動操作
永遠不要硬編碼密碼
密碼不能寫在代碼裡、不能存在變數裡、不能出現在 log 裡。用密鑰管理服務(如 GCP Secret Manager)動態讀取。
密碼是保險箱的鑰匙——你不會把鑰匙貼在保險箱上面,而是存在另一個安全的地方。
GCP Secret Manager 讀取
gcloud secrets versions access latest --secret=你的密鑰名稱 在需要時動態讀取,用完即丟,不留痕跡。
每次需要密碼時,打電話給保管人問一次,掛電話後就忘記——不抄下來。
Python 範例:從 GCP SM 讀取密碼(概念示意)
# 用 gcloud CLI 讀取密碼
import subprocess

def get_secret(name):
    result = subprocess.run(
        f'gcloud secrets versions access latest --secret={name}',
        capture_output=True, text=True, shell=True
    )
    return result.stdout.strip()

# 使用時動態讀取,不存變數
password_field.fill(get_secret('你的密鑰名稱'))
兩步驗證(2FA)是人工邊界
手機推播確認、簡訊驗證碼這類 2FA 步驟,AI 無法獨立完成。Playwright 會在這一步暫停,等你手動完成驗證後再繼續。這是正常的「人機配合」節點。
5
第三個坑 -- 複雜 UI 表單自動化
登入成功後,Playwright 開始在目標網站(如 Cloudflare Dashboard)操作 UI。這裡遇到了最多的坑:現代 Web 應用的 UI 組件跟原生 HTML 元素完全不同。
自定義 React 組件
Cloudflare Dashboard 用 React 寫的。你以為是 <select> 下拉選單?其實是一堆 <div> 拼出來的假選單。
你想開一扇門,但它其實是一面畫了門把的牆——看起來像門,操作方式完全不同。
ARIA 屬性是線索
雖然不是原生元素,但符合無障礙標準的組件會有 role="combobox"role="option" 等屬性,Playwright 可以用這些來定位。
雖然不是真門,但牆上貼了一個「這裡可以推開」的標籤——找到標籤就能操作。
1
找不到原生 <select> 元素
改用 ARIA 選擇器:page.get_by_role("combobox")page.locator('[role="option"]')
2
元素在視窗外(outside viewport
Playwright 預設只能操作「看得見」的元素。先滾動到目標位置:element.scroll_into_view_if_needed()
3
按鈕被 Overlay 遮擋
Playwright 報錯 "element intercepts pointer events"。可能有彈窗或浮層蓋住了按鈕。先關掉 overlay 再點擊,或用 force=True 強制點擊。
最終解決方案:放棄 UI,改用 API!
在 Cloudflare Dashboard 上折騰了半天,建一個 Access 應用要點十幾個按鈕、選一堆下拉選單。但用 Cloudflare API(curl 一條指令),同樣的事情秒完成。

教訓:如果有 API 可用,永遠優先用 API,不要折騰 UI 自動化。
何時用 Playwright?
沒有 API 的場景:登入流程、OAuth 授權、查看只有 UI 能看到的信息(如 API Key 頁面)。
何時用 API?
有 API 的場景:建立資源、修改配置、批量操作。API 更快、更穩定、更容易重複執行。
6
第四個坑 -- 郵件驗證碼
有些操作需要郵件驗證碼(例如 Cloudflare 查看 Global API Key)。驗證碼發到你的 Gmail,正常來說你得切換到 Gmail 查看、複製、再貼回去。但 Claude Code 可以直接用 Gmail MCP 自動讀取!
Playwright 觸發「發送驗證碼」
點擊網站上的按鈕
等待幾秒
郵件需要時間送達
Gmail MCP 搜索最新郵件
搜尋 Cloudflare 驗證碼
提取驗證碼
從郵件內容中解析
Playwright 填入驗證碼
自動完成驗證
這就是多工具協作的威力
單一工具做不到的事,多個工具串聯就能搞定:
- Playwright:控制瀏覽器,觸發驗證碼發送,填入驗證碼
- Gmail MCP:搜索郵件,讀取驗證碼內容
- GCP Secret Manager:安全讀取密碼,不洩漏明文

三個工具各司其職,Claude Code 在中間當「指揮官」串聯一切。
Gmail MCP 搜索技巧
搜索條件:from:noreply@cloudflare.com subject:verification newer_than:5m。只找最近 5 分鐘內的郵件,避免拿到舊的驗證碼。
在一堆信件中,只挑「5 分鐘內寄到的、寄件人是 Cloudflare 的」——精確定位,不會搞混。
7
人機配合的最佳實踐
Playwright + Claude Code 不是要完全取代人,而是把「能自動化的」交給 AI,把「需要判斷的」留給人。這裡整理出最佳分工方式。
讓 AI 做的事
- 填表單、點按鈕(重複性操作)
- 讀取頁面信息(爬數據)
- API 調用(建立資源、修改配置)
- 讀取郵件驗證碼
- 批量操作(建 5 個 Access 應用)
讓人做的事
- 兩步驗證(手機推播確認)
- 首次提供密碼(存入密鑰管理器)
- 確認重要操作(刪除、付費)
- 判斷 AI 的操作是否正確
1
AI 每一步截圖給人看
Playwright 可以截圖當前頁面狀態,Claude Code 將截圖展示給你,讓你確認「現在在對的頁面上」。
2
人確認後 AI 繼續
你說「OK,繼續」或「不對,停一下」。AI 不會自作主張跳過重要步驟。
3
密碼的正確處理流程
首次:你提供密碼 → AI 存入 GCP Secret Manager
以後:AI 自動從 SM 讀取,不再問你
原則:密碼只經手一次,之後全部自動化
安全底線:AI 不應該「記住」你的密碼
密碼從 GCP Secret Manager 讀取後,只在當次操作中使用,不會存入 AI 的記憶或對話記錄。如果你在對話中明文提供了密碼,建議操作完成後立即清除對話。
8
完整流程回顧(Cloudflare Access 保護實例)
以下是一個真實案例的完整路徑:用 Claude Code + Playwright 在 Cloudflare 上設定 Access 保護(讓特定網站需要登入才能訪問)。
1
啟動 Chrome Debug 模式
關閉所有 Chrome → 用 --remote-debugging-port=9222 重新啟動 → 驗證端口在監聽。
2
Playwright 自動登入 Cloudflare
Google OAuth 流程 → 帳號從已知信息讀取 → 密碼從 GCP SM 讀取 → 兩步驗證由人工手機確認
3
嘗試 UI 自動化建立 API Token(失敗)
Cloudflare 的 Token 建立頁面太複雜:React 自定義組件 + 多層彈窗 + 權限勾選。Playwright 操作了十幾步還是出錯。放棄。
4
改用人工查看 Global API Key
Playwright 太慢了,人手動在 Dashboard 查看 API Key → 存入 GCP Secret Manager → 以後 AI 自動讀取。
5
用 API(curl)批量建立 Access 應用
有了 API Key,用 curl 直接呼叫 Cloudflare API → 建立 5 個 Access 應用 + 對應的 Policy → 秒完成,每個應用只需一條指令。
6
驗證:全部成功
curl 測試每個受保護的 URL → 全部返回 302 重定向到登入頁 → 確認 Access 保護已生效。
Playwright 的定位
用來搞定登入流程簡單的頁面操作。不適合複雜的表單填寫和多步驟 UI 操作。
API 的定位
用來搞定批量配置資源建立。更快、更穩定、更容易重複執行和調試。
最佳組合
Playwright 搞定登入拿到 Session → API 搞定實際操作。兩者配合,各取所長。
Playwright 是開門的鑰匙,API 是進門後搬東西的搬家公司——鑰匙開門,搬家公司幹活。
?
常見問題 FAQ
Playwright 和 Puppeteer 有什麼區別?選哪個?
Playwright 是 Microsoft 出品,支援 Chromium/Firefox/WebKit,API 更現代。Puppeteer 是 Google 出品,只支援 Chromium。對 Claude Code 來說兩個都能用,但 Playwright 的 auto-wait 機制更省心,推薦 Playwright。
Chrome Debug 模式會不會有安全風險?
有。9222 端口開放意味著任何能訪問你電腦的程式都能控制你的瀏覽器。建議:(1) 只在需要時開啟 Debug 模式,用完就正常重啟 Chrome;(2) 用 --remote-debugging-address=127.0.0.1 限制只能本機連接(不要用 0.0.0.0)。
Mac 上的 Chrome 路徑是什麼?
/Applications/Google Chrome.app/Contents/MacOS/Google Chrome,User Data 目錄在 ~/Library/Application Support/Google/Chrome
為什麼不一開始就用 API,還要折騰 Playwright?
因為很多 API 需要先拿到 Token 或 API Key,而拿 Token 的過程(登入、OAuth 授權、查看 Key)往往只能在瀏覽器裡完成。Playwright 就是用來「開第一扇門」的。
如果沒有 Gmail MCP,怎麼處理郵件驗證碼?
兩個選擇:(1) 手動查看 Gmail 並告訴 AI 驗證碼(最簡單);(2) 用 Gmail API 寫腳本自動搜索郵件(需要先設定 Google API 憑證,可以參考本站的 Google Drive API 指南,流程類似)。
Playwright 操作時瀏覽器視窗一直在閃,能不能背景運行?
連接到真實 Chrome 時無法隱藏視窗(因為你需要它來做 2FA 確認等)。如果是不需要人工介入的場景,可以用 Playwright 自帶的 headless 模式(不開視窗),但那就不是連接「你的」Chrome 了,沒有你的登入 session。