A maioria das pessoas conhece o Crawlee quando tenta responder a outra pergunta: “qual navegador headless eu devo usar?”. Só que essa já é a pergunta errada — e o Crawlee existe justamente para deixar isso claro. Ele não é um navegador. É um framework em Node/TypeScript que usa um navegador quando isso faz sentido e dispensa quando não precisa.
Passei alguns dias testando o Crawlee 3.17.0 com um conjunto controlado de fixtures e alguns sites públicos de demonstração, no Node v22.22.3 e no macOS. A promessa principal — uma biblioteca, uma API, com um crawler HTTP ou um navegador real por baixo — foi a parte que mais quis validar, porque é essa afirmação que define se o Crawlee merece entrar na sua stack ou se é melhor usar o Playwright direto. Em resumo: a história dos dois motores se sustenta, com alguns asteriscos que eu explico mais adiante.
O que o Crawlee realmente é — e o que não é
O Crawlee se apresenta como uma biblioteca de web scraping e automação de navegador para Node.js, feita para facilitar a construção de crawlers confiáveis. O posicionamento oficial é bem amplo: extrair dados para AI, LLMs, RAG ou GPTs; baixar HTML, PDF, JPG, PNG e outros arquivos; compatível com Puppeteer, Playwright, Cheerio, JSDOM e HTTP puro; com modo headful ou headless; rotação de proxy incluída. É um escopo enorme, então vale dizer com clareza o que o Crawlee não é.
Ele não é um motor de renderização. Não traz o próprio navegador. Quando você precisa executar JavaScript, o Crawlee controla Playwright ou Puppeteer, que por sua vez controlam o Chromium (ou outro navegador). Também não é um serviço hospedado que você acessa pela rede — é uma dependência que você instala e roda por conta própria. O que o Crawlee é, com precisão, é a camada acima do coletor: as classes de crawler, a fila de requisições, o armazenamento e a lógica de seguir links. Pense nele como o framework de crawl, com um motor plugável na base.
Só para registrar: a versão que testei foi a 3.17.0 (lançada em 2026-06-04), é em TypeScript, a licença é Apache-2.0, e o repositório tinha cerca de 24,6 mil estrelas em 2026-07-09 no apify/crawlee. A contagem de estrelas muda — o repositório ganhou 53 nesse intervalo de dois dias em que acompanhei o projeto — então trate esse número como uma fotografia, não como um dado fixo.
Os dois motores: CheerioCrawler vs PlaywrightCrawler
É aqui que o design mostra seu valor — e onde gastei a maior parte do tempo.
CheerioCrawler é o caminho HTTP. Ele baixa o HTML cru pela rede e faz o parse com Cheerio — sem navegador, sem execução de JavaScript, sem renderização. É rápido e barato. PlaywrightCrawler é o caminho com navegador. Ele abre um Chromium de verdade, renderiza a página incluindo qualquer JavaScript que monta o DOM e ainda pode tirar screenshots.
São dois motores diferentes, com capacidades realmente distintas. O ponto do Crawlee é que eles usam a mesma interface. Ambos aceitam um requestHandler. Ambos expõem run(). Ambos percorrem links com enqueueLinks. Migrar de um motor para o outro é trocar a classe, não reescrever tudo — eu confirmei isso mantendo a lógica de extração byte a byte idêntica e mudando só qual classe de crawler a envolvia.

Um detalhe importante, porque é aí que a paridade termina: o acesso ao conteúdo é diferente. Dentro de um handler do CheerioCrawler, você recebe $ — um DOM estático, já processado, que você consulta como no jQuery. Dentro de um handler com navegador, você recebe um objeto page vivo. Então a fila, o roteamento e a parte de “salve esses dados, siga esses links” continuam iguais, mas a forma de ler a página muda. A própria documentação do Crawlee diz isso — ela limita a interface compartilhada às operações de crawl e mostra que o acesso ao conteúdo é a parte que varia.
| Motor | Como busca | Executa JavaScript? | Meu teste (1 página dinâmica) | Melhor para |
|---|---|---|---|---|
CheerioCrawler | HTTP puro + parse com Cheerio | Não | ~0.035s | HTML estático, APIs JSON, velocidade |
PlaywrightCrawler | Chromium real via Playwright | Sim | ~4.967s | Páginas renderizadas por JS, screenshots |
Esses tempos vieram de uma única máquina e de uma única execução — não são benchmark, são só a forma da troca. O caminho com navegador custou cerca de duas ordens de grandeza a mais no mesmo URL. Esse é o preço da renderização, e por isso ele não deve ser sua escolha padrão.
O teste: mesma URL, 0 vs 8/8
Promessas são baratas. O motivo de eu confiar na história dos dois motores é que consegui fazê-la falhar e depois corrigir trocando apenas uma classe.
Montei um fixture dinâmico local — uma página de catálogo em que os cards de produto são inseridos por JavaScript depois do carregamento, o tipo de página que virou padrão na web moderna. Apontei o CheerioCrawler para ela. O resultado foi 0 cards de produto. Isso não é bug; é física. O Cheerio nunca executou o JavaScript, então os cards nunca existiram no HTML que ele analisou. Depois apontei o PlaywrightCrawler para a mesma URL, sem mudar mais nada, e ele renderizou 8 de 8 produtos e ainda capturou uma screenshot como prova.

Para garantir que isso não era uma peculiaridade do meu próprio fixture, repeti o mesmo padrão em um site público — a página de demonstração JavaScript Quotes to Scrape, que constrói as citações no cliente. O resultado foi o mesmo no mesmo sentido: o CheerioCrawler viu 0 citações, o PlaywrightCrawler recuperou 10.

Quero ser cuidadoso sobre o que isso prova. É uma reprodução limpa de algo que o próprio Crawlee já documenta — desde a versão 3.0, o framework compartilha a mesma classe base e a mesma interface entre os tipos de crawler. Então isto é validação, não descoberta. Mas é exatamente aí que está o valor: a frase de marketing “uma interface, HTTP ou navegador” é real, e aqui está o recibo do 0 → dados completos, tanto em um fixture que eu controlo quanto em um site que eu não controlo.
Onde o caminho HTTP ganha
Seria fácil ler a seção acima como “use sempre o navegador”. Não faça isso. O motivo de o design com dois motores ser importante é justamente porque o navegador é o plano B caro, não o padrão.
Em conteúdo estático, o CheerioCrawler foi preciso e rápido. Meu fixture estático de catálogo retornou 12 de 12 produtos com cobertura total, seguindo a paginação via enqueueLinks({ selector: '.next-page' }), em cerca de 0.155 segundos. Uma página de artigo entregou o título e todos os 3 de 3 parágrafos do corpo, separando direitinho o conteúdo da estrutura de login/assinatura/copyright.
O ponto mais importante: uma página cujo conteúdo é carregado por JavaScript muitas vezes tem uma API JSON logo atrás. Os dados do meu fixture dinâmico estavam em um endpoint, e quando apontei o CheerioCrawler direto para essa API, ele recuperou 8 de 8 produtos — sem navegador, em cerca de 0.035 segundos. Os mesmos dados que o caminho com navegador levou quase cinco segundos para renderizar. A lição é antiga, mas continua válida: se você consegue reproduzir a requisição subjacente, faça isso em vez de abrir o Chromium. O Crawlee permite escolher isso por crawler, sem trocar de framework.
A parte de framework de crawl — o motivo de escolher Crawlee em vez de uma biblioteca de navegador pura
Se tudo o que você precisasse fosse renderizar uma única página, não precisaria do Crawlee — bastaria usar Playwright ou Puppeteer sozinhos. O que uma biblioteca de navegador pura não entrega é um crawl de verdade: fila, deduplicação, controle de profundidade, retries. Essa é a parte do Crawlee que não tem a ver com motores.
Executei um crawl no mesmo hostname, a partir da raiz do fixture, usando enqueueLinks com controle de profundidade. O Crawlee percorreu 11 páginas nas profundidades {0:1, 1:3, 2:7} — uma raiz, três páginas a um clique, sete páginas a dois cliques — e respeitou maxRequestsPerCrawl como condição de parada. O RequestQueue cuidou do controle. Quando mandei uma requisição para uma página retornando HTTP 500, o Crawlee tentou novamente e então expôs a falha via failedRequestHandler, em vez de engolir o erro silenciosamente ou derrubar a execução.

Esse é o argumento mais forte a favor do Crawlee em comparação com uma ferramenta de navegador isolada: a orquestração do crawl já vem pronta e, mais importante, é a mesma orquestração tanto para HTTP quanto para navegador. Você escreve a lógica de fila e seguimento uma vez. E decide separadamente se cada crawler vai ou não renderizar JavaScript.
Instalação e o download oculto do navegador
A instalação foi, no geral, tranquila, com uma armadilha que pega usuários de primeira viagem.
npm install crawlee playwright rodou sem problemas — 0 vulnerabilidades reportadas. Mas o PlaywrightCrawler não vai iniciar até que você também execute npx playwright install chromium, que baixa um binário do Chromium de cerca de 81.7 MiB. Instalar só o pacote crawlee não baixa um navegador. Se você pular essa etapa e for direto para um crawler com navegador, vai encontrar um erro de inicialização que não é nada óbvio se você ainda não conhece o modelo de empacotamento do Playwright. É um comportamento herdado do Playwright, não um defeito do Crawlee, mas é um ponto real de atrito na primeira execução que vale avisar.

Mais um detalhe operacional: por padrão, o Crawlee grava em um diretório local storage/. Meu harness de teste redirecionou isso para um diretório temporário e desativou a persistência para manter tudo limpo, mas uma execução padrão vai deixar uma pasta storage/ no seu projeto. Não é um problema — só algo bom de saber antes que apareça no git status.
Um terceiro motor, em resumo
A história de paridade do Crawlee não se limita ao Cheerio e ao Playwright. Existe também o PuppeteerCrawler, e eu conferi até onde vai a afirmação de “mesma interface” nele — no nível de classe e superfície de API, não com um crawl real.
As três classes de crawler derivam da mesma base BasicCrawler. O CheerioCrawler passa por um HttpCrawler; o PlaywrightCrawler e o PuppeteerCrawler passam por um BrowserCrawler compartilhado. Inspecionando o pacote instalado, há 24 métodos públicos em comum entre os três motores, incluindo as operações de fila e armazenamento em que todo o design se apoia — run, addRequests, pushData, getData, getDataset, exportData, getRequestQueue, useState, stop. PuppeteerCrawler e PlaywrightCrawler chegam a expor exatamente o mesmo conjunto de métodos públicos. As diferenças entre motores ficam só na fronteira HTTP versus navegador, que é exatamente onde se espera que elas apareçam.
Vale deixar claro o limite: eu não executei um crawl real com PuppeteerCrawler. A dependência opcional puppeteer não estava instalada no meu pacote de teste, e exercitá-la exigiria mais um download de navegador. Então essa paridade com Puppeteer foi verificada estruturalmente — mesma classe base, mesmos métodos compartilhados, mesma forma de contexto do handler — e não por uma execução de fato. E mesmo quando a interface bate, o comportamento por baixo não é exatamente igual: a orientação oficial do Crawlee observa que o Playwright espera elementos automaticamente, enquanto o Puppeteer exige espera explícita. Isso é uma característica do motor, não uma falha do Crawlee, mas significa que “mesma API” não é “mesmo código dentro de todo handler”.
O que eu não testei
Aqui está o que deixei de propósito de fora nesta rodada, para você não ler meus resultados como algo maior do que realmente são.
- Escala. Tudo rodou em fixtures pequenos e crawls curtos em sites públicos. Não fiz uma execução longa de 100–1.000 páginas, então não posso falar de auto-scaling ou estabilidade sob carga real.
- Persistência da fila e retomada. Não interrompi um crawl no meio para ver se o
RequestQueueretomaria corretamente após uma falha. Isso é uma capacidade importante em trabalhos longos e não foi testada aqui. - Exportação de Dataset e KeyValueStore. Eu escrevi manualmente as exportações JSON/CSV no harness. A ergonomia de exportação embutida do
Dataset/KeyValueStore— provavelmente um dos maiores benefícios de usar o framework — eu não exercitei. - Proxy e pools de sessão. O Crawlee traz rotação de proxy e recursos de fingerprinting. Estou tratando isso estritamente como tema de conformidade e operação, não como argumento de “burlar anti-bot”, e também não fiz stress test desses recursos.
E os tempos acima são de uma única máquina e de uma única execução. Eles mostram a forma do custo entre HTTP e navegador. Não são benchmarks, e eu não citaria como tal.
Prós e contras
Prós
- Uma única superfície de API para crawling HTTP e com navegador — trocar o motor realmente é trocar a classe, confirmado com 0 → dados completos tanto em um fixture local quanto em um site público.
- Um framework de crawl de verdade:
RequestQueue,enqueueLinkscom controle de profundidade, retries efailedRequestHandler, não só um renderizador de página. - Extração HTTP precisa (12/12 estático, 3/3 parágrafos de artigo, 8/8 via API JSON) quando o JavaScript não atrapalha.
- O caminho com navegador recupera conteúdo que o caminho HTTP simplesmente não consegue ver e ainda tira screenshots.
- Apache-2.0, TypeScript, mantido ativamente.
Contras
- Os crawlers com navegador precisam de um
npx playwright install chromiumseparado (~81.7 MiB) que onpm install crawleenão faz — fácil de esquecer. - Renderização com navegador tem custo real por página (~5s versus abaixo de 1s no meu teste de uma página).
- Efeito colateral padrão de criar um diretório
storage/em execuções normais. - Escala, persistência/retomada da fila e ergonomia de exportação de Dataset não foram comprovados nos meus testes.
- Recursos de proxy e fingerprinting devem ser usados dentro dos termos do site e da lei — uma responsabilidade, não um truque para se apoiar.
Quando usar Crawlee versus uma API gerenciada
Crawlee é uma ferramenta para você mesmo construir, e essa é a escolha certa para muitas equipes. Use-o quando quiser assumir o crawler no seu próprio código Node, misturar crawling HTTP e com navegador no mesmo projeto sem trocar de framework e controlar sozinho a fila e o armazenamento. Se você se sente confortável operando e, mais tarde, escalando uma frota de navegadores, o Crawlee oferece uma base limpa e bem desenhada para isso.
O outro caminho é não operar essa infraestrutura. Se cuidar de instâncias Chromium, rotação de proxy e tratamento anti-bot não é onde você quer gastar tempo de engenharia, uma API gerenciada é a alternativa — e é aí que entra nossa própria stack para desenvolvedores na Thunderbit. Para usuários técnicos, Thunderbit não é a extensão do Chrome; é uma API de scraping com AI, servidor MCP e CLI. Você chama POST /distill para transformar uma página em Markdown limpo, pronto para LLM, ou POST /extract com um JSON Schema para receber dados estruturados de volta, com renderMode none, basic ou full, para você decidir quando a renderização completa vale a pena. O servidor MCP permite que um agente de AI (Claude, Cursor e outros clientes MCP) faça scraping durante a tarefa, e a CLI roda no terminal ou em CI:
Experimente Thunderbit para extração de dados da web
npx -y @thunderbit/thunderbit-cli distill "<url>" -f markdown > out.md
A diferença que importa para desenvolvedores: o Crawlee entrega a matéria-prima — HTML renderizado, nós analisados — e você assume o pipeline; uma API gerenciada devolve JSON estruturado, compatível com schema, com renderização em JavaScript, CAPTCHAs e anti-bot tratados no servidor. São trabalhos diferentes. Se você quer máximo controle e não se importa com a operação, Crawlee. Se quer os dados sem manter uma frota de navegadores, a rota gerenciada. Muitas equipes acabam usando os dois: um para crawls sob medida e outro para os casos de “só me traga os dados estruturados”. Você pode ver essa troca de custo em preços da Thunderbit.
Veredito
Vale usar Crawlee? Sim — se você é desenvolvedor Node ou TypeScript e quer um único framework que cubra crawling HTTP e com navegador, com uma fila de crawl de verdade por baixo. A promessa dos dois motores é o motivo para escolhê-lo, e ela se sustentou bem nos meus testes: a mesma URL saiu de 0 para todos os dados com uma troca de classe, a extração estática foi precisa e rápida, e o crawl com fila e profundidade funcionou como documentado.
Entre com duas coisas em mente. Reserve espaço para o download oculto do navegador na primeira vez que usar PlaywrightCrawler, e não presuma que os pontos que eu não testei — escala, retomada após crash, exports embutidos — funcionem tão bem quanto os que testei até rodá-los na sua própria carga de trabalho. Como base para construir seu próprio crawler, o Crawlee é um trabalho forte e bem pensado. Como pipeline de dados pronto e sem manutenção, ele é um ponto de partida — não o destino.
Experimente Thunderbit para extração de dados da web Get Started Free
Perguntas frequentes
O Crawlee é gratuito e sob qual licença ele está?
Sim. O Crawlee é open source sob a licença Apache-2.0 e pode ser instalado pelo npm (npm install crawlee). A versão que testei foi a 3.17.0. Para usar os crawlers com navegador, é necessário baixar separadamente o Chromium via Playwright, que também é gratuito, mas adiciona cerca de 81.7 MiB ao setup.
CheerioCrawler vs PlaywrightCrawler — qual devo usar?
Use CheerioCrawler quando os dados estiverem no HTML bruto ou em uma API JSON subjacente — ele é muito mais rápido e nunca abre navegador. Use PlaywrightCrawler quando o conteúdo for renderizado por JavaScript, o que você percebe quando o caminho HTTP retorna resultados vazios. Nos meus testes, o motor HTTP retornou 0 itens em uma página renderizada por JS, e o motor com navegador trouxe tudo. Como compartilham a mesma API, a troca é mudar a classe, não reescrever.
O Crawlee precisa de navegador para rodar?
Só os crawlers com navegador. O CheerioCrawler não precisa de navegador nenhum. O PlaywrightCrawler (e o PuppeteerCrawler) precisam de um binário de navegador — instale com npx playwright install chromium. Note que npm install crawlee sozinho não baixa navegador, que é o tropeço mais comum na primeira execução.
O Crawlee lida com paginação e crawls em várias páginas?
Sim, e esse é um dos principais motivos para escolhê-lo em vez de uma biblioteca de navegador isolada. enqueueLinks segue links (inclusive seletores de paginação como .next-page), o RequestQueue deduplica e gerencia o crawl, e você tem controle de profundidade e limites com maxRequestsPerCrawl. Nos testes, um crawl no mesmo hostname percorreu 11 páginas nas profundidades 0–2, e as requisições com falha apareceram via failedRequestHandler.
Como o Crawlee se compara a uma API de scraping hospedada?
O Crawlee é auto-hospedado: você escreve e executa o crawler, e é responsável por escala, proxies e anti-bot. Uma API gerenciada como os endpoints distill/extract da Thunderbit devolve Markdown limpo ou JSON estruturado compatível com schema, com renderização e anti-bot tratados no servidor, acessados por API, servidor MCP e CLI. Escolha o Crawlee para ter controle máximo do seu próprio pipeline; escolha uma API gerenciada quando preferir não operar e escalar a infraestrutura de navegador por conta própria.


