cute-web-scraper
cute-web-scraper
Un servidor MCP que le da a Claude poderes de raspado web. Gratuito, local, sin clave de API, sin cuenta en la nube.
Pide en inglés sencillo. Obtiene las páginas, renderiza el JavaScript cuando es necesario, supera los bloqueos y devuelve markdown limpio o una tabla consultable — sin selectores, sin código de pegamento.
Por qué este
Entra. Cuatro niveles escalonados — HTTP simple, huellas TLS del navegador, un navegador real y luego un navegador sigiloso. ASOS, eBay, Booking.com y Trustpilot devuelven datos reales, en una conexión doméstica sin proxies.
No desperdicia tu contexto. Los artículos se limpian de navegación, banners de cookies y pies de página: una página de noticias de BBC pasa de 20 513 caracteres a 3 198. Los resultados grandes se guardan en una tabla SQLite que consultas con SQL en lugar de pegarlos en el chat.
Dice la verdad sobre el fracaso. Cinco de los sitios probados sirvieron una negativa bajo un estado de éxito — un intersticial bajo HTTP 200, una verificación de bot bajo 202 — y uno sirvió contenido real bajo 403. La detección de bloqueo pesa el cuerpo de la página, no el código de estado, para que no recibas un fragmento reportado como datos.
Sitios completos, no páginas individuales. Descubrimiento de sitemaps, obtención en paralelo y 24 herramientas que cubren productos, contactos, catálogos de Shopify, lugares, PDFs y seguimiento de cambios.
Instalación
pipx install git+https://github.com/maccydee/cute-web-scraperChromium se descarga automáticamente la primera vez que usas js_render (una única vez, ~130 MB).
Related MCP server: mcp-server-scraper
Conéctalo a Claude Code
claude mcp add cute-web-scraper -- cute-web-scraperLuego solo pregunta:
Scrape every product from https://example-shop.com and give me a CSV of name and price.Herramientas
Obtención y descubrimiento
Herramienta | Qué hace |
| Busca en la web y obtén resultados clasificados — la vía de entrada cuando tienes una pregunta, no una URL |
| Una URL a markdown limpio, con título, estado y número de enlaces |
| Informa de las llamadas API que hace una página, con su JSON — lee la fuente de datos directamente |
| Muchas URLs en paralelo, devolviendo resultados y errores por URL |
| Descubre las páginas de un sitio mediante sitemap, con respaldo a seguir enlaces |
| Detecta la plataforma, encuentra el sitemap, informa si se necesita JavaScript |
Extracción
Herramienta | Qué hace |
| Campos arbitrarios mediante selectores CSS — convierte cualquier listado en una tabla |
| Datos estructurados de producto (nombre, precio, moneda, disponibilidad, marca, sku, valoración) desde JSON-LD, OpenGraph o microdatos |
| Direcciones de correo en una lista de URLs, con contexto circundante |
| Números de teléfono en una lista de URLs, con contexto circundante |
| Cada hipervínculo, resuelto a URLs absolutas |
| Perfiles sociales en ocho plataformas |
| Un catálogo completo de Shopify, una fila por variante |
| Las colecciones de una tienda Shopify y sus recuentos de productos |
Lugares y negocios locales
Herramienta | Qué hace |
| Busca por nombre o descripción — nombre, dirección, coordenadas, teléfono, sitio web, horario de apertura |
| Todos los negocios de una categoría dentro de un radio de un lugar |
Seguimiento de cambios
Herramienta | Qué hace |
| Obtiene una página y la compara con la última comprobación — nuevo, igual o cambiado |
| Páginas en seguimiento y cuándo se vieron por última vez |
| Deja de seguir una página |
Tablas de resultados
Herramienta | Qué hace |
| Tablas de resultados guardadas con recuentos de filas y columnas |
| Columnas de una tabla, recuento de filas y una muestra |
| SQL de solo lectura sobre una tabla guardada — filtra, agrega, agrupa, ordena y opcionalmente guarda el resultado como una nueva tabla |
| Escribe una tabla a CSV o JSON en disco |
| Elimina una tabla guardada |
Una ejecución típica las combina: analyze_website → crawl_site → fetch_pages → query_table.
Extracción de campos arbitrarios
extract_by_selector cubre todo lo que los extractores fijos no cubren:
Get the title, price and link from every product on these 40 pages,
save it as `catalogue`, then show me anything under £50.fields asigna nombres de columnas a selectores CSS. row_selector hace que cada coincidencia sea una fila — eso es lo que convierte un listado en una tabla. Un sufijo @attr lee un atributo en lugar de texto, con href y src resueltos a URLs absolutas:
{"name": "h3 a@title", "price": ".price_color", "link": "h3 a@href"}Conduciendo una página
fetch_page acepta actions, que se ejecutan antes de leer la página — puertas de cookies, botones de "cargar más", desplazamiento infinito y formularios de búsqueda:
[{"action": "click", "selector": "#accept-cookies"},
{"action": "scroll_to_bottom", "max_rounds": 10}]Acciones disponibles: click, type, press, wait, wait_for, scroll, scroll_to_bottom y click_until_gone. Cada una informa de lo que hizo, de modo que un paso que no coincidió silenciosamente sea visible en lugar de dejarte adivinando.
Leyendo la API en lugar de la página
Cuando un sitio es difícil de analizar, inspect_network lo renderiza e informa de las solicitudes que hizo. Una página JavaScript casi siempre carga sus datos desde un endpoint que puedes obtener directamente — más barato que analizar el marcado, y sobrevive a rediseños que rompen los selectores:
Inspect the network on this listing page, then fetch whatever JSON endpoint it uses.Observando cambios
Check https://example.com/pricing for changes.track_changes guarda una instantánea e informa de new, same o changed con un diff unificado. Eso es monitoreo sin programador — comprueba cuando quieras y ve solo la diferencia.
Comandos de barra
El servidor incluye cuatro flujos de trabajo listos para usar, que aparecen como comandos de barra en Claude Code: scrape_site, scrape_shopify_store, find_contacts y compare_prices.
Trabajando con raspados grandes
Cualquier herramienta que devuelva filas acepta save_as. En lugar de poner los datos en la conversación, escribe una tabla de resultados y devuelve un resumen:
Extract the whole catalogue from deathwishcoffee.com into a table called `catalogue`,
then tell me the price range and how many variants are out of stock.Claude llama a extract_shopify_store(save_as="catalogue"), recibe un recuento de filas y una lista de columnas, y luego responde con query_table:
SELECT COUNT(*) AS variants, MIN(price) AS cheapest,
MAX(price) AS dearest, SUM(available) AS in_stock
FROM catalogueLa tabla puede contener 100 000 filas y ninguna de ellas entra en la conversación. query_table es estrictamente de solo lectura — se ejecuta contra un manejador SQLite de solo lectura y rechaza cualquier cosa que no sea un SELECT, de modo que una consulta nunca puede modificar o eliminar datos guardados.
Las tablas viven en un archivo SQLite en ~/.cute-web-scraper/results.db (establece SCRAPER_DB_PATH para moverlo).
Limpieza de datos
query_table también acepta save_as, que persiste el resultado como una nueva tabla. SQL ya expresa las operaciones de limpieza habituales, así que no hay un conjunto separado de herramientas de edición:
SELECT DISTINCT * FROM leads -- deduplicate
SELECT street || ', ' || city AS address FROM leads -- merge columns
SELECT name, phone FROM leads WHERE phone IS NOT NULL -- drop columns and rows
SELECT vendor AS brand FROM catalogue -- renameLa tabla fuente queda intacta a menos que apuntes deliberadamente a su propio nombre, y la respuesta dice replaced_existing_table cuando lo haces — así un filtro en el lugar nunca es una pérdida silenciosa de filas.
Lugares y negocios locales
find_places busca un solo lugar; find_places_nearby devuelve todo lo de una categoría dentro de un radio, que es el caso de generación de leads local:
Find every dentist within 4km of Bath, save it as `leads`,
then tell me how many have a website but no phone number.Las categorías aceptan nombres amigables (cafe, dentist, hotel, solicitor, gym, hairdresser, …) o una etiqueta OpenStreetMap cruda como amenity=dentist.
Una nota sobre la fuente de datos. Esto es OpenStreetMap, no Google Maps. Google era el objetivo obvio y no funciona: un navegador automatizado recibe un intersticial de consentimiento de cookies, y una vez superado, una carcasa de mapa degradada sin panel de lugares. El nivel sigiloso no ayuda, porque esto es un muro de consentimiento en lugar de detección de bots — un problema diferente del que resuelve el sigilo.
OpenStreetMap da los mismos campos — nombre, dirección, coordenadas, teléfono, sitio web, horario de apertura, categoría — a través de endpoints abiertos documentados sin clave. Lo único para lo que no tiene equivalente son las valoraciones con estrellas y los recuentos de reseñas, que son datos propietarios de Google.
Ambos endpoints son gestionados por voluntarios. La política de Nominatim de una solicitud por segundo se aplica internamente independientemente de SCRAPER_DELAY_MS, y las consultas de Overpass pasan por varios espejos públicos, porque la instancia principal devuelve regularmente 504 bajo carga.
La salida de las herramientas también está limitada a SCRAPER_MAX_INLINE_CHARS (25 000 por defecto). Más allá de eso, un resultado se trunca con una nota que apunta a save_as — así una sola llamada no puede llenar tu contexto por accidente.
Ejemplos de prompts
Export the whole catalogue from deathwishcoffee.com and tell me the price range.
Find all email addresses on https://company.com and its contact pages.
What platform is https://myblog.com on? Does it need JavaScript to scrape?
Scrape these 200 product pages into a table, then show me everything under £50 that's in stock.
Extract the social media links from these 10 agency sites: [urls...]Configuración
Todo es una variable de entorno, con valores predeterminados que funcionan sin configuración.
Variable | Predeterminado | Significado |
|
| Retraso base entre solicitudes al mismo dominio |
|
| Máximo de solicitudes en paralelo |
|
| Cuánto tiempo una página obtenida sigue siendo reutilizable |
|
| Páginas en caché antes de la expulsión por uso menos reciente |
| sin establecer | Token Bearer para el modo HTTP |
| sin establecer | Perfil de Chrome del que heredar sesiones iniciadas |
|
| Reintentar solicitudes bloqueadas con huellas TLS del navegador |
|
| Navegador sigiloso de último recurso para los bloqueos más difíciles |
|
| Dónde se almacenan las tablas de resultados |
|
| Límite máximo de lo que una sola herramienta devuelve en línea |
Agrupar una lista larga de URL en una sola tabla requiere mode: "append" en cada llamada después de la primera, o cada lote reemplaza al anterior. Las páginas renderizadas que vuelven escasas pueden recibir wait_ms, o mejor wait_for con un selector CSS.
Cómo se comporta
Contenido principal, no toda la página. Las páginas con forma de artículo se procesan con trafilatura, que aísla el cuerpo y descarta el mobiliario circundante; se eligió porque en un benchmark independiente de 2,008 páginas obtiene una puntuación F1 de 0,791 frente al 0,674 de Readability. Se aplica por página y no de forma universal: el mismo benchmark muestra que los extractores divergen entre 20 y 30 puntos en cuadrículas de productos y colecciones, donde el "contenido principal" no es un artículo, por lo que las páginas de listado conservan el documento completo. Pasa main_content: false para forzar eso en cualquier lugar.
Cuatro niveles, que escalan solo cuando se rechaza. Un cliente HTTP simple maneja la mayoría de las páginas. Si un sitio rechaza, la solicitud se reintenta con huellas TLS reales del navegador (Chrome, luego Safari), porque algunos sitios toman la huella del propio protocolo de enlace TLS y ningún cambio de cabecera los supera. js_render: true renderiza en Chromium para aplicaciones de una sola página. Como último recurso, un navegador con parche sigiloso maneja sitios que necesitan JavaScript y rechazan la automatización ordinaria.
Cada nivel corrige un fallo distinto, y ninguno es un superconjunto de los demás: el nivel TLS no puede ejecutar JavaScript, y Playwright es un navegador detectablemente automatizado. Cada resultado informa qué nivel lo sirvió. Establece SCRAPER_IMPERSONATE=0 o SCRAPER_STEALTH=0 para desactivar los dos últimos y dejar que los bloqueos se mantengan.
Los dos últimos niveles son evasión, no cortesía: existen para superar la detección de bots que los sitios implementaron deliberadamente. Solo se ejecutan después de un rechazo, nunca en un sitio que sirvió la página con normalidad.
Retroceso adaptativo. Las solicitudes al mismo dominio se espacian según SCRAPER_DELAY_MS, medido de inicio a inicio, por lo que el retraso limita la tasa de solicitudes en lugar de sumarse a respuestas lentas. Cuando un dominio responde con rechazo (un 429, un 403, un desafío de Cloudflare), el retraso para ese dominio se duplica, hasta 60 segundos, y disminuye de nuevo una vez que las solicitudes vuelven a tener éxito. Los dominios se rastrean de forma independiente, por lo que raspar dos sitios a la vez no cuesta nada extra.
robots.txt no se aplica. Solo se lee para localizar sitemaps; sus reglas Disallow no se consultan y no hay ninguna configuración para cambiarlo. El retraso adaptativo por dominio es el mecanismo de cortesía de esta herramienta.
Una caché breve. Las páginas obtenidas se reutilizan durante cinco minutos, por lo que ejecutar fetch_pages y luego extract_emails sobre las mismas URL no obtiene todo dos veces.
Modo HTTP
El valor predeterminado es stdio, que es lo que usa claude mcp add más arriba. Para ejecutar en su lugar una instancia compartida persistente:
SCRAPER_AUTH_TOKEN=$(openssl rand -hex 16) cute-web-scraper --http --port 8080claude mcp add --transport http cute-web-scraper http://127.0.0.1:8080/mcpSe vincula a 127.0.0.1 y expone /mcp además de un endpoint /health. Vincular más allá del loopback requiere SCRAPER_AUTH_TOKEN, y el servidor se niega a iniciarse sin él en lugar de publicar silenciosamente un scraper abierto en tu red.
Limitaciones
Sin rotación de proxies ni resolución de CAPTCHA. Un sitio que sobrevive a los cuatro niveles se informa como bloqueado en lugar de adivinarse.
LinkedIn y similares pueden necesitar
SCRAPER_CHROME_USER_DATA_DIRapuntando a un perfil de Chrome con sesión iniciada.SCRAPER_DELAY_MS=0elimina el retraso cortés, pero el retroceso aún se activa cuando un sitio responde con rechazo.La extracción de teléfonos es deliberadamente conservadora: requiere un código de país o un prefijo de troncal, por lo que omite algunos formatos locales simples en lugar de devolver años y números de pedido.
Desarrollo
uv sync --extra devuv run pytest -vuv run pytest -m integration -v -suv run ruff check src/ tests/ && uv run mypy src/cute_web_scraper/Las pruebas unitarias son herméticas y nunca tocan la red. Las pruebas de integración acceden a sitios en vivo y están excluidas de la ejecución predeterminada.
Licencia
MIT — consulta LICENSE.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseNot gradedqualityNot gradedmaintenanceAn MCP server for web content extraction that converts HTML pages into clean, LLM-optimized Markdown using Mozilla's Readability. It supports batch processing, intelligent multi-page crawling, and configurable caching while respecting robots.txt standards.51
- AlicenseAqualityCmaintenanceMCP server for web scraping — extract clean markdown, links, and metadata from any URL. Free Firecrawl alternative.5935MIT
- AlicenseNot gradedqualityCmaintenanceOpen-source web scraper and extraction MCP server with JavaScript rendering, markdown output, PDF/DOCX parsing, structured errors, and validated extraction contract diagnostics for agents.2AGPL 3.0
- AlicenseNot gradedqualityAmaintenanceRemote MCP server for web scraping with anti-bot evasion. Provides stealth HTTP fetching, headless browser with Cloudflare bypass, CSS selectors, YouTube transcripts, and Markdown conversion.1MIT
Related MCP Connectors
All HasData scraping tools in one MCP server: Google, TikTok, Instagram, maps, e-commerce and more.
One MCP server for 180+ live web-data APIs returning clean JSON from sites that block scrapers.
Firecrawl MCP — wraps the Firecrawl API (firecrawl.dev) for web
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/maccydee/cute-web-scraper'
If you have feedback or need assistance with the MCP directory API, please join our Discord server