Blog Logo

O Cloudflare já consegue fazer scraping de sites inteiros com uma única chamada

Há pouco tempo me deparei com algo do Cloudflare que me deixou de boca aberta. Eles lançaram um endpoint chamado /crawl dentro do serviço Browser Rendering que, literalmente, você passa uma URL e ele mesmo começa a percorrer o site inteiro, página por página, e te devolve o conteúdo no formato que quiser. Uma única chamada.

Quando vi isso pensei “isso é bom demais para ser verdade”. Então fui pesquisar, ler a documentação, testar de verdade, e aqui vou te contar o que encontrei, o bom e o nem tão bom.


O que é o Browser Rendering e onde o /crawl se encaixa

Antes de entrar no endpoint em si, é preciso entender o que é o Browser Rendering do Cloudflare, porque o /crawl vive dentro desse serviço.

O Browser Rendering é basicamente um navegador que o Cloudflare mantém rodando na própria infraestrutura deles. Você manda requisições, ele executa o JavaScript, carrega a página como um navegador real faria, e te devolve o resultado. Até agora era usado principalmente com Puppeteer ou Playwright diretamente de um Worker do Cloudflare, o que exigia escrever código.

O endpoint /crawl é a novidade, está em beta aberta, e é a versão “sem código” de tudo isso. Você diz o que quer e ele faz. Sem scripts, sem spiders, sem configurar nada.

É pensado especialmente para casos como estes:

  • RAG (Retrieval-Augmented Generation): quando você quer alimentar um modelo de linguagem com informações de um site específico.
  • Ingestão de documentação: por exemplo, pegar toda a documentação de uma biblioteca e processá-la.
  • Capturas de conteúdo: tirar uma foto do que tem em um site num determinado momento.

O que ele não é - e isso é importante deixar claro desde o início - é um scraper para monitorização em tempo real. Se você precisa consultar o preço de um produto a cada 30 segundos, isso não é o que você procura.


Como funciona por dentro

O processo é assíncrono, e isso precisa ficar bem claro porque senão vai parecer que algo deu errado.

O que acontece quando você faz a chamada é o seguinte: o Cloudflare cria um “job” nos servidores deles, começa a percorrer o site que você indicou, e quando termina (o que pode demorar bastante, já aviso), você pode consultar os resultados com outro endpoint usando o ID do job.

O resultado chega com o conteúdo de cada página no formato que você pediu: HTML, Markdown ou JSON estruturado. O Markdown é especialmente útil se você vai passar para um LLM depois, pois é um formato limpo e fácil de processar.


Passo 1: Obtenha seu Account ID e crie a API Key

As primeiras duas coisas que você precisa são: o Account ID do Cloudflare e uma API Key com as permissões corretas.

Account ID: Acesse o dashboard do Cloudflare em dash.cloudflare.com, vá em Workers & Pages, e na barra lateral direita você já vai ver. Copie e guarde num bloco de notas porque vai precisar em breve.

API Key: Vá em dash.cloudflare.com/profile/api-tokens e crie um novo token. A permissão que você precisa é esta:

Account > Browser Rendering > Edit

Sem essa permissão não vai conseguir fazer nenhuma chamada ao endpoint. Depois de criado, copie o token também porque só vão te mostrar uma vez.


Passo 2: Inicie o crawl

Com o Account ID e o token em mãos, é hora de fazer a chamada. O endpoint é:

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

Um exemplo básico com curl fica assim:

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

Isso é o mínimo indispensável. A resposta que você vai receber de volta vai ser algo assim:

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

Guarde esse id porque é ele que você vai precisar para consultar os resultados.


Passo 3: Configure a chamada do seu jeito

Aqui é onde a coisa fica interessante, porque tem um monte de parâmetros que dá para ajustar. O que eu fiz foi passar a documentação pro ChatGPT junto com o site que queria scrapeado e pedi para ele gerar o body completo da chamada. Não tem nenhum mistério e poupa muito tempo.

Esses são os parâmetros mais úteis que você pode colocar no body:

url (obrigatório): A URL de onde começa o percurso.

limit: O máximo de páginas que vai processar. No plano gratuito não pode ultrapassar 100 por chamada.

depth: Quantos níveis de profundidade você quer que explore. Com 1 só visita páginas diretamente linkadas a partir da URL inicial. Com 2 também entra nos links dessas páginas, e assim por diante.

render: Por padrão é true, o que significa que executa JavaScript como um navegador de verdade. Se o site que você quer scrapeado é estático (como um blog ou documentação sem JS), pode colocar false e vai ser muito mais rápido.

includePatterns / excludePatterns: Arrays de padrões glob para indicar quais páginas incluir ou excluir. Por exemplo, se só quer páginas do blog:

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

Ou se quer evitar a seção de busca e mapas:

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

rejectResourceTypes: Para dizer que não carregue certos recursos durante a navegação. Se não importam imagens nem fontes, adicione aqui e o processo vai rodar mais leve:

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

responseFormat: Para indicar o formato de saída. Você pode pedir json, markdown, html ou vários ao mesmo tempo.

Um exemplo mais completo poderia ser este:

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

Passo 4: Extração estruturada com IA (o mais poderoso)

Isso é o que mais me chamou atenção quando descobri. Você pode passar um prompt de IA e um schema JSON para que o Cloudflare, usando o Workers AI por baixo, extraia os dados já estruturados diretamente.

Imagine que você quer puxar dados de produtos de uma loja online. O body da chamada ficaria assim:

{
  "url": "https://loja-exemplo.com/produtos",
  "limit": 50,
  "responseFormat": ["json"],
  "aiOptions": {
    "prompt": "Extrai a informação de cada produto que encontrares na 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" }
            }
          }
        }
      }
    }
  }
}

O resultado chega com os dados já no formato que você pediu. Não é perfeito - mais sobre isso na conclusão - mas para uma primeira passagem sem escrever um único seletor CSS é bastante decente.


Passo 5: Consulte o estado e colete os resultados

Como o processo é assíncrono, você precisa consultar o estado até que termine. O endpoint para isso é:

curl -X GET "https://api.cloudflare.com/client/v4/accounts/SEU_ACCOUNT_ID/browser-rendering/crawl/SEU_JOB_ID" \
  -H "Authorization: Bearer SEU_API_TOKEN"

A resposta vai te dizer em que ponto está:

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

Quando o status mudar para finished, os resultados completos já estão disponíveis. Vão ter esta cara:

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

Os resultados ficam disponíveis por 14 dias desde que o job termina, então não precisa ter pressa para baixá-los, mas também não se esqueça deles.


Quanto tempo demora e o que encontrei

Aqui vem a parte que vai te surpreender, e não para o bem.

No meu teste peguei um site com uma lista de itens de um videogame, coloquei o limite em 100 páginas, e demorou quase uma hora para terminar. Uma hora para 100 páginas. Não fiquei reclamando na hora porque não estava ali esperando, vai sozinho, mas se comparar com fazer um scraper com Scrapy ou até com BeautifulSoup, a diferença é enorme.

Dito isso, os resultados não foram ruins de jeito nenhum. Para uma beta que usou IA para detectar os campos, capturou bastante coisa do que pedi. Não com a precisão que você teria construindo os seletores na mão, mas para uma primeira iteração sem código é respeitável.


Preços e limites

No plano gratuito (Workers Free) você tem:

  • 5 chamadas por dia no máximo
  • Cada chamada pode processar até 100 páginas, não mais

Se precisar de mais, o plano pago (Workers Paid, $5/mês) te dá 10 horas de tempo de navegador por mês. Uma vez que passar dessas 10 horas, o preço é de $0,09 por hora adicional. Não é caro se usar de forma pontual.

Os jobs têm um tempo máximo de execução de 7 dias, que é mais do que suficiente para qualquer site normal.


O problema dos CAPTCHAs e proteções anti-bot

Isso é importante ter em mente: o endpoint /crawl não consegue contornar proteções anti-bot. E aqui vem a ironia: o próprio Cloudflare vende essas proteções para os clientes deles. Então se um site tem o Bot Management do Cloudflare ativado ou tem CAPTCHAs, o crawler simplesmente não vai conseguir processá-lo.

Faz sentido na lógica deles, mas significa que há sites que você simplesmente não vai conseguir scrapeado assim. Se entrar numa página e aparecer aquele famoso “Verificando que você é humano” do Cloudflare, esqueça.


Quando faz sentido usar e quando não faz

Depois de testar, isso é o que ficou claro para mim.

Faz sentido usar quando você quer montar um RAG, precisa ingerir documentação de um site para passar para um LLM, ou quer capturar o conteúdo de um site sem se complicar com código. A integração com o Workers AI para extração estruturada também é interessante para casos onde o site não é muito complexo.

Não faz sentido quando você precisa de dados estruturados com muita precisão, quando o site tem proteções anti-bot, ou quando o tempo de resposta importa. Para esses casos, fazer na mão com Python, Playwright ou um spider do Scrapy continua sendo a melhor opção. Você vai terminar antes e com mais controle.

No meu caso pessoal, estou voltando para o método manual. Não porque isso seja ruim, mas porque o que eu faço normalmente precisa de mais precisão e menos tempo de espera. Mas se você nunca fez scraping e tem um caso de uso simples como o de RAG, vale muito a pena dar uma olhada.


Conclusão

O endpoint /crawl do Cloudflare é uma ferramenta genuinamente útil para os casos certos. O fato de uma empresa de infraestrutura de rede ter lançado um crawler com IA embutida e exposto como uma API REST sem necessidade de código é impressionante. Mas ainda está em beta, os tempos são lentos, e não é a bala de prata que faz desaparecer a necessidade de saber fazer scraping.

Se você testar, me conta nos comentários como foi. E se tiver alguma dúvida sobre os passos, é só perguntar.


O que você achou?

Deixe sua opinião, pergunta ou sugestão. Os comentários são sincronizados com GitHub Discussions .

Voltar ao blog