Web Scraper Service

Un servidor MCP basado en Python para web scraping sin interfaz gráfica. Extrae el contenido principal de texto de páginas web y lo genera como Markdown, texto o HTML.

Documentación

Web Scrapper Service (MCP Stdin/Stdout & HTTP)

Build Test Version License Python PEP8 GHCR Patchright Docker

Un servidor MCP basado en Python para scraping web robusto y sin interfaz gráfica: extrae el contenido de texto principal de páginas web y genera Markdown, texto o HTML para una integración perfecta con IA y automatización.

Características principales

  • Scraping web con navegador sin interfaz (Playwright, BeautifulSoup, Markdownify)
  • Genera Markdown, texto o HTML
  • Diseñado para integración con MCP (Model Context Protocol) stdio/JSON-RPC
  • Transporte dual: stdio (predeterminado) y HTTP transmisible para modo de servicio compartido
  • Grupo de navegadores persistente: Chromium permanece activo entre solicitudes para un scraping rápido
  • Espera inteligente del DOM: estabilización de contenido basada en MutationObserver en lugar de espera fija
  • Dockerizado, con imágenes preconstruidas
  • Configurable mediante variables de entorno
  • Manejo robusto de errores (tiempos de espera, errores HTTP, Cloudflare, etc.)
  • Limitación de velocidad por dominio
  • Integración fácil con herramientas de IA e IDE (Cursor, Claude Desktop, Continue, JetBrains, Zed, etc.)
  • Instalación con un clic para Cursor, instalador interactivo para Claude

Inicio rápido

Ejecutar con Docker (modo stdio — un contenedor por cliente)

docker run -i --rm ghcr.io/justazul/web-scrapper-stdio

Ejecutar como Servicio HTTP Compartido (un contenedor, múltiples clientes)

docker run -d --name web-scraper \
  -e MCP_TRANSPORT=streamable-http \
  -e MCP_HTTP_PORT=8080 \
  -e BROWSER_POOL_SIZE=3 \
  -p 8080:8080 \
  --shm-size=3gb \
  ghcr.io/justazul/web-scrapper-stdio

O con Docker Compose:

docker compose --profile service up -d

Instalación con un clic (IDE Cursor)

Add to Cursor


Modos de transporte

stdio (predeterminado)

Cada cliente MCP genera su propio contenedor mediante docker run -i. Simple, sin configuración, funciona con cualquier cliente MCP.

{
  "mcpServers": {
    "web-scrapper-stdio": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "ghcr.io/justazul/web-scrapper-stdio"]
    }
  }
}

HTTP transmisible (servicio compartido)

Ejecute un contenedor persistente que atienda a múltiples clientes MCP a través de HTTP. Ahorra recursos al ejecutar múltiples instancias de herramientas de IA (por ejemplo, múltiples sesiones de Claude Code).

Inicie el servicio:

docker run -d --name web-scraper \
  -e MCP_TRANSPORT=streamable-http \
  -e MCP_HTTP_PORT=8080 \
  -p 8080:8080 \
  --shm-size=3gb \
  ghcr.io/justazul/web-scrapper-stdio

Conéctese desde su cliente MCP:

{
  "mcpServers": {
    "web-scrapper": {
      "url": "http://localhost:8080/mcp"
    }
  }
}

Integración con herramientas de IA e IDE

Este servicio admite integración con una amplia gama de herramientas de IA e IDE que implementan el Protocolo de Contexto de Modelo (MCP). A continuación se muestran ejemplos de configuración listos para usar en los entornos más populares. Reemplace la imagen/etiqueta según sea necesario para compilaciones personalizadas.

IDE Cursor

Agregue a su .cursor/mcp.json (a nivel de proyecto) o ~/.cursor/mcp.json (global):

{
  "mcpServers": {
    "web-scrapper-stdio": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "ghcr.io/justazul/web-scrapper-stdio"
      ]
    }
  }
}

Claude Desktop

Agregue a su configuración MCP de Claude Desktop (normalmente claude_desktop_config.json):

{
  "mcpServers": {
    "web-scrapper-stdio": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "ghcr.io/justazul/web-scrapper-stdio"
      ]
    }
  }
}

Claude Code

Agregue a su .mcp.json o ~/.claude.json global:

modo stdio (un contenedor por sesión):

{
  "mcpServers": {
    "web-scrapper-stdio": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "ghcr.io/justazul/web-scrapper-stdio"]
    }
  }
}

modo HTTP (servicio compartido — inicie el servicio primero):

{
  "mcpServers": {
    "web-scrapper": {
      "url": "http://localhost:8080/mcp"
    }
  }
}

Continue (Plugin de VSCode/JetBrains)

Agregue a su continue.config.json o mediante la configuración MCP del plugin Continue:

{
  "mcpServers": {
    "web-scrapper-stdio": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "ghcr.io/justazul/web-scrapper-stdio"
      ]
    }
  }
}

IntelliJ IDEA (Asistente de IA de JetBrains)

Vaya a Configuración > Herramientas > Asistente de IA > Protocolo de Contexto de Modelo (MCP) y agregue un nuevo servidor. Use:

{
  "command": "docker",
  "args": [
    "run",
    "-i",
    "--rm",
    "ghcr.io/justazul/web-scrapper-stdio"
  ]
}

Editor Zed

Agregue a su configuración MCP de Zed (consulte la documentación de Zed para la ruta exacta):

{
  "mcpServers": {
    "web-scrapper-stdio": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "ghcr.io/justazul/web-scrapper-stdio"
      ]
    }
  }
}

Uso

Servidor MCP (Herramienta/Prompt)

Este scraper web se utiliza como herramienta MCP (Protocolo de Contexto de Modelo), lo que permite que los modelos de IA u otra automatización lo usen directamente.

Herramienta: scrape_web

Parámetros:

  • url (cadena, obligatorio): La URL a extraer
  • max_length (entero, opcional): Longitud máxima del contenido devuelto (predeterminado: ilimitado)
  • timeout_seconds (entero, opcional): Tiempo de espera en segundos para la carga de la página (predeterminado: 30)
  • user_agent (cadena, opcional): Cadena de User-Agent personalizada pasada directamente al navegador (predeterminado: un agente aleatorio)
  • wait_for_network_idle (booleano, opcional): Esperar a que la actividad de red se estabilice antes de extraer (predeterminado: true)
  • custom_elements_to_remove (lista de cadenas, opcional): Elementos HTML adicionales (selectores CSS) a eliminar antes de la extracción
  • grace_period_seconds (flotante, opcional): Tiempo de espera para el renderizado de JS después de la navegación. Usa MutationObserver para detección inteligente. Establezca 0 para omitir por completo. (predeterminado: 0.5)
  • output_format (cadena, opcional): markdown, text o html (predeterminado: markdown)
  • click_selector (cadena, opcional): Si se proporciona, haga clic en el elemento que coincida con este selector después de la navegación y antes de la extracción

Devuelve:

  • Contenido con formato Markdown extraído de la página web, como cadena
  • Los errores se informan como cadenas que comienzan con [ERROR] ...

Ejemplo: Usando click_selector y custom_elements_to_remove

{
  "url": "http://uitestingplayground.com/clientdelay",
  "click_selector": "#ajaxButton",
  "grace_period_seconds": 10,
  "custom_elements_to_remove": [".ads-banner", "#popup"],
  "output_format": "markdown"
}

Prompt: scrape

Parámetros:

  • url (cadena, obligatorio): La URL a extraer
  • output_format (cadena, opcional): markdown, text o html (predeterminado: markdown)

Devuelve:

  • Contenido extraído de la página web en el formato elegido

Nota:

  • Markdown se devuelve por defecto, pero se puede solicitar texto o HTML mediante output_format.
  • El scraper no verifica robots.txt e intentará obtener cualquier URL proporcionada.
  • No se incluye API REST ni herramienta CLI; esta es una herramienta MCP pura de stdio/JSON-RPC.
  • El scraper siempre extrae el contenido completo de <body> de las páginas web, aplicando solo la eliminación esencial de ruido (eliminando script, style, nav, footer, aside, header y etiquetas similares sin contenido). El scraper detecta y maneja las pantallas de desafío de Cloudflare, devolviendo una cadena de error específica.

Configuración

Puede anular la mayoría de las opciones de configuración usando variables de entorno:

Configuración principal

  • DEFAULT_TIMEOUT_SECONDS: Tiempo de espera para cargas de página y navegación (predeterminado: 30)
  • DEFAULT_MIN_CONTENT_LENGTH: Longitud mínima de contenido para texto extraído (predeterminado: 100)
  • DEFAULT_MIN_CONTENT_LENGTH_SEARCH_APP: Longitud mínima de contenido para dominios search.app (predeterminado: 30)
  • DEFAULT_MIN_SECONDS_BETWEEN_REQUESTS: Retraso mínimo entre solicitudes al mismo dominio (predeterminado: 2)
  • DEFAULT_GRACE_PERIOD_SECONDS: Período de gracia predeterminado para renderizado de JS (predeterminado: 0.5)
  • DEBUG_LOGS_ENABLED: Establezca true para habilitar registros de nivel de depuración (predeterminado: false)

Grupo de navegadores

  • BROWSER_POOL_ENABLED: Habilitar grupo de navegadores persistente (predeterminado: true). Establezca false para lanzamiento de navegador por solicitud (comportamiento original).
  • BROWSER_POOL_SIZE: Número de instancias de Chromium para mantener activas (predeterminado: 2). Cada instancia usa ~100-200MB de RAM.

Transporte

  • MCP_TRANSPORT: Modo de transporte — stdio o streamable-http (predeterminado: stdio)
  • MCP_HTTP_PORT: Puerto del servidor HTTP al usar transporte streamable-http (predeterminado: 8080)
  • MCP_HTTP_HOST: Dirección de enlace del servidor HTTP (predeterminado: 0.0.0.0)

Bypass de Cloudflare

  • CAPTCHA_API_KEY: Clave API para el servicio de resolución de captchas. Cuando se establece, los desafíos de Cloudflare Turnstile se resuelven automáticamente. Cuando está vacío (predeterminado), las páginas protegidas por CF devuelven un error.
  • CAPTCHA_PROVIDER: Proveedor de resolución de captchas — 2captcha, capsolver o capmonster (predeterminado: 2captcha)
  • CAPTCHA_BASE_URL: Endpoint de API personalizado del solucionador (predeterminado: usa la URL oficial del proveedor)
  • CAPTCHA_TIMEOUT: Tiempo de espera en segundos para la resolución de captchas (predeterminado: 120)

Configuración de pruebas

  • DEFAULT_TEST_REQUEST_TIMEOUT: Tiempo de espera para solicitudes de prueba (predeterminado: 10)
  • DEFAULT_TEST_NO_DELAY_THRESHOLD: Umbral para omitir retrasos artificiales en pruebas (predeterminado: 0.5)

Manejo de errores y limitaciones

  • El scraper detecta y devuelve errores para fallos de navegación, tiempos de espera, errores HTTP (incluido 404) y desafíos anti-bot de Cloudflare.
  • La limitación de velocidad se aplica por dominio (predeterminado: 2 segundos entre solicitudes).
  • Bypass de Cloudflare: Usa Patchright (anti-detección a nivel de CDP) para evasión pasiva. La mayoría de los sitios protegidos por CF se extraen sin activar un desafío. Cuando se activa un desafío Turnstile y CAPTCHA_API_KEY está establecido, se resuelve automáticamente mediante API de terceros.
  • Limitaciones:
    • Sin API REST ni herramienta CLI (solo MCP stdio/JSON-RPC)
    • Sin soporte para contenido no HTML (PDF, imágenes, etc.)
    • Sin autenticación ni gestión de sesiones para páginas protegidas
    • No está diseñado para scraping a gran escala ni para violar los términos del sitio

Desarrollo y pruebas

Ejecutar pruebas (Docker Compose)

Todas las pruebas deben ejecutarse usando Docker Compose. No ejecute pruebas fuera de Docker.

  • Todas las pruebas:
    docker compose up --build --abort-on-container-exit test
    
  • Solo pruebas del servidor MCP:
    docker compose up --build --abort-on-container-exit test_mcp
    
  • Solo pruebas del scraper:
    docker compose up --build --abort-on-container-exit test_scrapper
    

Ejecutar benchmarks

docker compose run --rm benchmark

Los resultados se almacenan en benchmarks/RESULTS.md.


Contribuciones

¡Las contribuciones son bienvenidas! Abra issues o pull requests para correcciones de errores, funciones o mejoras. Si planea realizar cambios significativos, abra un issue primero para discutir su propuesta.


Licencia

Este proyecto está licenciado bajo la Licencia MIT.