🎯 一款可定制、具备反检测功能的云浏览器,由自主研发的 Chromium驱动,专为网页爬虫AI 代理设计。👉立即试用
返回博客

Hugging Face smolagents + Scrapeless MCP:在Python中构建AI网络爬虫

Ava Wilson
Ava Wilson

Expert in Web Scraping Technologies

17-Jul-2026

TL;DR:

  • 一个Hugging Face代理可以从一个MCP端点获取21个实时网络工具。ToolCollection.from_mcp 指向 https://api.scrapeless.com/mcp 可以为smolagents提供 CodeAgent 浏览器控制、页面抓取以及谷歌搜索和趋势,同时渲染、代理路由和反检测仍然在服务器端处理。
  • 托管路径是纯Python。 通过设置 x-api-token 头的可流式HTTP替换任何本地服务器进程——无需Node.js,只需一个 pip install "smolagents[mcp]"
  • 工具界面在模型之前就已可用。scrape_markdown 的简单函数调用返回一个实时页面的干净markdown——本指南演示页面为4,249个字符——因此您只需一个Scrapeless API密钥即可测试连接。
  • AI抓取程序按含义提取,而不是按选择器。 代理读取markdown并返回您请求的字段,因此通常情况下,网站重设计不会打破CSS选择器脚本的情况也不会给您带来额外成本。
  • 唯一的额外先决条件是模型密钥。 工具列出、直接工具调用和代理构建都可以在没有模型密钥的情况下运行;只有推理往返需要Hugging Face令牌或其他支持的提供者。
  • 免费开始。app.scrapeless.com 的免费计划上创建您的API密钥。

这个集成实现了什么

基于选择器的抓取程序是一种赌注,认为目标页面永远不会改变,而这个赌注往往会输。AI抓取程序采取了不同的立场:作为干净文本获取页面,让语言模型提取您想要的字段,并停止关心价格这周位于哪个 div 中。

smolagents 是Hugging Face的小代理库——其代理编写Python代码来调用工具,而不是发出JSON工具调用。它自身缺少的就是到达实时网络的方法。这正是模型上下文协议的工作:模型上下文协议规范定义了服务器如何广告任何客户端可以列出和调用的已类型化工具。如果你对此协议不熟悉,关于什么是MCP以及它是如何工作的的入门介绍涵盖了从头到尾的概念。

将两者结合在一起,您将在几十行Python代码中获得一个程序化的AI抓取程序:smolagents提供推理循环,Scrapeless MCP服务器提供作为可调用工具的抓取、渲染和搜索。本指南一步步构建该抓取程序,并准确显示哪些部分仅使用Scrapeless密钥即可运行。

为什么选择Scrapeless MCP

Scrapeless MCP服务器将抓取基础设施暴露为21个已类型化工具,而重工作是在服务器上完成的,而不是在您的进程中。 scrape_htmlscrape_markdownscrape_screenshot以不同形状捕获单个页面。十六个 browser_* 工具在抓取浏览器上操作云浏览器会话——一个由自开发的Chromium驱动的反检测云浏览器——适用于代理需要点击、输入和滚动的工作。 google_searchgoogle_trends涵盖发现。

有三个属性对这个构建至关重要:

  • 一个密钥,托管传输。 驱动平台其余部分的同一个Scrapeless API密钥验证MCP端点。您的Python进程从未启动浏览器或Node服务器。
  • 无模型可测试性。 工具列表和执行时没有任何LLM参与,因此集成可以逐层证明,而不是通过代理的推理进行调试。
  • 优先使用markdown的提取路径。 页面markdown捕获的大小仅为其原始HTML的一个分数,这意味着每次提取的令牌更少,模型阅读时的噪声更少。 scrape_markdown 正是返回这一点。

如果您的技术栈也是LangChain,该端点同样适用——LangChain + Scrapeless MCP指南 从适配器一侧讲述了相同的内容。

先决条件

  • Python 3.10或更新版本——本指南中的运行使用的是Python 3.12。
  • 在仪表板中获取Scrapeless API密钥——开发者文档覆盖了密钥创建和端点参考。
  • 仅针对最终代理的往返:一个 Hugging Face 令牌(或任何模型提供商 smolagents 支持的凭证)。在此之前的每个步骤都可以不使用它。

安装和配置

一个额外的包引入了代理库和 MCP 客户端基础设施。这些版本是本指南撰写时使用的版本 — smolagents 1.26.0,mcp 1.27.1,mcpadapt 0.1.20:

bash Copy
pip install "smolagents[mcp]==1.26.0"

导出您的密钥,以便脚本可以从环境中读取,而不是从源代码中读取:

bash Copy
export SCRAPELESS_API_KEY="sk_your_key_here"

通过可流式传输的 HTTP 连接并列出工具

连接是一个字典,而不是配置文件。ToolCollection.from_mcp 接受与底层可流式传输的 HTTP 客户端相同的参数,因此端点 URL、传输名称和身份验证头在一个字面量中传递:

python Copy
# connect_and_list.py — 与 Scrapeless MCP 服务器握手,列出工具
import os

from smolagents import ToolCollection

server = {
    "url": "https://api.scrapeless.com/mcp",
    "transport": "streamable-http",
    "headers": {"x-api-token": os.environ["SCRAPELESS_API_KEY"]},
}

with ToolCollection.from_mcp(server, trust_remote_code=True, structured_output=False) as tc:
    names = sorted(tool.name for tool in tc.tools)
    print(f"工具数量: {len(names)}")
    print("\n".join(names))

上下文管理器拥有连接生命周期:在进入时执行 MCP 握手,在退出时干净地断开连接。有一个参数值得一提:MCP 工具规范 允许服务器将结果作为纯文本或结构化内容返回,而 Scrapeless 工具返回文本 — 因此显式传递 structured_output=False。smolagents 1.26 警告每当省略该参数,因为其默认值在未来的版本中计划发生变化。

正确的握手会打印 工具数量: 21,随后是工具的名称:十六个 browser_* 工具,google_searchgoogle_trendsscrape_htmlscrape_markdownscrape_screenshot

也存在标准输入输出路径,供希望启动本地服务器进程的客户端使用 — 背后有不同生命周期的同样 21 个工具:

json Copy
{
  "mcpServers": {
    "scrapeless": {
      "command": "npx",
      "args": ["-y", "scrapeless-mcp-server"],
      "env": { "SCRAPELESS_KEY": "sk_your_key_here" }
    }
  }
}

对于仅限 Python 的构建,可流式传输 HTTP 是更短的路径:除了 pip 之外没有什么需要安装,也不需要持续运行。

在免费计划下获取您的 API 密钥:app.scrapeless.com

在任何模型介入之前调用 scrape_markdown

集合中的每个工具都是可调用的 smolagents Tool 对象,因此可以直接调用抓取层 — 没有代理或模型密钥的介入:

python Copy
# call_tool.py — 作为普通函数调用执行一个 MCP 工具
import json
import os

from smolagents import ToolCollection

server = {
    "url": "https://api.scrapeless.com/mcp",
    "transport": "streamable-http",
    "headers": {"x-api-token": os.environ["SCRAPELESS_API_KEY"]},
}

with ToolCollection.from_mcp(server, trust_remote_code=True, structured_output=False) as tc:
    tools = {tool.name: tool for tool in tc.tools}
    raw = str(tools["scrape_markdown"](url="https://quotes.toscrape.com/"))
    # 托管的工具在 "Response:" 行之后返回页面作为 JSON 引号字符串 — 解码它以获取 markdown 本身。
    body = raw.split("\n\n", 1)[1] if raw.startswith("Response:") else raw
    text = json.loads(body) if body.startswith('"') else body
    print(f"scrape_markdown 返回了 {len(text):,} 个字符的 markdown")
    print(text[:160])

在报价演示网站上,这返回了 4,249 个字符的 markdown,以页面标题和第一个引用开头 — 可读文本,页面装饰已被剥离。该单一调用是抓取器的整个获取层。之后的所有内容都是解释。

将工具附加到 CodeAgent

将集合绑定到代理是一个构造函数,并且在任何模型调用发生之前就可以工作。代理对象按名称索引每个 MCP 工具,旁边是其内置的 final_answer

python Copy
# attach_agent.py — 将 MCP 工具接口传递给 smolagents CodeAgent
import os

from smolagents import CodeAgent, InferenceClientModel, ToolCollection

server = {
    "url": "https://api.scrapeless.com/mcp",
    "transport": "streamable-http",
    "headers": {"x-api-token": os.environ["SCRAPELESS_API_KEY"]},
}

with ToolCollection.from_mcp(server, trust_remote_code=True, structured_output=False) as tc:
    model = InferenceClientModel(model_id="Qwen/Qwen2.5-72B-Instruct")
    agent = CodeAgent(tools=[*tc.tools], model=model, add_base_tools=False)
    print(sorted(agent.tools.keys()))

add_base_tools=False 保持工具箱仅包含 MCP 工具和代理的内置 final_answer。对于一个应该仅获取页面的爬虫,您可以进一步缩小范围——仅传递您想要的工具,比如 tools=[t for t in tc.tools if t.name == "scrape_markdown"]——这样模型就无法在不必要的浏览器会话或搜索调用中游走。较小的工具箱也意味着较小的系统提示和模型更少的错误判断。

提示驱动的使用:AI 爬虫运行

提取步骤是一个提示,而不是解析器。您告诉代理读取哪个页面以及返回哪些字段,代理决定调用 scrape_markdown,读取结果并组装答案——smolagents 用类型化输入向模型描述每个工具,用与 JSON Schema 规范 定义的机器可读字段约束相同的结构。

注意:这最后一步是本指南中的一个前提缺口——代理的往返需要一个模型提供者。在运行之前,用 Hugging Face 令牌设置 HF_TOKEN(或配置 smolagents 支持的其他提供者)。上述每个块仅使用 Scrapeless 密钥运行。

python Copy
# run_scraper.py — 模型往返(需要 HF_TOKEN 或其他提供者)
result = agent.run(
    "在 https://quotes.toscrape.com/ 上调用 scrape_markdown 并返回页面上的引用的 JSON 数组。 "
    "每个项目必须准确具有这几个键: "
    "text(字符串),author(字符串),tags(字符串数组)。 "
    "仅返回 JSON 数组,无需评论。"
)
print(result)

提示形状控制输出形状。命名确切的键和类型,要求“仅 JSON 数组”,并保持每次运行一个页面会让您得到可以 json.loads 并在下游验证的输出。当页面上缺少某个字段时,指示代理使用 null 而不是捏造一个值——模型在未被告知不这样做的情况下,会自信地填补空白。

您将获得什么

从获取层,您得到 markdown 作为字符串:页面标题作为标题,链接文本以括号保留,正文文本按阅读顺序。来自引用网站的 4,249 字符捕获如下开始:

text Copy
# [Quotes to Scrape](https://quotes.toscrape.com/)

[Login](https://quotes.toscrape.com/login)

“我们所创造的世界是我们思维的过程。

从代理运行中,您得到无论您的提示强制执行的合同——在这里,是 {text, author, tags} 对象的 JSON 数组,每个页面上的引用一个。排列的价值在于目标网站更改其类名的那一天:markdown 仍然包含引用,提示仍然命名字段,而爬虫仍然返回相同的模式,而基于选择器的脚本返回为空。

结论

集成是三个小步骤:将 ToolCollection.from_mcp 指向托管的端点,通过直接调用 scrape_markdown 来证明获取层,然后将工具绑定到 CodeAgent 并让提示进行提取。每一层都可以单独测试,只有最后一层需要模型密钥,而经典爬虫中最容易出错的部分——解析——是模型可以吸收的部分。

准备好让您的代理进行真实的网页交互吗?

MCP 端点使用与 Scrapeless 平台其他部分相同的 API 密钥进行身份验证——计划和包含的配额请见 定价页面。在 app.scrapeless.com 上的免费计划中创建一个密钥,上面的握手脚本将在不到一分钟的时间内打印出您的 21 个工具。

常见问题

问:什么是 AI 爬虫?

AI 爬虫是一种使用语言模型作为提取步骤的爬虫,而不是手写的解析规则。传统的爬虫将抓取和解析与特定页面结构结合在一起;而 AI 爬虫则将页面作为文本抓取,并要求模型返回命名字段,这在布局更改打破选择器时仍然有效。

问:我需要 Hugging Face 令牌才能调用 Scrapeless 工具吗?

不需要。列出工具、直接调用 scrape_markdown 和构造 CodeAgent 都仅使用 Scrapeless API 密钥进行身份验证。Hugging Face 令牌(或其他提供者的密钥)仅用于一件事:agent.run() 推理往返。

问:我应该通过可流式传输的 HTTP 连接还是 stdio?

对于 Python 项目,使用可流式传输的 HTTP:它不需要本地进程,并通过头部进行身份验证。stdio 传输(npx -y scrapeless-mcp-server,通过 SCRAPELESS_KEY 环境变量进行身份验证)适合自行管理服务器进程的桌面 MCP 客户端。这两种传输都暴露相同的工具表面。
问:代理可以只使用一个工具而不是所有21个吗?

可以。在构建代理之前过滤集合——tools=[t for t in tc.tools if t.name == "scrape_markdown"]——模型只会看到该工具。对于单一目的的爬虫,这是推荐的方式:系统提示缩小,并且模型无法启动你从未打算启动的浏览器会话。

问:对于依赖JavaScript的页面或防爬虫挑战背后的页面怎么办?

渲染发生在服务器端,因此你的Python代码不会改变。scrape_htmlscrape_markdown处理需要JavaScript执行的页面,browser_*工具驱动全云浏览器会话,用于需要点击或输入的流程。代理路由和反检测是托管服务的一部分,而不是代理需要推理的内容。

问:哪些模型可以与smolagents一起使用?

任何库支持的提供者。InferenceClientModel涵盖通过Hugging Face推理提供者提供的模型,库也包含OpenAIModelAzureOpenAIModelAmazonBedrockModelLiteLLMModel以及本地后端如TransformersModel——查看smolagents模型参考以获取当前列表。MCP端是与模型无关的:不论哪个模型推理,它们的工具看起来都相同。

问:用AI代理抓取数据合法吗?

适用与任何爬虫相同的规则:只收集公共页面,尊重目标网站的条款和robots指令,保持量的有限,并在适用的隐私法下处理任何个人数据。代理改变了提取的方式,而不是你被允许收集的内容——如有疑问,在扩大工作负载之前请咨询法律顾问。

在Scrapeless,我们仅访问公开可用的数据,并严格遵循适用的法律、法规和网站隐私政策。本博客中的内容仅供演示之用,不涉及任何非法或侵权活动。我们对使用本博客或第三方链接中的信息不做任何保证,并免除所有责任。在进行任何抓取活动之前,请咨询您的法律顾问,并审查目标网站的服务条款或获取必要的许可。

最受欢迎的文章

目录