Volver al blog

LlamaIndex + Scrapeless: Alimenta tu índice con páginas web en vivo.

Alex Johnson
Alex Johnson

Senior Web Scraping Engineer

22-Jul-2026

Un índice de recuperación es tan actual como los documentos que incluyas en él. LlamaIndex maneja bien el troceado, la incrustación y la recuperación; la parte que se rompe silenciosamente es el paso antes de todo eso, donde las páginas web en vivo deben convertirse en texto limpio.

Conectar LlamaIndex al Servidor MCP de Scrapeless cubre ese paso. Las herramientas MCP devuelven las páginas renderizadas como markdown, LlamaIndex las envuelve como objetos Document, y el resto de tu pipeline de ingestión continúa sin cambios. Esta guía ejecuta la conexión, el descubrimiento de herramientas, una recuperación real de página y la división de documento a nodo de principio a fin.

Lo que Esta Configuración Le Da a Su Índice

Tu código de ingestión obtiene 21 herramientas llamadas desde una conexión, y llegan como herramientas nativas de LlamaIndex en lugar de algo que debas envolver tú mismo.

Los grupos son importantes para la ingestión:

  • Recuperación de páginasscrape_markdown devuelve una página ya convertida a markdown, que es el formato que mejor manejan tanto un divisor como un modelo de incrustación. scrape_html y scrape_screenshot devuelven las otras dos formas.
  • Búsquedagoogle_search y google_trends permiten que un trabajo de ingestión descubra URLs en lugar de recibir una lista fija.
  • Control de navegador en vivo — dieciséis herramientas browser_* para páginas que necesitan interacción antes de que exista el contenido.

El renderizado, el enrutamiento proxy y el manejo de acceso ocurren del lado del servidor, por lo que el proceso de ingestión sigue siendo un trabajo sencillo en Python sin necesidad de instalar un navegador.

Por qué el Servidor MCP de Scrapeless

La especificación del Protocolo de Contexto de Modelo define cómo un cliente descubre herramientas y sus esquemas de argumentos desde un servidor, lo que hace que esto sea diferente de escribir un helper de fetch: la lista de herramientas y los parámetros de cada herramienta llegan del servidor en lugar de estar codificados de forma fija en tu proyecto. Las llamadas viajan como mensajes JSON-RPC 2.0.

Scrapeless alberga el endpoint, por lo que no hay un proceso de servidor que ejecutar junto a tu indexador. La autenticación es solo un encabezado. El grupo browser_* está respaldado por el Navegador de Extracción Scrapeless, y los parámetros por herramienta están documentados en la documentación de Scrapeless.

Requisitos Previos

  • Python 3.10 o posterior. Tanto llama-index-core como llama-index-tools-mcp declaran actualmente >=3.10,<4.0.
  • Una clave API de Scrapeless desde el tablero.
  • Solo para la sección del agente: un paquete de integración de LLM como llama-index-llms-openai más la clave de ese proveedor.

Nota: Todo lo realizado en la sección de ingestión a continuación se ejecutó con una clave de Scrapeless y sin clave de proveedor de modelo. La conexión MCP, el descubrimiento de herramientas, los esquemas de argumentos, la llamada en vivo a la herramienta y la división de Document a nodo se ejecutaron. El paso del agente al final es una brecha de requisito previo: construir un FunctionAgent genera ImportError: llama-index-llms-openai package not found sin una integración de LLM instalada, por lo que ese bloque se muestra como el código que agregas en lugar de como salida capturada.

Instalación

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

Ese paquete trae consigo llama-index-core y el cliente mcp. Establece la clave en tu shell:

bash Copy
export SCRAPELESS_API_KEY="your_api_key_here"

Conectar y Listar las Herramientas

BasicMCPClient toma la URL del endpoint y los encabezados; McpToolSpec convierte la lista de herramientas del servidor en herramientas de 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("conteo de herramientas:", len(tools))
    print("nombres de muestra:", sorted(t.metadata.name for t in tools)[:6])

asyncio.run(main())
text Copy
conteo de herramientas: 21
nombres de muestra: ['browser_click', 'browser_close', 'browser_create', 'browser_get_html', 'browser_get_text', 'browser_go_back']

La API es asíncrona en toda su extensión, por lo que el ejemplo se ejecuta dentro de asyncio.run. Los nombres de las herramientas llegan de manera plana, sin prefijo de servidor ni espacio de nombres con puntos, por lo que scrape_markdown es el nombre literal que tu código y tu agente usarán.

Tomar Solo las Herramientas Que Necesita el Trabajo

Un trabajo de ingestión rara vez necesita control de sesión del navegador. McpToolSpec acepta allowed_tools y devuelve solo aquellas, lo que mantiene la superficie pequeña y los esquemas fáciles de leer:

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, allowed_tools=["scrape_markdown"])
tools = await spec.to_tool_list_async()

Copy
tool = tools[0]
print("cantidad filtrada:", len(tools))
print("nombre:", tool.metadata.name)
print("campos de fn_schema:", list(tool.metadata.fn_schema.model_fields))

asyncio.run(main())

Copy
```text
cantidad filtrada: 1
nombre: scrape_markdown
campos de fn_schema: ['url']

El esquema proviene del servidor, por lo que es el contrato real en lugar de una suposición: scrape_markdown toma una sola url. LlamaIndex lo expone como fn_schema, el mismo modelo de Pydantic que un agente usaría para construir su llamada.

¿Listo para señalar esto a tus propias fuentes? Crea una cuenta gratuita en Scrapeless y conéctate con la clave de tu tablero.

Convierte Páginas en Vivo en Nodos

Esta es la parte que importa para la recuperación. Llama a la herramienta directamente, envuelve cada resultado como un Document con su fuente en los metadatos, luego divide en nodos:

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"documentos: {len(docs)}")

    splitter = SentenceSplitter(chunk_size=256, chunk_overlap=32)
    nodes = splitter.get_nodes_from_documents(docs)
    print(f"nodos después de dividir: {len(nodes)}")
    print(f"fuente del primer nodo: {nodes[0].metadata['source']}")
    print(f"caracteres del primer nodo: {len(nodes[0].get_content())}")

asyncio.run(main())
text Copy
documentos: 2
nodos después de dividir: 14
fuente del primer nodo: https://quotes.toscrape.com/js/
caracteres del primer nodo: 571

Varias cosas en esa salida merecen ser leídas con atención.

La primera URL es una página renderizada por el cliente: su contenido es escrito en el DOM por un script y aún así produjo markdown utilizable, porque el renderizado ocurrió del lado del servidor antes de la conversión. Una simple solicitud HTTP de esa misma URL devuelve un marcado sin ningún contenido en él.

chunk_size=256 cuenta tokens, no caracteres, razón por la cual el primer nodo tiene 571 caracteres de largo. Dimensionar un divisor en caracteres es una forma común de acabar con fragmentos que desbordan el contexto de un modelo de incrustación.

El metadata={"source": url} en cada Document sobrevive a la división y se encuentra en cada nodo derivado de él. Eso es lo que permite que un resultado de recuperación cite de dónde proviene, y es mucho más fácil adjuntarlo aquí que reconstruirlo más tarde.

Markdown es el formato intermedio adecuado para esto: los encabezados y enlaces sobreviven, mientras que los scripts, estilos y marcas de diseño no, por lo que el presupuesto de incrustación va al contenido.

Dale las Herramientas a un Agente

Una vez que las herramientas están en mano, un agente puede decidir cuál llamar en lugar de seguir una lista fija de URLs. Este paso necesita un paquete de integración de LLM y la clave del proveedor.

Nota: Este bloque es una brecha de requisito previo. Sin una integración de LLM instalada, construir el agente genera ImportError: paquete llama-index-llms-openai no encontrado, por favor ejecuta pip install llama-index-llms-openai, por lo que no se muestra ninguna salida para ello.

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="Investiga páginas públicas y devuelve notas limpias con fuentes.",
)

response = await agent.run("Resumen de los autores citados en quotes.toscrape.com")
print(response)

Conclusión

Conectar LlamaIndex al Servidor MCP de Scrapeless requiere un cliente, una especificación de herramienta y un encabezado. El servidor suministra 21 herramientas con sus propios esquemas de argumentos, allowed_tools las reduce a lo que realmente necesita un trabajo de ingesta, y scrape_markdown devuelve páginas en el formato que tanto un divisor como un modelo de incrustación prefieren.

El hábito que vale la pena conservar es adjuntar la URL fuente como metadatos de Document en el momento de la recuperación. Cuesta un diccionario, sobrevive a la división de nodos y es lo que convierte un impacto de recuperación en una respuesta que puedes rastrear hasta una página.
Comience con el plan gratuito de Scrapeless para obtener una clave, consulte los precios de Scrapeless cuando dimensione una ejecución de ingestión y vea el resumen del servidor MCP de Scrapeless para la referencia completa de la herramienta.

Preguntas Frecuentes

P: ¿Cuál es el punto final del servidor Scrapeless MCP para LlamaIndex?

El punto final hospedado es https://api.scrapeless.com/mcp, al que se accede con su clave en el encabezado x-api-token a través de BasicMCPClient. No hay un proceso de servidor local para ejecutar, porque las herramientas se sirven de forma remota.

P: ¿Cuántas herramientas expone el servidor Scrapeless MCP a LlamaIndex?

Una conexión en vivo devuelve 21: dieciséis herramientas de control de sesión browser_*, tres herramientas de recuperación de páginas (scrape_markdown, scrape_html, scrape_screenshot), y dos herramientas de búsqueda (google_search, google_trends). Enumérelas en tiempo de ejecución en lugar de asumir, ya que un servidor puede agregar herramientas entre lanzamientos.

P: ¿Puedo cargar solo algunas herramientas MCP?

Sí. Pase allowed_tools=["scrape_markdown"] a McpToolSpec y la lista volverá solo con esa herramienta. Para la ingestión, vale la pena hacerlo: mantiene los esquemas legibles y evita que un agente abra sesiones de navegador que no necesita.

P: ¿Necesito una clave LLM para recuperar páginas a través de MCP?

No. La conexión, descubrimiento de herramientas, inspección de esquemas y tool.acall(...) directo funcionan solo con la clave de Scrapeless. Se necesita un proveedor de modelo una vez que entrega las herramientas a un agente, porque es entonces cuando algo tiene que decidir qué herramienta llamar.

P: ¿Por qué usar markdown en lugar de HTML para la recuperación?

Markdown mantiene la estructura que ayuda a la recuperación: encabezados, listas, enlaces, y elimina los scripts, estilos y marcas de diseño que consumen contexto de incrustación sin agregar significado. scrape_html sigue siendo la elección correcta cuando se pretende ejecutar sus propios selectores en lugar de incrustar el texto.

P: ¿Cómo puedo hacer un seguimiento de qué página provino un fragmento recuperado?

Coloque la URL en Document(metadata={"source": url}) cuando cree el documento. Esa metadata se copia en cada nodo que el separador deriva de él, por lo que cada fragmento recuperado lleva su origen sin ninguna contabilidad adicional.

P: ¿Qué debo verificar antes de ingerir un sitio?

Revise los términos del sitio y sus directrices en /robots.txt, que siguen el estándar del Protocolo de Exclusión de Robots. Mantenga la ingestión a páginas públicas, trabaje desde una lista de URL explícita o un paso de descubrimiento acotado, y registre la URL de origen en cada documento para que la procedencia de cualquier cosa que devuelva el índice siga siendo clara.

En Scrapeless, solo accedemos a datos disponibles públicamente y cumplimos estrictamente con las leyes, regulaciones y políticas de privacidad del sitio web aplicables. El contenido de este blog es sólo para fines de demostración y no implica ninguna actividad ilegal o infractora. No ofrecemos garantías y renunciamos a toda responsabilidad por el uso de la información de este blog o enlaces de terceros. Antes de realizar cualquier actividad de scraping, consulte a su asesor legal y revise los términos de servicio del sitio web de destino u obtenga los permisos necesarios.

Artículos más populares

Catalogar