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

LlamaIndex + Scrapeless:将实时网页馈送到您的索引中

Alex Johnson
Alex Johnson

Senior Web Scraping Engineer

22-Jul-2026

检索索引的时效性仅与您放入其中的文档相关。LlamaIndex 在分块、嵌入和检索方面表现出色;但在这一切之前,实时网页必须转化为干净的文本,这一步骤往往静默失效。

将 LlamaIndex 连接到 Scrapeless MCP 服务器可以处理该步骤。MCP 工具将渲染后的页面返回为 markdown,LlamaIndex 将其包装为 Document 对象,其余的摄取管道保持不变。本指南运行连接、工具发现、实际页面获取以及文档到节点的拆分,整个过程完整无漏。

此设置为您的索引提供了什么

您的摄取代码通过一个连接获得 21 个可调用的工具,这些工具以原生的 LlamaIndex 工具形式出现,而不是您自己包装的工具。

分组对于摄取来说很重要:

  • 页面检索scrape_markdown 返回已转换为 markdown 的页面,这是分割器和嵌入模型都能最好处理的格式。scrape_htmlscrape_screenshot 返回另外两种格式。
  • 搜索google_searchgoogle_trends 让摄取作业发现 URL,而不是拿到一个固定的列表。
  • 实时浏览器控制 — 十六个 browser_* 工具用于在内容存在之前需要交互的页面。

渲染、代理路由和访问处理都发生在服务器端,因此摄取过程保持为一个简单的 Python 作业,不需要安装浏览器。

为什么选择 Scrapeless MCP 服务器

模型上下文协议规范 定义了客户端如何从服务器发现工具及其参数模式,这使得它与编写抓取助手有所不同:工具列表和每个工具的参数从服务器返回,而不是在您的项目中硬编码。调用通过 JSON-RPC 2.0 消息传输。

Scrapeless 托管端点,因此没有服务器进程与您的索引器并行运行。身份验证仅需一个头部。browser_* 组由 Scrapeless 抓取浏览器 支持,每个工具的参数在 Scrapeless 文档 中有详细记录。

先决条件

  • Python 3.10 或更高版本。目前 llama-index-corellama-index-tools-mcp 都声明为 >=3.10,<4.0
  • 从仪表板获取的 Scrapeless API 密钥。
  • 仅针对代理部分:如 llama-index-llms-openai 之类的 LLM 集成包以及该供应商的密钥。

注意:下面摄取部分中的所有操作均使用 Scrapeless 密钥和没有模型提供者密钥执行。MCP 连接、工具发现、参数模式、实时工具调用以及 Document 到节点的拆分都运行正常。最后的代理步骤是一个前提条件的缺口 — 在没有安装 LLM 集成的情况下构造 FunctionAgent 会引发 ImportError: llama-index-llms-openai package not found,因此该块被显示为您添加的代码,而不是捕获的输出。

安装

bash Copy
pip install "llama-index-tools-mcp==0.4.8"

该包随附 llama-index-coremcp 客户端。请在您的 shell 中设置密钥:

bash Copy
export SCRAPELESS_API_KEY="your_api_key_here"

连接并列出工具

BasicMCPClient 接受端点 URL 和头部;McpToolSpec 将服务器的工具列表转换为 LlamaIndex 工具:

python Copy
import asyncio, os
from llama_index.tools.mcp import BasicMCPClient, McpToolSpec

async def main():
    client = BasicMCPClient(
        "https://api.scrapeless.com/mcp",
        headers={"x-api-token": os.environ["SCRAPELESS_API_KEY"]},
    )
    spec = McpToolSpec(client=client)
    tools = await spec.to_tool_list_async()
    print("工具数量:", len(tools))
    print("示例名称:", sorted(t.metadata.name for t in tools)[:6])

asyncio.run(main())
text Copy
工具数量: 21
示例名称: ['browser_click', 'browser_close', 'browser_create', 'browser_get_html', 'browser_get_text', 'browser_go_back']

该 API 在整个过程中都是异步的,这就是示例运行在 asyncio.run 中的原因。工具名称以扁平的形式到达,没有服务器前缀或点状名称空间,因此 scrape_markdown 是您的代码和代理将使用的字面名称。

仅获取作业所需的工具

摄取作业很少需要浏览器会话控制。McpToolSpec 接受 allowed_tools 并仅返回这些工具,这样可以保持表面简洁,参数模式易于阅读:

python Copy
import asyncio, os
from llama_index.tools.mcp import BasicMCPClient, McpToolSpec

async def main():
    client = BasicMCPClient(
        "https://api.scrapeless.com/mcp",
        headers={"x-api-token": os.environ["SCRAPELESS_API_KEY"]},
    )
text Copy
过滤后的数量:1
名称:scrape_markdown
fn_schema 字段:['url']

该架构来自服务器,因此它是真实的合同,而不是假设:scrape_markdown 接受一个 url。LlamaIndex 将其暴露为 fn_schema,这是代理用于构建其调用的相同 Pydantic 模型。

准备好将其指向您自己的来源了吗? 创建一个免费的 Scrapeless 帐户 并使用您仪表板上的密钥进行连接。

将实时页面转换为节点

这是检索时重要的部分。直接调用工具,将每个结果包装为 Document,其元数据中包含源,然后拆分为节点:

python Copy
import asyncio, os
from llama_index.tools.mcp import BasicMCPClient, McpToolSpec
from llama_index.core import Document
from llama_index.core.node_parser import SentenceSplitter

async def main():
    client = BasicMCPClient(
        "https://api.scrapeless.com/mcp",
        headers={"x-api-token": os.environ["SCRAPELESS_API_KEY"]},
    )
    spec = McpToolSpec(client=client, allowed_tools=["scrape_markdown"])
    tool = (await spec.to_tool_list_async())[0]

    urls = [
        "https://quotes.toscrape.com/js/",
        "https://quotes.toscrape.com/page/2/",
    ]

    docs = []
    for url in urls:
        markdown = str(await tool.acall(url=url))
        docs.append(Document(text=markdown, metadata={"source": url}))
    print(f"文档数量:{len(docs)}")

    splitter = SentenceSplitter(chunk_size=256, chunk_overlap=32)
    nodes = splitter.get_nodes_from_documents(docs)
    print(f"拆分后的节点数量:{len(nodes)}")
    print(f"第一个节点源:{nodes[0].metadata['source']}")
    print(f"第一个节点字符数:{len(nodes[0].get_content())}")

asyncio.run(main())
text Copy
文档数量:2
拆分后的节点数量:14
第一个节点源:https://quotes.toscrape.com/js/
第一个节点字符数:571

输出中的几个内容值得仔细阅读。

第一个 URL 是一个客户端渲染的页面 - 它的内容是通过脚本写入 DOM 的 - 它仍然生成了可用的 markdown,因为渲染发生在转换之前的服务器端。对同一 URL 的普通 HTTP 获取返回的标记中没有任何内容。

chunk_size=256 计算的是令牌,而不是字符,这就是第一个节点长度为 571 个字符的原因。以字符来设置拆分器的大小是导致最终得到溢出嵌入模型上下文的块的常见方式。

每个 Document 上的 metadata={"source": url} 在拆分后依然保存并出现在从中派生的每个节点上。这使得检索结果可以引用其来源,并且在这里附加要比后期重建容易得多。

Markdown 是这个过程的正确中间格式:标题和链接得以保留,而脚本、样式和布局标记则不会,因此嵌入预算用于内容。

将工具交给代理

一旦拿到工具,代理可以决定调用哪个,而不是遵循固定的 URL 列表。此步骤需要一个 LLM 集成包和该提供者的密钥。

注意:此块是个先决条件缺口。如果没有安装 LLM 集成,构建代理会引发 ImportError: llama-index-llms-openai package not found, please run pip install llama-index-llms-openai,因此没有输出。

python Copy
from llama_index.core.agent.workflow import FunctionAgent
from llama_index.llms.openai import OpenAI

agent = FunctionAgent(
    tools=tools,
    llm=OpenAI(model="gpt-4.1-mini"),
    system_prompt="研究公共页面并返回干净的笔记及其来源。",
)

response = await agent.run("总结 quotes.toscrape.com 上引用的作者")
print(response)

结论

将 LlamaIndex 连接到 Scrapeless MCP 服务器需要一个客户端、一个工具规格和一个头部。服务器提供 21 个带有自己参数架构的工具,allowed_tools 将它们缩小到输入作业实际需要的内容,而 scrape_markdown 将页面以拆分器和嵌入模型都喜欢的格式返回。

值得保留的习惯是在提取时将源 URL 附加为 Document 元数据。它只需一个字典,就能在节点拆分中保存,并且它使得检索结果成为可以追溯到页面的答案。
开始使用Scrapeless免费计划以获取密钥,在您评估摄取运行时查看Scrapeless定价,并查看Scrapeless MCP服务器概述以获取完整的工具参考。

常见问题

问:LlamaIndex的Scrapeless MCP服务器端点是什么?

托管的端点是 https://api.scrapeless.com/mcp,通过 BasicMCPClient 使用您的密钥在 x-api-token 头中访问。没有本地服务器进程需要运行,因为工具是远程提供的。

问:Scrapeless MCP服务器向LlamaIndex提供多少工具?

实时连接返回21个:16个 browser_* 会话控制工具,3个页面检索工具(scrape_markdownscrape_htmlscrape_screenshot),以及2个搜索工具(google_searchgoogle_trends)。在运行时枚举它们,而不是假设,因为服务器可以在版本之间添加工具。

问:我可以只加载某些MCP工具吗?

可以。将 allowed_tools=["scrape_markdown"] 传递给 McpToolSpec,返回的列表仅包含该工具。对于摄取来说,这是值得做的——它保持模式可读,并防止代理打开它不需要的浏览器会话。

问:我需要LLM密钥才能通过MCP获取页面吗?

不需要。连接、工具发现、模式检查和直接的 tool.acall(...) 都只需要Scrapeless密钥。当您将工具交给代理时,需要模型提供者,因为那时需要决定调用哪个工具。

问:为什么使用Markdown而不是HTML进行检索?

Markdown保留了有助于检索的结构——标题、列表、链接——并去掉了会消耗嵌入上下文但未添加意义的脚本、样式和布局标记。当您打算运行自己的选择器而不是嵌入文本时,scrape_html仍然是正确的选择。

问:我如何跟踪检索到的块来自哪个页面?

在创建文档时,将URL放入 Document(metadata={"source": url}) 中。该元数据会复制到分割器从中派生的每个节点上,因此每个检索到的块都携带其来源,无需额外的记录。

问:在摄取一个站点之前,我应该检查什么?

查看该站点的条款及其 /robots.txt 指令,遵循 机器人排除协议标准。将摄取保持在公共页面,使用明确的URL列表或有限的发现步骤,记录每个文档的源URL,以便索引返回的任何内容的来源保持清晰。

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

最受欢迎的文章

目录