<?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/tags/playwright/</link>
        <description>Recent content in Playwright on KnightLi的博客</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-cn</language>
        <lastBuildDate>Sun, 24 May 2026 17:51:28 +0800</lastBuildDate><atom:link href="https://knightli.com/tags/playwright/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>browser-harness、Playwright、Puppeteer 怎么选？浏览器自动化工具对比</title>
        <link>https://knightli.com/2026/05/24/browser-harness-playwright-puppeteer-comparison/</link>
        <pubDate>Sun, 24 May 2026 17:51:28 +0800</pubDate>
        
        <guid>https://knightli.com/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; 由微软维护，背后团队和早期 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/2026/05/19/cloakbrowser-stealth-chromium-browser-automation/</link>
        <pubDate>Tue, 19 May 2026 10:56:50 +0800</pubDate>
        
        <guid>https://knightli.com/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/2026/05/17/ai-goofish-monitor/</link>
        <pubDate>Sun, 17 May 2026 17:24:03 +0800</pubDate>
        
        <guid>https://knightli.com/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/2026/04/15/playwright-cli-video-recording/</link>
        <pubDate>Wed, 15 Apr 2026 08:22:45 +0800</pubDate>
        
        <guid>https://knightli.com/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/2026/04/15/playwright-cli-session-management/</link>
        <pubDate>Wed, 15 Apr 2026 08:15:12 +0800</pubDate>
        
        <guid>https://knightli.com/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/2026/04/14/playwright-cli-storage-state-commands/</link>
        <pubDate>Tue, 14 Apr 2026 22:19:55 +0800</pubDate>
        
        <guid>https://knightli.com/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;这条命令会把当前浏览器上下文中的状态保存到 &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; 里的状态启动浏览器上下文。常见用途就是跳过重复登录，直接进入已登录环境。&lt;/p&gt;
&lt;h2 id=&#34;03-查看当前-cookies&#34;&gt;03 查看当前 cookies
&lt;/h2&gt;&lt;p&gt;如果你只是想确认当前会话里到底有哪些 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;这条命令会列出当前上下文中的 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;这个用法适合调试鉴权、复现特定会话，或者在脚本前手动注入 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; 适合看当前会话里的临时状态。&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;。如果某个页面逻辑依赖一次性会话数据，可以从这里检查。&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、会话管理与常用命令</title>
        <link>https://knightli.com/2026/04/12/playwright-cli-getting-started/</link>
        <pubDate>Sun, 12 Apr 2026 14:36:58 +0800</pubDate>
        
        <guid>https://knightli.com/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-会话管理做得比较完整&#34;&gt;3. 会话管理做得比较完整
&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 长时间工作，还可以直接给它指定环境变量：&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>
