<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Puppeteer on KnightLi的博客</title>
        <link>https://knightli.com/zh-tw/tags/puppeteer/</link>
        <description>Recent content in Puppeteer on KnightLi的博客</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-tw</language>
        <lastBuildDate>Sun, 24 May 2026 17:51:28 +0800</lastBuildDate><atom:link href="https://knightli.com/zh-tw/tags/puppeteer/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>browser-harness、Playwright、Puppeteer 怎麼選？瀏覽器自動化工具對比</title>
        <link>https://knightli.com/zh-tw/2026/05/24/browser-harness-playwright-puppeteer-comparison/</link>
        <pubDate>Sun, 24 May 2026 17:51:28 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/24/browser-harness-playwright-puppeteer-comparison/</guid>
        <description>&lt;p&gt;在瀏覽器自動化和自動化測試領域，&lt;code&gt;Playwright&lt;/code&gt; 和 &lt;code&gt;Puppeteer&lt;/code&gt; 是最常被拿來比較的兩個工具。它們都可以控制瀏覽器、點擊頁面、抓取內容、產生截圖或 PDF，也都和 Chrome DevTools Protocol 有很深關係。&lt;/p&gt;
&lt;p&gt;但如果把 &lt;code&gt;browser-use/browser-harness&lt;/code&gt; 放進來，問題就不只是「哪個測試框架更強」，而是變成兩類工具的對比：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Playwright&lt;/code&gt; / &lt;code&gt;Puppeteer&lt;/code&gt;：面向人類工程師寫確定性腳本。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;browser-harness&lt;/code&gt;：面向 AI Agent 操作真實瀏覽器。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;前者適合測試、爬蟲和工程化自動化；後者更像給 Claude Code、Codex CLI、Gemini 這類 Agent 準備的瀏覽器控制層。&lt;/p&gt;
&lt;h2 id=&#34;playwright-和-puppeteer-的關係&#34;&gt;Playwright 和 Puppeteer 的關係
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Puppeteer&lt;/code&gt; 最早由 Google Chrome 團隊推出，天然服務於 Chromium 和 Chrome 自動化。它的 API 簡潔，生態成熟，特別適合圍繞 Chrome 做截圖、PDF、頁面抓取和輕量自動化。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Playwright&lt;/code&gt; 由 Microsoft 維護，背後團隊和早期 Puppeteer 有很深淵源。它吸收了 Puppeteer 的很多經驗，同時把跨瀏覽器、自動等待、上下文隔離、測試報告和調試工具鏈做得更完整。&lt;/p&gt;
&lt;p&gt;簡單說：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;只圍繞 Chrome 做輕量任務，&lt;code&gt;Puppeteer&lt;/code&gt; 仍然很順手。&lt;/li&gt;
&lt;li&gt;做跨瀏覽器 E2E 測試、複雜 SPA 自動化和團隊測試工程，&lt;code&gt;Playwright&lt;/code&gt; 通常更合適。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;核心區別總覽&#34;&gt;核心區別總覽
&lt;/h2&gt;&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;維度&lt;/th&gt;
          &lt;th&gt;Puppeteer&lt;/th&gt;
          &lt;th&gt;Playwright&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;主導方&lt;/td&gt;
          &lt;td&gt;Google&lt;/td&gt;
          &lt;td&gt;Microsoft&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;瀏覽器支援&lt;/td&gt;
          &lt;td&gt;主要面向 Chrome / Chromium&lt;/td&gt;
          &lt;td&gt;Chromium、Firefox、WebKit&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;語言支援&lt;/td&gt;
          &lt;td&gt;主要是 JavaScript / TypeScript&lt;/td&gt;
          &lt;td&gt;JavaScript / TypeScript、Python、Java、.NET&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;自動等待&lt;/td&gt;
          &lt;td&gt;需要更多顯式等待&lt;/td&gt;
          &lt;td&gt;Locator 和 auto-waiting 更完整&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;多上下文隔離&lt;/td&gt;
          &lt;td&gt;支援，但不是最突出的優勢&lt;/td&gt;
          &lt;td&gt;BrowserContext 體驗很強&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;工具鏈&lt;/td&gt;
          &lt;td&gt;簡潔、成熟、偏基礎&lt;/td&gt;
          &lt;td&gt;Codegen、Trace Viewer、測試報告更完整&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;典型場景&lt;/td&gt;
          &lt;td&gt;Chrome 自動化、截圖、PDF、輕量抓取&lt;/td&gt;
          &lt;td&gt;跨瀏覽器 E2E 測試、複雜前端應用自動化&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;瀏覽器支援&#34;&gt;瀏覽器支援
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Puppeteer&lt;/code&gt; 的優勢在 Chrome。它和 Chromium 結合緊密，如果你的目標就是控制 Chrome、產生 PDF、截圖、跑簡單爬蟲，Puppeteer 的心智負擔很低。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Playwright&lt;/code&gt; 的優勢在跨瀏覽器。它原生支援 Chromium、Firefox 和 WebKit。WebKit 這一點很關鍵，因為很多 Safari 相關問題不能只靠 Chrome 測出來。對需要覆蓋桌面端、行動端和不同瀏覽器核心的應用來說，Playwright 更適合作為主力工具。&lt;/p&gt;
&lt;p&gt;這也是兩者選擇的第一道分界線：只看 Chrome，可以用 Puppeteer；要認真做跨瀏覽器測試，優先 Playwright。&lt;/p&gt;
&lt;h2 id=&#34;自動等待與穩定性&#34;&gt;自動等待與穩定性
&lt;/h2&gt;&lt;p&gt;瀏覽器自動化最煩人的問題，往往不是「不會點擊」，而是頁面還沒準備好。元素可能還沒掛到 DOM，可能被遮擋，可能正在動畫中，可能按鈕還是 disabled。&lt;/p&gt;
&lt;p&gt;Puppeteer 裡經常會寫：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;waitForSelector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;#submit-btn&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;click&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;#submit-btn&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這沒有問題，但等待邏輯需要工程師自己想清楚。頁面越複雜，腳本裡越容易出現各種 &lt;code&gt;waitForSelector&lt;/code&gt;、&lt;code&gt;waitForTimeout&lt;/code&gt; 和重試邏輯。&lt;/p&gt;
&lt;p&gt;Playwright 的 Locator 機制和自動等待更完整：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;locator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;#submit-btn&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;click&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;在點擊之前，Playwright 會自動檢查元素是否可見、可操作、穩定、沒有被遮擋，並在合理時間內重試。這對 React、Vue、Next.js 這類非同步渲染很多的現代 Web 應用尤其重要，可以明顯減少 flaky test。&lt;/p&gt;
&lt;h2 id=&#34;多帳號和上下文隔離&#34;&gt;多帳號和上下文隔離
&lt;/h2&gt;&lt;p&gt;如果你要模擬多個使用者，或者想讓多個任務共享同一個瀏覽器行程但隔離 Cookie、LocalStorage 和 Session，&lt;code&gt;BrowserContext&lt;/code&gt; 就很重要。&lt;/p&gt;
&lt;p&gt;Puppeteer 也支援上下文隔離，但 Playwright 把這件事做成了核心能力。你可以在一個瀏覽器實例裡快速建立多個獨立 context，每個 context 像一個乾淨的瀏覽器環境，卻不需要反覆啟動完整瀏覽器行程。&lt;/p&gt;
&lt;p&gt;這對這些場景很有價值：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;多帳號並發測試。&lt;/li&gt;
&lt;li&gt;多角色協作流程測試。&lt;/li&gt;
&lt;li&gt;電商、IM、協作文檔等多使用者場景。&lt;/li&gt;
&lt;li&gt;需要隔離 Cookie 和登入狀態的爬取任務。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;工具鏈差異&#34;&gt;工具鏈差異
&lt;/h2&gt;&lt;p&gt;Playwright 是更工程化的方案。它內建了很多測試開發會用到的工具：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;codegen&lt;/code&gt;：在網頁上操作，自動產生腳本。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Trace Viewer&lt;/code&gt;：失敗後回看每一步的截圖、DOM、網路請求和 console 日誌。&lt;/li&gt;
&lt;li&gt;Test Runner：支援斷言、並行、重試、報告和專案矩陣。&lt;/li&gt;
&lt;li&gt;Locator：支援按文字、角色、label、test id 等方式定位元素。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Puppeteer 則更像一個輕量瀏覽器控制庫。它不臃腫，API 直接，適合嵌入腳本、服務端任務和自定義自動化流程。&lt;/p&gt;
&lt;p&gt;如果你要搭企業級測試體系，Playwright 的配套工具會省很多事。如果你只是要寫一個 Node.js 腳本，把網頁轉 PDF 或定時截圖，Puppeteer 反而更乾脆。&lt;/p&gt;
&lt;h2 id=&#34;browser-harness-放在哪裡&#34;&gt;browser-harness 放在哪裡
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;browser-harness&lt;/code&gt; 和 Playwright、Puppeteer 不是同一類工具。&lt;/p&gt;
&lt;p&gt;Playwright 和 Puppeteer 主要假設「人類寫腳本」。人類工程師要決定選擇器、等待條件、斷言邏輯和異常處理。它們追求的是確定性：同樣的腳本，在同樣的頁面狀態下，應該給出同樣的結果。&lt;/p&gt;
&lt;p&gt;browser-harness 主要假設「AI Agent 操作瀏覽器」。它的目標不是提供一套巨大的高階 API，而是透過 CDP 連接真實 Chrome，把截圖、座標點擊、DOM、網路請求和 helper 暴露給 Agent。Agent 可以觀察頁面、判斷下一步、遇到缺能力時補 helper，再把站點經驗沉澱成 skill。&lt;/p&gt;
&lt;p&gt;這就讓它更適合開放任務：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;登入後台後下載帳單。&lt;/li&gt;
&lt;li&gt;在內部系統裡填一組表單。&lt;/li&gt;
&lt;li&gt;處理經常改版的 OA 或 SaaS 頁面。&lt;/li&gt;
&lt;li&gt;按使用者目標探索頁面，而不是執行固定腳本。&lt;/li&gt;
&lt;li&gt;讓 Claude Code、Codex CLI 這類工具擁有瀏覽器操作能力。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;三者核心對比&#34;&gt;三者核心對比
&lt;/h2&gt;&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;維度&lt;/th&gt;
          &lt;th&gt;Puppeteer&lt;/th&gt;
          &lt;th&gt;Playwright&lt;/th&gt;
          &lt;th&gt;browser-harness&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;面向對象&lt;/td&gt;
          &lt;td&gt;人類工程師&lt;/td&gt;
          &lt;td&gt;人類工程師和測試團隊&lt;/td&gt;
          &lt;td&gt;AI Agent&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;主要目標&lt;/td&gt;
          &lt;td&gt;控制 Chrome&lt;/td&gt;
          &lt;td&gt;穩定跨瀏覽器自動化&lt;/td&gt;
          &lt;td&gt;讓 Agent 操作真實瀏覽器&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;腳本方式&lt;/td&gt;
          &lt;td&gt;手寫 JS/TS 自動化&lt;/td&gt;
          &lt;td&gt;手寫腳本 + 測試框架&lt;/td&gt;
          &lt;td&gt;使用者下目標，Agent 分步執行&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;元素定位&lt;/td&gt;
          &lt;td&gt;CSS、XPath、DOM API&lt;/td&gt;
          &lt;td&gt;Locator、文字、角色、CSS&lt;/td&gt;
          &lt;td&gt;截圖視覺、座標、DOM、CDP&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;等待機制&lt;/td&gt;
          &lt;td&gt;更多手動控制&lt;/td&gt;
          &lt;td&gt;自動等待很強&lt;/td&gt;
          &lt;td&gt;由 Agent 觀察和調整&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;瀏覽器環境&lt;/td&gt;
          &lt;td&gt;通常啟動自動化瀏覽器&lt;/td&gt;
          &lt;td&gt;通常啟動測試瀏覽器&lt;/td&gt;
          &lt;td&gt;常連接真實 Chrome&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;最適合&lt;/td&gt;
          &lt;td&gt;Chrome 腳本、截圖、PDF、輕量抓取&lt;/td&gt;
          &lt;td&gt;E2E 測試、跨瀏覽器驗證、複雜 SPA&lt;/td&gt;
          &lt;td&gt;AI 助手、開放網頁任務、真實帳號工作流&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;程式碼體感對比&#34;&gt;程式碼體感對比
&lt;/h2&gt;&lt;p&gt;Puppeteer 更像直接控制 Chrome：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;puppeteer&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;puppeteer&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;browser&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;puppeteer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;launch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;page&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;browser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;newPage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;goto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;https://example.com&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;waitForSelector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;#submit-btn&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;click&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;#submit-btn&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;browser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;close&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;})();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Playwright 更強調 Locator 和自動等待：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;chromium&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;playwright&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;browser&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;chromium&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;launch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;page&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;browser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;newPage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;goto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;https://example.com&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;locator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;#submit-btn&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;click&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;browser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;close&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;})();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;browser-harness 的使用體感則完全不同。你通常不是寫完整腳本，而是在 Agent 環境裡下達目標：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;幫我打開後台，下載上個月的帳單，並整理成報銷用的文件。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Agent 會借助 browser-harness 反覆執行類似流程：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;截圖，理解目前頁面。&lt;/li&gt;
&lt;li&gt;點擊某個座標或定位某個元素。&lt;/li&gt;
&lt;li&gt;輸入文字、上傳檔案、下載檔案。&lt;/li&gt;
&lt;li&gt;遇到彈窗時判斷如何關閉。&lt;/li&gt;
&lt;li&gt;缺少 helper 時補充程式碼。&lt;/li&gt;
&lt;li&gt;把可重用流程沉澱為 domain skill。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這不是傳統測試腳本的寫法，而是瀏覽器 Agent 的工作方式。&lt;/p&gt;
&lt;h2 id=&#34;怎麼選&#34;&gt;怎麼選
&lt;/h2&gt;&lt;p&gt;選擇 &lt;code&gt;Puppeteer&lt;/code&gt;，通常是因為：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;專案主要跑在 Node.js 裡。&lt;/li&gt;
&lt;li&gt;只需要 Chrome 或 Chromium。&lt;/li&gt;
&lt;li&gt;任務是截圖、PDF、簡單頁面抓取或輕量自動化。&lt;/li&gt;
&lt;li&gt;你希望 API 簡潔、依賴少，自己控制更多細節。&lt;/li&gt;
&lt;li&gt;你對 Chrome DevTools Protocol 有較深依賴。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;選擇 &lt;code&gt;Playwright&lt;/code&gt;，通常是因為：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你要做標準 UI 自動化或 E2E 測試。&lt;/li&gt;
&lt;li&gt;需要覆蓋 Chromium、Firefox 和 WebKit。&lt;/li&gt;
&lt;li&gt;團隊主語言可能是 Python、Java 或 C#。&lt;/li&gt;
&lt;li&gt;頁面是複雜 SPA，非同步狀態多，容易出現 flaky test。&lt;/li&gt;
&lt;li&gt;你需要 codegen、Trace Viewer、測試報告和並行測試。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;選擇 &lt;code&gt;browser-harness&lt;/code&gt;，通常是因為：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你在開發或使用 AI Agent。&lt;/li&gt;
&lt;li&gt;你希望模型像人一樣操作真實瀏覽器。&lt;/li&gt;
&lt;li&gt;任務步驟不固定，需要邊看頁面邊判斷。&lt;/li&gt;
&lt;li&gt;目標網站經常改版，或者彈窗、iframe、shadow DOM 很多。&lt;/li&gt;
&lt;li&gt;你想把真實網頁工作流交給 Claude Code、Codex CLI 等工具處理。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;簡單結論&#34;&gt;簡單結論
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Playwright&lt;/code&gt; 和 &lt;code&gt;Puppeteer&lt;/code&gt; 是瀏覽器自動化工具，核心是讓人寫出可靠腳本。兩者相比，Puppeteer 更輕、更貼近 Chrome；Playwright 更完整、更適合跨瀏覽器測試和複雜前端應用。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;browser-harness&lt;/code&gt; 則是另一個方向：它不是為了取代 Playwright 或 Puppeteer 寫測試，而是為了讓 AI Agent 接管真實瀏覽器。它犧牲了一部分傳統腳本的確定性，換來更強的開放任務適應能力。&lt;/p&gt;
&lt;p&gt;所以答案不是三選一，而是按任務分層：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;測試工程：優先 Playwright。&lt;/li&gt;
&lt;li&gt;Chrome 輕量腳本：Puppeteer 很合適。&lt;/li&gt;
&lt;li&gt;AI Agent 上網辦事：看 browser-harness。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;參考資料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;browser-use/browser-harness：&lt;a class=&#34;link&#34; href=&#34;https://github.com/browser-use/browser-harness&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/browser-use/browser-harness&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Playwright 官方文件：&lt;a class=&#34;link&#34; href=&#34;https://playwright.dev/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://playwright.dev/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Puppeteer 官方文件：&lt;a class=&#34;link&#34; href=&#34;https://pptr.dev/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://pptr.dev/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Chrome DevTools Protocol：&lt;a class=&#34;link&#34; href=&#34;https://chromedevtools.github.io/devtools-protocol/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://chromedevtools.github.io/devtools-protocol/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        
    </channel>
</rss>
