<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Playwright on KnightLi的博客</title>
        <link>https://knightli.com/zh-tw/tags/playwright/</link>
        <description>Recent content in Playwright 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/playwright/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>
        <item>
        <title>CloakBrowser 是什麼？給 Playwright 和 Puppeteer 換一個更像真實用戶的瀏覽器</title>
        <link>https://knightli.com/zh-tw/2026/05/19/cloakbrowser-stealth-chromium-browser-automation/</link>
        <pubDate>Tue, 19 May 2026 10:56:50 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/19/cloakbrowser-stealth-chromium-browser-automation/</guid>
        <description>&lt;p&gt;&lt;code&gt;CloakHQ/CloakBrowser&lt;/code&gt; 是一個面向瀏覽器自動化的開源項目。它不是普通的 Playwright 配置，也不是單純注入一段 JavaScript，而是圍繞自定義 Chromium 二進制構建，讓瀏覽器指紋、WebGL、Canvas、音頻、字體、GPU、屏幕信息、WebRTC、網絡時序等信號更接近真實瀏覽器。&lt;/p&gt;
&lt;p&gt;項目地址：&lt;a class=&#34;link&#34; href=&#34;https://github.com/CloakHQ/CloakBrowser&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/CloakHQ/CloakBrowser&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;截至寫作時，GitHub API 顯示這個倉庫已有約 1.5 萬 star，主要語言是 Python，許可證爲 MIT。README 對它的定位很直接：一個可替代 Playwright / Puppeteer 啓動器的 Stealth Chromium。&lt;/p&gt;
&lt;h2 id=&#34;它解決什麼問題&#34;&gt;它解決什麼問題
&lt;/h2&gt;&lt;p&gt;很多自動化腳本在普通 Headless Chromium 下會暴露明顯自動化特徵，例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;navigator.webdriver&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;Headless UA 泄漏。&lt;/li&gt;
&lt;li&gt;插件、字體、屏幕、GPU 等指紋不自然。&lt;/li&gt;
&lt;li&gt;CDP 行爲和真實用戶輸入不一致。&lt;/li&gt;
&lt;li&gt;默認臨時 profile 缺少正常瀏覽痕跡。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CloakBrowser 的思路是把一部分指紋修改放到 Chromium 源碼層，而不是隻在運行時做配置或 JS patch。這樣對 Playwright 用戶來說，使用方式仍然接近原來的瀏覽器自動化 API，但底層瀏覽器換成了項目提供的自定義構建。&lt;/p&gt;
&lt;p&gt;這類工具適合做合規的自動化測試、站點兼容性驗證、反爬系統自測、Agent 瀏覽器環境實驗。不要把它用於未授權訪問、賬號濫用、繞過平臺風控或違反服務條款的場景。&lt;/p&gt;
&lt;h2 id=&#34;基本使用方式&#34;&gt;基本使用方式
&lt;/h2&gt;&lt;p&gt;Python 安裝：&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install cloakbrowser
&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;JavaScript / Node.js 安裝：&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm install cloakbrowser playwright-core
&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;README 給出的 Python 示例很接近 Playwright：&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;/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-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;cloakbrowser&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;launch&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;n&#34;&gt;browser&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#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;n&#34;&gt;page&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;browser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new_page&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;n&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;goto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://protected-site.com&amp;#34;&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;n&#34;&gt;browser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;close&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;JavaScript 示例：&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;/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;import&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 class=&#34;nx&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;cloakbrowser&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;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;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://protected-site.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 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;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;第一次運行時，項目會自動下載對應平臺的 Chromium 二進制文件，README 提到體積約 200MB，並會緩存到本地。&lt;/p&gt;
&lt;h2 id=&#34;browser-profile-manager&#34;&gt;Browser Profile Manager
&lt;/h2&gt;&lt;p&gt;CloakBrowser 還提供一個 Browser Profile Manager，可以自託管瀏覽器 profile，管理不同指紋、代理和持久會話。README 中的 Docker 啓動方式如下：&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker run -p 8080:8080 -v cloakprofiles:/data cloakhq/cloakbrowser-manager
&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;/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;http://localhost:8080
&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;這個方向更像開源的瀏覽器 profile 管理工具，適合需要多 profile、持久 cookie、隔離會話的自動化測試或內部 QA 場景。&lt;/p&gt;
&lt;h2 id=&#34;和普通-playwright-有什麼差別&#34;&gt;和普通 Playwright 有什麼差別
&lt;/h2&gt;&lt;p&gt;普通 Playwright 的優點是穩定、官方維護、API 成熟。CloakBrowser 的差別在於它使用自定義 Chromium，並提供一組源代碼級別的指紋 patch。&lt;/p&gt;
&lt;p&gt;README 裏列出的能力包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Canvas、WebGL、Audio、Fonts、GPU、Screen 等指紋處理。&lt;/li&gt;
&lt;li&gt;WebRTC IP spoofing。&lt;/li&gt;
&lt;li&gt;代理相關信號處理。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;humanize=True&lt;/code&gt; 模擬更自然的鼠標、鍵盤和滾動行爲。&lt;/li&gt;
&lt;li&gt;Python 與 JavaScript 雙端 API。&lt;/li&gt;
&lt;li&gt;Docker 鏡像與 CDP server 模式。&lt;/li&gt;
&lt;li&gt;持久 profile。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也就是說，它更適合對“瀏覽器環境真實性”有要求的自動化任務，而不是替代所有 Playwright 使用場景。&lt;/p&gt;
&lt;h2 id=&#34;使用時要注意什麼&#34;&gt;使用時要注意什麼
&lt;/h2&gt;&lt;p&gt;第一，瀏覽器自動化和反檢測相關工具有很強的合規邊界。它可以用於測試自己的站點、驗證自動化環境、做內部 QA，也可以用於研究瀏覽器指紋；但不應被用於未經授權的抓取、賬號批量註冊、繞過訪問控制、攻擊或濫用服務。&lt;/p&gt;
&lt;p&gt;第二，README 中也說明，CloakBrowser 不內置代理輪換，也不是驗證碼解決服務。它提供瀏覽器層能力，網絡信譽、賬號信譽、行爲策略和目標站點規則仍然會影響結果。&lt;/p&gt;
&lt;p&gt;第三，自定義 Chromium 二進制意味着供應鏈安全要額外關注。正式使用前建議檢查版本、二進制來源、簽名說明、許可證和更新機制。&lt;/p&gt;
&lt;h2 id=&#34;適合誰&#34;&gt;適合誰
&lt;/h2&gt;&lt;p&gt;適合三類用戶：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;已經在用 Playwright / Puppeteer，但需要更接近真實瀏覽器環境的開發者。&lt;/li&gt;
&lt;li&gt;做瀏覽器自動化測試、兼容性測試或反爬策略驗證的團隊。&lt;/li&gt;
&lt;li&gt;需要給 AI Agent 提供瀏覽器執行環境的開發者。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果只是普通網頁測試，原生 Playwright 已經夠用。如果目標是研究瀏覽器指紋、profile 隔離和真實瀏覽器行爲，CloakBrowser 值得關注。&lt;/p&gt;
&lt;h2 id=&#34;小結&#34;&gt;小結
&lt;/h2&gt;&lt;p&gt;CloakBrowser 的關鍵點不是“多寫一個自動化封裝”，而是把瀏覽器自動化的一部分僞裝能力下沉到 Chromium 構建層。它保留了 Playwright / Puppeteer 的使用習慣，同時提供自定義瀏覽器、profile 管理、Docker 和 CDP server。&lt;/p&gt;
&lt;p&gt;這類工具能力強，也更需要謹慎使用。判斷是否值得接入，重點看你的場景是否真的需要自定義 Chromium，而不是只因爲普通 Headless 瀏覽器被某些檢測服務標記。&lt;/p&gt;
&lt;p&gt;參考項目：&lt;a class=&#34;link&#34; href=&#34;https://github.com/CloakHQ/CloakBrowser&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/CloakHQ/CloakBrowser&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>ai-goofish-monitor：用 AI 自動盯閒魚商品的開源監控系統</title>
        <link>https://knightli.com/zh-tw/2026/05/17/ai-goofish-monitor/</link>
        <pubDate>Sun, 17 May 2026 17:24:03 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/17/ai-goofish-monitor/</guid>
        <description>&lt;p&gt;ai-goofish-monitor 是 Usagi-org 開源的閒魚商品監控系統。&lt;/p&gt;
&lt;p&gt;它的目標很明確：把閒魚搜尋、篩選、商品分析、結果記錄和通知推送自動化，幫助使用者從大量二手商品裡更快找到符合條件的目標。專案基於 Playwright 做頁面自動化，再接入支援圖片輸入的 AI 模型，對商品資訊做進一步判斷。&lt;/p&gt;
&lt;p&gt;專案地址：&lt;a class=&#34;link&#34; href=&#34;https://github.com/Usagi-org/ai-goofish-monitor&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/Usagi-org/ai-goofish-monitor&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;先說結論&#34;&gt;先說結論
&lt;/h2&gt;&lt;p&gt;ai-goofish-monitor 更像一個「閒魚採購情報面板」，而不是簡單的關鍵字提醒腳本。&lt;/p&gt;
&lt;p&gt;它有幾個明顯特點：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;有完整 Web 管理介面，可以管理任務、帳號、AI 標準、日誌和結果。&lt;/li&gt;
&lt;li&gt;支援多任務並發，每個任務可以配置關鍵字、價格、篩選條件和 AI Prompt。&lt;/li&gt;
&lt;li&gt;使用 Playwright 抓取閒魚頁面，適合處理需要登入態和頁面互動的場景。&lt;/li&gt;
&lt;li&gt;使用 AI 判斷商品是否符合需求，不只依賴關鍵字匹配。&lt;/li&gt;
&lt;li&gt;支援 ntfy.sh、企業微信、Bark、Telegram、Webhook 等通知渠道。&lt;/li&gt;
&lt;li&gt;支援 Cron 定時任務、多帳號管理、代理輪換、失敗重試和 Docker 部署。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它適合經常在閒魚找特定商品的人，比如二手數位產品、攝影器材、顯卡、硬碟、遊戲機、樂器、家電和收藏品。但它也不是「自動撿漏神器」。閒魚搜尋結果本身會變，帳號登入態可能失效，平台風控也會影響自動化穩定性。使用時更應該把它當成輔助篩選工具，而不是完全替代人工判斷。&lt;/p&gt;
&lt;h2 id=&#34;它解決什麼問題&#34;&gt;它解決什麼問題
&lt;/h2&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;好價格出現時間短，發現太晚就沒了。&lt;/li&gt;
&lt;li&gt;同一個商品可能有多個地區、價格、成色和賣家差異。&lt;/li&gt;
&lt;li&gt;低價商品裡混著配件、損壞品、翻新貨和誘導性標題。&lt;/li&gt;
&lt;li&gt;想持續盯多個關鍵字時，手動搜尋很難堅持。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;普通關鍵字提醒只能解決一部分問題。比如你搜尋「ThinkPad X1」，可能會混入配件、壞屏、空盒、拆機件；你搜尋「索尼 A7C」，又可能遇到鏡頭套裝、租賃資訊、標題黨和價格異常。&lt;/p&gt;
&lt;p&gt;ai-goofish-monitor 的思路是：先用自動化把候選商品抓出來，再交給 AI 按你的需求做二次判斷，最後把值得關注的結果推送給你。&lt;/p&gt;
&lt;h2 id=&#34;核心功能&#34;&gt;核心功能
&lt;/h2&gt;&lt;p&gt;專案 README 裡列出的核心能力比較完整：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Web 視覺化管理：任務管理、帳號管理、AI 標準編輯、運行日誌、結果瀏覽。&lt;/li&gt;
&lt;li&gt;AI 驅動：支援自然語言建立任務，並用多模態模型分析商品。&lt;/li&gt;
&lt;li&gt;多任務並發：不同任務可以獨立配置關鍵字、價格、篩選條件和 AI Prompt。&lt;/li&gt;
&lt;li&gt;進階篩選：支援包郵、新發布時間範圍、省 / 市 / 區三級區域篩選。&lt;/li&gt;
&lt;li&gt;即時通知：支援 ntfy.sh、企業微信、Bark、Telegram、Webhook 等多渠道。&lt;/li&gt;
&lt;li&gt;定時調度：支援 Cron 配置週期性任務。&lt;/li&gt;
&lt;li&gt;帳號與代理輪換：多帳號管理、任務綁定帳號、代理池輪換與失敗重試。&lt;/li&gt;
&lt;li&gt;Docker 部署：支援容器化部署。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這些能力組合起來，覆蓋了從「建立監控任務」到「收到命中提醒」的完整鏈路。&lt;/p&gt;
&lt;h2 id=&#34;工作流是什麼樣&#34;&gt;工作流是什麼樣
&lt;/h2&gt;&lt;p&gt;一個典型流程大概是這樣：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;部署服務並打開 Web UI。&lt;/li&gt;
&lt;li&gt;匯入閒魚帳號登入態。&lt;/li&gt;
&lt;li&gt;建立監控任務。&lt;/li&gt;
&lt;li&gt;設定關鍵字、價格區間、地區、新發布範圍等篩選條件。&lt;/li&gt;
&lt;li&gt;編寫或讓 AI 生成判斷標準。&lt;/li&gt;
&lt;li&gt;任務按即時或定時方式運行。&lt;/li&gt;
&lt;li&gt;Playwright 打開頁面並抓取商品資訊。&lt;/li&gt;
&lt;li&gt;AI 根據標題、描述、圖片和 Prompt 判斷是否符合需求。&lt;/li&gt;
&lt;li&gt;命中結果寫入 SQLite。&lt;/li&gt;
&lt;li&gt;系統透過配置的通知渠道推送結果。&lt;/li&gt;
&lt;li&gt;使用者在 Web UI 裡查看結果、日誌和價格歷史。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;這個流程裡，AI 的價值主要在第 8 步。它可以理解「我想要成色好、價格合理、不要配件、不要維修機、最好同城自取」這類自然語言條件，比單純關鍵字規則靈活。&lt;/p&gt;
&lt;h2 id=&#34;docker-部署&#34;&gt;Docker 部署
&lt;/h2&gt;&lt;p&gt;專案推薦使用 Docker 部署：&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;/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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git clone https://github.com/Usagi-org/ai-goofish-monitor &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; ai-goofish-monitor
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cp .env.example .env
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;vim .env
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker compose up -d
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker compose logs -f app
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker compose down
&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;預設 Web UI 地址是：&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;http://127.0.0.1:8000
&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;/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;ghcr.io/usagi-org/ai-goofish:latest
&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;如果映像存取慢，README 裡也給了加速映像示例：&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;/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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker pull ghcr.nju.edu.cn/usagi-org/ai-goofish:latest
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker tag ghcr.nju.edu.cn/usagi-org/ai-goofish:latest ghcr.io/usagi-org/ai-goofish:latest
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker compose up -d
&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;Docker 映像已內建 Chromium，不需要宿主機額外安裝瀏覽器。預設持久化目錄包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;data/&lt;/code&gt;：SQLite 主儲存，保存任務、結果和價格歷史。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;state/&lt;/code&gt;：登入狀態 cookie 文件。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;prompts/&lt;/code&gt;：任務提示詞。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;logs/&lt;/code&gt;：運行日誌。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;images/&lt;/code&gt;：商品圖片和任務臨時圖片目錄。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果修改了 &lt;code&gt;.env&lt;/code&gt; 裡的 &lt;code&gt;SERVER_PORT&lt;/code&gt;，也要同步調整 &lt;code&gt;docker-compose.yaml&lt;/code&gt; 的連接埠映射。&lt;/p&gt;
&lt;h2 id=&#34;最少配置&#34;&gt;最少配置
&lt;/h2&gt;&lt;p&gt;專案的最少配置主要圍繞 AI 模型和 Web UI 登入：&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;/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-env&#34; data-lang=&#34;env&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;your_api_key
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;OPENAI_BASE_URL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;your_openai_compatible_base_url
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;OPENAI_MODEL_NAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;your_multimodal_model
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;WEB_USERNAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;admin
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;WEB_PASSWORD&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;change_me
&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;其中前三項是 AI 模型接入必填項：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;OPENAI_API_KEY&lt;/code&gt;：模型 API Key。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OPENAI_BASE_URL&lt;/code&gt;：OpenAI 相容介面地址。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OPENAI_MODEL_NAME&lt;/code&gt;：支援圖片輸入的模型名稱。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;WEB_USERNAME&lt;/code&gt; 和 &lt;code&gt;WEB_PASSWORD&lt;/code&gt; 用於 Web UI 登入。README 提到預設帳號密碼是 &lt;code&gt;admin/admin123&lt;/code&gt;，生產環境必須修改。&lt;/p&gt;
&lt;h2 id=&#34;第一次使用&#34;&gt;第一次使用
&lt;/h2&gt;&lt;p&gt;第一次使用時，流程大致是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;打開 &lt;code&gt;http://127.0.0.1:8000&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;登入 Web UI。&lt;/li&gt;
&lt;li&gt;進入「閒魚帳號管理」。&lt;/li&gt;
&lt;li&gt;使用專案提供的 Chrome 擴充套件匯出閒魚登入態 JSON。&lt;/li&gt;
&lt;li&gt;把登入態貼到系統裡。&lt;/li&gt;
&lt;li&gt;登入態文件會保存到 &lt;code&gt;state/&lt;/code&gt;，例如 &lt;code&gt;state/acc_1.json&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;回到「任務管理」，建立任務並綁定帳號。&lt;/li&gt;
&lt;li&gt;運行任務並查看結果。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;這裡最關鍵的是登入態。由於閒魚並不是開放給第三方隨意抓取的標準 API，專案需要用瀏覽器登入狀態來模擬正常頁面存取。登入態失效、風控、驗證碼、帳號異常都會影響任務運行。&lt;/p&gt;
&lt;h2 id=&#34;ai-任務和關鍵字任務&#34;&gt;AI 任務和關鍵字任務
&lt;/h2&gt;&lt;p&gt;專案支援兩類任務建立方式。&lt;/p&gt;
&lt;p&gt;第一類是 &lt;code&gt;AI判断&lt;/code&gt;。&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;成色要好，描述裡不能有進水、維修、暗病。&lt;/li&gt;
&lt;li&gt;優先同城，能面交更好。&lt;/li&gt;
&lt;li&gt;圖片裡要能看到序列號、包裝或關鍵配件。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;第二類是 &lt;code&gt;关键词判断&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;它更接近傳統規則監控：根據關鍵字、價格、地區等條件直接建立任務，不經過 AI 生成流程。適合規則簡單、誤報可以接受的場景。&lt;/p&gt;
&lt;p&gt;實際使用中可以混合使用：關鍵字負責初篩，AI 負責減少誤報。&lt;/p&gt;
&lt;h2 id=&#34;web-ui-能做什麼&#34;&gt;Web UI 能做什麼
&lt;/h2&gt;&lt;p&gt;Web UI 是這個專案區別於普通腳本的重要部分。&lt;/p&gt;
&lt;p&gt;任務管理頁可以配置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AI 建立任務。&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;
&lt;li&gt;帳號綁定。&lt;/li&gt;
&lt;li&gt;定時規則。&lt;/li&gt;
&lt;/ul&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;刪除帳號。&lt;/li&gt;
&lt;li&gt;為任務指定帳號。&lt;/li&gt;
&lt;li&gt;讓系統自動選擇帳號。&lt;/li&gt;
&lt;/ul&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;查詢歷史記錄。&lt;/li&gt;
&lt;li&gt;查看任務運行過程。&lt;/li&gt;
&lt;li&gt;排查登入態失效、風控和 AI 調用問題。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;系統設定頁可以：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;查看系統狀態。&lt;/li&gt;
&lt;li&gt;編輯 Prompt。&lt;/li&gt;
&lt;li&gt;調整代理和輪換配置。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;對於長期監控來說，Web UI 很關鍵。否則任務一多，配置、日誌、結果和通知都會變得難維護。&lt;/p&gt;
&lt;h2 id=&#34;資料儲存&#34;&gt;資料儲存
&lt;/h2&gt;&lt;p&gt;專案目前在線主儲存使用 SQLite，預設路徑是：&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;data/app.sqlite3
&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;Docker 預設把 SQLite 主庫掛載到：&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;./data:/app/data
&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;config.json&lt;/code&gt;、&lt;code&gt;jsonl/&lt;/code&gt;、&lt;code&gt;price_history/&lt;/code&gt; 匯入一次歷史資料。&lt;/p&gt;
&lt;p&gt;需要注意的是，&lt;code&gt;state/&lt;/code&gt;、&lt;code&gt;prompts/&lt;/code&gt;、&lt;code&gt;logs/&lt;/code&gt;、&lt;code&gt;images/&lt;/code&gt; 仍然是檔案系統目錄，不在 SQLite 中。商品圖片會臨時保存到類似下面的目錄：&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;images/task_images_&amp;lt;task_name&amp;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;/p&gt;
&lt;p&gt;這種結構比較適合個人或小團隊部署：SQLite 足夠輕，遷移也簡單；檔案目錄保留登入態、圖片和日誌，排查問題更直觀。&lt;/p&gt;
&lt;h2 id=&#34;通知渠道&#34;&gt;通知渠道
&lt;/h2&gt;&lt;p&gt;專案支援多種通知渠道，常見配置包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;NTFY_TOPIC_URL&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GOTIFY_URL&lt;/code&gt; / &lt;code&gt;GOTIFY_TOKEN&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;BARK_URL&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WX_BOT_URL&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TELEGRAM_BOT_TOKEN&lt;/code&gt; / &lt;code&gt;TELEGRAM_CHAT_ID&lt;/code&gt; / &lt;code&gt;TELEGRAM_API_BASE_URL&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WEBHOOK_*&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;通知是這類工具的核心體驗。監控系統如果只把結果寫進後台，使用者仍然需要反覆打開頁面查看；有推送之後，命中商品才能在第一時間觸達。&lt;/p&gt;
&lt;p&gt;更實用的配置方式是按商品價值分層：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;普通關鍵字命中只寫入後台。&lt;/li&gt;
&lt;li&gt;AI 高置信度結果推送到手機。&lt;/li&gt;
&lt;li&gt;高價值商品推送到企業微信或 Telegram。&lt;/li&gt;
&lt;li&gt;調試階段開啟更多日誌，穩定後減少噪音。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;開發者運行&#34;&gt;開發者運行
&lt;/h2&gt;&lt;p&gt;如果不使用 Docker，本地開發需要：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Python 3.10+&lt;/li&gt;
&lt;li&gt;Node.js + npm&lt;/li&gt;
&lt;li&gt;Playwright CLI&lt;/li&gt;
&lt;li&gt;Chromium 或 Chrome / Edge 瀏覽器&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;基礎命令：&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;/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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git clone https://github.com/Usagi-org/ai-goofish-monitor
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; ai-goofish-monitor
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cp .env.example .env
&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;/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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;chmod +x start.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;./start.sh
&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;start.sh&lt;/code&gt; 會檢查 Playwright CLI 和瀏覽器條件，自動安裝依賴、建置前端、複製建置產物並啟動後端。&lt;/p&gt;
&lt;p&gt;手動啟動後端：&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;python -m src.app
&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;/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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;uvicorn src.app:app --host 0.0.0.0 --port &lt;span class=&#34;m&#34;&gt;8000&lt;/span&gt; --reload
&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;/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;/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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; web-ui
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm install
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm run dev
&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;/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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PYTEST_DISABLE_PLUGIN_AUTOLOAD&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; pytest
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; web-ui &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run build
&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;h2 id=&#34;適合哪些人&#34;&gt;適合哪些人
&lt;/h2&gt;&lt;p&gt;ai-goofish-monitor 適合這些使用者：&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;有 OpenAI 相容模型 API，並願意為 AI 判斷支付調用成本的人。&lt;/li&gt;
&lt;li&gt;熟悉 Docker 或基本命令列部署的人。&lt;/li&gt;
&lt;li&gt;需要把命中結果推送到手機、企業微信或 Telegram 的使用者。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它不太適合這些情況：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;完全不懂部署，只想要一個即開即用 App。&lt;/li&gt;
&lt;li&gt;不願意處理登入態、驗證碼和帳號風控。&lt;/li&gt;
&lt;li&gt;需要官方授權、強合規的資料介面。&lt;/li&gt;
&lt;li&gt;想大規模高頻抓取平台資料。&lt;/li&gt;
&lt;li&gt;希望 AI 自動判斷交易風險並替你下單。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;使用風險和邊界&#34;&gt;使用風險和邊界
&lt;/h2&gt;&lt;p&gt;這類工具一定要注意邊界。&lt;/p&gt;
&lt;p&gt;第一，遵守平台規則。&lt;/p&gt;
&lt;p&gt;閒魚有自己的服務條款、風控策略和帳號安全機制。自動化存取可能觸發限制。不要高頻抓取，不要繞過風控，不要把它用於騷擾賣家、批量採集隱私或破壞平台秩序。&lt;/p&gt;
&lt;p&gt;第二，保護帳號登入態。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;state/&lt;/code&gt; 裡保存的是登入狀態 cookie 文件。它本質上等同於帳號存取憑證，不能提交到 Git 倉庫，也不要放到不可信伺服器上。伺服器如果暴露在公網，Web UI 必須修改預設密碼，並建議放在 VPN、反向代理鑑權或內網之後。&lt;/p&gt;
&lt;p&gt;第三，AI 判斷不是事實保證。&lt;/p&gt;
&lt;p&gt;AI 可以幫你減少誤報，但不能保證商品真實、賣家可信、價格合理或交易安全。最終仍然要人工看商品詳情、賣家評價、聊天記錄、發貨方式和支付流程。&lt;/p&gt;
&lt;p&gt;第四，注意成本。&lt;/p&gt;
&lt;p&gt;如果每個候選商品都交給多模態模型分析，調用成本可能很快上升。建議先用關鍵字、價格和區域做強篩選，再把少量候選交給 AI。&lt;/p&gt;
&lt;p&gt;第五，注意隱私。&lt;/p&gt;
&lt;p&gt;商品截圖、聊天相關內容、帳號狀態和通知內容都可能包含敏感資訊。通知 Webhook、日誌目錄和資料庫都要妥善保護。&lt;/p&gt;
&lt;h2 id=&#34;和普通腳本的差別&#34;&gt;和普通腳本的差別
&lt;/h2&gt;&lt;p&gt;普通閒魚監控腳本通常只做三件事：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;搜尋關鍵字。&lt;/li&gt;
&lt;li&gt;判斷價格。&lt;/li&gt;
&lt;li&gt;發通知。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;ai-goofish-monitor 更進一步：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用 Web UI 管理任務和帳號。&lt;/li&gt;
&lt;li&gt;用 AI Prompt 表達複雜購買標準。&lt;/li&gt;
&lt;li&gt;用多模態模型看商品圖和描述。&lt;/li&gt;
&lt;li&gt;用 SQLite 保存結果和價格歷史。&lt;/li&gt;
&lt;li&gt;用日誌頁排查任務失敗原因。&lt;/li&gt;
&lt;li&gt;用代理輪換和多帳號機制提高穩定性。&lt;/li&gt;
&lt;li&gt;用定時任務支援長期運行。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也正因為功能更多，它的部署和維護成本更高。對普通使用者來說，Docker 部署是最省事的方式；對開發者來說，Web UI、FastAPI、Playwright、SQLite 這套結構也比較容易二次開發。&lt;/p&gt;
&lt;h2 id=&#34;可以怎麼用&#34;&gt;可以怎麼用
&lt;/h2&gt;&lt;p&gt;比較實用的使用方式是從小任務開始。&lt;/p&gt;
&lt;p&gt;比如你想找一台二手相機，可以先建立一個任務：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;關鍵字：&lt;code&gt;A7C&lt;/code&gt;、&lt;code&gt;索尼 A7C&lt;/code&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;AI 標準：排除單鏡頭、排除維修機、排除明顯配件、關注快門數和成色&lt;/li&gt;
&lt;li&gt;通知：只推送 AI 判斷通過的結果&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;穩定運行後，再逐步增加任務數量。不要一開始就上幾十個關鍵字、多個帳號和高頻 Cron。先看登入態穩定性、誤報率、AI 成本和通知噪音，再調參數。&lt;/p&gt;
&lt;h2 id=&#34;總結&#34;&gt;總結
&lt;/h2&gt;&lt;p&gt;ai-goofish-monitor 把閒魚監控從「關鍵字腳本」推進到了「可管理的 AI 監控系統」。它用 Playwright 處理頁面自動化，用 AI 處理複雜判斷，用 Web UI 管理任務和結果，用 SQLite 保存資料，再透過多種通知渠道把結果推送出來。&lt;/p&gt;
&lt;p&gt;它最適合個人或小團隊做特定商品監控，尤其是二手數位產品、硬體、攝影器材這類價格波動大、發布時間敏感、描述噪音多的品類。&lt;/p&gt;
&lt;p&gt;但它也需要謹慎使用：登入態要保護，預設密碼要改，抓取頻率要克制，AI 結果要人工複核，平台規則和隱私邊界不能忽視。把它當成輔助篩選工具，它會很有價值；把它當成全自動交易系統，就容易高估它的能力。&lt;/p&gt;
&lt;p&gt;參考連結：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/Usagi-org/ai-goofish-monitor&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Usagi-org/ai-goofish-monitor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/Usagi-org/ai-goofish-monitor/blob/master/README_EN.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;專案英文 README&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/Usagi-org/ai-goofish-monitor/blob/master/DISCLAIMER.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;專案免責聲明&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Playwright CLI 視訊錄製：錄屏、章節標記、Overlay 與除錯取捨</title>
        <link>https://knightli.com/zh-tw/2026/04/15/playwright-cli-video-recording/</link>
        <pubDate>Wed, 15 Apr 2026 08:22:45 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/04/15/playwright-cli-video-recording/</guid>
        <description>&lt;p&gt;如果你想把瀏覽器自動化過程錄成影片，用來做除錯、文件示範，或作為執行結果留存，&lt;code&gt;Playwright CLI&lt;/code&gt; 已經提供了相當直接的做法。它輸出的是 WebM 影片，編碼為 VP8/VP9。&lt;/p&gt;
&lt;p&gt;這篇按照官方 &lt;code&gt;video-recording&lt;/code&gt; 參考文件整理，重點包括基礎錄製流程、章節標記、完整 hero script 錄製、Overlay API，以及 video 與 tracing 的差異。文中的命令列、程式碼片段與參數說明均按參考內容保留。&lt;/p&gt;
&lt;h2 id=&#34;01-基礎錄製流程&#34;&gt;01 基礎錄製流程
&lt;/h2&gt;&lt;p&gt;最基本的流程就是：先打開瀏覽器，再開始錄製，執行操作，最後停止並保存。&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;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Open browser first&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli open
&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;c1&#34;&gt;# Start recording&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli video-start demo.webm
&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;c1&#34;&gt;# Add a chapter marker for section transitions&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli video-chapter &lt;span class=&#34;s2&#34;&gt;&amp;#34;Getting Started&amp;#34;&lt;/span&gt; --description&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Opening the homepage&amp;#34;&lt;/span&gt; --duration&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2000&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;c1&#34;&gt;# Navigate and perform actions&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli goto https://example.com
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli snapshot
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli click e1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Add another chapter&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli video-chapter &lt;span class=&#34;s2&#34;&gt;&amp;#34;Filling Form&amp;#34;&lt;/span&gt; --description&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Entering test data&amp;#34;&lt;/span&gt; --duration&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli fill e2 &lt;span class=&#34;s2&#34;&gt;&amp;#34;test input&amp;#34;&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;c1&#34;&gt;# Stop and save&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli video-stop
&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;video-chapter&lt;/code&gt; 很適合在不同階段之間插入章節卡片，讓錄出來的影片更容易理解。&lt;/p&gt;
&lt;h2 id=&#34;02-最佳實務&#34;&gt;02 最佳實務
&lt;/h2&gt;&lt;h3 id=&#34;1-使用描述性檔名&#34;&gt;1. 使用描述性檔名
&lt;/h3&gt;&lt;p&gt;如果影片是要給別人看，或之後還要回頭查找，檔名最好直接帶上場景和上下文。&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;/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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Include context in filename&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli video-start recordings/login-flow-2024-01-15.webm
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli video-start recordings/checkout-test-run-42.webm
&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;h3 id=&#34;2-錄製完整-hero-script&#34;&gt;2. 錄製完整 hero script
&lt;/h3&gt;&lt;p&gt;官方建議：如果影片是要交付給使用者，或作為 proof of work，最好把場景整理成一段程式碼，再用 &lt;code&gt;run-code&lt;/code&gt; 執行。這樣比較容易控制動作節奏、停頓時機，以及影片中的標註效果。參考文件也提到，Playwright 新增了一些特別適合這類錄製流程的 API。&lt;/p&gt;
&lt;p&gt;建議流程如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先用 CLI 走一遍場景，並記下所有 locator 和 action。之後如果要做高亮，會需要用這些 locator 取得對應的 bounding box。&lt;/li&gt;
&lt;li&gt;為影片另外建立一個腳本檔案，並依照下面的方式撰寫。輸入內容時用 &lt;code&gt;pressSequentially&lt;/code&gt; 搭配 &lt;code&gt;delay&lt;/code&gt;，停頓時間也盡量安排得自然。&lt;/li&gt;
&lt;li&gt;使用 &lt;code&gt;playwright-cli run-code --filename your-script.js&lt;/code&gt; 執行。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Important: Overlays are &lt;code&gt;pointer-events: none&lt;/code&gt; — they do not interfere with page interactions. You can safely keep sticky overlays visible while clicking, filling, or performing any actions on the page.&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;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;42
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;43
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;44
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;45
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;46
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;47
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;48
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;49
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;50
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;51
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;52
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;53
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;54
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;55
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;56
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;57
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;58
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;59
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;60
&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-js&#34; data-lang=&#34;js&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;page&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;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;screencast&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;start&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;video.webm&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1280&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;height&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;800&lt;/span&gt; &lt;span class=&#34;p&#34;&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;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://demo.playwright.dev/todomvc&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;c1&#34;&gt;// Show a chapter card — blurs the page and shows a dialog.
&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;c1&#34;&gt;// Blocks until duration expires, then auto-removes.
&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;c1&#34;&gt;// Use this for simple use cases, but always feel free to hand-craft your own beautiful
&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;c1&#34;&gt;// overlay via await page.screencast.showOverlay().
&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;screencast&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;showChapter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Adding Todo Items&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&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;nx&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;We will add several items to the todo list.&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;nx&#34;&gt;duration&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2000&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;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;c1&#34;&gt;// Perform action
&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;getByRole&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;textbox&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;What needs to be done?&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;pressSequentially&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Walk the dog&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;delay&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;60&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;getByRole&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;textbox&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;What needs to be done?&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;press&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Enter&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;waitForTimeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1000&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;c1&#34;&gt;// Show next chapter
&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;screencast&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;showChapter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Verifying Results&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&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;nx&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;Checking the item appeared in the list.&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;nx&#34;&gt;duration&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2000&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;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;c1&#34;&gt;// Add a sticky annotation that stays while you perform actions.
&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;c1&#34;&gt;// Overlays are pointer-events: none, so they won&amp;#39;t block clicks.
&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;annotation&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;page&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;screencast&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;showOverlay&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sb&#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;sb&#34;&gt;    &amp;lt;div style=&amp;#34;position: absolute; top: 8px; right: 8px;
&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;sb&#34;&gt;      padding: 6px 12px; background: rgba(0,0,0,0.7);
&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;sb&#34;&gt;      border-radius: 8px; font-size: 13px; color: white;&amp;#34;&amp;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;sb&#34;&gt;      ✓ Item added successfully
&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;sb&#34;&gt;    &amp;lt;/div&amp;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;sb&#34;&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;c1&#34;&gt;// Perform more actions while the annotation is visible
&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;getByRole&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;textbox&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;What needs to be done?&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;pressSequentially&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Buy groceries&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;delay&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;60&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;getByRole&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;textbox&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;What needs to be done?&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;press&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Enter&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;waitForTimeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1500&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;c1&#34;&gt;// Remove the annotation when done
&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;annotation&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;dispose&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;c1&#34;&gt;// You can also highlight relevant locators and provide contextual annotations.
&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;bounds&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;page&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getByText&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Walk the dog&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;boundingBox&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;screencast&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;showOverlay&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sb&#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;sb&#34;&gt;    &amp;lt;div style=&amp;#34;position: absolute;
&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;sb&#34;&gt;      top: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;bounds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;px;
&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;sb&#34;&gt;      left: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;bounds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;px;
&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;sb&#34;&gt;      width: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;bounds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;px;
&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;sb&#34;&gt;      height: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;bounds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;height&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;px;
&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;sb&#34;&gt;      border: 1px solid red;&amp;#34;&amp;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;sb&#34;&gt;    &amp;lt;/div&amp;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;sb&#34;&gt;    &amp;lt;div style=&amp;#34;position: absolute;
&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;sb&#34;&gt;      top: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;bounds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;bounds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;height&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;px;
&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;sb&#34;&gt;      left: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;bounds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;bounds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;width&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;px;
&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;sb&#34;&gt;      transform: translateX(-50%);
&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;sb&#34;&gt;      padding: 6px;
&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;sb&#34;&gt;      background: #808080;
&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;sb&#34;&gt;      border-radius: 10px;
&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;sb&#34;&gt;      font-size: 14px;
&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;sb&#34;&gt;      color: white;&amp;#34;&amp;gt;Check it out, it is right above this text
&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;sb&#34;&gt;    &amp;lt;/div&amp;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;sb&#34;&gt;  `&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;duration&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2000&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;screencast&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;stop&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;這段程式碼的價值不只是「錄下來」，而是把影片做得更清楚：章節卡片負責分段，&lt;code&gt;pressSequentially&lt;/code&gt; 讓輸入更自然，&lt;code&gt;showOverlay&lt;/code&gt; 則能提供提示、高亮與說明。&lt;/p&gt;
&lt;p&gt;文件最後也補了一句：Embrace creativity, overlays are powerful.&lt;/p&gt;
&lt;h2 id=&#34;03-overlay-api-速覽&#34;&gt;03 Overlay API 速覽
&lt;/h2&gt;&lt;p&gt;錄製影片時，Overlay API 很適合拿來做章節切換、局部提示與持續註解。官方給出的摘要如下：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Method&lt;/th&gt;
          &lt;th&gt;Use Case&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;page.screencast.showChapter(title, { description?, duration?, styleSheet? })&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Full-screen chapter card with blurred backdrop — ideal for section transitions&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;page.screencast.showOverlay(html, { duration? })&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Custom HTML overlay — use for callouts, labels, highlights&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;disposable.dispose()&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Remove a sticky overlay added without duration&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;page.screencast.hideOverlays()&lt;/code&gt; / &lt;code&gt;page.screencast.showOverlays()&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Temporarily hide/show all overlays&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;如果你的目標是把自動化過程做成「可觀看的影片」，這組 API 基本就是最值得優先掌握的部分。&lt;/p&gt;
&lt;h2 id=&#34;04-tracing-和-video-的差異&#34;&gt;04 Tracing 和 Video 的差異
&lt;/h2&gt;&lt;p&gt;官方文件把兩者的定位區分得很清楚：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Feature&lt;/th&gt;
          &lt;th&gt;Video&lt;/th&gt;
          &lt;th&gt;Tracing&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Output&lt;/td&gt;
          &lt;td&gt;WebM file&lt;/td&gt;
          &lt;td&gt;Trace file (viewable in Trace Viewer)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Shows&lt;/td&gt;
          &lt;td&gt;Visual recording&lt;/td&gt;
          &lt;td&gt;DOM snapshots, network, console, actions&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Use case&lt;/td&gt;
          &lt;td&gt;Demos, documentation&lt;/td&gt;
          &lt;td&gt;Debugging, analysis&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Size&lt;/td&gt;
          &lt;td&gt;Larger&lt;/td&gt;
          &lt;td&gt;Smaller&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;可以簡單這樣理解：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;video&lt;/code&gt; 更適合示範、交付與回看「使用者看到的過程」&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tracing&lt;/code&gt; 更適合排查問題、檢查動作細節，以及分析執行上下文&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;兩者不是互相取代，而是各自對應不同目標。&lt;/p&gt;
&lt;h2 id=&#34;05-使用限制&#34;&gt;05 使用限制
&lt;/h2&gt;&lt;p&gt;文件裡也提醒了兩個很實際的限制：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Recording adds slight overhead to automation&lt;/li&gt;
&lt;li&gt;Large recordings can consume significant disk space&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也就是說，錄製功能雖然很好用，但會替自動化流程增加一些額外開銷；如果影片很長，磁碟占用也會明顯上升。&lt;/p&gt;
&lt;h2 id=&#34;06-快速總結&#34;&gt;06 快速總結
&lt;/h2&gt;&lt;p&gt;如果只抓重點，可以記住下面幾件事：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;video-start&lt;/code&gt; / &lt;code&gt;video-stop&lt;/code&gt; 對應最基本的影片錄製流程&lt;/li&gt;
&lt;li&gt;&lt;code&gt;video-chapter&lt;/code&gt; 可以替影片加上章節過渡，讓示範更清楚&lt;/li&gt;
&lt;li&gt;更進階的錄製場景，適合寫成腳本後用 &lt;code&gt;run-code&lt;/code&gt; 執行&lt;/li&gt;
&lt;li&gt;&lt;code&gt;showOverlay&lt;/code&gt; 和 &lt;code&gt;showChapter&lt;/code&gt; 可以明顯提升影片可讀性&lt;/li&gt;
&lt;li&gt;&lt;code&gt;video&lt;/code&gt; 適合示範，&lt;code&gt;tracing&lt;/code&gt; 適合除錯，最好依目標選擇&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你已經在用 &lt;code&gt;Playwright CLI&lt;/code&gt; 做自動化示範、驗收留存或 proof of work，那麼 &lt;code&gt;video recording&lt;/code&gt; 會是一塊很值得補上的能力。&lt;/p&gt;
&lt;h2 id=&#34;參考連結&#34;&gt;參考連結
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Playwright CLI video-recording 參考文件：https://github.com/microsoft/playwright-cli/blob/main/skills/playwright-cli/references/video-recording.md&lt;/li&gt;
&lt;li&gt;Playwright CLI 專案首頁：https://github.com/microsoft/playwright-cli&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Playwright CLI 會話管理：多瀏覽器會話、隔離、持久化與清理</title>
        <link>https://knightli.com/zh-tw/2026/04/15/playwright-cli-session-management/</link>
        <pubDate>Wed, 15 Apr 2026 08:15:12 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/04/15/playwright-cli-session-management/</guid>
        <description>&lt;p&gt;如果你在用 &lt;code&gt;Playwright CLI&lt;/code&gt; 做自動化，很快就會碰到一個實際問題：同一時間裡，能不能開多個互不干擾的瀏覽器會話？答案是可以，而且 &lt;code&gt;Playwright CLI&lt;/code&gt; 已經把這套機制做得很直接。&lt;/p&gt;
&lt;p&gt;這篇就按照官方 &lt;code&gt;session-management&lt;/code&gt; 參考文件，整理它最實用的幾個部分：命名會話、會話隔離、持久化 profile、並發模式，以及常見清理命令。文中的命令列與命令區塊說明均按參考內容保留。&lt;/p&gt;
&lt;h2 id=&#34;01-命名瀏覽器會話&#34;&gt;01 命名瀏覽器會話
&lt;/h2&gt;&lt;p&gt;官方建議用 &lt;code&gt;-s&lt;/code&gt; 參數隔離不同瀏覽器上下文：&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;/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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Browser 1: Authentication flow&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli -s&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;auth open https://app.example.com/login
&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;c1&#34;&gt;# Browser 2: Public browsing (separate cookies, storage)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli -s&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;public open https://example.com
&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;c1&#34;&gt;# Commands are isolated by browser session&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli -s&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;auth fill e1 &lt;span class=&#34;s2&#34;&gt;&amp;#34;user@example.com&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli -s&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;public snapshot
&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;session&lt;/code&gt; 名稱對應不同瀏覽器上下文。你可以把 &lt;code&gt;auth&lt;/code&gt; 用在登入流程，把 &lt;code&gt;public&lt;/code&gt; 用在匿名存取，它們之間不會共用 cookies 或本地狀態。&lt;/p&gt;
&lt;h2 id=&#34;02-瀏覽器會話隔離了什麼&#34;&gt;02 瀏覽器會話隔離了什麼
&lt;/h2&gt;&lt;p&gt;每個瀏覽器會話都會獨立維護下面這些內容：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cookies&lt;/li&gt;
&lt;li&gt;LocalStorage / SessionStorage&lt;/li&gt;
&lt;li&gt;IndexedDB&lt;/li&gt;
&lt;li&gt;Cache&lt;/li&gt;
&lt;li&gt;Browsing history&lt;/li&gt;
&lt;li&gt;Open tabs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這意味著如果你在 &lt;code&gt;auth&lt;/code&gt; 會話裡登入了某個網站，並不會自動影響 &lt;code&gt;public&lt;/code&gt; 會話。做多帳號測試、登入態驗證、匿名對比時，這一點尤其重要。&lt;/p&gt;
&lt;h2 id=&#34;03-瀏覽器會話相關命令&#34;&gt;03 瀏覽器會話相關命令
&lt;/h2&gt;&lt;p&gt;官方文件把會話管理裡最常用的一組命令放在了一起：&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;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# List all browser sessions&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli list
&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;c1&#34;&gt;# Stop a browser session (close the browser)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli close                 &lt;span class=&#34;c1&#34;&gt;# stop the default browser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli -s&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;mysession close   &lt;span class=&#34;c1&#34;&gt;# stop a named browser&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;c1&#34;&gt;# Stop all browser sessions&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli close-all
&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;c1&#34;&gt;# Forcefully kill all daemon processes (for stale/zombie processes)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli kill-all
&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;c1&#34;&gt;# Delete browser session user data (profile directory)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli delete-data              &lt;span class=&#34;c1&#34;&gt;# delete default browser data&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli -s&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;mysession delete-data &lt;span class=&#34;c1&#34;&gt;# delete named browser data&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;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;list&lt;/code&gt;：看目前有哪些會話&lt;/li&gt;
&lt;li&gt;&lt;code&gt;close&lt;/code&gt; / &lt;code&gt;close-all&lt;/code&gt; / &lt;code&gt;kill-all&lt;/code&gt;：結束會話或清理卡住的瀏覽器程序&lt;/li&gt;
&lt;li&gt;&lt;code&gt;delete-data&lt;/code&gt;：刪除某個會話對應的使用者資料目錄&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你只是結束瀏覽器，通常先用 &lt;code&gt;close&lt;/code&gt;；如果已經出現殘留程序或殭屍程序，再用 &lt;code&gt;kill-all&lt;/code&gt; 會更合適。&lt;/p&gt;
&lt;h2 id=&#34;04-用環境變數設定預設會話&#34;&gt;04 用環境變數設定預設會話
&lt;/h2&gt;&lt;p&gt;如果你不想每條命令都重複寫 &lt;code&gt;-s=mysession&lt;/code&gt;，官方還提供了環境變數方式：&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;PLAYWRIGHT_CLI_SESSION&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;mysession&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli open example.com  &lt;span class=&#34;c1&#34;&gt;# Uses &amp;#34;mysession&amp;#34; automatically&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;-s&lt;/code&gt; 時，命令就會預設使用 &lt;code&gt;mysession&lt;/code&gt; 這個瀏覽器會話。&lt;/p&gt;
&lt;h2 id=&#34;05-常見模式並發抓取&#34;&gt;05 常見模式：並發抓取
&lt;/h2&gt;&lt;p&gt;參考文件給了一個很典型的並發抓取例子：&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;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#!/bin/bash
&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;c1&#34;&gt;# Scrape multiple sites concurrently&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;c1&#34;&gt;# Start all browsers&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli -s&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;site1 open https://site1.com &lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli -s&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;site2 open https://site2.com &lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli -s&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;site3 open https://site3.com &lt;span class=&#34;p&#34;&gt;&amp;amp;&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;nb&#34;&gt;wait&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;c1&#34;&gt;# Take snapshots from each&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli -s&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;site1 snapshot
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli -s&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;site2 snapshot
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli -s&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;site3 snapshot
&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;c1&#34;&gt;# Cleanup&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli close-all
&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;/p&gt;
&lt;h2 id=&#34;06-常見模式ab-測試會話&#34;&gt;06 常見模式：A/B 測試會話
&lt;/h2&gt;&lt;p&gt;另一個常見場景，是同時對比不同實驗版本：&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;/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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Test different user experiences&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli -s&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;variant-a open &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://app.com?variant=a&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli -s&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;variant-b open &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://app.com?variant=b&amp;#34;&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;c1&#34;&gt;# Compare&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli -s&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;variant-a screenshot
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli -s&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;variant-b screenshot
&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;這種寫法很適合做 A/B 頁面差異對比，因為兩個版本在獨立會話裡運行，截圖和狀態檢查也更容易分開管理。&lt;/p&gt;
&lt;h2 id=&#34;07-持久化瀏覽器-profile&#34;&gt;07 持久化瀏覽器 profile
&lt;/h2&gt;&lt;p&gt;官方文件特別說明：預設情況下，瀏覽器 profile 只保存在記憶體裡。&lt;/p&gt;
&lt;p&gt;如果你希望把瀏覽器 profile 持久化到磁碟，需要在 &lt;code&gt;open&lt;/code&gt; 時加上 &lt;code&gt;--persistent&lt;/code&gt;：&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;/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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Use persistent profile (auto-generated location)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli open https://example.com --persistent
&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;c1&#34;&gt;# Use persistent profile with custom directory&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli open https://example.com --profile&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/path/to/profile
&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;這個能力適合需要長期複用登入態、本地快取或擴充除錯環境的場景。尤其在反覆除錯同一站點時，持久化 profile 往往會比每次從零開始更高效。&lt;/p&gt;
&lt;h2 id=&#34;08-預設瀏覽器會話&#34;&gt;08 預設瀏覽器會話
&lt;/h2&gt;&lt;p&gt;如果沒有顯式傳入 &lt;code&gt;-s&lt;/code&gt;，那麼命令會使用預設瀏覽器會話：&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;/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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# These use the same default browser session&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli open https://example.com
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli snapshot
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli close  &lt;span class=&#34;c1&#34;&gt;# Stops default browser&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;-s&lt;/code&gt; 的幾條命令預設是在同一個預設會話裡連續執行的。&lt;/p&gt;
&lt;h2 id=&#34;09-打開時附帶會話配置&#34;&gt;09 打開時附帶會話配置
&lt;/h2&gt;&lt;p&gt;除了會話名，官方也給出了幾種常見的啟動配置方式：&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Open with config file&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli open https://example.com --config&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;.playwright/my-cli.json
&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;c1&#34;&gt;# Open with specific browser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli open https://example.com --browser&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;firefox
&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;c1&#34;&gt;# Open in headed mode&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli open https://example.com --headed
&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;c1&#34;&gt;# Open with persistent profile&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli open https://example.com --persistent
&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;firefox&lt;/code&gt;，或者讓某個會話始終以 &lt;code&gt;headed&lt;/code&gt; 模式啟動，方便人工觀察。&lt;/p&gt;
&lt;h2 id=&#34;10-官方給出的最佳實務&#34;&gt;10 官方給出的最佳實務
&lt;/h2&gt;&lt;p&gt;參考文件列了三條很實用的最佳實務。&lt;/p&gt;
&lt;h3 id=&#34;1-用有語義的會話名&#34;&gt;1. 用有語義的會話名
&lt;/h3&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;/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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# GOOD: Clear purpose&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli -s&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;github-auth open https://github.com
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli -s&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;docs-scrape open https://docs.example.com
&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;c1&#34;&gt;# AVOID: Generic names&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli -s&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;s1 open https://github.com
&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;github-auth&lt;/code&gt;、&lt;code&gt;docs-scrape&lt;/code&gt; 這種名字，後面維護腳本時會清楚很多。&lt;/p&gt;
&lt;h3 id=&#34;2-用完及時清理&#34;&gt;2. 用完及時清理
&lt;/h3&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;/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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Stop browsers when done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli -s&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;auth close
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli -s&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;scrape close
&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;c1&#34;&gt;# Or stop all at once&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli close-all
&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;c1&#34;&gt;# If browsers become unresponsive or zombie processes remain&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli kill-all
&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;/p&gt;
&lt;h3 id=&#34;3-刪除陳舊瀏覽器資料&#34;&gt;3. 刪除陳舊瀏覽器資料
&lt;/h3&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Remove old browser data to free disk space&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli -s&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;oldsession delete-data
&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;/p&gt;
&lt;h2 id=&#34;11-快速總結&#34;&gt;11 快速總結
&lt;/h2&gt;&lt;p&gt;如果只抓重點，可以記住下面這幾件事：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-s=&amp;lt;name&amp;gt;&lt;/code&gt; 用來建立並使用獨立瀏覽器會話&lt;/li&gt;
&lt;li&gt;不同會話之間會隔離 cookies、各種儲存、快取、歷史紀錄和分頁&lt;/li&gt;
&lt;li&gt;&lt;code&gt;close-all&lt;/code&gt; 適合統一關閉，&lt;code&gt;kill-all&lt;/code&gt; 適合處理異常殘留程序&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--persistent&lt;/code&gt; 用來把 profile 落盤，適合長期複用狀態&lt;/li&gt;
&lt;li&gt;會話名盡量語義化，舊資料定期清理&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你的工作流裡已經有登入態複用、多帳號並行、A/B 對比或批次抓取需求，那麼 &lt;code&gt;session management&lt;/code&gt; 基本就是 &lt;code&gt;Playwright CLI&lt;/code&gt; 裡最值得先掌握的一塊能力。&lt;/p&gt;
&lt;h2 id=&#34;參考連結&#34;&gt;參考連結
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Playwright CLI session-management 參考文件：https://github.com/microsoft/playwright-cli/blob/main/skills/playwright-cli/references/session-management.md&lt;/li&gt;
&lt;li&gt;Playwright CLI 專案首頁：https://github.com/microsoft/playwright-cli&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Playwright CLI storage state 用法：保存登入狀態、讀取 Cookies 與本地儲存</title>
        <link>https://knightli.com/zh-tw/2026/04/14/playwright-cli-storage-state-commands/</link>
        <pubDate>Tue, 14 Apr 2026 22:19:55 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/04/14/playwright-cli-storage-state-commands/</guid>
        <description>&lt;p&gt;如果你用 &lt;code&gt;Playwright CLI&lt;/code&gt; 做瀏覽器自動化，&lt;code&gt;storage state&lt;/code&gt; 幾乎就是最常用的能力之一。它的作用很直接：把目前瀏覽器裡的登入狀態和本地狀態保存下來，後面繼續重用，避免每次都重新登入。&lt;/p&gt;
&lt;h2 id=&#34;01-保存目前的-storage-state&#34;&gt;01 保存目前的 storage state
&lt;/h2&gt;&lt;p&gt;最常見的情境，就是先登入一次，再把目前狀態匯出到檔案。&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli storage-state save auth.json
&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;這條命令會把目前瀏覽器 context 中的狀態保存到 &lt;code&gt;auth.json&lt;/code&gt;。之後如果想重用登入狀態，通常就是從這一步開始。&lt;/p&gt;
&lt;h2 id=&#34;02-載入既有的-storage-state&#34;&gt;02 載入既有的 storage state
&lt;/h2&gt;&lt;p&gt;已有狀態檔後，可以在啟動時直接載入。&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli --storage-state auth.json
&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;auth.json&lt;/code&gt; 裡的狀態啟動瀏覽器 context。最常見的用途，就是跳過重複登入，直接進入已登入環境。&lt;/p&gt;
&lt;h2 id=&#34;03-查看目前-cookies&#34;&gt;03 查看目前 cookies
&lt;/h2&gt;&lt;p&gt;如果你只是想確認目前 session 裡到底有哪些 cookies，可以直接查看。&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli cookies
&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;這條命令會列出目前 context 中的 cookies，適合用來排查登入狀態是否存在、cookie 是否寫入成功。&lt;/p&gt;
&lt;h2 id=&#34;04-設定-cookies&#34;&gt;04 設定 cookies
&lt;/h2&gt;&lt;p&gt;如果你已經有 cookie 資料，也可以直接寫入。&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli cookies &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;[{&amp;#34;name&amp;#34;:&amp;#34;session&amp;#34;,&amp;#34;value&amp;#34;:&amp;#34;abc&amp;#34;,&amp;#34;domain&amp;#34;:&amp;#34;example.com&amp;#34;,&amp;#34;path&amp;#34;:&amp;#34;/&amp;#34;}]&amp;#39;&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;這個用法適合調試驗證流程、重現特定 session，或在腳本執行前手動注入 cookie 條件。&lt;/p&gt;
&lt;h2 id=&#34;05-讀取-localstorage&#34;&gt;05 讀取 localStorage
&lt;/h2&gt;&lt;p&gt;有些網站的登入狀態或前端狀態不只存在 cookies 裡，也會放在 &lt;code&gt;localStorage&lt;/code&gt;。&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli local-storage
&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;localStorage&lt;/code&gt; 內容。排查「明明像是登入了，但頁面行為還是不對」時，這一步很有用。&lt;/p&gt;
&lt;h2 id=&#34;06-寫入-localstorage&#34;&gt;06 寫入 localStorage
&lt;/h2&gt;&lt;p&gt;如果需要模擬某些前端狀態，也可以直接設定。&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli local-storage &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; token abc123
&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;localStorage&lt;/code&gt;。常見用途是注入 token、偏好設定或某些前端開關。&lt;/p&gt;
&lt;h2 id=&#34;07-讀取-sessionstorage&#34;&gt;07 讀取 sessionStorage
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;sessionStorage&lt;/code&gt; 適合查看目前 session 裡的暫時狀態。&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli session-storage
&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;sessionStorage&lt;/code&gt;。如果某個頁面流程依賴一次性的 session 資料，可以從這裡檢查。&lt;/p&gt;
&lt;h2 id=&#34;08-寫入-sessionstorage&#34;&gt;08 寫入 sessionStorage
&lt;/h2&gt;&lt;p&gt;需要時，也可以手動設定 &lt;code&gt;sessionStorage&lt;/code&gt;。&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli session-storage &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; key value
&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;/p&gt;
&lt;h2 id=&#34;09-查看-indexeddb&#34;&gt;09 查看 IndexedDB
&lt;/h2&gt;&lt;p&gt;對較重的 Web 應用來說，真正關鍵的本地資料可能在 &lt;code&gt;IndexedDB&lt;/code&gt; 裡。&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli indexed-db
&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;IndexedDB&lt;/code&gt; 資料。遇到複雜單頁應用、離線快取或本地資料庫式狀態時，可以優先檢查這裡。&lt;/p&gt;
&lt;h2 id=&#34;10-一個最實用的工作流&#34;&gt;10 一個最實用的工作流
&lt;/h2&gt;&lt;p&gt;如果你只是想穩定重用登入狀態，最簡單的流程通常是這樣：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先打開站點並手動完成登入。&lt;/li&gt;
&lt;li&gt;執行下面這條命令保存狀態：&lt;/li&gt;
&lt;/ol&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli storage-state save auth.json
&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;ol start=&#34;3&#34;&gt;
&lt;li&gt;後續執行時直接載入：&lt;/li&gt;
&lt;/ol&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli --storage-state auth.json
&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;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;playwright-cli cookies&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;playwright-cli local-storage&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;playwright-cli session-storage&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;playwright-cli indexed-db&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這個順序已經能覆蓋大部分「狀態沒有完整恢復」的問題。&lt;/p&gt;
&lt;h2 id=&#34;11-使用時要注意什麼&#34;&gt;11 使用時要注意什麼
&lt;/h2&gt;&lt;p&gt;有三點最值得注意：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;storage state&lt;/code&gt; 檔案本質上是敏感資料，裡面可能包含登入 cookie 或 token，不要隨便提交到倉庫。&lt;/li&gt;
&lt;li&gt;只恢復 cookies 不一定夠，很多現代網站還依賴 &lt;code&gt;localStorage&lt;/code&gt;、&lt;code&gt;sessionStorage&lt;/code&gt; 或 &lt;code&gt;IndexedDB&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;狀態檔不是永久有效，cookie 過期、帳號變更或環境切換後，通常都要重新生成。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;12-快速總結&#34;&gt;12 快速總結
&lt;/h2&gt;&lt;p&gt;如果只記一句話：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Playwright CLI&lt;/code&gt; 的 &lt;code&gt;storage state&lt;/code&gt;，就是把瀏覽器目前狀態保存下來，再在後續任務裡繼續使用。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;而在實際排查裡，最常用的一組命令就是這些：&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;/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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli storage-state save auth.json
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli --storage-state auth.json
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli cookies
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli local-storage
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli session-storage
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli indexed-db
&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;先保存，再載入；如果還是不對，再分層檢查 cookies 和各類本地儲存，基本就是這份參考文件最實用的部分。&lt;/p&gt;
&lt;h2 id=&#34;參考連結&#34;&gt;參考連結
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Playwright CLI storage-state 參考文件：https://github.com/microsoft/playwright-cli/blob/main/skills/playwright-cli/references/storage-state.md&lt;/li&gt;
&lt;li&gt;Playwright CLI 專案首頁：https://github.com/microsoft/playwright-cli&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Playwright CLI 使用入門：安裝、Skills、Session 管理與常用命令</title>
        <link>https://knightli.com/zh-tw/2026/04/12/playwright-cli-getting-started/</link>
        <pubDate>Sun, 12 Apr 2026 14:36:58 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/04/12/playwright-cli-getting-started/</guid>
        <description>&lt;p&gt;如果你最近在用 Claude Code、GitHub Copilot 或其他 coding agent 做瀏覽器自動化，&lt;code&gt;microsoft/playwright-cli&lt;/code&gt; 是一個很值得關注的新工具。它不是傳統意義上那種「給人手動敲命令用」的瀏覽器小工具，而是一個面向 coding agent 的 Playwright CLI，強調的是更低的 token 開銷、更輕量的命令介面，以及和 Skills 工作流的結合。&lt;/p&gt;
&lt;p&gt;從官方 README 來看，Playwright CLI 的核心思路很明確：相比 MCP 把大量工具 schema 和頁面結構塞進模型上下文，CLI 命令方式更緊湊，也更適合在大程式碼庫、測試任務與瀏覽器自動化之間來回切換的 agent 工作流。&lt;/p&gt;
&lt;h2 id=&#34;01-playwright-cli-是什麼&#34;&gt;01 Playwright CLI 是什麼
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;playwright-cli&lt;/code&gt; 是微軟開源的一個 Playwright 命令列工具，官方描述是「CLI for common Playwright actions」。它主要用來完成這些事情：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;開啟頁面並驅動瀏覽器&lt;/li&gt;
&lt;li&gt;錄製與生成 Playwright 程式碼&lt;/li&gt;
&lt;li&gt;抓取頁面快照，取得元素引用&lt;/li&gt;
&lt;li&gt;截圖、匯出 PDF&lt;/li&gt;
&lt;li&gt;搭配 coding agent 進行自動化測試與網頁操作&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;目前 GitHub README 對它的定位說得非常清楚：如果你正在使用 coding agents，CLI 往往比 Playwright MCP 更合適；如果你更需要持久狀態、豐富的 introspection 與長時間的 agentic loop，MCP 仍然有它的價值。&lt;/p&gt;
&lt;p&gt;換句話說，Playwright CLI 更像是「替 AI 編碼助手準備的瀏覽器自動化介面」，而不只是給人類工程師手動點網頁的工具。&lt;/p&gt;
&lt;h2 id=&#34;02-它的優點在哪裡&#34;&gt;02 它的優點在哪裡
&lt;/h2&gt;&lt;h3 id=&#34;1-更適合-agent-工作流&#34;&gt;1. 更適合 agent 工作流
&lt;/h3&gt;&lt;p&gt;官方 README 把第一個優點直接寫成 &lt;code&gt;Token-efficient&lt;/code&gt;。它不會強制把整頁資料都塞進 LLM 上下文，而是透過更短、更專用的命令讓 agent 操作瀏覽器。&lt;/p&gt;
&lt;p&gt;這對 coding agent 很重要。因為在真實專案裡，agent 不只是跑瀏覽器，還要讀程式碼、改檔案、跑測試、看日誌。如果瀏覽器工具本身就很「吃上下文」，整體效率會明顯下降。&lt;/p&gt;
&lt;h3 id=&#34;2-能和-skills-一起工作&#34;&gt;2. 能和 Skills 一起工作
&lt;/h3&gt;&lt;p&gt;README 裡特別強調了 &lt;code&gt;playwright-cli install --skills&lt;/code&gt;。這代表官方不是把它當成單純的 shell 工具，而是設計成可以被 Claude Code、GitHub Copilot 等 agent 直接使用的技能入口。&lt;/p&gt;
&lt;p&gt;如果你的工作流本來就建立在 Skills 之上，那 Playwright CLI 的接入會更自然。&lt;/p&gt;
&lt;h3 id=&#34;3-session-管理做得比較完整&#34;&gt;3. Session 管理做得比較完整
&lt;/h3&gt;&lt;p&gt;Playwright CLI 支援 session。預設情況下，瀏覽器 profile 保存在記憶體裡，同一個 session 內的 cookies 和 storage 會在多次 CLI 呼叫之間保留；如果加上 &lt;code&gt;--persistent&lt;/code&gt;，還可以把 profile 落到磁碟，跨瀏覽器重啟繼續使用。&lt;/p&gt;
&lt;p&gt;這讓它比「一條命令開瀏覽器，跑完就丟掉」的玩具型工具更實用，也更適合持續除錯與 agent 長流程執行。&lt;/p&gt;
&lt;h3 id=&#34;4-自帶可視化監控面板&#34;&gt;4. 自帶可視化監控面板
&lt;/h3&gt;&lt;p&gt;README 裡提供了 &lt;code&gt;playwright-cli show&lt;/code&gt;，用來打開一個 dashboard，觀察和控制所有執行中的瀏覽器 session。對於 agent 在背景跑自動化任務的場景，這一點很有價值，因為你可以隨時接手、觀察、排錯，而不是只能盲跑。&lt;/p&gt;
&lt;h2 id=&#34;03-安裝與環境要求&#34;&gt;03 安裝與環境要求
&lt;/h2&gt;&lt;p&gt;根據目前 GitHub README，Playwright CLI 的基本要求是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Node.js 18 或更高版本&lt;/li&gt;
&lt;li&gt;Claude Code、GitHub Copilot 或其他 coding agent&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;安裝命令如下：&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm install -g @playwright/cli@latest
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli --help
&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;/p&gt;
&lt;ul&gt;
&lt;li&gt;官方目前推薦安裝的是 &lt;code&gt;@playwright/cli&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;不要把它和 npm 上歷史遺留、已廢棄的舊包 &lt;code&gt;playwright-cli&lt;/code&gt; 混為一談&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也就是說，真正該安裝的是 scoped package，而不是舊時代的同名歷史包。&lt;/p&gt;
&lt;h2 id=&#34;04-如何開始用&#34;&gt;04 如何開始用
&lt;/h2&gt;&lt;h3 id=&#34;1-安裝-skills&#34;&gt;1. 安裝 skills
&lt;/h3&gt;&lt;p&gt;如果你希望讓 coding agent 直接使用 Playwright CLI，官方建議先安裝 skills：&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli install --skills
&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;README 裡明確寫到，Claude Code、GitHub Copilot 等工具會使用本地安裝的 skills。&lt;/p&gt;
&lt;h3 id=&#34;2-直接讓-agent-呼叫-cli&#34;&gt;2. 直接讓 agent 呼叫 CLI
&lt;/h3&gt;&lt;p&gt;如果你不想先處理 skills，也可以直接讓 agent 讀取 CLI 的說明資訊：&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-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Test the &amp;#34;add todo&amp;#34; flow on https://demo.playwright.dev/todomvc using playwright-cli.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Check playwright-cli --help for available commands.
&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;官方把這種方式叫做「Skills-less operation」。意思是即使沒有預先安裝 skill，也可以透過 CLI 的自描述能力來驅動 agent。&lt;/p&gt;
&lt;h3 id=&#34;3-手動體驗一遍最小流程&#34;&gt;3. 手動體驗一遍最小流程
&lt;/h3&gt;&lt;p&gt;README 裡給了一組很適合入門的 TodoMVC 範例：&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;/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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli open https://demo.playwright.dev/todomvc/ --headed
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Buy groceries&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli press Enter
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Water flowers&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli press Enter
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli check e21
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli check e35
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli screenshot
&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 CLI 的互動方式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;open&lt;/code&gt; 負責開頁面&lt;/li&gt;
&lt;li&gt;&lt;code&gt;type&lt;/code&gt; 和 &lt;code&gt;press&lt;/code&gt; 負責輸入&lt;/li&gt;
&lt;li&gt;&lt;code&gt;check&lt;/code&gt; 用元素引用操作核取方塊&lt;/li&gt;
&lt;li&gt;&lt;code&gt;screenshot&lt;/code&gt; 保存結果&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;05---headedsession-與監控面板&#34;&gt;05 &lt;code&gt;--headed&lt;/code&gt;、session 與監控面板
&lt;/h2&gt;&lt;h3 id=&#34;--headed&#34;&gt;&lt;code&gt;--headed&lt;/code&gt;
&lt;/h3&gt;&lt;p&gt;Playwright CLI 預設是 headless 的。如果你想直接看到瀏覽器視窗，需要在 &lt;code&gt;open&lt;/code&gt; 時明確加上 &lt;code&gt;--headed&lt;/code&gt;：&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli open https://playwright.dev --headed
&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;/p&gt;
&lt;h3 id=&#34;session&#34;&gt;session
&lt;/h3&gt;&lt;p&gt;官方 README 很強調 session 的用法。你可以用不同 session 把不同專案或網站隔離開來：&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;/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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli open https://playwright.dev
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli -s&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;example open https://example.com --persistent
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli list
&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 長時間工作，也可以直接透過環境變數指定 session：&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PLAYWRIGHT_CLI_SESSION&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;todo-app claude .
&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;常用的 session 管理命令包括：&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;/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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli list
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli close-all
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli kill-all
&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;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;list&lt;/code&gt; 用來列出所有 session&lt;/li&gt;
&lt;li&gt;&lt;code&gt;close-all&lt;/code&gt; 用來正常關閉所有瀏覽器&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kill-all&lt;/code&gt; 用來強制結束所有瀏覽器程序&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;監控面板&#34;&gt;監控面板
&lt;/h3&gt;&lt;p&gt;如果你想看 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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli show
&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;根據 README 的說明，這個 dashboard 主要有兩種視圖：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Session grid：依 workspace 查看所有活動 session，附即時畫面、URL 和頁面標題&lt;/li&gt;
&lt;li&gt;Session detail：查看單個 session 的即時介面，還能接管滑鼠與鍵盤&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這讓 Playwright CLI 不只是「命令列可用」，而是具備了比較成熟的可觀測性。&lt;/p&gt;
&lt;h2 id=&#34;06-常用命令先記住哪些&#34;&gt;06 常用命令先記住哪些
&lt;/h2&gt;&lt;p&gt;如果你是第一次接觸 Playwright CLI，不需要一開始就把所有命令背下來。先記住下面這些最核心的就夠了：&lt;/p&gt;
&lt;h3 id=&#34;頁面與互動&#34;&gt;頁面與互動
&lt;/h3&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;/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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli open &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;url&lt;span class=&#34;o&#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;playwright-cli goto &amp;lt;url&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli click &amp;lt;ref&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli fill &amp;lt;ref&amp;gt; &amp;lt;text&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; &amp;lt;text&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli hover &amp;lt;ref&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli press &amp;lt;key&amp;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;h3 id=&#34;取得頁面結構&#34;&gt;取得頁面結構
&lt;/h3&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;/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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli snapshot
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli snapshot &amp;lt;ref&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli snapshot --depth&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;N
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli &lt;span class=&#34;nb&#34;&gt;eval&lt;/span&gt; &amp;lt;func&amp;gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;ref&lt;span class=&#34;o&#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;snapshot&lt;/code&gt; 很關鍵，因為很多後續操作都依賴元素引用 &lt;code&gt;ref&lt;/code&gt;。通常你會先抓一次快照，再用回傳的元素編號去點擊、填寫、勾選或截圖。&lt;/p&gt;
&lt;h3 id=&#34;輸出結果&#34;&gt;輸出結果
&lt;/h3&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli screenshot
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli pdf
&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;h3 id=&#34;分頁&#34;&gt;分頁
&lt;/h3&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;/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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli tab-list
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;playwright-cli tab-new &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;url&lt;span class=&#34;o&#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;playwright-cli tab-close &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;index&lt;span class=&#34;o&#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;playwright-cli tab-select &amp;lt;index&amp;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;h2 id=&#34;07-它適合誰&#34;&gt;07 它適合誰
&lt;/h2&gt;&lt;p&gt;如果你屬於下面這些場景，Playwright CLI 很值得試：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你在用 Claude Code、Copilot 或其他 coding agent 做 E2E 測試&lt;/li&gt;
&lt;li&gt;你希望瀏覽器自動化介面更輕量，不想把大量頁面結構塞進上下文&lt;/li&gt;
&lt;li&gt;你希望同一個瀏覽器 session 能跨多次命令持續存在&lt;/li&gt;
&lt;li&gt;你想在 agent 自動跑網頁任務時，隨時打開監控面板觀察進度&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你的重點是「瀏覽器自動化如何和 coding agent 高效配合」，Playwright CLI 很可能會比傳統的人類手動除錯方式更順手。&lt;/p&gt;
&lt;h2 id=&#34;參考連結&#34;&gt;參考連結
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a class=&#34;link&#34; href=&#34;https://github.com/microsoft/playwright-cli&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/microsoft/playwright-cli&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;README: &lt;a class=&#34;link&#34; href=&#34;https://github.com/microsoft/playwright-cli/blob/main/README.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/microsoft/playwright-cli/blob/main/README.md&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        
    </channel>
</rss>
