- 人工智能
- AI Agent
- 多智能体
- MCP 服务
- 工具调用
- 浏览器控制
【免费下载链接】hive
Multi-Agent Harness for Production AI
导读
web_scrape是 Hive 多 Agent 生产框架(hive_toolsMCP 工具集)中负责网页内容抓取与提取的核心工具:它通过 Playwright 驱动无头 Chromium 渲染 JavaScript 页面、借助 playwright-stealth 规避机器人检测,再用 BeautifulSoup 剥离噪声元素、提取正文,并将提取结果落盘供 Agent 按需读取。本文以 web_scrape_tool/README.md 为主体骨架,结合 web_scrape_tool.py 源码与 test_web_scrape_tool.py 测试用例,从参数语义、安装配置、工作流程、错误处理到 SSRF 防护原理逐一展开,帮助你完整掌握该工具的能力边界与正确用法。
一、工具定位:Agent 的"网页阅读器"
web_scrape的定位非常明确——当 Agent 需要读取某个具体 URL 的内容、从网站提取数据、或阅读文章与文档时使用它(源码 docstring 中的描述,见 web_scrape_tool.py)。它与同目录下的web_search形成互补:web_search负责"找到相关页面",web_scrape负责"把找到的页面读进上下文"。
在 tools/README.md 的 "Web & Search" 工具清单中,web_scrape与web_search、search_wikipedia、exa_*等并列,共同构成 Agent 的联网信息获取能力。该工具支持三类典型场景:
- 读取指定 URL 的正文内容:如阅读一篇技术文章、一份产品文档;
- 从网站提取结构化数据:如抓取列表页的条目、标题、链接;
- 阅读 JavaScript 渲染的动态页面:SPA、带懒加载的内容,普通 HTTP 请求拿不到,必须由无头浏览器渲染。
工具不要求任何环境变量(README 明确说明),但会依赖HIVE_STORAGE_PATH/HIVE_HOME来决定提取文本的落盘目录(详见下文"落盘机制")。
二、参数详解:五个入参与返回结构
2.1 参数表
工具共接受 5 个参数(均通过 FastMCP@mcp.tool()装饰器暴露,见 web_scrape_tool.py):
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
url | str | 是 | 无 | 待抓取的网页 URL |
selector | str | 否 | None | CSS 选择器,用于只提取指定区域(如'article'、'.main-content') |
include_links | bool | 否 | False | 是否在响应中附带提取到的链接列表 |
max_length | int | 否 | 50000 | 提取文本的最大长度(取值范围 1000-500000) |
respect_robots_txt | bool | 否 | True(README 声明值) | 是否遵守目标站点的 robots.txt 规则 |
版本差异说明:README 表格中
respect_robots_txt默认值为True,而当前源码签名中默认值为False(web_scrape_tool.py),docstring 也注明"默认 False——操作者已获授权进行这些一次性的低量抓取,如需为单次调用重新启用检查可传 True"(web_scrape_tool.py)。这说明实现上默认放行、按调用显式开启合规检查。同样,README 中的max_length参数在当前源码中并未实现——实际实现是将全文(不截断)写入磁盘(见下文"落盘机制"与测试 test_web_scrape_tool.py)。引用该工具时请以实际源码签名为准。
2.2 返回值结构
成功时返回一个元数据字典(web_scrape_tool.py):
url:请求的原始 URL;final_url:重定向后的最终 URL(链接解析以此为基准);title:页面<title>文本;description:meta description,缺失时回退到 Open Graphog:description;page_type:article|listing|page(见下文"页面类型启发式");total_length:落盘文本的总字符数;saved_to:正文文件的绝对路径;headings:H1-H6 标题大纲(最多 100 条,每条含level与text);structured_data(可选):json_ld数组与open_graph字典;links(可选,仅include_links=True):最多 50 条{text, href}链接。
注意:正文文本本身不会出现在 JSON 响应中,而是写入磁盘文件,响应只携带saved_to路径与total_length元数据。
三、安装与注册:Chromium 与可选依赖
3.1 依赖安装
README 给出了两条命令(README):
uv pip install playwright playwright-stealth uv run playwright install chromiumplaywright-stealth用于规避机器人检测,Chromium 是实际渲染引擎。从 tools/src/aden_tools/tools/init.py 的导入逻辑可以看到,playwright是可选依赖:未安装时register_web_scrape被置为None,该工具会从 MCP 工具集中优雅降级移除,不影响其他工具注册。因此在实际部署中,若 Agent 不需要网页抓取能力,可以跳过上述安装。
3.2 MCP 注册方式
工具通过register_tools(mcp: FastMCP)函数注册(web_scrape_tool.py),在tools/src/aden_tools/tools/__init__.py中被统一汇总后注册进hive_toolsMCP server。该 server 在 tools/mcp_servers.json 中声明为 stdio 传输、由uv run python mcp_server.py --stdio启动,描述为"提供 web_search、web_scrape、send_email 与数据工具"。上层 Agent 框架通过 core/framework/loader/mcp_client.py 等 MCP 客户端机制加载此 server 即可获得web_scrape调用能力。
四、核心工作流:从 URL 校验到文本落盘
从源码(web_scrape_tool.py)可以还原完整的执行管线:
4.1 第一步:URL 规范化与 SSRF 检查
无协议 URL 自动补全https://前缀(web_scrape_tool.py,对应测试 test_web_scrape_tool.py)。随后在发起任何网络请求之前(包括 robots.txt 请求)执行 SSRF 防护检查_check_url_target(web_scrape_tool.py):
- 解析主机名,缺失则报错;
- IP 字面量走快速路径:命中内网段直接拦截;
- 域名走 DNS 解析(5 秒超时上限),任一解析结果命中内网地址即拦截;
- 判断逻辑
_is_internal_address(web_scrape_tool.py):非全局单播地址(含环回、私有网段、链路本地、多播)一律判为内部地址,解析失败则"fail closed"。
测试 test_web_scrape_tool.py 的参数化用例覆盖了127.0.0.1、10.0.0.1、192.168.1.1、169.254.169.254(AWS 元数据地址)等敏感目标,端到端测试也验证了对这些地址返回blocked_by_ssrf_protection: True(test_web_scrape_tool.py)。
4.2 第二步:robots.txt 检查
仅当respect_robots_txt=True时执行:用 httpx(5 秒超时、跟随重定向)拉取目标站点/robots.txt,经urllib.robotparser.RobotFileParser解析后用浏览器 UA 判断是否允许抓取(web_scrape_tool.py)。被禁止时返回Blocked by robots.txt错误并附skipped: True与提示(测试见 test_web_scrape_tool.py)。robots.txt 获取失败(HTTP 错误、超时等)则放行继续。
4.3 第三步:无头浏览器渲染
启动 Chromium 无头浏览器,携带四个启动参数(--no-sandbox、--disable-setuid-sandbox、--disable-dev-shm-usage、--disable-blink-features=AutomationControlled),以 1920x1080 视口、浏览器 UA(Chrome/131)与en-USlocale 创建上下文,并应用Stealth().apply_stealth_async(page)(web_scrape_tool.py)。
渲染阶段有两个关键机制:
- 导航级 SSRF 拦截:注册
page.route("**/*", ...)处理器,只检查document级导航请求(跳过 CSS/JS/图片等子资源,避免误伤与多余 DNS 查询),命中内网地址即route.abort("blockedbyclient")并记录错误(web_scrape_tool.py)——这防止了通过重定向绕过 SSRF 检查; - 超时分层:
page.goto用domcontentloaded等待策略、30 秒内部超时;随后wait_for_load_state("networkidle")只等 3 秒,超时则"拿已加载的内容继续"。注释明确解释:goto 的内部超时控制在 Agent 循环 60 秒预算内先触发,避免外层超时泄漏浏览器子进程([web_scrape_tool.py](https://link.gitcode.com/i/5696f479f5571eb30eb40b14e0c20da5#L242-L249, L280-L284))。
4.4 第四步:响应校验
goto返回None→Navigation failed: no response received;状态码非 200 →HTTP <status>: Failed to fetch URL,并对 401/403/429 附带"站点可能需要认证、封禁机器人或限流"的提示(web_scrape_tool.py);Content-Type非 HTML → 直接跳过(web_scrape_tool.py,对应测试 test_web_scrape_tool.py)。这些错误都在等待networkidle之前返回,测试专门验证了wait_for_load_state不会被调用(test_web_scrape_tool.py)。
4.5 第五步:结构化数据与正文提取
拿到渲染后的 HTML 后交给 BeautifulSoup 处理(web_scrape_tool.py):
- 先提取结构化数据再清理:JSON-LD 藏在
<script type="application/ld+json">中(这些 script 随后会被清除),Open Graph 从og:*的 meta 标签收集; - 清除噪声元素:
script、style、nav、footer、header、aside、noscript、iframe全部decompose(); - 提取标题与描述:
<title>文本、meta description,缺失时回退 OG 描述; - 标题大纲:收集 H1-H6 文本(上限 100 条);
- 页面类型启发式:
<article>数量 ≥ 3 →listing;恰 1 个或存在<main>→article;否则page(web_scrape_tool.py); - 定位目标子树:指定
selector时用soup.select_one(selector),未匹配返回No elements found matching selector并提示改用更宽泛选择器或走自动检测;未指定时按<main>→role="main"→<article>→ 常见内容类名(content/post/entry/article-body)→<body>的顺序自动回退(web_scrape_tool.py); - 结构保真清洗:块级元素(p、h1-h6、li、tr、div、section、article、blockquote)前后插入换行,
<br>转为换行,然后get_text(separator=" ")提取,最后压缩行内空白、折叠连续空行(web_scrape_tool.py)。测试验证段落/标题/列表的换行结构得以保留(test_web_scrape_tool.py); - 链接处理:
include_links=True时,正文中的<a>先被替换为text形式的 Markdown 内联链接(这样 Agent 读正文就能直接拿到目标地址),并单独收集最多 50 条links列表。相对链接一律基于final_url(重定向后地址)用urljoin转成绝对链接(web_scrape_tool.py),测试覆盖了相对路径、根相对路径、绝对链接、重定向后基准、锚点与查询参数保持等六类场景(test_web_scrape_tool.py)。
4.6 第六步:正文落盘而非内联返回
这是该工具最具 Agent 友好性的设计决策。源码注释明确指出:把多 KB 页面文本 JSON 包裹进响应,会对每个换行和引号做转义,污染 Agent 上下文(web_scrape_tool.py)。因此正文被完整写入磁盘(不截断、不分页),文件名格式为web_scrape_<unix毫秒>_<sanitized-host>.txt,UTF-8 纯文本(无 JSON 包装),落盘目录解析逻辑见_resolve_scrape_artifact_dir:
- 设置了
HIVE_STORAGE_PATH→ 写入<HIVE_STORAGE_PATH>/data(与 Agent 溢出文件同目录,由框架 tool_registry 注入 MCP 子进程环境); - 否则写入
<HIVE_HOME>/tool-artifacts(浏览器检查工具共用目录); HIVE_HOME缺省为~/.hive(web_scrape_tool.py)。
docstring 建议 Agent 通过terminal_exec("cat <saved_to>")(大输出用terminal_output_get)或terminal_rg按需读取正文(web_scrape_tool.py)。测试断言响应中不包含content/length/truncated等内联字段,且total_length与磁盘文件长度一致(test_web_scrape_tool.py)。
五、错误处理速查表
README 列出的错误字典与源码一一对应:
| 错误消息 | 触发条件 | 源码位置 |
|---|---|---|
HTTP <status>: Failed to fetch URL | 服务器返回非 200 状态码 | web_scrape_tool.py |
Navigation failed: no response received | 浏览器无法导航到 URL(goto 返回 None) | web_scrape_tool.py |
No elements found matching selector: <selector> | CSS 选择器未匹配任何元素 | web_scrape_tool.py |
Request timed out | 页面加载超过 60 秒(PlaywrightTimeout) | web_scrape_tool.py |
Blocked by robots.txt: <url> | 目标 URL 被站点 robots.txt 禁止 | web_scrape_tool.py |
Browser error: <error> | Playwright/Chromium 底层异常 | web_scrape_tool.py |
Scraping failed: <error> | HTML 解析或其他异常 | web_scrape_tool.py |
Blocked: ... internal address/DNS resolution failed | SSRF 防护拦截或 DNS 解析失败(5 秒超时) | web_scrape_tool.py |
Skipping non-HTML content (Content-Type: ...) | 目标返回非 HTML 内容类型 | web_scrape_tool.py |
多处错误附带hint字段(如 401/403/429 提示"站点可能需要认证、封禁机器人或限流",404 提示"资源可能不存在或服务器宕机",robots.txt 拦截提示"如你获授权可传respect_robots_txt=False"),Agent 可直接据此调整策略。
六、使用建议与注意事项
综合 README 的 Notes 与源码实现,整理出以下实战要点:
- JS 渲染能力:工具会等
networkidle(最多 3 秒)再提取,SPA 与动态加载页面可正常提取;若页面持续有网络活动,也会用已加载内容继续,不会无限等待; - URL 补全:不带协议的 URL 自动加
https://,但建议显式写全协议; - 正文读取方式:响应中只有元数据,正文在
saved_to指向的文件里,请用终端工具cat/rg读取,勿期望响应内联正文; - 链接绝对化:
include_links=True时正文内链接会变成textMarkdown 格式,且基于重定向后的最终 URL 解析,无需担心相对路径失效; - 合规与安全:SSRF 防护默认开启且无法关闭(内网/环回/元数据地址一律拦截);robots.txt 检查按 README 声明默认开启,但当前源码默认
False,如需合规抓取请在调用时显式传respect_robots_txt=True; - 可选依赖:未安装 playwright 时工具自动从工具集移除,不会破坏 MCP server 启动;
- 测试参考:完整的 Mock 测试套件位于 test_web_scrape_tool.py,覆盖参数行为、链接转换、结构化数据、错误处理、robots.txt 与 SSRF 防护,可作为理解工具行为边界的权威参考。
七、源码速览
| 文件 | 作用 |
|---|---|
| web_scrape_tool/README.md | 工具官方文档(本文主体) |
| web_scrape_tool/web_scrape_tool.py | 工具完整实现(含 SSRF、robots、提取、落盘) |
| web_scrape_tool/init.py | register_tools导出 |
| tools/init.py | 工具批量注册与 playwright 可选依赖降级 |
| test_web_scrape_tool.py | 行为测试套件 |
| mcp_servers.json | hive_toolsMCP server 声明 |
| tools/README.md | 工具总览(Web & Search 分类) |
- 人工智能
- AI Agent
- 多智能体
- MCP 服务
- 工具调用
- 浏览器控制
【免费下载链接】hive
Multi-Agent Harness for Production AI
相关推荐
探秘Playwright Stealth:无痕浏览的Python神器
探秘Playwright Stealth:无痕浏览的Python神器 在数字世界的隐蔽战线,每一个请求都可能暴露你的踪迹。但今天,我们有了一个新的秘密武器——
网页爬虫Lightdash UnfurlService 深度解析:基于 Playwright 的无头浏览器截图与截图就绪指示器架构
Lightdash UnfurlService 深度解析:基于 Playwright 的无头浏览器截图与截图就绪指示器架构 导读 本文聚焦 Lightdash
后端前端数据分析数据可视化人工智能AI Agent无头浏览器服务如何防SSRF攻击:Browserless私有网络拦截机制深度剖析
无头浏览器服务如何防SSRF攻击:Browserless私有网络拦截机制深度剖析 Browserless 是一个可在 Docker 中部署的无头浏览器自动化服务
后端API网关
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考