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

Pydantic AI + Scrapeless:通过 MCP 为您的代理提供实时网络工具

Daniel Kim
Daniel Kim

Lead Scraping Automation Engineer

22-Jul-2026

TL;DR:

  • Pydantic AI 通过可流式传输的 HTTP 连接到 Scrapeless MCP 服务器,并为代理提供 21 个实时网络工具,从 scrape_markdown 到完整的浏览器自动化工具集。
  • 连接使用了 pydantic_ai.mcp 中的三个类:StreamableHttpTransportFastMCPClientMCPToolset,你将其附加到 Agent
  • 握手、工具列表和真实的 scrape_markdown 调用都在没有模型提供者密钥的情况下运行;只有最后的 agent.run 生成需要一个。
  • defer_model_check=True 允许在模型密钥存在之前构建 Agent,因此你可以先连接并检查工具集。
  • 一个 scrape_markdown 调用返回目标页面的干净 Markdown,准备将其作为上下文返回给模型。
  • Scrapeless 免费计划 上开始,连接你的第一个代理。

Pydantic AI 为代理提供了结构:类型化输出、验证过的工具参数以及组合工具的简洁方式。它没有为代理提供访问实时网络的方式。这个差距正是模型上下文协议所弥补的。将 Pydantic AI 指向 MCP 服务器,该服务器暴露的每个工具都成为你的代理可以调用的工具,参数模式以与其余 Pydantic AI 代码相同的方式进行验证。

此指南将 Pydantic AI 连接到 Scrapeless MCP 服务器,列出其提供的工具,真实调用一个,并将整个工具集附加到 Agent —— 所有操作都已针对实时服务器进行验证。唯一需要模型提供者密钥的步骤是在最后的生成调用中,这篇文章明确说明了这一点。

为什么选择 Scrapeless MCP

Scrapeless MCP 服务器暴露了代理可以直接调用的网页抓取和浏览器工具,因此你无需自己构建或托管抓取层。单个连接提供 21 个工具:scrape_markdownscrape_html 用于页面内容,google_searchgoogle_trends 用于搜索数据,scrape_screenshot 用于截图,以及一个完整的 browser_* 集合,用于驱动云浏览器执行点击、输入、滚动和导航。有关服务器本身的详细信息,请参考 Scrapeless MCP 服务器 的帖子;此指南则是关于如何将其与 Pydantic AI 连接在一起。

由于这些工具在 Scrapeless 基础设施上运行,代理可以获得渲染的页面和搜索结果,而无需本地浏览器或代理池。browser_* 工具驱动 Scrapeless 云浏览器,因此代理可以导航交互式页面并读取渲染内容。

先决条件

  • Python 3.10 或更高版本。
  • 从仪表板获取的 Scrapeless API 密钥,导出为 SCRAPELESS_API_KEY
  • 仅用于最终生成步骤的模型提供者密钥(如 OPENAI_API_KEY)。握手、工具列表和工具调用不需要该密钥。

安装

安装 Pydantic AI 的 MCP 额外功能,这将引入 MCP 客户端类。

bash Copy
pip install "pydantic-ai-slim[mcp]"

在终端中设置你的 Scrapeless 密钥。运行时使用实际密钥并在源代码中保留占位符。

bash Copy
export SCRAPELESS_API_KEY="sk_your_key_here"

连接并列出工具

连接由三个对象组成。StreamableHttpTransport 命名终端并在 x-api-token 头中携带 API 密钥,FastMCPClient 通过该传输协议进行通信,MCPToolset 封装客户端以便 Pydantic AI 可以使用它。输入工具集的异步上下文将运行握手;list_tools 返回服务器提供的工具。

python Copy
import asyncio
import os

from pydantic_ai.mcp import FastMCPClient, MCPToolset, StreamableHttpTransport

transport = StreamableHttpTransport(
    url="https://api.scrapeless.com/mcp",
    headers={"x-api-token": os.environ["SCRAPELESS_API_KEY"]},
)
scrapeless = MCPToolset(FastMCPClient(transport))


async def main() -> None:
    async with scrapeless:
        tools = await scrapeless.list_tools()
        names = sorted(t.name for t in tools)
        print("工具数量:", len(names))
        print("工具:", ", ".join(names))


asyncio.run(main())

实时服务器返回 21 个工具,并且在此之前没有设置模型提供者密钥。

text Copy
工具数量: 21
工具: browser_click, browser_close, browser_create, browser_get_html, browser_get_text, browser_go_back, browser_go_forward, browser_goto, browser_press_key, browser_screenshot, browser_scroll, browser_scroll_to, browser_snapshot, browser_type, browser_wait, browser_wait_for, google_search, google_trends, scrape_html, scrape_markdown, scrape_screenshot

工具名称是扁平的,没有服务器前缀,因此 scrape_markdown 恰好可以通过该名称进行访问。传输和消息层遵循 模型上下文协议规范,该规范本身基于 JSON-RPC 2.0 规范

直接调用工具

在将工具交给代理之前,先自己调用一个工具,看看它返回什么。direct_call_tool 通过名称和参数调用工具,这是确认工具是否有效并检查其输出的最快方法。

python Copy
import asyncio
import os

from pydantic_ai.mcp import FastMCPClient, MCPToolset, StreamableHttpTransport

transport = StreamableHttpTransport(
    url="https://api.scrapeless.com/mcp",
    headers={"x-api-token": os.environ["SCRAPELESS_API_KEY"]},
)
scrapeless = MCPToolset(FastMCPClient(transport))


async def main() -> None:
    async with scrapeless:
        result = await scrapeless.direct_call_tool("scrape_markdown", {"url": "https://quotes.toscrape.com/"})
        markdown = result if isinstance(result, str) else str(result)
        print("markdown 字符数:", len(markdown))
        print("包含引用:", "The world as we have created it" in markdown)


asyncio.run(main())

调用返回页面的Markdown格式,内容检查确认目标页面上确实存在真实的引用。

text Copy
markdown 字符数: 4308
包含引用: True

这是您的代理获得的形态:可以进行推理的干净Markdown,而不是必须剥离的原始HTML。Pydantic AI MCP 客户端文档 完整涵盖了工具集方法。

将工具附加到代理

附加是一个参数:将工具集传递给 Agenttoolsets。由于正常的 Agent 构造会立即验证模型,defer_model_check=True 允许它在设置模型键之前构建,因此您可以先连接和检查工具集。

python Copy
import asyncio
import os

from pydantic_ai import Agent
from pydantic_ai.mcp import FastMCPClient, MCPToolset, StreamableHttpTransport

transport = StreamableHttpTransport(
    url="https://api.scrapeless.com/mcp",
    headers={"x-api-token": os.environ["SCRAPELESS_API_KEY"]},
)
scrapeless = MCPToolset(FastMCPClient(transport))

# defer_model_check 允许代理在设置模型键之前构建,
# 因此工具集可以首先连线并检查。
agent = Agent("openai:gpt-4o", toolsets=[scrapeless], defer_model_check=True)


async def main() -> None:
    async with scrapeless:
        names = sorted(t.name for t in await scrapeless.list_tools())
    web = [n for n in names if n.startswith(("scrape_", "google_"))]
    print("代理连接了", len(names), "个Scrapeless工具")
    print("网络工具:", web)


asyncio.run(main())

代理现在携带每个Scrapeless工具,而网页抓取子集是大多数教程首先会用到的部分。

text Copy
代理连接了 21 个Scrapeless工具
网络工具: ['google_search', 'google_trends', 'scrape_html', 'scrape_markdown', 'scrape_screenshot']

要仅将几个工具交给代理而不是全部21个,MCPToolset 提供了 filteredrenamed,这样您可以将代理限制为仅 scrape_markdowngoogle_search,而不是完整的浏览器集合。

运行提示

工具集附加后,代理决定何时调用工具。这是需要模型提供者密钥的一步。

注意:agent.run 需要一个模型提供者密钥,如 OPENAI_API_KEY。以上所有内容——握手、21个工具列表、scrape_markdown 调用和附件——都可以在没有它的情况下运行。只有这一生成调用是前提差距;下面展示的是它所需的确切形式,而不是捕获的结果。

python Copy
async def run_prompt() -> None:
    async with agent:
        result = await agent.run(
            "使用 scrape_markdown 获取 https://quotes.toscrape.com/ "
            "并列出前三个引用及其作者。"
        )
    print(result.output)


asyncio.run(run_prompt())

在运行时,模型读取提示,使用 URL 调用 scrape_markdown,接收之前调用已经演示的 Markdown,并写下答案。工具层在您直接调用或让模型调用时是相同的。

结论

Pydantic AI加上Scrapeless MCP服务器是从光秃秃的代理到读写实时网络的捷径。三个类建立了连接,list_tools 显示了21个工具,direct_call_tool 证明了一个工具有效,toolsets 参数将它们全部附加。只有生成步骤需要模型密钥,这使得整个集成在您承诺提供者之前可以探索。根据上面的脚本,从您代理需要的工具中将工具集限制到所需的工具,让模型完成其余的工作。
创建一个免费的Scrapeless账户以获取API密钥,并在计划持续代理时查看Scrapeless定价

常见问题

问:Pydantic AI是否需要模型密钥来列出MCP工具?

不需要。握手、list_toolsdirect_call_tool仅通过Scrapeless API密钥运行。模型提供者密钥仅在agent.run时需要,当模型本身决定调用哪些工具,因此您可以在承诺提供者之前探索和测试整个工具表面。

问:FastMCPClient和MCPToolset有什么区别?

FastMCPClient通过传输协议与MCP协议通信,并公开低级操作,如list_toolsMCPToolset封装该客户端,以便Pydantic AI可以将服务器的工具视为代理工具,并增加filteredrenamed等工具集功能。您将MCPToolset附加到Agent上,而不是客户端。

问:如何连接到标准输入输出MCP服务器而不是HTTP?

交换传输。使用StdioTransport与服务器命令,而不是使用带有URL的StreamableHttpTransport,然后将其包装在相同的FastMCPClientMCPToolset中。Scrapeless MCP服务器是一个托管的HTTP端点,因此本指南使用StreamableHttpTransport

问:为什么在构建代理时使用defer_model_check?

构建Agent通常会立即验证模型提供者,如果没有设置密钥则会失败。defer_model_check=True将该检查推迟到运行时,因此您可以构建代理,连接工具集,并在没有模型密钥的情况下检查可用工具。

问:如何仅向代理提供部分工具?

使用MCPToolset.filtered公开一个子集,或使用renamed更改工具在模型中的显示方式。将代理的范围限制为scrape_markdowngoogle_search比在任务只需内容和搜索的情况下提供所有21个工具更安全。

问:scrape_markdown返回什么?

它返回目标页面呈现为Markdown,在验证调用中,引用页面的字符数为4,308,包含页面的真实文本。Markdown比原始HTML更易于模型推理,因此它是将页面内容反馈到提示中的良好默认值。

问:通过工具进行抓取是否受到目标规则的约束?

是的。这些工具获取公共页面,您仍然负责遵守每个目标的条款及其爬虫排除协议指令。保持抓取量有限且数据公开,并将代理的范围限制在任务实际需要的工具上。

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

最受欢迎的文章

目录