Crawlee vale a pena? Teste prático com CheerioCrawler e PlaywrightCrawler

Última atualização em August 17, 2026
Crawlee vale a pena? Teste prático com CheerioCrawler e PlaywrightCrawler
Resumo com IA
Neste artigo, analisamos o Crawlee em profundidade, comparando seus dois motores principais — CheerioCrawler e PlaywrightCrawler — em cenários reais de extração. Mostramos quando o caminho HTTP é suficiente, quando é necessário recorrer ao navegador e quais recursos são compartilhados entre os dois. Também abordamos configuração, limitações, prós e contras, além de orientações práticas para escolher o motor certo para cada site.

O que torna o Crawlee útil é que a orquestração de crawl dele funciona tanto com parsing via HTTP quanto com execução no navegador. Ou seja, a mesma URL pode devolver resultados bem diferentes, dependendo do crawler escolhido e da condição de prontidão definida.

Na página pública Quotes to Scrape JS, o CheerioCrawler encontrou 0 quotes-alvo, enquanto o PlaywrightCrawler encontrou 10 depois de esperar por .quote. O fluxo de crawl até parece parecido, mas não foi só trocar uma classe em uma linha: o handler do Cheerio usava $, enquanto o handler do Playwright usava page, espera explícita e extração do lado do navegador.

O que o Crawlee realmente é

Crawlee (o projeto apify/crawlee, versão 3.17.0) é uma biblioteca de web scraping e automação de navegador para Node.js e TypeScript. Ela suporta crawling via HTTP com Cheerio ou JSDOM, e crawling em navegador com Playwright ou Puppeteer. O projeto é licenciado sob Apache-2.0; revise as obrigações de aviso e atribuição para a sua distribuição.

O modelo mental que importa aqui é separar “buscar a página” de “ler a página”. Um caminho baixa o HTML bruto e não executa JavaScript. O outro abre o Chromium e consegue executar os scripts da página, mas ainda depende de uma condição de prontidão adequada e pode deixar passar conteúdo bloqueado por interação, carregado sob demanda, em shadow DOM, com falha de API ou protegido por bot. O Crawlee expõe conceitos de ciclo de vida equivalentes nesses dois caminhos, e não primitivas de DOM intercambiáveis.

Essa é a parte que vale entender antes de escrever sequer um seletor, porque a escolha entre esses dois motores determina se o seu scraper vai retornar dados ou voltar vazio em um site específico.

Principais recursos: dois motores, uma mesma API

Crawlee two engines one API

O CheerioCrawler busca o HTML e faz o parsing com Cheerio; o PlaywrightCrawler controla o Chromium e consegue capturar screenshots. Ambos usam requestHandler, expõem run() e compartilham conceitos de crawl como filas e descoberta de links. Porém, os contextos dos handlers são diferentes: no teste, o caminho com Cheerio extraía via $, enquanto o caminho com navegador usava page, waitForSelector e $$eval. A estrutura de fila e ciclo de vida pode continuar familiar, mas o código de extração talvez precise de adaptação ou reescrita.

Por baixo disso, o Crawlee entrega a infraestrutura de que um crawl real precisa. Um RequestQueue gerencia a frente de URLs a visitar, elimina duplicatas e controla o que já foi processado. enqueueLinks descobre e adiciona novas URLs à fila — com filtro por seletor e por hostname — para que o crawl possa avançar sozinho. Um Dataset reúne os registros extraídos para exportação. Por padrão, o Crawlee persiste tudo isso em uma pasta local storage/ no disco — o que é prático para retomar execuções e um pouco irritante na primeira vez em que você encontra uma pasta storage/ que não pediu dentro do projeto (no meu harness, redirecionei isso para um diretório temporário e desativei a persistência para manter o teste limpo).

Cada peça, isoladamente, não chama atenção. O ponto é que elas são compartilhadas entre os dois motores, então a fila, a descoberta de links e o dataset se comportam do mesmo jeito tanto no crawl via HTTP quanto no navegador. Você aprende uma API e ganha duas estratégias de busca.

Configuração: o navegador instalado separadamente

A instalação testada não incluiu um executável do Chromium depois da instalação dos pacotes.

Crawlee setup install weight

npm install crawlee playwright instalou sem problemas para mim — 85 pacotes, 0 vulnerabilidades, sem drama. Se você parar aí e rodar um CheerioCrawler, tudo funciona, porque crawling via HTTP não precisa de navegador.

Neste ambiente, o Chromium precisou ser instalado separadamente com npx playwright install chromium; sem isso, o PlaywrightCrawler falhou ao iniciar. A carga observada do navegador foi de aproximadamente 82 MiB, mas as anotações originais não preservam se esse número se referia ao tamanho de transferência ou ao tamanho em disco. É uma observação específica da máquina, não uma propriedade fixa do produto. Os caminhos da documentação e o comportamento dos pacotes podem mudar, então este artigo não afirma que a omissão seja universal ou permanentemente não documentada.

Considere a configuração testada como dois passos: instalar os pacotes Node e, depois, instalar o navegador usado pelo caminho do Playwright. Verifique novamente as instruções atuais de configuração do Crawlee e do Playwright para as versões e a plataforma em que você for implantar.

Na prática: a mesma página, duas respostas bem diferentes

Crawlee Cheerio 0 vs Playwright 8/8

O teste principal enviou o mesmo fixture renderizado em JavaScript para os dois crawlers. A URL e os campos-alvo eram os mesmos; as primitivas de extração, não.

No fixture local, o CheerioCrawler retornou 0 cards-alvo porque eles não existiam no HTML bruto. O PlaywrightCrawler aguardou por #dynamic-products article.product-card e então retornou todos os 8 cards esperados, além de capturar uma screenshot. Esse resultado comprova a completude do fixture para os campos selecionados depois daquela espera; não significa que um navegador enxergue todos os estados possíveis da página. Os arquivos brutos e a screenshot estão no repositório de benchmark.

Crawlee public Quotes JS ten

Na página pública Quotes to Scrape JS, o CheerioCrawler encontrou 0 quotes-alvo e o PlaywrightCrawler aguardou por .quote antes de extrair 10. Isso confirma a mesma divisão entre HTTP e navegador em um alvo público, embora a classe do crawler, o contexto do handler, a condição de espera e a primitiva de extração sejam diferentes em cada caso.

A conclusão útil é mais restrita: valide os campos obrigatórios no caminho HTTP e só faça a escalada para um crawler de navegador quando o retorno bruto não contiver esses campos. O handler no navegador também precisa aguardar uma condição ligada a esses campos.

O caminho HTTP produziu todos os registros esperados nos fixtures controlados de catálogo estático e artigo, decodificou todos os oito itens esperados de uma resposta JSON direta, percorreu um grafo limitado de 11 páginas e encaminhou uma resposta 500 para failedRequestHandler. Esses são testes de capacidade separados, e não uma única nota de precisão. Contra a página pública Books to Scrape, o seletor configurado retornou 20 produtos como teste rápido.

TesteMotorResultado
Extração estática: catálogo + paginaçãoCheerioCrawler12/12 produtos esperados
Extração de artigoCheerioCrawlertítulo + 3/3 parágrafos
Transporte: resposta JSON diretaCheerioCrawler8/8 produtos esperados
Travessia: grafo de links internosCheerioCrawler11 páginas, profundidades {0:1, 1:3, 2:7}
Tratamento de falha: HTTP 500CheerioCrawlerstatus encaminhado ao handler de falha
Renderização: fixture localCheerioCrawler0 cards-alvo no HTML bruto
Renderização: fixture localPlaywrightCrawler8/8 após espera pelo seletor-alvo
Renderização: Quotes JSCheerioCrawler0 quotes-alvo no HTML bruto
Renderização: Quotes JSPlaywrightCrawler10 após espera pelo seletor-alvo

Os tempos completos e os números por teste estão em results/crawlee-test-summary.json.

Agora, os alertas honestos, porque um teste em uma única máquina e uma única execução tem limites — e eu não vou fingir o contrário. Isso são tempos, não benchmarks — uma máquina, uma execução por teste, então trate o custo maior por página do caminho com navegador como “mais lento de forma significativa do que execuções com Cheerio abaixo de um segundo”, e não como um número publicado. E há várias coisas que eu não testei neste ciclo: rotação de proxy, pools de sessão, execuções em grande escala com centenas ou milhares de páginas, persistência do RequestQueue e retomada após falha, o motor Puppeteer e a ergonomia de exportação do Dataset/KeyValueStore (aqui, eu escrevi as exportações manualmente). Posso atestar a história dos dois motores e a precisão em nível de fixture. Não posso atestar escala nem comportamento anti-bloqueio, então não vou fingir que posso.

O que é compartilhado e o que precisa mudar

Crawlee one-line engine switch

A superfície comum é a orquestração do crawl. As duas classes de crawler aceitam requestHandler e expõem run(). Filas, metadados de request, descoberta de links, hooks de falha e conceitos de armazenamento podem ser organizados de forma consistente em qualquer um dos caminhos de execução. Isso reduz a quantidade de infraestrutura que a equipe precisa reaprender quando um alvo exige navegador.

A superfície de acesso à página não é comum. Um handler do CheerioCrawler recebe acesso orientado a Cheerio, como $, e pode trabalhar com o corpo da resposta sem navegador. O handler testado do PlaywrightCrawler recebe page; ele aguarda um seletor e faz a avaliação sobre o DOM do navegador. Mesmo quando os dois handlers emitem o mesmo schema de registro, eles chegam até ele por APIs diferentes. Um adaptador reutilizável poderia ocultar parte dessa diferença, mas este harness não implementou nem demonstrou isso.

Essa distinção importa para estimativas. Trocar a classe do crawler pode preservar a fila, o dataset e a política de URLs, mas seletores, verificações de prontidão, screenshots, etapas de interação e tratamento de erros ainda podem mudar. Por isso, o artigo trata “infraestrutura de crawl compartilhada” como o benefício comprovado e rejeita “migração em uma linha” como uma promessa sem sustentação.

Um fluxo prático para escolher o motor

Use primeiro o caminho HTTP quando o HTML retornado ou uma resposta JSON direta contiver os campos necessários. Defina um contrato de completude — chaves obrigatórias, quantidade mínima de itens ou um seletor-alvo — e falhe explicitamente quando ele não for atendido. Um array vazio não prova que a página não tem dados; nestes dois casos em JavaScript, isso significou apenas que a representação escolhida não continha os elementos-alvo.

Condição do alvoComece comFaça a escalada quando
Os campos obrigatórios estão no HTML retornadoCheerioCrawlerSeletor ou campos obrigatórios estiverem ausentes
Uma resposta JSON reproduzível contém os dadosCheerioCrawlerA requisição depender de estado disponível apenas no navegador
A página insere os elementos-alvo após a execuçãoPlaywrightCrawlerNão se aplica; defina uma verificação de prontidão específica do alvo
O tipo de alvo é desconhecidoHTTP primeiro com validação de completudeA validação falhar com um resultado tipado de “representação incompleta”

Faça a escalada desse erro tipado para um handler de navegador quando a execução for necessária. Neste harness, a página local aguardava por #dynamic-products article.product-card, enquanto a página pública de quotes aguardava por .quote. Essas condições fazem parte do contrato de extração. Um evento genérico de carregamento não comprovaria que os dados da aplicação chegaram, e o teste não sustenta uma regra universal de espera.

Depois da escalada, mantenha o schema de saída estável, mesmo com primitivas de DOM diferentes. Registre qual motor produziu o resultado, qual condição de prontidão foi satisfeita e se a validação dos campos obrigatórios passou. Isso torna o fallback de HTTP para navegador observável, em vez de transformar campos ausentes em registros aceitos silenciosamente.

Por fim, trate a instalação do navegador e o custo operacional como entradas de implantação. A observação de cerca de 82 MiB só é útil como ordem de grandeza local; meça a build exata do navegador, a plataforma, o comportamento de cache e o impacto da imagem no seu ambiente. Rotação de proxy, sessões, persistência, recuperação de falha e concorrência sustentada ainda precisam de testes próprios antes que este fixture possa orientar uma escolha em escala de produção.

Prós e contras

Prós:

  • Crawlers HTTP e de navegador compartilham conceitos de ciclo de vida, mas expõem contextos de extração específicos do motor.
  • Extração HTTP com precisão total em catálogos estáticos, artigos e APIs JSON.
  • Infraestrutura compartilhada entre os dois motores: RequestQueue, enqueueLinks com controle de profundidade, Dataset.
  • O caminho com navegador executou os scripts do fixture e recuperou todos os itens esperados nos dois testes renderizados em JS.
  • Tratamento de falha limpo — o HTTP 500 apareceu sem derrubar o processo.
  • Licença Apache-2.0; usuários downstream devem revisar as obrigações de aviso e atribuição.

Contras:

  • No ambiente testado, o motor de navegador precisou de uma instalação separada do Chromium; sem isso, o PlaywrightCrawler não iniciava.
  • O caminho HTTP não consegue expor elementos que não existem no HTML bruto; sem validação de completude, isso pode parecer um resultado vazio válido.
  • O caminho com navegador carrega um binário adicional e teve custo local por página mais alto nesta execução; tamanho e tempo variam conforme build e plataforma.
  • Execuções padrão deixam uma pasta storage/ no disco.
  • Apenas Node/TypeScript — não ajuda se o seu stack for Python.

Para quem é — e para quem deve passar longe

O Crawlee faz sentido para equipes de Node ou TypeScript que precisam de crawling via HTTP e navegador com conceitos compartilhados de fila e ciclo de vida. Um caminho prático é tentar primeiro o crawler HTTP, validar os campos obrigatórios e, se houver falha tipada de completude, escalar para um handler de navegador com uma condição de prontidão específica do alvo. O código de acesso ao DOM do handler é específico do motor, mesmo quando a infraestrutura de fila e descoberta de links é compartilhada.

Reveja suas expectativas — ou procure outra solução — se você trabalha em um ambiente Python (o Crawlee é Node/TS — existe um port em Python, mas este pacote testou a biblioteca Node), se todos os seus alvos são estáticos e você prefere um scraper HTTP mais enxuto e de propósito único, ou se precisa de comportamento comprovado em escala — rotação de proxy, pools de sessão, retomada após falha — algo que esta análise prática não cobriu. E, se você for usar PlaywrightCrawler, instale o Chromium antes; caso contrário, ele simplesmente não roda.

Alternativas, incluindo onde o Thunderbit entra

O Crawlee é um software open source que você executa e mantém por conta própria. Não há taxa por chamada de fornecedor, mas computação de navegador, banda, proxies, armazenamento, observabilidade e engenharia continuam sendo custos operacionais. Você assume a escolha do crawler, o binário do navegador, o estado de armazenamento e a lógica de prontidão.

Revisão relacionada: avaliação do scrapy-playwright.

Um serviço gerenciado de extração transfere para o fornecedor a responsabilidade pela aquisição e pela definição do schema. Nós construímos o Thunderbit, mas não o executamos nesses fixtures, então este artigo não serve de base para comparação de qualidade, latência, paridade de recursos ou custo. A decisão relevante é se a sua equipe quer o controle in-process do Crawlee ou uma fronteira de serviço por chamada.

Revisões relacionadas de benchmark: a comparação completa de scrapers open source, Playwright vs Puppeteer nas mesmas páginas e a análise do Scrapy sem request replay no navegador.

Experimente Thunderbit para extração de dados da web

Veredito

O Crawlee é um forte candidato para equipes de Node ou TypeScript que querem orquestração de crawl compartilhada entre HTTP e execução no navegador. Os handlers testados não eram intercambiáveis: migrar para Playwright exigiu page, espera por seletor-alvo e extração do lado do navegador. Proxy, sessão, persistência, retomada e comportamento em grande escala continuam em aberto.

Experimente Thunderbit para extração de dados da web Get Started Free

Perguntas frequentes

Qual é a diferença real entre os dois crawlers do Crawlee? CheerioCrawler busca HTML via HTTP e não executa JavaScript. PlaywrightCrawler controla o Chromium e consegue executar scripts da página e capturar screenshots, com custo local por página mais alto. Eles compartilham conceitos de ciclo de vida, mas não têm contextos de handler idênticos: neste harness, o caminho HTTP usou $, enquanto o caminho com Playwright usou page, espera por seletor-alvo e avaliação do lado do navegador.

Por que o PlaywrightCrawler não roda depois que instalo o Crawlee? No ambiente testado, a instalação do pacote não forneceu um executável de navegador. Instalar o Chromium com npx playwright install chromium resolveu a falha de inicialização. A carga observada foi de cerca de 82 MiB, mas a medição original não preservou se era tamanho de transferência ou em disco, então reavalie isso para a sua plataforma e build.

O CheerioCrawler consegue raspar páginas renderizadas em JavaScript? Ele não executa o JavaScript da página. Ainda assim, pode acessar um endpoint JSON disponível ao cliente, como mostra o fixture de resposta direta. Quando os dados necessários só aparecem depois da execução no navegador, use um crawler de navegador e uma condição de prontidão ligada a esses campos.

O Crawlee é preciso para extração estática comum? Nos fixtures controlados, os handlers produziram 12/12 produtos esperados do catálogo, 3/3 parágrafos esperados do artigo e 8/8 itens esperados da resposta JSON direta. Esses são testes de completude de fixture, não uma nota geral de precisão para sites não testados.

O Crawlee é gratuito para uso comercial? Ele é publicado sob Apache-2.0. Confirme a licença atual no repositório e revise as obrigações de aviso e atribuição para a sua distribuição.

Antes de adotar em produção, teste os pontos que este fixture deixou em aberto: concorrência repetida em páginas representativas, comportamento de proxy e sessão, recuperação persistente da fila após interrupção, limpeza de processos do navegador e exportação do dataset em caso de falha. Preserve a versão do navegador e o caminho de instalação resolvidos junto com esses resultados. As duas classes de crawler reduzem a divergência de orquestração, mas não eliminam a necessidade de verificações de prontidão específicas do motor, orçamentos de recursos e tratamento de falhas operacionais.

Ke
Ke
CTO na Thunderbit | Cientista de Dados Sênior e Especialista em ML Com quase uma década de experiência em machine learning e data science, Ke Shen é ex-aluno da Columbia University e foi Cientista de Dados Sênior na Walmart Labs. Com profunda experiência, reconhecida pelos pares, em Python, R, Java e Estatística, ele compartilha insights testados em batalha sobre como levar algoritmos complexos de IA da teoria à arquitetura pronta para produção.
Topics
Ferramentas de Web ScrapingAI Web Scraper
Sumário
Thunderbit · Agente de dados web com IA

Extraia dados de qualquer página em 1 clique

Aprovado por mais de 250.000 usuários
plano gratuito disponível
Da página web para a planilha
Descreva o que você precisa — o Agente de IA da Thunderbit extrai e exporta para Excel, Google Sheets, Airtable ou Notion. Comece grátis.
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week