Web Scraping MCP Server

Obtén cualquier página web pública a través de proxies gestionados, con renderizado de JavaScript opcional y reglas de extracción.

Documentación

Servidor MCP de Web Scraping

Un servidor de Model Context Protocol (MCP) alojado que le brinda a Claude, Cursor, Windsurf y cualquier otro cliente MCP una herramienta de solo lectura para obtener cualquier página web pública. Sale a través de proxies administrados, renderiza JavaScript cuando una página lo necesita y devuelve markdown limpio, texto plano, HTML crudo o JSON estructurado, sin nada que alojar y sin navegador en tu stack.

Este es el recurso de respaldo para sitios sin API dedicada. Cuando un sitio sí tiene una en el catálogo de HasData, esa herramienta devuelve campos parseados y esta devuelve una página.

1,000 créditos gratis cada mes, sin necesidad de tarjeta. Una obtención simple cuesta 1 crédito, así que el nivel gratuito cubre 1,000 de ellas.

https://mcp.hasdata.com/api/mcp?apis=web_scraping

Glama score tool contract MCP Tools npm PyPI License

Contenido

Lo que necesitas

Un cliente MCP y una clave de API de HasData desde el panel de control, gratis de crear sin tarjeta. Este es un servidor remoto, así que la ruta más simple es una URL y un encabezado x-api-key, sin contenedor que ejecutar. Un cliente que solo habla stdio lo alcanza a través de un lanzador delgado, publicado como @hasdata/web-scraping-mcp en npm y hasdata-web-scraping-mcp en PyPI, mostrado abajo.

Inicio rápido

La URL del servidor es la misma para cada cliente. Lo ejecutamos de forma práctica en Claude Code y Claude Desktop. Los otros bloques siguen el formato documentado de cada cliente para un servidor remoto.

CampoValor
URLhttps://mcp.hasdata.com/api/mcp?apis=web_scraping
TransporteHTTP, transmisible
Encabezado de autenticaciónx-api-key: HASDATA_API_KEY

Los clientes con soporte OAuth pueden agregar la misma URL como conector e iniciar sesión sin poner una clave en un archivo de configuración.

Claude Code
claude mcp add --transport http web-scraping "https://mcp.hasdata.com/api/mcp?apis=web_scraping" \
  --header "x-api-key: HASDATA_API_KEY"
Claude Desktop

Configuración, luego Conectores, luego Agregar conector personalizado, luego pega https://mcp.hasdata.com/api/mcp?apis=web_scraping e inicia sesión.

Para la ruta de archivo de configuración, Claude Desktop carga solo servidores locales (stdio), así que alcanza un servidor remoto a través de un lanzador stdio. El paquete @hasdata/web-scraping-mcp es ese lanzador, y lee la clave del entorno. Agrega esto a claude_desktop_config.json:

{
  "mcpServers": {
    "web-scraping": {
      "command": "npx",
      "args": ["-y", "@hasdata/web-scraping-mcp"],
      "env": { "HASDATA_API_KEY": "YOUR_KEY" }
    }
  }
}

Para Python en lugar de Node, cambia el lanzador por el paquete de PyPI, que uvx ejecuta sin instalación manual:

{
  "mcpServers": {
    "web-scraping": {
      "command": "uvx",
      "args": ["hasdata-web-scraping-mcp"],
      "env": { "HASDATA_API_KEY": "YOUR_KEY" }
    }
  }
}
Cursor

~/.cursor/mcp.json para cada proyecto, o .cursor/mcp.json para uno solo:

{
  "mcpServers": {
    "web-scraping": {
      "url": "https://mcp.hasdata.com/api/mcp?apis=web_scraping",
      "headers": { "x-api-key": "HASDATA_API_KEY" }
    }
  }
}
Windsurf

~/.codeium/windsurf/mcp_config.json. Windsurf llama al campo serverUrl, no url:

{
  "mcpServers": {
    "web-scraping": {
      "serverUrl": "https://mcp.hasdata.com/api/mcp?apis=web_scraping",
      "headers": { "x-api-key": "HASDATA_API_KEY" }
    }
  }
}
VS Code

.vscode/mcp.json en el espacio de trabajo:

{
  "servers": {
    "web-scraping": {
      "type": "http",
      "url": "https://mcp.hasdata.com/api/mcp?apis=web_scraping",
      "headers": { "x-api-key": "HASDATA_API_KEY" }
    }
  }
}

Ejemplos de indicaciones

  • Obtén esta página como markdown y resúmela.
  • Lee esta página de documentación y extrae cada bloque de código.
  • Obtén los títulos y enlaces de la página principal de este sitio como JSON.
  • Esta página carga su contenido con JavaScript, así que renderízala y espera la lista de resultados antes de leer.
  • Obtén esta página a través de un proxy residencial alemán y dime si los precios difieren.
  • Toma una captura de pantalla de esta página.

Una llamada responde a cada una de estas. Lo que cambia entre ellas es cuánto del navegador pediste, y eso es lo que cuesta la llamada.

Herramientas

Una herramienta. El costo depende de lo que actives, y la tabla está en Precios.

Obtener página web

hasdata_web_scraping_web_scraping_scrapeWebPage

Obtiene una URL.

ParámetroTipoRequeridoNotas
urlstringLa página a obtener
outputFormatarrayCualquiera de markdown, text, html, json. Ver Formatos de salida
jsRenderingbooleanRenderiza la página en un navegador. Activado por defecto, y la principal palanca de costo
proxyTypestringdatacenter o residential
proxyCountrystringUS, UK, DE, IE, FR, IT, SE, BR, CA, JP, SG, IN o ID
headersobjectEncabezados de solicitud personalizados
waitnumberMilisegundos a esperar después de la carga
waitForstringSelector CSS a esperar antes de leer
jsScenarioarrayAcciones a ejecutar en la página. Ver abajo
extractRulesobjectSelectores CSS para extraer campos nombrados
aiExtractRulesobjectUn esquema tipado que un LLM llena desde la página
extractLinksbooleanRecopila los enlaces de la página
extractEmailsbooleanRecopila las direcciones de correo en la página
screenshotbooleanCaptura la página renderizada
blockResourcesbooleanOmite imágenes y hojas de estilo
blockAdsbooleanOmite solicitudes de anuncios
blockUrlsarrayOmite estas URLs
includeOnlyTagsarrayConserva solo elementos que coincidan con estos selectores
excludeTagsarrayElimina elementos que coincidan con estos selectores
removeBase64ImagesbooleanElimina imágenes base64 en línea de la salida

extractRules mapea un nombre de campo a un selector CSS, con @attr para leer un atributo en lugar de texto.

{ "title": "h1", "link_href": "a#link @href", "page_text": "body" }

jsScenario es un array de acciones ejecutadas en orden, que cubre click, wait, waitFor, waitForAndClick, scrollX, scrollY, fill y evaluate para JavaScript arbitrario. Necesita jsRendering activado.

aiExtractRules describe la forma que quieres y permite que un modelo la llene desde el HTML. Cada clave es un campo de salida, tipado como string, number, boolean, list o item para un objeto anidado.

Formatos de salida

Esta es la parte que vale la pena leer antes de tu primera llamada, porque la forma de la respuesta se mueve con outputFormat.

Pide exactamente uno de markdown, text o html, y el contenido llega como una cadena simple en text en el nivel superior.

{
  "url": "https://api.hasdata.com/scrape/web/",
  "status": 200,
  "json": null,
  "text": "# Example Domain\n\nThis domain is for use in documentation examples without needing permission. Avoid use in operations.\n\n[Learn more](https://iana.org/domains/example)\n"
}

Incluye json, solo o junto a otro formato, y todo se mueve dentro de json, el text de nivel superior se vuelve null, y los formatos solicitados se convierten en claves allí junto a los metadatos de la página.

{
  "json": {
    "requestMetadata": { "id": "7764031a-43f7-4102-8561-a7b7a6f1cbf5", "status": "ok" },
    "statusCode": 200,
    "statusText": "OK",
    "headers": { "server": "nginx", "content-type": "text/html; charset=utf-8" },
    "extractedData": { "title": "Hacker News", "firstStory": ["iPhone Duo", "apple.com", "Show HN: What if the speed of light was 5 km/h?"] }
  },
  "text": null
}

extractedData contiene los resultados de extractRules. Un selector que coincide con varios elementos devuelve todos como un array, así que .titleline a en una página de listado devuelve cada coincidencia en lugar de la primera.

Errores y rutas de fallo

Planifica para estos en lugar de asumir un camino feliz.

extractLinks y extractEmails no hacen nada a menos que outputFormat incluya json. Ponen links y emails dentro del objeto json, y no hay lugar para ellos en una respuesta markdown simple. Pedirlos con outputFormat: ["text"] devuelve el texto y silenciosamente sin enlaces.

Un 404 o un 403 en la página objetivo es una llamada exitosa. El estado propio de la página regresa como statusCode dentro de json, o como status en el nivel superior, y la solicitud se factura de cualquier manera. Verifica el estado antes de parsear el cuerpo.

jsRendering está activado por defecto, y es lo que cuesta la llamada. Apagarlo lleva una obtención de 10 créditos a 1. La mayoría de las páginas estáticas, documentación, artículos y cualquier cosa renderizada en servidor no lo necesitan. Actívalo cuando el contenido llegue vacío sin él.

waitFor supera a wait. Un retraso fijo es una suposición que es demasiado corta en una carga lenta o desperdiciada en una rápida. Un selector CSS espera por lo que realmente necesitas y regresa tan pronto como aparece.

Un proxy residencial cuesta de cinco a quince veces el precio de uno de centro de datos. Recurre a él cuando una obtención de centro de datos regresa bloqueada, en lugar de como predeterminado.

includeOnlyTags y excludeTags toman selectores querySelectorAll. Un selector inválido no reduce nada en lugar de dar error, así que una respuesta sospechosamente completa es el síntoma de un error tipográfico.

aiExtractRules ejecuta un modelo sobre el HTML, así que no es ni gratis ni determinista. Dos llamadas en la misma página pueden diferir en redacción. Cuando un selector CSS puede hacer el trabajo, extractRules es más barato y repetible.

Los resultados que llevan datos también llevan un requestMetadata.id que vale la pena citar en soporte.

Precios, nivel gratuito y límites

El costo depende de dos interruptores, y nada más lo cambia.

Proxy de centro de datosProxy residencial
jsRendering: false1 crédito5 créditos
jsRendering: true10 créditos15 créditos

El renderizado está activado por defecto, así que una llamada no configurada cuesta 10. Una página estática obtenida con jsRendering: false cuesta 1, lo que la convierte en la herramienta más barata del catálogo cuando no necesitas un navegador.

El nivel gratuito es 1,000 créditos cada mes sin tarjeta. Eso es 1,000 obtenciones simples, o 100 renderizadas. Se renueva con el ciclo de facturación.

Los planes de pago comienzan en $49 al mes por 200,000 créditos, que son 200,000 obtenciones simples o 20,000 renderizadas. El precio unitario baja con el volumen en los planes de alto volumen.

Tu plan también establece la concurrencia. El nivel gratuito permite 1 solicitud a la vez, Startup 15, Business 30, Growth 50, y los planes de alto volumen van de 200 a 1,500. Reintenta en el 429 con retroceso en cualquier cosa desatendida, porque un agente que rastrea una lista de URLs alcanzará el techo antes que tú.

Los créditos se descuentan solo de solicitudes exitosas. Una página que responde 404 sigue siendo una obtención exitosa de un 404.

Cómo se compara

La comparación que vale la pena hacer es contra obtener la página tú mismo, y contra las otras herramientas de este catálogo.

fetch en tu propio códigoUna herramienta HasData dedicadaEste servidor
Bloqueado por protección de botsA menudoManejadoManejado
Páginas con mucho JavaScriptNecesita un navegador que ejecutesManejadoUn parámetro
Geo-orientaciónTus propios proxiesIntegradoUn parámetro
SalidaHTML crudoCampos parseados para ese sitioMarkdown, texto, HTML o JSON
CoberturaCualquier cosaLos sitios con una herramientaCualquier cosa pública
CostoTu infraestructuraPor llamadaDesde 1 crédito por llamada

La fila que decide contra una herramienta dedicada es la cobertura. Amazon, Zillow, Yelp y el resto devuelven campos tipados porque alguien mantiene un parser para ese sitio. Este devuelve una página de cualquier sitio y te deja el parseo a ti, que es el intercambio correcto solo cuando no existe una herramienta dedicada.

Contra tu propio fetch, la pregunta es si el objetivo se defiende. Para una página amigable, tu propio código es gratis y esto no vale un crédito.

Preguntas frecuentes

¿Qué es un servidor MCP de web scraping?

Un servidor MCP expone herramientas que un cliente de IA puede invocar. Este permite que un agente obtenga cualquier URL pública a través de proxies gestionados y la reciba como markdown, texto, HTML o JSON estructurado, sin necesidad de un navegador o un grupo de proxies en tu stack.

¿Necesito mis propios proxies o un navegador sin interfaz gráfica?

No. Ambos están del lado del servidor. La única credencial es tu clave de HasData.

¿Cómo hago que las llamadas sean más baratas?

Establece jsRendering: false. Esa es la diferencia entre 10 créditos y 1. Añade blockResources cuando sí necesites renderizado, para que el navegador omita imágenes y hojas de estilo.

¿Cómo sé si una página necesita renderizado?

Obténla una vez sin renderizar, por 1 crédito. Si el contenido que quieres está ahí, has terminado. Si el cuerpo vuelve como una cáscara vacía, renderízala.

¿Puede rellenar un formulario o hacer clic para pasar a la siguiente página?

Sí, con jsScenario, que ejecuta los pasos click, fill, waitFor, scrollY y evaluate en orden sobre la página renderizada.

¿Cuál es la diferencia entre extractRules y aiExtractRules?

extractRules toma selectores CSS, y es barato, rápido y repetible. aiExtractRules describe los campos que quieres y permite que un modelo lea la página, lo que maneja páginas cuya estructura no puedes fijar, pero cuesta más y puede variar entre ejecuciones.

¿Puedo obtener una captura de pantalla?

Sí, con screenshot: true en una llamada renderizada.

¿Puedo usar esto junto con otras APIs de HasData?

Sí. Una clave cubre todo, y un endpoint sirve a todos mediante el parámetro apis. Apunta un cliente a ?apis=web_scraping,google_serp para obtener ambos conjuntos de herramientas en una sola conexión, o a mcp.hasdata.com/api/mcp para el catálogo completo.

¿Está HasData afiliado con los sitios que obtengo?

No. HasData es un servicio independiente. Esta herramienta obtiene páginas que tú nombras, así que lo que vuelve es lo que ese sitio publique, y eres responsable de usarlo conforme a los términos de ese sitio y la ley que te aplique.

Cumplimiento y datos personales

Esta herramienta apunta a donde tú la apuntes, lo que te pone más responsabilidad que una específica de un sitio. Dos cosas merecen una decisión antes de que construyas. extractEmails recopila direcciones, y una dirección es un dato personal en el sentido del RGPD y regulado por separado para marketing bajo la Ley CAN-SPAM, las reglas de ePrivacy y sus equivalentes. Y una página detrás de un inicio de sesión, un muro de pago o una exclusión de robots no se vuelve pública por el hecho de que un proxy pueda alcanzarla. Obtén lo que sea genuinamente público, conserva solo lo que tu propósito necesite y revisa tus propias obligaciones.

Enlaces de HasData

Otros servidores MCP de HasData: Google Search, Google Images, Google Scholar, Google Maps, Google Trends, Bing, DuckDuckGo, YouTube, TikTok, Instagram, Amazon, Walmart, Shopify, Yelp, Yellow Pages, Zillow, Redfin, Airbnb, Booking.com, Indeed, Glassdoor.

Desarrollo

El lanzador es un puente delgado de stdio hacia el servidor remoto, así que no hay nada que compilar.

npm install
HASDATA_API_KEY=your_key_here npm test

Las pruebas en test/ verifican el contrato de la herramienta, la parte que puede romperse sin un commit aquí. Comprueban que ?apis=web_scraping devuelve la única herramienta esperada, que su nombre no ha cambiado, que todavía requiere url y lleva una descripción, que los parámetros que documenta este README siguen en el esquema, y que la clave en uso es realmente aceptada.

Dos pruebas fijan el comportamiento del formato de salida, porque es la parte de este README que más probablemente atrape a un lector y la parte que un refactor probablemente cambie. Una pide solo markdown y verifica que el contenido llegue como una cadena en el nivel superior. La otra pide json con extractRules y verifica que la extracción aterrice en extractedData dentro de json. Ambas se ejecutan sin renderizado, así que el par cuesta 2 créditos.

La suite de contrato también se ejecuta semanalmente en un horario, porque la lista de herramientas ascendente puede cambiar sin que nadie toque este repositorio.

Contribuciones

Una tabla de herramientas, una muestra de respuesta o un comportamiento documentado que no coincida con la realidad merece un issue. Hay una plantilla exactamente para eso. Las solicitudes de extracción (pull requests) son bienvenidas para lo mismo, y para cualquier cosa en el lanzador.

Licencia

MIT, ver LICENSE.