联系管理员

开通文章发布权限

扫码 添加微信
微信图片
电话: QQ:1602036736

agent-browser skill 浏览器自动化

从"AI 在后台悄悄点浏览器"到"你亲眼看着 AI 操作浏览器"——一次完整实战记录。

背景

大模型驱动的编码助手(AI Agent)越来越多地需要"动手操作浏览器":帮用户查资料、填表单、抓数据、打开数据手册。但大多数时候,浏览器在后台无头运行,用户只能看到结果文字,看不到过程——体验就像隔着一堵墙。

本文记录两件事:

  1. 如何给 AI 安装并使用 agent-browser 这个浏览器自动化 skill;

  2. 如何把无头浏览器的画面实时投屏到前端,让用户亲眼看着 AI 操作。

实战场景:AI 打开立创商城,搜索 STM32F103C8T6,打开它的数据手册——并全程可视。

agent-browser 是什么

agent-browser 是 Vercel 官方出品的浏览器自动化 CLI(GitHub 40k+ star,skills 生态 648k+ 安装量)。核心特点:

  • 基于 CDP(Chrome DevTools Protocol),不依赖 Playwright / Puppeteer;

  • 通过可访问性树快照(accessibility-tree snapshot)给 AI 提供紧凑的 @eN 元素引用,一次交互只需 200~400 token;

  • 浏览器跨命令保持运行,操作像"同一个会话";

  • 支持无头 Chromium、真实 Chrome(带 profile)、云浏览器三种模式。

安装

# 1. 通过 skills 生态安装 skill(注册到 Agent 的 skill 索引)
npx skills add https://github.com/vercel-labs/agent-browser --skill agent-browser -g -y

# 2. 安装 CLI
npm i -g agent-browser

# 3. 下载内置浏览器内核(无头 Chrome)
agent-browser install

三分钟上手:核心工作流

AI 操作浏览器的循环只有四步:

agent-browser open <url>        # 1. 打开页面
agent-browser snapshot -i       # 2. 看页面上有什么(只列可交互元素)
agent-browser click @e3         # 3. 对快照里的引用 @eN 进行操作
agent-browser snapshot -i       # 4. 页面一变,重新快照

常用命令一览:

类别命令
导航open back forward / reload
读取snapshot get text @e1 get url / get title
交互click fill type press Enter select / upload
等待wait @e1 wait --text "..." wait --load networkidle
提取get text get html eval <js>
截图screenshot / screenshot --annotate(带编号标注,适配多模态模型)

关键纪律@eN 引用在页面变化后会失效,任何点击/导航后都必须重新快照。AI 自动化失败 90% 都是"等待没等对"或"用了过期的引用"。

实战:逛立创商城,查 STM32F103C8T6 数据手册

第一步:打开立创商城

agent-browser open "https://www.szlcsc.com"

页面标题正常返回,但随后就被弹回空白页——立创商城(国内站)部署了 WAF 反爬。

遭遇 WAF:JS 挑战 + 无头检测

用 HTTP 直连看服务端返回:

Status: 203
<script>var _xvasu = 1104951776; var _xvtsc = 300; ...</script>

这是典型的 JS 挑战:服务器先返回一段混淆脚本,要求浏览器执行计算并种下 cookie 后重载,才会给真实内容。同时 WAF 检测自动化特征(navigator.webdriver、CDP 残留变量 cdc_* 等),命中就 location 跳转到 about:blank——这正是"页面打不开"的根因。

破局一:注入反检测脚本

agent-browser 支持 --init-script,在页面任何 JS 执行之前注入脚本:

// init_undetect.js
Object.defineProperty(navigator, 'webdriver', { get: () => undefined });
try {
  for (const key of Object.getOwnPropertyNames(window)) {
    if (key.startsWith('cdc_')) { try { delete window[key]; } catch (e) {} }
  }
} catch (e) {}
agent-browser open "https://so.szlcsc.com/global.html?k=STM32F103C8T6" \ 
  --init-script ./init_undetect.js

页面 URL 稳定了,但 body 仍是空壳——WAF 的 JS 挑战对自动化环境依旧"不配合"。

破局二:绕过 SPA 空壳,直接拿数据

WAF 拦得住浏览器渲染,拦不住"以普通 HTTP 客户端直连":

# PowerShell 直连商品页(带浏览器 UA + Referer)
$r = Invoke-WebRequest -Uri "https://item.szlcsc.com/9243.html" -Headers @{
  "User-Agent" = "Mozilla/5.0 ... Chrome/151.0.0.0 Safari/537.36"
  "Referer"    = "https://www.szlcsc.com/"
} -UseBasicParsing

页面居然完整返回(146KB),JSON-LD 结构化数据里直接解析出数据手册:

{
  "@type": "CreativeWork",
  "name": "STM32F103C8T6 Datasheet",
  "url": "https://atta.szlcsc.com/upload/public/pdf/source/20220812/8363ACEC51AD55ECEB84799464F7CB85.pdf"
}

(注意:立创料号是 C8734,不是网上常传的 C8739。)

打开数据手册

agent-browser open "https://atta.szlcsc.com/upload/public/pdf/source/20220812/8363ACEC51AD55ECEB84799464F7CB85.pdf"

PDF 自动下载到本地(C8734_单片机(MCU-MPU-SOC)_STM32F103C8T6_规格书_WJ115614.PDF),用系统 PDF 阅读器打开即可。

小结:真实网站的反爬是"组合拳"——无头检测、JS 挑战、SPA 壳。破局思路不是死磕渲染,而是多通道并行:浏览器走不通就直连抓数据,能拿到结果就是胜利。

进阶:把浏览器搬到前台——实时投屏

需求

AI 在后台操作浏览器,用户看不见。要让用户"亲眼看到"。

方案选型

方案优点缺点
--headed 有头窗口最简单在部分环境参数不生效(实测被忽略,仍是 headless)
agent-browser 自带 stream(WebSocket 推帧)官方能力daemon 生命周期不稳定,端口易漂移,协议文档缺失
自建 CDP 截图流 + Web 播放器(本文方案)完全可控、稳定需要 ~60 行代码

架构

agent-browser --cdp 9222 ──► 系统 Chrome(有头窗口,桌面可见)
CDP (WebSocket)
                            viewer_server.js(截图轮询推流)
HTTP /frame
                            浏览器打开 http://127.0.0.1:9333/  ← 实时画面

三个关键决策:

  1. 用系统真实 Chrome + --remote-debugging-port=9222,绕开 agent-browser 内置浏览器的 headless 问题,窗口真实弹出;

  2. agent-browser 用 --cdp 9222 连接,AI 照常操作,但操作落在可见窗口里;

  3. 截图用 Page.captureScreenshot 轮询,而非 Page.startScreencast——Chrome 147 实测 screencast 不推帧,captureScreenshot 任何版本都稳定。

核心代码(viewer_server.js 节选)

// 连接 CDP → 找到真实页面 target → 附加会话 → 开启截图轮询
function attachTo(targetId) {
  trackedSend('Target.attachToTarget', { targetId, flatten: true });
}

// attach 成功后:
trackedSend('Page.enable', {}, pageSessionId);
trackedSend('Page.captureScreenshot', { format: 'jpeg', quality: 55 }, pageSessionId);

// 收到截图响应 → 更新最新帧 → 250ms 后继续拍下一张
if (method === 'Page.captureScreenshot' && msg.result && msg.result.data) {
  latestFrame = Buffer.from(msg.result.data, 'base64');
  setTimeout(() => {
    trackedSend('Page.captureScreenshot', { format: 'jpeg', quality: 55 }, pageSessionId);
  }, 250);
}

前端播放器页面(约 40 行 HTML):一个 <img>,每 120ms 请求一次 /frame?t=<时间戳>,实现约 4~8 fps 的实时画面;帧接口返回最新 JPEG,带 Cache-Control: no-store 防止缓存。

效果

  • 桌面弹出真实 Chrome 窗口,用户可直接看;

  • http://127.0.0.1:9333/ 播放器页面实时同步;

  • agent-browser 每次导航/点击,两个画面同步更新(实测帧大小随页面内容变化,如必应首页 13KB → 125KB)。

踩坑清单(省得你再踩一遍)

  1. agent-browser 的 daemon 在 CLI 命令间会退出 → 用 viewer 持续持有 CDP 连接,daemon 被"保活",CLI 通信也稳定了(此前频繁出现的 WaitDelay expired 错误随之消失)。

  2. --headed 可能被静默忽略--headless=new 仍在进程参数里)→ 放弃内置浏览器,改用系统 Chrome + --cdp

  3. bash/shell 工具默认会杀掉子进程 → 启动 Chrome 这类 GUI 进程要保留后台进程(detached),否则窗口一闪就没。

  4. 立创商城 WAF:203 + JS 挑战 + 无头跳转 → 反检测脚本 + 直连解析 JSON-LD。

  5. Chrome 147 screencast 不推帧 → 换 captureScreenshot 轮询。

  6. 响应消息没有 method 字段 → 调试 CDP 时用 msgId → method 的 pending map,别用 msg.method 判断响应。

结束语

从"装一个 skill"到"AI 真的替你逛了趟商城、查了份数据手册、还把全过程实时投屏给你看",核心收获是:Agent 工具链的默认能力往往不够"可观测",但 CDP 这条通路,加上几十行胶水代码,就能把 AI 的每个动作都变成你眼前看得见的画面。

技术要点:

  • 浏览器自动化:agent-browser(open → snapshot → act → re-snapshot)

  • 反爬对抗:--init-script 反检测 + 多通道直连

  • 实时投屏:系统 Chrome + CDP captureScreenshot 轮询 + Web 播放器

相关文件:

  • init_undetect.js —— 反自动化检测注入脚本

  • viewer_server.js —— CDP 截图流 + Web 播放器服务

评论

快捷导航

把好文章收藏到微信

打开微信,扫码查看

关闭

还没有账号?立即注册