Blog Logo

Cloudflare ya puede scrapear webs enteras por ti con una sola llamada

Hace poco me topé con algo de Cloudflare que me dejó con la boca abierta. Han sacado un endpoint llamado /crawl dentro de su servicio Browser Rendering que, literalmente, le pasas una URL y él solo se pone a recorrer toda la web, página por página, y te devuelve el contenido en el formato que tú quieras. Una sola llamada.

Cuando lo vi pensé “esto es demasiado bonito para ser verdad”. Así que me puse a cacharrear, a leer la documentación, a probarlo de verdad, y te cuento lo que me encontré, lo bueno y lo no tan bueno.


Qué es Browser Rendering y dónde encaja el /crawl

Antes de meternos con el endpoint en sí, hay que entender qué es Browser Rendering de Cloudflare, porque el /crawl está dentro de ese servicio.

Browser Rendering es básicamente un navegador que Cloudflare tiene corriendo en su propia infraestructura. Tú le mandas peticiones y él ejecuta el JavaScript, carga la página como lo haría un navegador normal, y te devuelve el resultado. Hasta ahora se usaba sobre todo con Puppeteer o Playwright directamente desde un Worker de Cloudflare, lo cual requería código.

El endpoint /crawl es lo nuevo, está en beta abierta, y es la versión “sin código” de todo esto. Le dices qué quieres y él lo hace. Sin scripts, sin spiders, sin montar nada.

Está pensado especialmente para casos como estos:

  • RAG (Retrieval-Augmented Generation): cuando quieres nutrir a un modelo de lenguaje con información de una web concreta.
  • Ingesta de documentación: por ejemplo, coger toda la documentación de una librería y procesarla.
  • Auditorías de contenido: sacar una foto de lo que hay en una web en un momento dado.

Lo que no es, y esto es importante dejarlo claro desde el principio, es un scraper para monitorización en tiempo real. Si necesitas consultar el precio de un producto cada 30 segundos, esto no es lo tuyo.


Cómo funciona por dentro

El proceso es asíncrono, y esto hay que tenerlo muy claro porque si no te va a dar la sensación de que algo falla.

Lo que pasa cuando haces la llamada es esto: Cloudflare crea un “job” en sus servidores, empieza a recorrer la web que le has indicado, y cuando termina (que puede tardar bastante, ya te aviso), puedes consultar los resultados con otro endpoint usando el ID del job.

El resultado te llega con el contenido de cada página en el formato que hayas pedido: HTML, Markdown o JSON estructurado. El Markdown es especialmente útil si luego quieres pasárselo a un LLM, porque es un formato limpio y fácil de procesar.


Paso 1: Consigue tu Account ID y crea la API Key

Lo primero que necesitas son dos cosas: tu Account ID de Cloudflare y una API Key con los permisos correctos.

Account ID: Entra al dashboard de Cloudflare en dash.cloudflare.com, ve a Workers & Pages, y en la barra lateral derecha lo verás directamente. Cópialo y guárdalo en un bloc de notas porque lo vas a usar ahora.

API Key: Ve a dash.cloudflare.com/profile/api-tokens y crea un token nuevo. En los permisos, el que te hace falta es este:

Account > Browser Rendering > Edit

Sin ese permiso no podrás hacer ninguna llamada al endpoint. Una vez creado, copia el token también porque solo te lo van a mostrar una vez.


Paso 2: Lanza el crawl

Ya con el Account ID y el token, toca hacer la llamada. El endpoint es:

POST https://api.cloudflare.com/client/v4/accounts/{ACCOUNT_ID}/browser-rendering/crawl

Un ejemplo básico con curl sería así:

curl -X POST "https://api.cloudflare.com/client/v4/accounts/TU_ACCOUNT_ID/browser-rendering/crawl" \
  -H "Authorization: Bearer TU_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://ejemplo.com",
    "limit": 10,
    "depth": 1
  }'

Eso es lo mínimo indispensable. La respuesta que recibirás de vuelta será algo así:

{
  "success": true,
  "result": {
    "id": "abc123def456",
    "status": "running"
  }
}

Guarda ese id porque es el que vas a necesitar para consultar los resultados.


Paso 3: Configura la llamada a tu gusto

Aquí es donde la cosa se pone interesante, porque hay un montón de parámetros que puedes ajustar. Yo lo que hice fue pasarle la documentación a ChatGPT con la web que quería scrapear y pedirle que me generara el body completo de la llamada. No tiene ningún misterio y te ahorra tiempo.

Estos son los parámetros más útiles que puedes meter en el body:

url (obligatorio): La URL desde la que empieza a recorrer.

limit: El máximo de páginas que va a procesar. En el plan gratuito no puedes pasar de 100 por llamada.

depth: Cuántos niveles de profundidad quieres que explore. Con 1 solo visita las páginas enlazadas directamente desde la URL inicial. Con 2 también entraría en los enlaces de esas páginas, y así.

render: Por defecto es true, lo que significa que ejecuta JavaScript como haría un navegador. Si la web que quieres scrapear es estática (como un blog o documentación sin JS), puedes poner false y será mucho más rápido.

includePatterns / excludePatterns: Arrays de patrones glob para decirle qué páginas incluir o excluir. Por ejemplo, si solo quieres páginas del blog:

"includePatterns": ["/blog/*"]

O si quieres evitar la sección de búsqueda y los mapas:

"excludePatterns": ["/search*", "/maps*"]

rejectResourceTypes: Para decirle que no cargue ciertos recursos mientras navega. Si no te importan las imágenes ni las fuentes, añádelos aquí y el proceso irá más ligero:

"rejectResourceTypes": ["image", "font", "stylesheet"]

responseFormat: Para indicar el formato de salida. Puedes pedir json, markdown, html o varios a la vez.

Un ejemplo más completo podría ser este:

{
  "url": "https://docs.ejemplo.com",
  "limit": 100,
  "depth": 2,
  "render": false,
  "excludePatterns": ["/search*", "/changelog*"],
  "rejectResourceTypes": ["image", "font"],
  "responseFormat": ["markdown", "json"]
}

Paso 4: Extracción estructurada con IA (lo más potente)

Esto es lo que más me llamó la atención cuando lo descubrí. Puedes pasarle un prompt de IA y un schema JSON para que Cloudflare, usando Workers AI por detrás, te extraiga los datos ya estructurados directamente.

Imagina que quieres sacar datos de productos de una tienda online. El body de la llamada quedaría algo así:

{
  "url": "https://tienda-ejemplo.com/productos",
  "limit": 50,
  "responseFormat": ["json"],
  "aiOptions": {
    "prompt": "Extrae la información de cada producto que encuentres en la página",
    "jsonSchema": {
      "type": "object",
      "properties": {
        "products": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": { "type": "string" },
              "price": { "type": "number" },
              "description": { "type": "string" },
              "in_stock": { "type": "boolean" }
            }
          }
        }
      }
    }
  }
}

El resultado te llega con los datos ya en el formato que le has pedido. No es perfecto, y esto lo veremos en el apartado de conclusiones, pero para un primer barrido sin tener que escribir ni un selector CSS es bastante decente.


Paso 5: Consulta el estado y recoge los resultados

Como el proceso es asíncrono, tienes que ir consultando el estado hasta que termine. El endpoint para esto es:

curl -X GET "https://api.cloudflare.com/client/v4/accounts/TU_ACCOUNT_ID/browser-rendering/crawl/TU_JOB_ID" \
  -H "Authorization: Bearer TU_API_TOKEN"

La respuesta te dirá en qué punto está:

{
  "result": {
    "id": "abc123def456",
    "status": "running",
    "total": 100,
    "finished": 47
  }
}

Cuando el status cambie a finished, ya puedes ver los resultados completos. Tendrán esta pinta:

{
  "result": {
    "status": "finished",
    "total": 100,
    "finished": 100,
    "records": [
      {
        "url": "https://ejemplo.com/pagina-1",
        "metadata": {
          "title": "Título de la página",
          "status": 200
        },
        "markdown": "# Título\n\nContenido de la página...",
        "html": "<html>...</html>"
      }
    ]
  }
}

Los resultados se guardan durante 14 días desde que el job termina, así que no tengas prisa en descargarlos, pero tampoco te olvides de ellos.


Cuánto tarda y qué me encontré yo

Aquí va la parte que te va a sorprender, y no para bien.

En mi prueba cogí una web con un listado de items de un videojuego, puse el límite a 100 páginas, y tardó casi una hora en terminar. Una hora para 100 páginas. No es que me quejara en ese momento porque no estaba yo delante esperando, va solo, pero si comparas eso con hacer un scraper con Scrapy o incluso con Beautiful Soup, la diferencia es enorme.

Eso sí, los resultados no estuvieron mal del todo. Para ser beta y haber usado IA para detectar los campos, capturó bastantes cosas que le pedí. No con la precisión que tendrías si construyeras tú los selectores a mano, pero para una primera iteración sin código es respetable.


Precios y límites

En el plan gratuito (Workers Free) tienes:

  • 5 llamadas al día como máximo
  • Cada llamada puede procesar hasta 100 páginas, no más

Si necesitas más, el plan de pago (Workers Paid, 5 $ al mes) te da 10 horas de tiempo de navegador al mes. Una vez que te pasas de esas 10 horas, el precio es de 0,09 $ por hora adicional. No es caro si lo usas de forma puntual.

Los jobs tienen un tiempo máximo de ejecución de 7 días, que es más que suficiente para cualquier web normal.


El tema de los CAPTCHAs y las protecciones anti-bot

Esto es importante que lo tengas en mente: el endpoint /crawl no puede saltarse protecciones anti-bot. Y aquí viene el chiste: el propio Cloudflare ofrece esas protecciones a sus clientes. Así que si una web tiene activado el Bot Management de Cloudflare o tiene CAPTCHAs, el crawler no podrá procesarla.

Lo cual tiene su lógica, pero significa que hay webs que simplemente no vas a poder scrapear con esto. Si entras a una página y te aparece el famoso “Verificando que eres humano” de Cloudflare, olvídate.


¿Cuándo lo usarías y cuándo no?

Después de haberlo probado, esto es lo que me ha quedado claro.

Tiene sentido usarlo cuando quieres montar un RAG, necesitas ingerir documentación de una web para pasársela a un LLM, o quieres hacer una captura del contenido de un sitio sin complicarte con código. La integración con Workers AI para la extracción estructurada también es interesante para casos donde la web no es muy compleja.

No tiene sentido cuando necesitas datos estructurados con mucha precisión, cuando la web tiene protecciones anti-bot, o cuando el tiempo de respuesta importa. Para esos casos, hacerlo a mano con Python, Playwright o un spider de Scrapy sigue siendo mejor opción. Acabarás antes y con más control.

En mi caso personal, me vuelvo al método manual. No porque esto sea malo, sino porque para lo que yo hago normalmente necesito más precisión y menos tiempo de espera. Pero si nunca has hecho scraping y tienes un caso de uso simple como el de RAG, merece mucho la pena echarle un vistazo.


Conclusión

El endpoint /crawl de Cloudflare es una herramienta genuinamente útil para según qué casos. Que una empresa de infraestructura de red meta un crawler que funciona con IA por dentro y lo expongan como una API REST sin necesidad de código es una pasada. Pero todavía está en beta, los tiempos son lentos y no es la bala de plata que hace desaparecer la necesidad de saber scrapear.

Si lo pruebas, cuéntame en los comentarios cómo te ha ido. Y si tienes alguna duda sobre los pasos, pregunta sin problema.


¿Qué te ha parecido?

Déjame tu opinión, pregunta o sugerencia. Los comentarios se sincronizan con GitHub Discussions .

Volver al blog