Marcos Ramírez BETA
Código Python de scraping recolocándose sobre una estructura web que cambia

Scrapling: el scraper de Python que se repara cuando la web cambia

· ⏱ 8+ min lectura

Hay un momento en la vida de todo el que ha escrito un scraper en el que te das cuenta de que tu trabajo no es escribir el scraper. Es mantenerlo vivo.

Lo montas un domingo por la tarde, funciona precioso, extrae los datos, y te vas a dormir tranquilo. Tres semanas después la web le cambia una clase a un div, tu selector deja de encontrar nada, el script peta y tú te enteras porque el dato que dependía de eso lleva cuatro días en blanco. Y a arreglarlo otra vez.

Eso es el 90% del scraping en producción. No es la primera versión. Es las cincuenta siguientes.

Por eso me llamó la atención Scrapling, una librería de scraping para Python que arrancó con una promesa concreta: cuando la web cambia su estructura, el scraper se recoloca solo. Ya tiene 61.900 estrellas en GitHub, así que de nicho oculto, nada.

Vamos por partes.

La idea que lo separa de todo lo demás: adaptive scraping

Aquí está el truco que da nombre al vídeo del que salió este post, “el scraper que se repara a sí mismo”.

Cuando capturas un elemento con Scrapling, puedes pedirle que guarde una especie de huella de ese elemento: su posición en el árbol, sus atributos, el texto, los vecinos. Lo activas con auto_save=True. Si más adelante la web cambia y tu selector original deja de funcionar, activas adaptive=True y Scrapling usa esa huella para buscar el elemento que MÁS se parece al que guardaste, aunque ahora esté en otro sitio del DOM o con otra clase.

from scrapling.fetchers import StealthyFetcher

StealthyFetcher.adaptive = True
page = StealthyFetcher.fetch('https://example.com', headless=True, network_idle=True)
products = page.css('.product', auto_save=True)

No es magia, es similitud. Compara estructuras y elige la más cercana a la que un día le dijiste “esto es lo que quiero”. Y para el caso real de arriba (la web te cambia un nombre de clase y todo se va al garete) es exactamente lo que necesitas.

Es la diferencia entre un selector que dice “el tercer div con clase precio” y uno que dice “ese elemento que el mes pasado contenía el precio, esté donde esté ahora”. El primero se rompe con cualquier rediseño. El segundo, aguanta.

Los tres fetchers: del HTTP rápido al navegador completo

Scrapling no es solo un parser. Trae tres formas de traer la página, y cada una pesa distinto:

  • Fetcher: peticiones HTTP rápidas con impersonación de navegador. Para webs estáticas o APIs. Ligero y veloz.
  • StealthyFetcher: el modo anti-bot. Capaz de saltarse Cloudflare Turnstile, con prevención de fugas DNS-over-HTTPS. Para webs hostiles que te detectan y te bloquean.
  • DynamicFetcher: navegador completo vía Playwright/Chrome. Para contenido que se renderiza con JavaScript, SPAs, todo lo que un requests normal no ve.

La gracia es que la API es la misma para los tres. Empiezas con el Fetcher ligero y, si la web te da guerra, subes a StealthyFetcher o DynamicFetcher sin reescribir tu lógica de extracción. Eso, en scraping, se agradece mucho, porque normalmente no sabes lo agresiva que es una web hasta que te la encuentras.

Cada fetcher tiene además su clase de sesión para mantener cookies y estado entre peticiones. Útil cuando hay login de por medio.

El framework de spiders

Si vienes de Scrapy, esta parte te va a sonar. Scrapling trae su propio framework de spiders para crawls grandes, con concurrencia, pausa y reanudación, rotación de proxies con estrategias personalizables, cumplimiento opcional de robots.txt, modo streaming para emitir items en tiempo real y un modo desarrollo que cachea respuestas para que no machaques la web mientras depuras.

from scrapling.spiders import Spider, Response

class MySpider(Spider):
    name = "demo"
    start_urls = ["https://example.com/"]

    async def parse(self, response: Response):
        for item in response.css('.product'):
            yield {"title": item.css('h2::text').get()}

MySpider().start()

La sintaxis de selección es la de toda la vida: CSS y XPath, con un estilo de consulta tipo BeautifulSoup. O sea, no tienes que aprender un lenguaje nuevo para sacar datos. Lo que ya sabes, vale.

El rendimiento, con números

Aquí es donde Scrapling saca pecho. Según su propio benchmark, su parser extrae texto de 5.000 elementos anidados a velocidad de referencia (±1.0x), comparable a Parsel, y MUCHO más rápido que el clásico BeautifulSoup: 784 veces más rápido en ese test.

Que conste, esto es un benchmark del propio proyecto, así que tómalo con la cabeza fría. Pero el orden de magnitud encaja con lo conocido: BeautifulSoup es cómodo y lento, las librerías construidas sobre lxml vuelan. Scrapling está en el grupo de las que vuelan.

Comparativa rápida con lo que ya usas

HerramientaQué esPunto fuerteDónde flojea
BeautifulSoupParser de HTMLFacilísimo, ideal para extracciones puntualesLento y sin red propia (necesita requests)
ScrapyFramework de crawlingBatalla probada a gran escala, millones de páginasCurva de entrada, JS solo con plugins
CrawleeLibrería de crawling (Node y Python)Playwright nativo, fingerprinting integradoEcosistema más orientado a su plataforma
ScraplingFramework adaptativoSe recoloca solo, anti-bot, parser rapidísimoJoven, el adaptive cuesta CPU a gran escala

La conclusión sensata, y la repito porque es importante: ninguna gana siempre. Crawlee es estupenda para SPAs modernas. Scrapy sigue siendo el rey del crawl masivo multi-dominio. BeautifulSoup es perfecto para sacar cuatro datos de una página estática y olvidarte. Scrapling brilla en el caso concreto de extracción dirigida sobre webs que cambian y que te ponen pegas para entrar.

Cuándo NO deberías usar Scrapling

Voy a ser honesto, porque si solo te cuento lo bueno te estoy vendiendo una moto.

El adaptive scraping no es gratis. Esa similitud que recoloca elementos tiene un coste de CPU, y a escala de millones de páginas ese coste se nota. Apify lo señala en su análisis técnico: el tracking adaptativo te ahorra mantenimiento en scripts pequeños y dirigidos, pero introduce overhead computacional importante cuando lo escalas, y su framework de spiders todavía no tiene la arquitectura distribuida madura y probada que necesitas para crawls realmente masivos.

Traducido: si lo tuyo es rastrear medio internet, Scrapy lleva años haciéndolo y no lo vas a sustituir todavía. Si lo tuyo es sacar datos fiables de veinte webs concretas que se rediseñan cada dos por tres y te bloquean en cuanto pueden, Scrapling te va a ahorrar muchas tardes de domingo.

Herramienta para un problema, no para todos.

¿Y en Rust?

Lo pienso cada vez que veo una librería así de buena nacer en Python: ¿por qué no en Rust? El parsing de HTML y el crawling concurrente son justo el tipo de carga donde Rust va sobrado. Y existe ecosistema, el crate scraper para parsear y spider para crawlear van rapidísimos.

Pero hay una cosa que en Rust, hoy, no tienes: el adaptive scraping de Scrapling. Esa pieza de “recolócame el elemento cuando la web cambie” es lo que de verdad ahorra horas de mantenimiento, y es justo lo que no encuentras montado en el ecosistema Rust. Ahí hay un hueco. Y… a alguien se le ocurrirá llenarlo.

Cómo empezar

Es software libre, licencia BSD-3, gratis y sin restricciones comerciales. Necesitas Python 3.10 o superior.

pip install scrapling

Y si quieres todo, fetchers de navegador incluidos:

pip install "scrapling[all]"

La versión actual a día de hoy es la 0.4.9. Trae hasta integración de servidor MCP para que un asistente de Inteligencia Artificial te ayude a montar el scraping, que para los tiempos que corren tiene su sentido.

Preguntas frecuentes

¿Scrapling sustituye a Scrapy? No, o todavía no. Para crawls masivos multi-dominio, Scrapy sigue siendo más maduro y probado. Scrapling encaja mejor en extracción dirigida sobre webs hostiles o que cambian a menudo.

¿Es gratis? Sí. Es open source con licencia BSD-3, sin restricciones comerciales. Solo pagas tu tiempo y tu infraestructura.

¿Qué necesito para que funcione el modo anti-bot? El StealthyFetcher, que trae las capacidades de bypass (incluido Cloudflare Turnstile) y prevención de fugas DNS. Para JavaScript pesado, el DynamicFetcher, que usa Playwright por debajo.

¿El adaptive scraping funciona siempre? No es magia: busca el elemento más parecido al que guardaste. Si la web se rehace de cero, ningún sistema te salva. Pero para rediseños parciales (cambios de clases, reordenaciones) recupera el elemento sin que toques el código.

Fuentes

Compártelo si te ha resultado útil.

¿Cuántas veces se te ha roto un scraper porque la web cambió cuatro clases? Cuéntame.

Y si necesitas montar un scraper serio o automatizar extracción de datos para tu empresa, puedo ayudarte.

Y… a ver cuánto tarda en romperse el siguiente.

Artículos relacionados

Múltiples agentes de Inteligencia Artificial cargando módulos de conocimiento especializado desde una biblioteca digital

Agent Skills: el estándar que enseña a tus agentes cómo trabajar

Agent Skills es el formato abierto que permite a cualquier agente de Inteligencia Artificial cargar conocimiento especializado bajo demanda: desde cómo escribir en tu blog hasta cómo cerrar un artículo con el CTA correcto. Un skill es simplemente una carpeta con un fichero SKILL.md, pero la idea detrás es poderosa: separar el conocimiento del agente de la herramienta que lo ejecuta. Adoptado por más de treinta herramientas —incluyendo Claude Code, Cursor, GitHub Copilot y Gemini CLI— está convirtiéndose en el estándar de facto. En este post explico cómo funciona, presento el ecosistema en agentskills.io y el directorio de skills.sh, y cuento cómo llevo meses usándolo en este blog sin saber que tenía nombre. Incluyo ejemplos reales del sistema de skills del blog: desde subskills jerárquicos de copywriting hasta un skill de captación de clientes sin una sola línea de código.

Logo de OpenRouter con múltiples modelos de Inteligencia Artificial conectados

OpenRouter: 500 modelos de Inteligencia Artificial en una API

OpenRouter es un gateway unificado con más de 500 modelos de Inteligencia Artificial de docenas de proveedores mediante una sola API key y endpoint. Incluye casi 30 modelos gratuitos ideales para desarrollo, sin tarjeta de crédito. Su sistema de fallback automático cambia de modelo si uno falla, y su compatibilidad con OpenAI permite integrarlo fácilmente en herramientas como OpenCode y OpenClaw.