AI agent 愈來愈常需要「看見」網頁——改完前端要驗證畫面、抓登入後的資料、或是替我們跑一段重複的點擊流程。這些事情以前得寫一整套 Selenium、Puppeteer 專案才能做,現在 Playwright 直接把最常用的功能做成了命令列工具 playwright-cli,不用建專案、不用裝 npm 依賴,一行指令就能完成。這篇文章會介紹 Playwright 本身、和 Puppeteer 的差異、為什麼還要另外做一個 CLI、它跟 Playwright MCP 的分工,最後搭配 Claude Code 示範四個實際應用場景。

另外補充,本文以 Claude Code 來示範,但是很多 AI Agent 也都可以使用,例如不習慣文字介面可以用 Claude Desktops 的 Cowork 或是 Code,也可以用其他品牌的 Codex、Copilot、Gemini Cli、Antigravity 等,各種工具都可以嘗試看看。

Playwright 介紹

Playwright 是由 Microsoft 團隊在 2020 年開源的瀏覽器自動化框架,可以用程式控制 Chromium、Firefox、WebKit 三大瀏覽器核心,做 E2E 測試、網頁爬蟲、螢幕截圖、PDF 產生、表單自動填寫等各種網頁自動化工作。它的團隊成員其實大多來自 Google 的 Puppeteer 專案,後來跳槽到 Microsoft 重新設計,吸收了 Puppeteer 的經驗但解決掉當年的幾個痛點。

Playwright 支援 JavaScript / TypeScript、Python、Java、.NET 四種語言,官方還提供 VS Code 擴充套件、trace viewer 除錯工具、報告產生器,生態系算是目前瀏覽器自動化領域最完整的一套。

Playwright 與 Puppeteer 比較

兩者都能控制瀏覽器,但定位不太一樣。Puppeteer 最初只鎖定 Chromium,API 設計比較底層;Playwright 則從一開始就設計成跨瀏覽器、而且把「等待元素出現」「自動重試」這些以前要自己處理的事情內建了。

項目PlaywrightPuppeteer
維護方MicrosoftGoogle(Chrome DevTools 團隊)
支援瀏覽器Chromium、Firefox、WebKit主要 Chromium(Firefox 實驗性)
語言支援JS/TS、Python、Java、.NET僅 JS/TS
自動等待內建 auto-wait需自己加 waitFor
除錯工具Trace Viewer、Inspector、codegen較陽春
CLI 工具有(playwright-cli)無官方 CLI

簡單的結論:如果是新專案,幾乎沒有理由選 Puppeteer;如果已經用 Puppeteer 且只跑 Chromium 也沒遇到問題,那維持現狀也 OK。

為什麼需要 playwright-cli

傳統用 Playwright 要做一件小事——例如「幫我把某個網址截一張圖」——流程是:npm init 建專案 → 裝 @playwright/test → 寫一個 .spec.ts 檔 → 跑 npx playwright test。為了一張截圖搞一整個專案,明顯太重。

playwright-cli 就是為了這類「一次性」需求而生。它把最常用的功能包成子指令,直接用 npx playwright <子指令> 呼叫,不用專案、不用設定檔、不用寫測試:

  • playwright screenshot:抓網頁截圖(支援整頁、特定尺寸、暗色模式)
  • playwright pdf:把網頁輸出成 PDF
  • playwright codegen:錄製使用者操作,即時產生對應語言的程式碼
  • playwright open:開一個被 Playwright 控制的瀏覽器,方便手動探索
  • playwright install:下載瀏覽器二進位
  • playwright show-trace:打開 trace 檔做除錯

對 AI agent 來說這個設計特別重要——agent 不擅長維護長期的 session,但對「執行一個有明確輸入輸出的指令」非常在行。playwright-cli 剛好把瀏覽器操作拆成一個個原子指令,agent 呼叫完拿結果(圖片、HTML、JSON)就能繼續推理。

playwright-cli 與 Playwright MCP 的差異

既然 Microsoft 已經有 Playwright MCP(Model Context Protocol server,讓 AI agent 能長時間控制瀏覽器),為什麼還要多一個 CLI?這兩者其實是互補的,不是替代關係。

項目Playwright MCPplaywright-cli
運作模式常駐 server,AI 逐步呼叫一次性指令,執行完結束
Token 消耗高(每步回傳 DOM snapshot)低(只回傳結果檔)
適合場景探索式互動、試錯、不確定流程已知流程、批次處理、排程
可腳本化較難(要跑在 agent context 內)簡單(寫進 shell 或 cron)
重現性中(AI 每次決策略有差異)高(指令固定,結果可預期)

一句話記住:探索用 MCP、固化用 CLI。AI agent 第一次摸一個陌生網站時,用 MCP 逐步試出流程;確認可行之後,把流程寫成 CLI 指令或小腳本,之後重複執行就不用再消耗 AI token。後面的應用範例 4 會實際示範這個模式。

為什麼 CLI 省 token

Playwright MCP 每走一步(點擊、輸入、捲動)都會把當下的 accessibility tree 或 DOM snapshot 回傳到 AI 的 context 裡,方便 AI 推理下一步要做什麼。一個稍微複雜的頁面,單次 snapshot 幾 KB 到幾十 KB 都有,操作個十幾步 token 就燒掉一大把。

playwright-cli 則相反——AI agent 收到的只是「檔案路徑 + stdout 幾行」,真正的網頁內容留在磁碟上。需要「看」畫面時,才用多模態讀那張截圖(一次性成本);需要「看」內容時,可以自己寫一支小腳本把頁面轉成精簡的 Markdown 或 JSON,只把重點丟給 AI。這種「先把資訊壓縮成最小有用單位、再交給 AI」的設計,就是省 token 的核心。

把網頁轉成 Markdown 再交給 AI

playwright-cli 本身沒有內建 --format=md,不過自己寫支小腳本很簡單——用 Playwright 抓頁面 HTML,搭配 @mozilla/readability 抽正文、turndown 轉 Markdown,十幾行搞定:

// page2md.mjs — 抓網頁、抽正文、轉 Markdown
// 使用:node page2md.mjs https://example.com > output.md
import { chromium } from 'playwright';
import { Readability } from '@mozilla/readability';
import { JSDOM } from 'jsdom';
import TurndownService from 'turndown';

const url = process.argv[2];
const browser = await chromium.launch({ channel: 'chrome' });
const page = await browser.newPage();
await page.goto(url, { waitUntil: 'networkidle' });

const html = await page.content();
const doc = new JSDOM(html, { url }).window.document;
const article = new Readability(doc).parse();
const md = new TurndownService().turndown(article.content);

console.log(`# ${article.title}\n\n${md}`);
await browser.close();

這類腳本跑完吐出的 Markdown 通常只有原始 HTML 的 5–10%,雜訊(廣告、導覽列、側欄)也被 Readability 濾掉了。AI 讀的是精煉過的內容,token 消耗直接砍數倍。做研究、整理資料、摘要文章的場景特別適合。

安裝與初次使用

playwright-cli 依賴 Node.js 環境,安裝前請先確認本機有 Node.js 16 以上版本(建議 18 或更新)。因為我們都用 npx 呼叫,其實不用先 npm installnpx 會自動下載套件。

確認版本與基本指令

# 查看 playwright 版本(第一次執行會自動下載 npm 套件)
npx playwright --version

# 查看所有可用子指令
npx playwright --help

安裝瀏覽器

Playwright 預設會去下載它自己打包過的 Chromium、Firefox、WebKit 二進位檔(放在 ~/Library/Caches/ms-playwright/,總共約 600MB)。要完整安裝的話:

# 安裝所有預設瀏覽器(Chromium、Firefox、WebKit)
npx playwright install

# 只裝 Chromium(最常用、下載量最小)
npx playwright install chromium

用系統已安裝的 Chrome

如果不想多下載 170MB 的 Chromium,playwright-cli 支援直接使用本機已安裝的 Chrome 或 Edge,加上 --channel 參數即可。下面的所有範例都以此為主,其他像 chromiumfirefoxwebkitmsedge 也都是可以的選項。

# 使用系統 Chrome
npx playwright screenshot --channel=chrome https://example.com out.png

# 使用系統 Edge
npx playwright screenshot --channel=msedge https://example.com out.png

# 使用 Playwright 內建的 Chromium(需先 install)
npx playwright screenshot --browser=chromium https://example.com out.png

應用範例

接下來用四個實際場景展示 playwright-cli 的應用,從最基本的截圖、到錄製腳本、再到 AI agent 驅動的自動化,最後把流程固化成可排程的腳本。

應用 1:自動截圖驗證 UI

最基本但最實用的場景——改完前端想確認畫面是不是預期的樣子。以前要切到瀏覽器手動重新整理、比對、截圖;現在交給 Claude Code 跑一行 CLI 指令就好。

下面的指令實際針對 https://klab.tw 首頁抓全頁截圖,產出一張 3.4MB 的 PNG 檔:

# 抓 klab.tw 首頁整頁截圖,使用系統 Chrome
npx playwright screenshot \
  --channel=chrome \
  --full-page \
  https://klab.tw klab-home.png

# 指定視窗尺寸(模擬手機)
npx playwright screenshot \
  --channel=chrome \
  --viewport-size=375,812 \
  --full-page \
  https://klab.tw klab-mobile.png

# 等待特定元素出現再截圖(避免拍到還沒載入完的畫面)
npx playwright screenshot \
  --channel=chrome \
  --wait-for-selector="article" \
  https://klab.tw klab-ready.png

搭配 Claude Code 的工作流:改完 CSS 後,直接請 Claude 跑上面的指令、再用多模態讀取截圖,判斷畫面是否符合需求。比起我們自己切視窗重整,省下的是「注意力切換」這個最貴的成本。進階一點還能搭配 pixelmatch 套件做 baseline 比對,自動偵測視覺回歸。

應用 2:codegen 錄製操作產生程式碼

codegen 是 Playwright 內建的錄製器,執行後會同時開兩個視窗:一個是正常的瀏覽器可以讓我們點擊操作,另一個是 Playwright Inspector,會即時把我們的每個動作翻譯成 Playwright 程式碼。

例如對著 https://playwright.dev 錄製「在搜尋框輸入關鍵字」:

# 開啟錄製器,對 playwright.dev 錄製並輸出成 JS 檔
npx playwright codegen \
  --channel=chrome \
  --target=javascript \
  -o search.spec.js \
  https://playwright.dev

# 指定輸出 Python
npx playwright codegen \
  --channel=chrome \
  --target=python \
  -o search.py \
  https://playwright.dev

# 保存登入態(錄製完會把 cookie 存進 auth.json)
npx playwright codegen \
  --channel=chrome \
  --save-storage=auth.json \
  https://playwright.dev

錄製出來的檔案大概長這樣(Inspector 會自動挑選最穩的 selector,優先使用 getByRolegetByText 這類語意化定位):

import { test, expect } from '@playwright/test';

test('search playwright docs', async ({ page }) => {
  await page.goto('https://playwright.dev/');
  await page.getByRole('button', { name: 'Search' }).click();
  await page.getByRole('searchbox').fill('screenshot');
  await page.getByRole('link', { name: /Screenshots/ }).first().click();
});

codegen 的核心價值

  • 不用自己找 selector:Playwright 會自動挑最穩的定位方式,避開脆弱的 CSS 路徑
  • 即時預覽:錄完可以在 Inspector 按 Resume 直接重播驗證
  • 多語言輸出--target 支援 javascript、python、java、csharp
  • 保存登入態--save-storage / --load-storage 可以免去每次都要登入

適合網頁開發者做自動化測試嗎?

這是很多開發者第一次看到 codegen 時會問的問題。短答:Playwright 本身非常適合做 E2E 測試,但 codegen 錄出來的程式碼只適合當「第一份草稿」

錄製腳本直接拿來當測試會遇到幾個問題:缺少斷言(expect())、沒有 Page Object 結構、遇到 A/B test 或動態內容容易 flaky、沒有錯誤處理。實務上正確的用法是——先用 codegen 錄一份打底,再手動(或請 Claude Code)重構:抽出可重用的函式、補上斷言、拆分測試案例、處理等待與錯誤情況。

換個角度看,codegen 其實特別適合搭配 AI 使用。Claude 最弱的環節是「在它看不到的網頁裡猜正確 selector」,而 codegen 剛好補上這塊——我們先錄一份、讓 AI 接手寫成漂亮的測試套件,兩邊都做自己擅長的事。

常見應用場景

  • 新人學 Playwright 語法:邊點邊看程式碼怎麼寫
  • 探索陌生網站的 DOM 結構:比 F12 DevTools 快很多
  • 跟 QA/PM 協作:把測試步驟直接錄成可重播腳本
  • 給 AI 當種子:錄一份模糊的草稿,請 Claude Code 整理成正式測試
  • 寫爬蟲前的偵察:先錄一次人工操作、再改成批次執行

應用 3:連既有瀏覽器操控社群帳號

這個場景的概念類似 OpenClaw、browser-use 或 Claude Computer Use——使用者先在自己的瀏覽器手動登入社群帳號、過 2FA,AI agent 再接手做後續的操作。好處是完全不用把密碼交給程式、不用處理驗證碼、而且所有 session 狀態都跟平常使用瀏覽器一模一樣,反自動化偵測也比較不容易觸發。

核心技術是 Chrome DevTools Protocol(CDP)。啟動 Chrome 時加上 --remote-debugging-port 參數,Playwright 就能透過 connectOverCDP 附加到這個既有的瀏覽器:

# 啟動一個開啟除錯埠的 Chrome,使用獨立的 user-data 資料夾
# 之後在這個視窗手動登入想操作的社群帳號
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
  --remote-debugging-port=9222 \
  --user-data-dir=/tmp/chrome-agent-profile

接著寫一段 Node.js 小腳本,讓 Claude Code 可以附加上去操作。這段是示意程式,實務上會請 Claude 依照需求生成:

import { chromium } from 'playwright';

// 附加到既有的 Chrome(使用者已經在裡面登入好社群帳號)
const browser = await chromium.connectOverCDP('http://localhost:9222');
const context = browser.contexts()[0];
const page = context.pages()[0];

// 之後就能像操作一般 Playwright page 那樣做事
// 例如:彙整自己貼文的留言、整理書籤、匯出訊息
await page.goto('https://www.threads.net/@kyle');
const posts = await page.locator('article').allTextContents();
console.log(posts);

// 注意:結束時不要關 browser,避免關掉使用者的瀏覽器
await browser.close();

注意事項與倫理考量

  • 反自動化偵測:Facebook、Instagram、X 等大型平台有滑鼠軌跡、操作時序的風控機制,激進大量操作仍會被判定為機器人
  • 服務條款(ToS):多數社群平台禁止自動化操作,建議僅用於個人用途(整理自己的資料、匯出、管理)而非商業濫用或大量散播
  • CDP 埠安全性--remote-debugging-port 預設綁在 localhost,不要暴露到公網
  • 推薦的示範對象:風控較鬆的 Threads、Mastodon、或是自己擁有權限的 Discord 伺服器管理介面,比對 FB/IG 安全得多

應用 4:固化流程成腳本省下 AI token

這個範例呼應前面 MCP vs CLI 的討論——探索階段讓 AI 用 MCP 互動式地找出流程,一旦流程確定,就請 AI 把它寫成 playwright 腳本,之後每次執行都不再消耗 AI token。這是把 AI 當「一次性編譯器」的思維。

以「每日 klab.tw 首頁健康檢查」為例,流程包含:截圖、檢查關鍵元素、輸出報告。請 Claude Code 生成的腳本大概會長這樣:

// daily-check.mjs — 每日首頁健康檢查
import { chromium } from 'playwright';
import fs from 'node:fs/promises';

const browser = await chromium.launch({ channel: 'chrome' });
const page = await browser.newPage();

const start = Date.now();
await page.goto('https://klab.tw', { waitUntil: 'networkidle' });
const loadTime = Date.now() - start;

// 檢查關鍵元素是否存在
const articleCount = await page.locator('article').count();
const hasHeader = await page.locator('header').isVisible();

// 截圖存檔
const today = new Date().toISOString().slice(0, 10);
await page.screenshot({ path: `reports/${today}.png`, fullPage: true });

// 寫出 JSON 報告
const report = { date: today, loadTime, articleCount, hasHeader };
await fs.writeFile(`reports/${today}.json`, JSON.stringify(report, null, 2));
console.log(report);

await browser.close();

之後只要排 cron 或 GitHub Actions 每天跑一次 node daily-check.mjs,完全不需要再啟動 AI。同樣的模式也能用來做:

  • 批次幫所有文章頁產生 OG 社群分享用截圖
  • 監控特定頁面改版(存 baseline 截圖,用 pixelmatch 做 diff)
  • 定期抓 WordPress 後台的瀏覽數、留言數寫進 CSV
  • 每週自動產出站內連結健康檢查報告

這個思維的關鍵轉變是:AI 的角色從「每次執行者」變成「一次性作者」。寫好的程式本身就是資產,跑一百次成本和跑一次一樣,只有當流程真的改變時才需要 AI 再出手修改。

總結

Playwright 作為新一代瀏覽器自動化框架,解決了 Puppeteer 當年的跨瀏覽器、auto-wait 等痛點;而 playwright-cli 把最常用的功能做成一行指令可呼叫的工具,特別適合搭配 Claude Code 這類 AI agent 使用。Playwright MCP 和 playwright-cli 不是替代關係,而是「探索用 MCP、固化用 CLI」的分工。

本篇四個應用範例從簡單到進階——自動截圖、codegen 錄製、連既有瀏覽器操控社群、把流程固化成腳本——都是實際開發時可以立刻用上的場景。對網頁開發者來說,Playwright 本身做 E2E 測試非常合適,codegen 則適合當第一份草稿,再由我們或 AI 接手重構成正式的測試套件。希望這篇文章能幫助大家把「讓 AI 看見網頁」這件事,變成日常工作流程的一部分。

發佈留言