用 Hermes Agent 的浏览器工具链,5 分钟搭建自动化网页信息采集系统,无需安装 Playwright 或 Selenium,零依赖开箱即用。
为什么你需要浏览器三件套
如果你在用 Hermes Agent 做内容监控、竞品分析、数据采集或公众号素材收集,迟早会遇到一个经典痛点:web_extract 对很多站点不好使。
具体情况包括:
官方的降级方案(也是目前最稳定的方案)就是浏览器三件套——browser_navigate、browser_snapshot、browser_console。这三个工具底层基于 Playwright CDP 协议,但完全封装好了,你不需要安装任何浏览器驱动。
本文带你从零掌握这三个工具的实战用法,附完整代码、输出示例和 7 个实战踩坑记录。
工具速览与选择决策树
| 工具 | 作用 | 关键参数 | 返回内容 |
| `browser_navigate` | 打开 URL,加载完整页面 | `url`(必填) | 页面结构摘要 |
| `browser_snapshot` | 获取页面无障碍树结构快照 | 无必填参数 | DOM 结构骨架 |
| `browser_console` | 在页面中执行 JS 表达式 | `expression`(必填) | 表达式返回值 |
选择决策树:
需要提取网页正文? ├── 是普通网页 → 先用 web_extract(更快更省 token) │ └── web_extract 失败 → 用 browser_console 提取 ├── 是 GitHub 页面 → 直接用 browser_console(web_extract 必挂) ├── 是 The Verge / 媒体站 → 用 browser_console └── 被 Cloudflare 拦截 → Web Archive + browser_console 需要看页面结构找选择器? └── 用 browser_snapshot(只用一次,用完就切回 console)

实战 1:提取 GitHub Release 正文(附完整输出)
GitHub 的 releases 标签页(如 https://github.com/NousResearch/hermes-agent/releases/tag/v2026.4.16)用 web_extract 会返回 432 错误。用浏览器三件套可以完美绕过,且无需 GitHub Token。
第一步:navigate 打开页面
在 Hermes Agent 对话中直接调用:
browser_navigate(url="https://github.com/NousResearch/hermes-agent/releases")
这一步返回页面结构摘要,让你确认页面已加载。但注意:GitHub 是 SPA 混合渲染,navigate 返回时 JavaScript 可能还没完全执行完,所以 snapshot 看到的往往是骨架。
第二步:console 提取正文(核心步骤)
直接跳过 snapshot,用 console 定位正文容器:
browser_console(expression="document.querySelector('.markdown-body')?.innerText || document.querySelector('article')?.innerText || document.body.innerText.substring(0, 5000)")
这个表达式有三级智能降级:
1. .markdown-body:GitHub README 和 Release 正文专用容器,命中率最高
2. 标签:部分文档站点用 article 标签包裹正文
3. body.innerText.substring(0, 5000):万能兜底,截取前 5000 字符避免 token 爆炸
实际返回示例:
Hermes Agent v2026.4.16 ======================== ## What's New 🚀 - **Browser Console Tool**: New `browser_console` tool for executing JavaScript in loaded pages. Supports Promises for async extraction. - **Patch v2**: Fuzzy matching now uses 9 strategies instead of 3. Minor whitespace differences no longer break replacements. - **Terminal PTY**: Fixed SIGTERM handling in pseudo-terminal mode. Interactive CLIs (Codex, Claude Code) are now stable. ## Bug Fixes 🐛 - `read_file` offset parameter: Fixed off-by-one error when offset > 1 - `process.wait`: No longer hangs when process exits during poll cycle - `web_search`: Added bocha as native backend option for Chinese queries ## Breaking Changes ⚠️ - `browser_snapshot` now returns accessibility tree by default instead of raw HTML. Use `browser_console` for content extraction.
⚠️ **踩坑 1**:navigate 之后别急着 snapshot。GitHub 页面有大量动态加载内容(React 水合),snapshot 返回的无障碍树通常只有导航栏、footer 等骨架元素,**不含** Markdown 正文。正确的路径是 navigate → 直接跳到 console → 用 CSS 选择器精准提取。除非你需要确认页面 DOM 结构来找到正确的 class 名,否则永远不要在生产流程中加 snapshot 步骤。
⚠️ **踩坑 2**:`.markdown-body` 只在 GitHub 的文件页(README.md)和 Release 详情页有效。对于 GitHub 的 **Pull Request 页面**或 **Issue 页面**,正文在不同容器里。此时需要用 `.comment-body`(评论区每条评论的容器)或 `.js-comment-body`(旧版 Issue 页面)。建议先用 snapshot 快速扫一眼 DOM 结构,确定正确的 CSS 选择器后再写 console 表达式。一个快速验证方案:用 `browser_console(expression="document.querySelectorAll('[class*=comment]').length")` 看页面有多少评论容器。

实战 2:提取 The Verge 文章正文(含完整工作流)
The Verge 的 AI 专栏是获取行业新闻的关键信源,但 web_extract 对 The Verge 文章页几乎总是返回 0 字符。浏览器三件套可以稳定获取全文,而且能拿到 web_extract 拿不到的评论区内容。
完整四步流程
# 步骤1:打开 AI 专栏首页
browser_navigate(url="https://www.theverge.com/ai-artificial-intelligence")
# 步骤2:从首页提取最新文章列表(无需 snapshot)
browser_console(expression="Array.from(document.querySelectorAll('[data-analytics-link] h3, .duet--article--headline a')).slice(0, 5).map(el => ({title: el.innerText?.trim(), href: el.href || el.closest('a')?.href}))")
# 返回示例:
# [
# {"title": "OpenAI quietly launched a new moderation tool", "href": "https://www.theverge.com/2026/5/14/..."},
# {"title": "Anthropic's Claude can now browse the web", "href": "https://www.theverge.com/2026/5/14/..."},
# ...
# ]
# 步骤3:进入目标文章
browser_navigate(url="https://www.theverge.com/2026/5/14/openai-quietly-launched-moderation-tool")
# 步骤4:console 提取正文
browser_console(expression="document.querySelector('.duet--article--article-body-component')?.innerText || document.querySelector('[class*=article-body]')?.innerText || document.body.innerText.substring(0, 10000)")
提取结果示例
OpenAI quietly launched a new moderation tool that could reshape how AI companies handle content safety. The tool, called "Guardian," was rolled out to enterprise customers last week without a formal announcement. According to an internal document obtained by The Verge, Guardian uses a multi-layered approach... "We believe safety should be invisible but effective," said OpenAI's head of trust and safety, in a statement provided to The Verge. Industry analysts see this as a direct response to...
⚠️ **踩坑 3**:The Verge 站内搜索 `https://www.theverge.com/search?q=关键词` 对当日新文章经常返回空结果——搜索索引更新有延迟。但 AI 专栏首页 `https://www.theverge.com/ai-artificial-intelligence` 的 **"LATEST IN AI"** 区块会实时显示当日报道。正确入口:永远从专栏首页开始,不要从搜索开始。如果首页也找不到,用 `browser_console` 执行选择器直接从 DOM 抓取标题列表。
⚠️ **踩坑 4**:The Verge 的正文容器 class 名会随改版变化。截至 2026 年 5 月,实测有效的选择器是 `.duet--article--article-body-component`。如果这个选择器失效(console 返回 `undefined`),立即用 snapshot 扫一眼新 DOM 结构,找到新的 class 名。备选方案:The Verge 文章页面内所有 `
` 标签的文本通常就是正文,用 `browser_console(expression="Array.from(document.querySelectorAll('main p')).slice(0,30).map(p=>p.innerText).join('\n\n')")` 兜底。
实战 3:绕过 Cloudflare 拦截(OpenAI / Anthropic / Medium)
部分 AI 行业核心信源的官方博客被 Cloudflare 保护的严严实实:
| 站点 | 拦截类型 | 影响 |
| `openai.com/index/*` | URL 级别 Cloudflare 挑战 | 所有子路径无一幸免 |
| `anthropic.com/engineering/*` | 同上 | `/news/` 返回 404,`/engineering/` 被拦截 |
| `medium.com/*` | 双重拦截(Cloudflare + 付费墙) | Web Archive 快照也不稳定 |
解决方案:Web Archive 快照
# ❌ 直接访问会被 Cloudflare 拦截 browser_navigate(url="https://openai.com/index/why-we-no-longer-evaluate-swe-bench-verified") # ✅ 走 Web Archive 快照(注意日期用 YYYYMMDD 8位格式) browser_navigate(url="https://web.archive.org/web/20260514/https://openai.com/index/why-we-no-longer-evaluate-swe-bench-verified")
URL 格式务必正确:https://web.archive.org/web/[YYYYMMDD]/[完整协议+URL]。缺少 https:// 前缀或日期格式错误都会 404。
⚠️ **踩坑 5**:Web Archive 不是万能的。对 Medium 的付费墙文章和 `archive.ph` 自身的快照,Web Archive 经常返回 "Hrm" 错误(没有快照)。遇到这种情况不要再浪费时间,直接跳到终极兜底方案——HN 评论 API:
# 从 HN Algolia 找到文章的 objectID,然后拉取完整评论 curl -s "https://hn.algolia.com/api/v1/search?query=关键词&tags=story&hitsPerPage=5" # 从返回结果中找到 objectID(如 "44569445"),然后: curl -s "https://hn.algolia.com/api/v1/items/44569445" # 评论里往往包含文章核心数据、引用和多个角度的深度讨论

实战 4:构建自动化监控流水线(完整代码)
将三个工具组合成定时任务,实现"无人值守"的内容监控。以下是一个每分钟扫描 HN 热榜的完整流水线:
# === 监控流水线(Hermes Agent Cron 任务) ===
# 步骤1:打开 HN 首页
browser_navigate(url="https://news.ycombinator.com/")
# 步骤2:提取热榜前 15 条(标题 + URL)
browser_console(expression="Array.from(document.querySelectorAll('.titleline > a')).slice(0, 15).map(a => ({title: a.innerText, url: a.href}))")
# 返回示例:
# [
# {"title": "Show HN: I built an AI agent that manages my calendar", "url": "https://..."},
# {"title": "Claude Code can now deploy to production", "url": "https://..."},
# {"title": "Hermes Agent v2026.5.14 released with browser tools", "url": "https://..."},
# ...
# ]
# 步骤3:在 Hermes 对话中筛选(自然语言即可)
# "筛选含 AI/Agent/Claude/Hermes/LLM 关键词的条目,忽略广告"
# 步骤4:对筛选后的每条,进入详情页提取正文
browser_navigate(url="具体文章URL")
browser_console(expression="document.body.innerText.substring(0, 5000)")
# 记录正文到草稿文件
# 步骤5:生成汇总报告
# 写入 content/draft-YYYYMMDD-HHMM-ai-fengxiang-xxx.md
流水线核心参数:
| 参数 | 推荐值 | 说明 |
| 扫描间隔 | 15 分钟 | HN 热榜每 30 分钟大轮换 |
| 热榜截取数 | 前 15 条 | 覆盖 80% 的 AI 相关内容 |
| 正文截断长度 | 5000 字符 | 足够判断是否需要深度提取 |
| 关键词匹配 | AI/Agent/LLM/Claude/GPT | 全小写匹配,大小写不敏感 |
⚠️ **踩坑 6**:HN 首页用 `browser_navigate` 加载后,标题列表是 SSR 渲染的,不需要等 JS 执行。但 **`browser_snapshot` 对 HN 首页只返回结构骨架**(无障碍树里标题列表很稀疏),和 GitHub 一样的问题——直接跳到 `browser_console` 提取内容即可。另外注意:`.titleline > a` 这个选择器只选标题链接,不包含 meta 信息(points/comments)。如果需要完整信息,用这个表达式:
browser_console(expression="Array.from(document.querySelectorAll('.athing')).slice(0,10).map(row => { const title = row.querySelector('.titleline > a'); const meta = row.nextElementSibling; return { title: title?.innerText, url: title?.href, points: meta?.querySelector('.score')?.innerText, comments: meta?.querySelectorAll('a')[meta?.querySelectorAll('a').length-1]?.innerText }; })")
⚠️ **踩坑 7**:`browser_console` 的表达式如果太长(>400 字符),可能因为 URL 编码或 JSON 序列化问题被截断。解决方案:提前把长表达式拆成多次 console 调用——第一次拿标题列表,第二次拿 meta 信息,在 Hermes 对话中手动合并。不要试图一次搞定所有事情。
选择器速查表(持续更新)
| 站点 | 目标内容 | 推荐选择器 | 兜底方案 |
| GitHub README/Release | 正文 | `.markdown-body` | `article` → `body.innerText` |
| GitHub Issue/PR | 评论正文 | `.comment-body` | `.js-comment-body` |
| The Verge 文章 | 正文 | `.duet--article--article-body-component` | `main p` 拼接 |
| The Verge 首页 | 标题列表 | `[data-analytics-link] h3` | `.duet--article--headline a` |
| HN 首页 | 热榜标题 | `.titleline > a` | `.athing .title a` |
| HN 评论页 | 评论正文 | `.comment` | `.commtext` |
| Reddit 帖子 | 正文 | `[slot="text-body"]` | `shreddit-post` shadow DOM |
| 通用博客站 | 正文 | `article` | `.post-content` → `body.innerText` |
| 任何站点(兜底) | 全部文字 | `document.body.innerText.substring(0, 5000)` | 无 |
性能优化与 Token 节省
1. console 表达式控制在 200 字符以内:过长的 JS 在多轮对话中累积 token 消耗很大
2. innerText 截断到 5000-10000 字符:全量提取一篇 5000 字文章可能消耗 5000+ token。先截断,确认有价值后再全量提取
3. 不要连续 snapshot + console:snapshot 返回的文本也计 token。只在需要确认 DOM 结构时用一次 snapshot
4. 非 GitHub/The Verge 的普通站点优先用 web_extract:web_extract 走的是内部文本提取 pipeline,比浏览器加载快 3-5 倍,token 消耗也更低。浏览器工具链是降级方案,不是首选
5. 用 Promise 延迟提取替代 sleep:对于 SPA 页面,不要 sleep(5) 之后调用 console,而是直接在 console 表达式里用 Promise 做轮询等待:
// 在 console 表达式里自建等待逻辑,不占用对话轮次
new Promise(r => {
const check = () => {
const el = document.querySelector('.content-loaded');
if(el?.innerText?.length > 100) r(el.innerText.substring(0, 5000));
else setTimeout(check, 1500);
};
check();
})
与其他方案对比
| 方案 | 上手难度 | 稳定性 | 依赖 | 适用场景 |
| Hermes browser 三件套 | ⭐ 极低 | ⭐⭐⭐⭐ 高 | 零 | 对话式内容采集 |
| `web_extract` | ⭐ 极低 | ⭐⭐⭐ 中 | 零 | 普通网页快速提取 |
| Playwright 独立脚本 | ⭐⭐⭐ 中 | ⭐⭐⭐⭐⭐ 极高 | Node.js + 浏览器 | 复杂自动化测试 |
| Selenium | ⭐⭐⭐⭐ 高 | ⭐⭐⭐ 中 | Python + 驱动 | 传统 Web 自动化 |
| `curl` + 正则 | ⭐⭐ 低 | ⭐⭐ 低 | curl | 简单 JSON API |
对于 AI 创业者的日常需求(监控行业新闻、提取竞品信息、收集素材),浏览器三件套是性价比最高的方案——不需要搭建额外基础设施,在 Hermes Agent 对话里直接使用。
常见问题 FAQ
**Q1:browser_console 返回 `undefined` 怎么办?**
A:99% 的情况是 CSS 选择器不正确。解决流程:
1. 用 browser_snapshot 看页面实际 DOM 结构
2. 找到正文容器的 class 名或标签名
3. 更新 console 选择器
4. 仍不行的用兜底:document.body.innerText.substring(0, 3000)
**Q2:navigate 后要等多久页面才加载完?**
A:Hermes Agent 的 navigate 自带等待逻辑(等待 load 事件触发),通常 5-15 秒。但如果页面是 React/Vue 等 SPA 框架渲染的,load 事件触发后正文可能还没渲染完。此时需要在 console 表达式里自建轮询(见上文"性能优化"第 5 条)。
**Q3:能同时打开多个浏览器标签页吗?**
A:目前不能。浏览器工具链是单标签页模式,每次 navigate 会替换当前页面。如果需要同时监控多个页面,建议在多个独立的 Hermes Agent 对话中分别使用,或者按顺序依次 navigate→console→记录结果→下一个。
**Q4:navigate 打开页面后,能模拟点击、滚动、填表吗?**
A:browser_navigate 只负责打开 URL。点击、滚动、填表等交互操作可以通过 browser_console 执行 JS 来模拟:
// 模拟点击
document.querySelector('.load-more').click();
// 模拟滚动
window.scrollTo(0, document.body.scrollHeight);
// 模拟填表
document.querySelector('input[name="search"]').value = '关键词';
但 Hermes Agent 没有专用的 browser_click / browser_fill 工具,复杂交互建议用 Playwright 独立脚本。
**Q5:提取的内容怎么保存到文件?**
A:Hermes Agent 对话中可以用 write_file 工具将提取的正文写入 Markdown 文件:
write_file(path="/opt/hermes-home/projects/ai-neican/research/hn-20260514.md", content="[提取的正文]")
如果是定时 Cron 任务,直接写文件路径到 projects/ai-neican/content/ 目录即可被下游发布流程消费。
总结:记住这 4 条核心规则
1. navigate 开门,console 取货——snapshot 只用于调试 DOM,不要在生产流程里用它提取内容
2. 选择器不对就 snapshot——一次 snapshot 找到正确选择器,胜过盲目调整 10 次
3. 普通网页走 web_extract,不行再上浏览器——浏览器工具链是降级方案,不是首选
4. Cloudflare 拦截走 Web Archive,Archive 也没就走 HN 评论 API——永远有兜底,不要死磕
#Agent工坊 #HermesAgent #浏览器自动化 #网页采集 #AI工具 #技术教程
