La mayoría de las personas conoce Crawlee mientras intenta responder otra pregunta: «¿qué navegador sin interfaz debería usar?». Esa no es la pregunta correcta, y Crawlee es la razón. No es un navegador. Es el framework de Node/TypeScript que lo utiliza cuando lo necesitas y se lo salta cuando no.
Pasé un par de días probando Crawlee 3.17.0 con un conjunto controlado de fixtures y algunos sitios públicos de demostración, en Node v22.22.3 y macOS. La promesa principal —una sola librería, una sola API, con un crawler HTTP o un navegador real debajo— es lo que más quería poner a prueba, porque es la afirmación que decide si vale la pena añadir Crawlee a tu stack o si simplemente conviene ir directo a Playwright. Resumen rápido: la historia de los dos motores sí se sostiene, con algunos matices que comentaré más adelante.
Qué es realmente Crawlee (y qué no es)
Crawlee se define como una librería de automatización de navegadores y scraping web para Node.js, pensada para crear crawlers fiables. Su propuesta oficial es amplia: extraer datos para IA, LLMs, RAG o GPTs; descargar HTML, PDF, JPG, PNG y otros archivos; compatible con Puppeteer, Playwright, Cheerio, JSDOM y HTTP puro; modo visible o sin interfaz; y rotación de proxies incluida. Cubre muchísimo terreno, así que ayuda decir también qué no es Crawlee.
No es un motor de renderizado. No trae su propio navegador. Cuando necesitas ejecutar JavaScript, Crawlee controla Playwright o Puppeteer, y estos a su vez controlan Chromium (u otro navegador). Tampoco es un servicio alojado al que llamas por red: es una dependencia que instalas y ejecutas tú mismo. Lo que Crawlee sí es, con precisión, es la capa por encima del fetcher: las clases de crawler, la cola de solicitudes, el almacenamiento y la lógica para seguir enlaces. Piensa en él como el framework de rastreo, con un motor intercambiable por debajo.
Para que conste, la versión que probé fue 3.17.0 (publicada el 2026-06-04), está escrita en TypeScript, su licencia es Apache-2.0 y el repositorio rondaba los 24.6k estrellas al 2026-07-09 en apify/crawlee. El número de estrellas cambia —el repo sumó 53 durante los dos días que lo estuve mirando— así que tómalo como una captura puntual, no como un dato fijo.
Los dos motores: CheerioCrawler vs PlaywrightCrawler
Aquí es donde el diseño demuestra su valor, y donde pasé la mayor parte del tiempo.
CheerioCrawler es la ruta HTTP. Descarga el HTML en bruto y lo analiza con Cheerio —sin navegador, sin ejecutar JavaScript, sin renderizar. Es rápido y barato. PlaywrightCrawler es la ruta con navegador. Abre Chromium de verdad, renderiza la página incluyendo cualquier JavaScript que construya el DOM, e incluso puede tomar capturas de pantalla.
Dos motores distintos con capacidades realmente diferentes. El punto de Crawlee es que ambos se comportan igual por fuera. Los dos aceptan un requestHandler. Los dos exponen run(). Los dos rastrean enlaces con enqueueLinks. Pasar de un motor al otro es cambiar de clase, no rehacer el código —lo comprobé manteniendo la lógica de extracción byte a byte idéntica y cambiando solo la clase crawler que la envolvía.

Conviene ser exactos en un punto, porque ahí termina la equivalencia: el acceso al contenido cambia. Dentro de un handler de CheerioCrawler recibes $ —un DOM estático, ya parseado, que consultas como si fuera jQuery. Dentro de un handler con navegador recibes un objeto page vivo. Así que la cola, el enrutamiento y la parte de «envía estos datos, sigue estos enlaces» se mantienen idénticos, pero la línea donde realmente lees la página cambia de forma. La propia documentación de Crawlee lo dice: el contrato compartido se limita a las operaciones de rastreo, y el acceso al contenido es la parte variable.
| Motor | Cómo obtiene la página | ¿Ejecuta JavaScript? | Mi prueba (1 página dinámica) | Mejor para |
|---|---|---|---|---|
CheerioCrawler | HTTP directo + parseo con Cheerio | No | ~0.035s | HTML estático, APIs JSON, velocidad |
PlaywrightCrawler | Chromium real vía Playwright | Sí | ~4.967s | Páginas renderizadas con JS, capturas |
Estos tiempos provienen de una sola máquina y una sola ejecución —no son un benchmark, solo muestran la diferencia de coste. La ruta con navegador costó aproximadamente dos órdenes de magnitud más en la misma URL. Ese es el precio del renderizado, y por eso no deberías usarla por defecto.
La prueba: misma URL, 0 vs 8/8
Las afirmaciones cuestan poco. La razón por la que confío en la historia de los dos motores es que pude hacerla fallar y luego arreglarla cambiando una sola clase.
Construí un fixture dinámico local —una página de catálogo donde las tarjetas de productos se inyectan con JavaScript después de cargar, el tipo de página que ya es casi estándar en la web moderna. Apunté CheerioCrawler a esa URL. Devolvió 0 tarjetas de producto. Eso no es un error; es física. Cheerio nunca ejecutó el JavaScript, así que las tarjetas nunca existieron en el HTML que analizó. Después apunté PlaywrightCrawler a exactamente la misma URL, sin cambiar nada más, y renderizó 8 de 8 productos y además tomó una captura como prueba.

Para asegurarme de que no era una rareza de mi propio fixture, repetí el mismo patrón en un sitio público —la página de demo en JavaScript Quotes to Scrape, que construye las citas en el cliente. El mismo resultado en la misma dirección: CheerioCrawler vio 0 citas, PlaywrightCrawler recuperó 10.

Quiero ser cuidadoso con lo que esto demuestra. Es una reproducción limpia de algo que Crawlee ya documenta: desde la versión 3.0, el framework comparte la misma clase base y la misma interfaz entre sus tipos de crawler. Así que esto es verificación, no descubrimiento. Pero justo ahí está el valor: la promesa de marketing «una interfaz, HTTP o navegador» es real, y aquí está el recibo de 0 → datos completos tanto en un fixture que controlo como en un sitio que no.
Dónde gana la ruta HTTP
Sería fácil leer la sección anterior como «usa siempre el navegador». No lo hagas. Precisamente el diseño de dos motores importa porque el navegador es el plan B costoso, no el punto de partida.
En contenido estático, CheerioCrawler fue preciso y rápido. Mi fixture de catálogo estático devolvió 12 de 12 productos con cobertura total, siguiendo la paginación mediante enqueueLinks({ selector: '.next-page' }), en unos 0.155 segundos. Una página de artículo entregó su título y los 3 de 3 párrafos del cuerpo, separando limpiamente el contenido del texto legal de login/suscripción/derechos de autor.
Lo más importante: una página cuyo contenido se carga con JavaScript suele tener una API JSON detrás. Los datos de mi fixture dinámico vivían en un endpoint, y cuando apunté CheerioCrawler directamente a esa API, recuperó 8 de 8 productos —sin navegador, en unos 0.035 segundos. Los mismos datos que la ruta con navegador tardó casi cinco segundos en renderizar. La lección es vieja pero sigue siendo cierta: si puedes reproducir la petición subyacente, haz eso en lugar de lanzar Chromium. Crawlee te permite tomar esa decisión por crawler sin cambiar de framework.
La parte de framework de rastreo (la razón para elegir Crawlee frente a una librería de navegador desnuda)
Si solo necesitases renderizar una página, no necesitarías Crawlee —usarías Playwright o Puppeteer por separado. Lo que una librería de navegador pura no te da es un crawl: una cola, deduplicación, control de profundidad y reintentos. Esa es la parte de Crawlee que no tiene que ver con motores.
Ejecuté un rastreo dentro del mismo dominio desde la raíz del fixture usando enqueueLinks con seguimiento de profundidad. Crawlee recorrió 11 páginas distribuidas en las profundidades {0:1, 1:3, 2:7} —una raíz, tres páginas a un salto, siete páginas a dos saltos— y respetó maxRequestsPerCrawl como condición de parada. RequestQueue se ocupó de la contabilidad. Cuando lancé una solicitud a una página que devolvía HTTP 500, Crawlee reintentó y luego expuso el fallo mediante failedRequestHandler en vez de tragárselo en silencio o romper la ejecución.

Este es el mejor argumento a favor de Crawlee frente a una herramienta de navegador independiente: la orquestación del crawl viene integrada y, lo más importante, es la misma tanto si debajo hay HTTP como si hay navegador. Escribes una sola vez la lógica de cola y seguimiento. Luego decides por separado si cada crawler debe renderizar JavaScript.
Instalación y la descarga oculta del navegador
La instalación fue casi sin problemas, con una trampa que puede morder a quienes lo usan por primera vez.
npm install crawlee playwright se ejecutó limpio —sin vulnerabilidades reportadas. Pero PlaywrightCrawler no arrancará hasta que también ejecutes npx playwright install chromium, que descarga un binario de Chromium de unos 81.7 MiB. Instalar solo el paquete crawlee no descarga ningún navegador. Si te saltas ese paso y vas directo a un crawler con navegador, verás un error de arranque que no resulta obvio si no conoces ya el modelo de empaquetado de Playwright. Es un comportamiento heredado de Playwright, no un defecto de Crawlee, pero sí es un freno real en la primera ejecución que vale la pena mencionar.

Otra nota operativa: por defecto Crawlee escribe en un directorio local storage/. Mi entorno de pruebas redirigió eso a una carpeta temporal y desactivó la persistencia para mantener todo limpio, pero una ejecución estándar dejará una carpeta storage/ en tu proyecto. No es un problema, solo algo que conviene saber antes de verlo aparecer en git status.
Un tercer motor, brevemente
La historia de paridad de Crawlee no se limita a Cheerio y Playwright. También existe PuppeteerCrawler, y revisé hasta dónde llega la afirmación de «la misma interfaz» en su caso —a nivel de clase y de superficie de API, no con un rastreo real.
Las tres clases de crawler se remontan a la misma base BasicCrawler. CheerioCrawler pasa por HttpCrawler; PlaywrightCrawler y PuppeteerCrawler pasan por un BrowserCrawler compartido. Al inspeccionar el paquete instalado, hay 24 métodos públicos comunes a los tres motores, incluidas las operaciones de cola y almacenamiento sobre las que se construye todo el diseño —run, addRequests, pushData, getData, getDataset, exportData, getRequestQueue, useState, stop. PuppeteerCrawler y PlaywrightCrawler incluso exponen exactamente el mismo conjunto público de métodos. Las únicas diferencias entre motores están en la unión HTTP vs navegador, que es justo donde cabría esperarlas.
El límite que conviene decir con claridad: no ejecuté un crawl real con PuppeteerCrawler. La dependencia opcional puppeteer no estaba instalada en mi entorno de pruebas, y probarlo habría significado otra descarga de navegador. Así que la equivalencia con Puppeteer está verificada estructuralmente —misma clase base, mismos métodos compartidos, misma forma de contexto del handler—, no mediante una ejecución real. Y aun cuando la interfaz coincide, el comportamiento interno no es idéntico: la guía oficial de Crawlee señala que Playwright espera elementos automáticamente, mientras que Puppeteer te obliga a esperar de forma explícita. Eso es una característica del motor, no un fallo de Crawlee, pero significa que «misma API» no equivale a «mismo código dentro de cada handler».
Lo que no probé
Aquí está lo que esta ronda dejó deliberadamente fuera, para que no interpretes mis resultados como algo más amplio de lo que son.
- Escala. Todo se ejecutó con fixtures pequeños y rastreos cortos de sitios públicos. No hubo una ejecución larga de 100–1,000 páginas, así que no puedo hablar de autoscaling o estabilidad bajo carga real.
- Persistencia de cola y reanudación. Nunca maté un crawl a mitad de camino para ver si
RequestQueueretomaba limpiamente después de un fallo. Es una capacidad clave para trabajos largos y aquí no se probó. - Exportación de Dataset y KeyValueStore. En mi harness exporté JSON/CSV manualmente. La ergonomía de exportación integrada de
Dataset/KeyValueStore—que quizá sea una de las principales ventajas de usar el framework— no la ejercité. - Pools de proxy y sesión. Crawlee incluye rotación de proxies y funciones de fingerprinting. Las trato estrictamente como un tema de cumplimiento y operaciones, no como una promesa de «bypass anti-bot», y tampoco las sometí a estrés en un sentido u otro.
Y los tiempos de todo el artículo corresponden a una sola máquina y una sola ejecución. Muestran la forma del coste HTTP versus navegador. No son benchmarks, y no los citaría como tal.
Pros y contras
Pros
- Una sola superficie de API para crawling HTTP y con navegador —el cambio de motor realmente es un cambio de clase, verificado con 0 → datos completos tanto en un fixture local como en un sitio público.
- Un framework de rastreo de verdad:
RequestQueue,enqueueLinkscon control de profundidad, reintentos yfailedRequestHandler, no solo un renderizador de páginas. - Extracción HTTP precisa (12/12 estático, 3/3 párrafos de artículo, 8/8 vía API JSON) cuando JavaScript no interfiere.
- La ruta con navegador recupera contenido que la ruta HTTP no puede ver físicamente y además toma capturas.
- Apache-2.0, TypeScript y mantenimiento activo.
Contras
- Los crawlers con navegador requieren
npx playwright install chromiumaparte (~81.7 MiB), algo quenpm install crawleeno resuelve y que es fácil de pasar por alto. - El renderizado con navegador añade un coste real por página (~5 s frente a menos de un segundo en mi prueba de una página).
- Efecto secundario por defecto de crear un directorio
storage/en ejecuciones normales. - La escala, la reanudación tras fallos y la ergonomía de exportación de Dataset no quedaron demostradas en mis pruebas.
- Las funciones de proxy y fingerprinting deben usarse dentro de los términos del sitio y de la ley —una responsabilidad, no una ventaja para abusar de ella.
Cuándo usar Crawlee y cuándo una API gestionada
Crawlee es una herramienta para construir tú mismo, y esa es la decisión correcta para muchos equipos. Te conviene cuando quieres tener el crawler dentro de tu propia base de código Node, combinar crawling HTTP y con navegador en un solo proyecto sin cambiar de framework, y controlar tú mismo la cola y el almacenamiento. Si te sientes cómodo operando y, con el tiempo, escalando una flota de navegadores, Crawlee te da una base limpia y bien diseñada sobre la que construir.
La otra opción es no encargarte de esa infraestructura. Si no quieres dedicar tiempo de ingeniería a vigilar instancias de Chromium, rotación de proxies y manejo anti-bot, una API gestionada es la alternativa —y ahí encaja nuestro propio stack para desarrolladores en Thunderbit. Para usuarios técnicos, Thunderbit no es la extensión de Chrome; es una API de scraping con IA, un servidor MCP y una CLI. Llamas a POST /distill para convertir una página en Markdown limpio listo para LLM, o a POST /extract con un JSON Schema para obtener datos estructurados, con renderMode none, basic o full para decidir cuándo compensa renderizar con navegador. El servidor MCP permite que un agente de IA (Claude, Cursor y otros clientes MCP) haga scraping durante una tarea, y la CLI se ejecuta desde la terminal o desde CI:
Prueba Thunderbit para extraer datos web
npx -y @thunderbit/thunderbit-cli distill "<url>" -f markdown > out.md
La diferencia que importa para desarrolladores: Crawlee te entrega la materia prima —HTML renderizado, nodos analizados— y tú te encargas de la canalización; una API gestionada te devuelve JSON estructurado y alineado con tu esquema, con el renderizado JS, los CAPTCHAs y la parte anti-bot resueltos en el servidor. Son trabajos distintos. Si quieres máximo control y no te importa la operación, Crawlee. Si quieres los datos sin mantener una flota de navegadores, la vía gestionada. Muchos equipos terminan usando ambas: una para rastreos a medida y otra para los casos de «solo dame los datos estructurados». Puedes ver la diferencia de coste en los precios de Thunderbit.
Veredicto
¿Deberías usar Crawlee? Sí, si eres desarrollador Node o TypeScript y quieres un único framework que abarque crawling HTTP y con navegador, con una cola de rastreo real por debajo. La promesa de dos motores es precisamente la razón para elegirlo, y en mis pruebas se sostuvo con claridad: la misma URL pasó de 0 a datos completos con un cambio de clase, la extracción estática fue precisa y rápida, y el rastreo con cola y profundidad funcionó tal como se documenta.
Entra sabiendo dos cosas. Reserva presupuesto para la descarga oculta del navegador la primera vez que uses PlaywrightCrawler, y no asumas que las partes que no probé —escala, reanudación tras fallos, exportaciones integradas— funcionarán tan bien como las que sí probé hasta haberlas ejecutado sobre tu propia carga de trabajo. Como base para construir tu propio crawler, Crawlee es una pieza de ingeniería sólida y bien pensada. Como canal de datos terminado y totalmente automático, es un punto de partida, no el destino.
Prueba Thunderbit para extraer datos web Get Started Free
Preguntas frecuentes
¿Crawlee es gratis y bajo qué licencia está?
Sí. Crawlee es de código abierto bajo licencia Apache-2.0 y se instala desde npm (npm install crawlee). La versión que probé fue 3.17.0. Para ejecutar los crawlers con navegador hace falta una descarga separada de Chromium mediante Playwright, que también es gratuita pero añade unos 81.7 MiB a la instalación.
CheerioCrawler vs PlaywrightCrawler: ¿cuál debería usar?
Usa CheerioCrawler cuando los datos estén en el HTML en bruto o en una API JSON subyacente —es muchísimo más rápido y nunca abre un navegador. Usa PlaywrightCrawler cuando el contenido se renderiza con JavaScript, algo que notarás cuando la ruta HTTP devuelva resultados vacíos. En mis pruebas, el motor HTTP devolvió 0 elementos en una página renderizada por JS y el motor con navegador recuperó todo. Como comparten la misma API, cambiar es solo cambiar de clase, no rehacer el código.
¿Crawlee necesita un navegador para funcionar?
Solo para los crawlers con navegador. CheerioCrawler no necesita navegador en absoluto. PlaywrightCrawler (y PuppeteerCrawler) sí necesitan un binario de navegador —se instala con npx playwright install chromium. Ten en cuenta que npm install crawlee por sí solo no descarga ningún navegador, que es el tropiezo más común en la primera ejecución.
¿Crawlee puede manejar paginación y rastreos de varias páginas?
Sí, y esa es una de las razones principales para elegirlo frente a una librería de navegador independiente. enqueueLinks sigue enlaces (incluidos selectores de paginación como .next-page), RequestQueue deduplica y administra el crawl, y además tienes control de profundidad y límites con maxRequestsPerCrawl. En las pruebas, un rastreo dentro del mismo dominio recorrió 11 páginas entre las profundidades 0–2, y las solicitudes fallidas aparecieron mediante failedRequestHandler.
¿Cómo se compara Crawlee con una API de scraping gestionada?
Crawlee es autogestionado: tú escribes y ejecutas el crawler, y tú asumes la escala, los proxies y el manejo anti-bot. Una API gestionada como los endpoints distill/extract de Thunderbit devuelve Markdown limpio o JSON estructurado conforme a tu esquema, con el renderizado y la parte anti-bot resueltos en el servidor, expuesto a través de una API, un servidor MCP y una CLI. Elige Crawlee si quieres máximo control sobre tu propio pipeline; elige una API gestionada si prefieres no operar ni escalar tú mismo la infraestructura de navegador.


