🌐 OpenClaw 浏览器自动化进阶
无头浏览器 · 页面抓取 · 表单填写 · RPA 工作流
让 AI Agent 像人一样操作浏览器
📅 2026-06-09⏱️ 阅读 12 分钟🏷️ Browser · RPA · Automation
1. 浏览器自动化概览
OpenClaw 的 browser 工具基于 Playwright,支持完整的浏览器自动化。AI Agent 可以像人一样操作浏览器:打开页面、点击按钮、填写表单、截取截图。
| 操作 | 说明 | action |
| 📸 截图 | 截取页面截图 | screenshot |
| 🔍 快照 | 获取页面结构(DOM) | snapshot |
| 🖱️ 点击 | 点击页面元素 | act: click |
| ⌨️ 输入 | 在输入框中输入文字 | act: type / fill |
| 📜 滚动 | 滚动页面 | act: scrollIntoView |
| 🔗 导航 | 跳转到新 URL | navigate |
| 📋 选择 | 选择下拉框选项 | act: select |
| 🎯 悬停 | 鼠标悬停 | act: hover |
| 📄 PDF | 导出页面为 PDF | pdf |
2. 浏览器 Profile
OpenClaw 支持两种浏览器 Profile:
| Profile | 说明 | 使用场景 |
| openclaw(默认) | 隔离的无头浏览器 | 自动化、抓取、截图 |
| user | 用户已登录的浏览器 | 需要登录态的操作 |
// 使用默认隔离浏览器
browser({ action: "open", url: "https://miaoquai.com" })
// 使用用户已登录的浏览器(需要用户在场)
browser({
action: "open",
url: "https://github.com",
profile: "user"
})
⚠️ 注意:profile="user" 需要用户已登录且浏览器在运行。适用于需要登录态的场景(如 GitHub、飞书),但不适合全自动化。
3. Snapshot:页面快照
Snapshot 是 OpenClaw 浏览器自动化的核心。它将页面的 DOM 结构转换为 AI 可理解的格式。
📋 两种 Snapshot 格式
// Role 格式(默认)— 基于角色+名称
browser({
action: "snapshot",
refs: "role"
})
// 输出: [button "提交"] [input "用户名"] [link "首页"]
// Aria 格式 — 基于 aria-ref ID
browser({
action: "snapshot",
refs: "aria"
})
// 输出: [e12] [e15] [e18]
🎯 选择哪种格式?
| 格式 | 优点 | 缺点 | 推荐场景 |
| role | 可读性好,语义清晰 | 复杂页面可能重复 | 简单页面操作 |
| aria | 稳定唯一,跨调用一致 | 需要先 snapshot 获取 ID | 复杂页面、多步操作 |
4. 页面操作大全
🖱️ 点击
// 通过 ref 点击
browser({
action: "act",
kind: "click",
ref: "[button '提交']"
})
// 通过坐标点击
browser({
action: "act",
kind: "clickCoords",
x: 500,
y: 300
})
// 双击
browser({
action: "act",
kind: "click",
ref: "[link '文件名']",
doubleClick: true
})
⌨️ 输入文字
// fill — 直接填入(推荐,替换原有内容)
browser({
action: "act",
kind: "fill",
ref: "[input '搜索']",
text: "OpenClaw tutorial"
})
// type — 逐字输入(模拟人类打字)
browser({
action: "act",
kind: "type",
ref: "[input '评论']",
text: "这篇文章写得很好!",
slowly: true,
delayMs: 50
})
📜 滚动
// 滚动到元素可见
browser({
action: "act",
kind: "scrollIntoView",
ref: "[heading '相关文章']"
})
📋 选择下拉框
browser({
action: "act",
kind: "select",
ref: "[select '语言']",
values: ["zh-CN"]
})
⌨️ 键盘操作
// 按 Enter 提交
browser({
action: "act",
kind: "press",
key: "Enter"
})
// 按 Escape 关闭弹窗
browser({
action: "act",
kind: "press",
key: "Escape"
})
// 组合键 Ctrl+A
browser({
action: "act",
kind: "press",
key: "Control+a"
})
6. 智能页面抓取
// 方法 1: web_fetch(轻量级,推荐)
// 适合:静态页面、文章内容
web_fetch({ url: "https://example.com/article" })
// 方法 2: browser snapshot + evaluate
// 适合:动态页面、需要登录的页面
browser({ action: "open", url: "https://example.com" })
browser({ action: "snapshot" })
browser({
action: "act",
kind: "evaluate",
fn: `
Array.from(document.querySelectorAll('.article')).map(el => ({
title: el.querySelector('h2').textContent,
summary: el.querySelector('p').textContent,
link: el.querySelector('a').href
}))
`
})
// 方法 3: browser screenshot
// 适合:需要视觉信息的场景
browser({ action: "screenshot", fullPage: true })
🎯 选择哪种方法?
| 方法 | 速度 | 资源 | 适用场景 |
| web_fetch | 🟢 快 | 🟢 低 | 静态内容 |
| snapshot + evaluate | 🟡 中 | 🟡 中 | 动态内容 |
| screenshot | 🔴 慢 | 🔴 高 | 视觉信息 |
7. RPA 工作流
🤖 自动化登录 + 数据抓取
// RPA 流程:登录 → 导航 → 抓取 → 导出
// 1. 打开登录页
browser({ action: "open", url: "https://admin.example.com/login" })
// 2. snapshot 识别表单
browser({ action: "snapshot", refs: "aria" })
// 3. 填写凭据并登录
browser({ action: "act", kind: "fill", ref: "e12", text: "admin" })
browser({ action: "act", kind: "fill", ref: "e15", text: "xxx" })
browser({ action: "act", kind: "click", ref: "e18" })
// 4. 导航到数据页面
browser({ action: "navigate", url: "https://admin.example.com/data" })
// 5. 抓取数据
browser({
action: "act", kind: "evaluate",
fn: "JSON.stringify(Array.from(document.querySelectorAll('tr')).map(r => r.textContent))"
})
// 6. 截图存档
browser({ action: "screenshot", fullPage: true })
// 7. 导出 PDF
browser({ action: "pdf" })
8. 常见问题排查
| 问题 | 原因 | 解决 |
| snapshot 为空 | 页面未加载完成 | 加 wait 或 loadState |
| click 无效 | 元素被遮挡 | 先 scrollIntoView |
| fill 无效 | 输入框有验证 | 用 type 逐字输入 |
| 页面超时 | 网络慢或页面卡 | 增加 timeoutMs |
| 登录态丢失 | Cookie 过期 | 用 profile="user" |
9. 最佳实践
- ✅ 先 snapshot 再操作,了解页面结构
- ✅ 用 refs="aria" 做复杂多步操作
- ✅ 用 fill 而非 type,除非需要模拟打字
- ✅ 操作后再次 snapshot,验证结果
- ✅ 设置合理的 timeout,防止卡住
- ✅ 优先用 web_fetch,browser 是最后手段
- ❌ 不要在循环中频繁 snapshot,消耗资源
- ❌ 不要硬编码 ref,每次 snapshot 后 ref 可能变化