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 # 顯示版本號 = 已安裝
安裝 Playwright
Python 版安裝
pip install playwright playwright install chromium # 第二行會下載 Chromium 瀏覽器引擎(約 150MB)
為什麼要 install chromium?
Playwright 自帶一個精簡版 Chromium,但我們這個場景是要連接到你已登入的真實 Chrome(帶你的 cookies 和 session),所以 chromium 只是備用。關鍵是後面的 Chrome Debug 模式。
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。
關鍵命令(Windows)
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。原因:沒加
Chrome 啟動了但 curl 返回 Connection refused。原因:沒加
--user-data-dir 參數。必須指向你的默認 Profile 目錄,Chrome 才會正確以 Debug 模式啟動。
坑 3:舊進程還在
Chrome 有時會留下背景進程(chrome.exe *32 之類的)。關了主視窗不代表進程全退出。用
Chrome 有時會留下背景進程(chrome.exe *32 之類的)。關了主視窗不代表進程全退出。用
Get-Process chrome 確認全部清乾淨再啟動。
為什麼要 --restore-last-session?
因為我們強制關掉了 Chrome,加這個參數可以恢復之前打開的所有分頁,不會丟失你正在看的頁面。
因為我們強制關掉了 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 會在這一步暫停,等你手動完成驗證後再繼續。這是正常的「人機配合」節點。
手機推播確認、簡訊驗證碼這類 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 自動化。
在 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 在中間當「指揮官」串聯一切。
單一工具做不到的事,多個工具串聯就能搞定:
- 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 應用)
- 讀取頁面信息(爬數據)
- API 調用(建立資源、修改配置)
- 讀取郵件驗證碼
- 批量操作(建 5 個 Access 應用)
讓人做的事
- 兩步驗證(手機推播確認)
- 首次提供密碼(存入密鑰管理器)
- 確認重要操作(刪除、付費)
- 判斷 AI 的操作是否正確
- 首次提供密碼(存入密鑰管理器)
- 確認重要操作(刪除、付費)
- 判斷 AI 的操作是否正確
溝通方式
1
AI 每一步截圖給人看
Playwright 可以截圖當前頁面狀態,Claude Code 將截圖展示給你,讓你確認「現在在對的頁面上」。
2
人確認後 AI 繼續
你說「OK,繼續」或「不對,停一下」。AI 不會自作主張跳過重要步驟。
3
密碼的正確處理流程
首次:你提供密碼 → AI 存入 GCP Secret Manager
以後:AI 自動從 SM 讀取,不再問你
原則:密碼只經手一次,之後全部自動化
以後:AI 自動從 SM 讀取,不再問你
原則:密碼只經手一次,之後全部自動化
安全底線:AI 不應該「記住」你的密碼
密碼從 GCP Secret Manager 讀取後,只在當次操作中使用,不會存入 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。