Skip to main content
Glama
maccydee

cute-web-scraper

by maccydee

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.

CI Python 3.10+ License: MIT MCP Tests

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-scraper

Chromium 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-scraper

Luego 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

search_web

Busca en la web y obtén resultados clasificados — la vía de entrada cuando tienes una pregunta, no una URL

fetch_page

Una URL a markdown limpio, con título, estado y número de enlaces

inspect_network

Informa de las llamadas API que hace una página, con su JSON — lee la fuente de datos directamente

fetch_pages

Muchas URLs en paralelo, devolviendo resultados y errores por URL

crawl_site

Descubre las páginas de un sitio mediante sitemap, con respaldo a seguir enlaces

analyze_website

Detecta la plataforma, encuentra el sitemap, informa si se necesita JavaScript

Extracción

Herramienta

Qué hace

extract_by_selector

Campos arbitrarios mediante selectores CSS — convierte cualquier listado en una tabla

extract_products

Datos estructurados de producto (nombre, precio, moneda, disponibilidad, marca, sku, valoración) desde JSON-LD, OpenGraph o microdatos

extract_emails

Direcciones de correo en una lista de URLs, con contexto circundante

extract_phones

Números de teléfono en una lista de URLs, con contexto circundante

extract_links

Cada hipervínculo, resuelto a URLs absolutas

extract_social_links

Perfiles sociales en ocho plataformas

extract_shopify_store

Un catálogo completo de Shopify, una fila por variante

list_shopify_collections

Las colecciones de una tienda Shopify y sus recuentos de productos

Lugares y negocios locales

Herramienta

Qué hace

find_places

Busca por nombre o descripción — nombre, dirección, coordenadas, teléfono, sitio web, horario de apertura

find_places_nearby

Todos los negocios de una categoría dentro de un radio de un lugar

Seguimiento de cambios

Herramienta

Qué hace

track_changes

Obtiene una página y la compara con la última comprobación — nuevo, igual o cambiado

list_tracked

Páginas en seguimiento y cuándo se vieron por última vez

untrack

Deja de seguir una página

Tablas de resultados

Herramienta

Qué hace

list_tables

Tablas de resultados guardadas con recuentos de filas y columnas

get_table

Columnas de una tabla, recuento de filas y una muestra

query_table

SQL de solo lectura sobre una tabla guardada — filtra, agrega, agrupa, ordena y opcionalmente guarda el resultado como una nueva tabla

export_table

Escribe una tabla a CSV o JSON en disco

drop_table

Elimina una tabla guardada

Una ejecución típica las combina: analyze_websitecrawl_sitefetch_pagesquery_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 catalogue

La 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                         -- rename

La 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

SCRAPER_DELAY_MS

1000

Retraso base entre solicitudes al mismo dominio

SCRAPER_MAX_CONCURRENT

5

Máximo de solicitudes en paralelo

SCRAPER_CACHE_TTL_S

300

Cuánto tiempo una página obtenida sigue siendo reutilizable

SCRAPER_CACHE_MAX_ENTRIES

500

Páginas en caché antes de la expulsión por uso menos reciente

SCRAPER_AUTH_TOKEN

sin establecer

Token Bearer para el modo HTTP

SCRAPER_CHROME_USER_DATA_DIR

sin establecer

Perfil de Chrome del que heredar sesiones iniciadas

SCRAPER_IMPERSONATE

1

Reintentar solicitudes bloqueadas con huellas TLS del navegador

SCRAPER_STEALTH

1

Navegador sigiloso de último recurso para los bloqueos más difíciles

SCRAPER_DB_PATH

~/.cute-web-scraper/results.db

Dónde se almacenan las tablas de resultados

SCRAPER_MAX_INLINE_CHARS

25000

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 8080
claude mcp add --transport http cute-web-scraper http://127.0.0.1:8080/mcp

Se 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_DIR apuntando a un perfil de Chrome con sesión iniciada.

  • SCRAPER_DELAY_MS=0 elimina 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 dev
uv run pytest -v
uv run pytest -m integration -v -s
uv 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.

A
license - permissive license
A
quality
A
maintenance

Maintenance

Maintainers
Response time
Release cycle
1Releases (12mo)
Commit activity

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

  • F
    license
    Not graded
    quality
    Not graded
    maintenance
    An 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
  • A
    license
    Not graded
    quality
    C
    maintenance
    Open-source web scraper and extraction MCP server with JavaScript rendering, markdown output, PDF/DOCX parsing, structured errors, and validated extraction contract diagnostics for agents.
    2
    AGPL 3.0
  • A
    license
    Not graded
    quality
    A
    maintenance
    Remote 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.
    1
    MIT

View all related MCP servers

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

View all MCP Connectors

Latest Blog Posts

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