APRENDIZADO & COGNIÇÃO

Web Scraping eficiente: Do Headless Browser às APIs ocultas

Quando você decide criar um agregador de dados em tempo real, a primeira ideia que vem à cabeça para coletar…

Quando você decide criar um agregador de dados em tempo real, a primeira ideia que vem à cabeça para coletar informações de grandes plataformas é: “Vou subir um Puppeteer, simular cliques humanos e pronto”.

Foi exatamente isso que fiz quando comecei a construir a base de dados do NaveIdeal, uma plataforma criada para minerar, higienizar e auditar ofertas de veículos de múltiplos portais (como OLX, WebMotors e iCarros) em tempo real, calculando a defasagem contra a Tabela FIPE para ranquear as melhores oportunidades do mercado.

No papel, parecia perfeito. Na prática, me fez desistir do projeto no primeiro mês.

Neste post, quero compartilhar as 3 fases de maturidade de Web Scraping pelas quais passei, os erros de consumo de memória que quase derrubaram a infraestrutura e como saí de instâncias pesadas de Chromium para requisições de alta performance consumindo frações míseras de CPU e RAM.

1. O Ponto de Partida e o Pesadelo da RAM (Puppeteer)
No início, para garantir que as páginas carregassem scripts dinâmicos e contornassem desafios visuais, configurei uma fila usando puppeteer-cluster e puppeteer-extra-plugin-stealth.

A lógica de extração era parecida com isto:

async function scrapeComBrowser(page, url) { await page.goto(url, { waitUntil: "domcontentloaded", timeout: 60000 }); await page.waitForSelector("#price-box-container", { timeout: 10000 }); const dados = await page.evaluate(() => { const titulo = document.querySelector("h1")?.innerText || ""; const preco = document.querySelector("#price-box-container")?.innerText || ""; return { titulo, preco }; }); return dados;}

Onde a conta não fechava:
Consumo de Memória: Cada aba ou instância do Chromium consome facilmente entre 150 MB e 350 MB de RAM. Multiplique isso por uma concorrência mínima de 4 workers em um servidor modesto e você terá a máquina travando ou muito lenta.

Overhead de CPU: O Chromium renderiza CSS (mas temos como configurar para o puppeteer não renderizar isso), calcula layout e processa scripts que você não precisa para nada se o seu objetivo for apenas extrair texto e JSON.

Fragilidade e Timeouts: Quedas de conexão no protocolo do DevTools (protocolTimeout) eram comuns durante varreduras contínuas.

2. A Virada de Chave: HTTP Puro + Cheerio
Percebi que em 80% das páginas que eu precisava varrer, o HTML inicial já vinha com o conteúdo renderizado no servidor (SSR) ou embutido em tags iniciais. Eu não precisava executar JavaScript no cliente, precisava apenas fazer o download do HTML cru e fazer o parse da árvore estática.

Trocamos o Puppeteer por um cliente HTTP otimizado (com suporte a proxies residenciais e headers humanizados) aliado ao Cheerio (uma implementação rápida e leve do núcleo do jQuery voltada para o servidor).

const cheerio = require("cheerio");const proxyManager = require("./services/proxyManager");//aqui esta configurado os proxys residenciasasync function scrapeComCheerio(url) { const response = await proxyManager.fetch({ url }); const $ = cheerio.load(response.body); const title = $("h1").first().text().trim(); const precoTxt = $("#price-box-container").text().trim(); const preco = Number(precoTxt.replace(/D/g, "")); return { title, preco };}

O impacto imediato:
Memória RAM: Caiu de centenas de megabytes por worker para menos de 30 MB no processo total.

Velocidade: Uma requisição que as vezes levava até 10 ou 15 segundos no Chromium passou a ser resolvida em 500ms a 1.2s.

3. O Santo Graal: Mineração Direta de APIs e Payloads Ocultos
Se usar Cheerio já reduziu o consumo em 80%, a descoberta seguinte mudou completamente o jogo: muitos portais modernos trafegam dados estruturados por trás das cortinas.

Em vez de fazer o scraping visual de dezenas de elementos (.div > span > a), começamos a inspecionar a aba Network das plataformas. Descobrimos que portais robustos como a WebMotors alimentam suas listagens e telas através de APIs REST internas ou dados serializados.

No extrator do NaveIdeal, em vez de baixar todo o HTML de uma listagem para caçar tags CSS, consumimos diretamente os endpoints de busca com filtros ordenados:

async function extrairViaApiInterna(estado, tipo, pagina = 1) { const apiUrl = `https://www.site.com.br/api/search/${tipo}?state=${estado}&actualPage=${pagina}&displayPerPage=24`; const response = await proxyManager.fetch({ url: apiUrl, headers: { "Accept": "application/json", "Origin": "https://www.site.com.br" } }); const json = JSON.parse(response.body); const anuncios = json.SearchResults || []; return anuncios.map(item => ({ id: item.UniqueId, marca: item.Specification?.Make?.Value, modelo: item.Specification?.Model?.Value, versao: item.Specification?.Version?.Value, ano: item.Specification?.YearModel, preco: item.Prices?.Price, fotos: item.Media?.Photos?.map(p => p.PhotoPath) }));}

Por que isso é superior?
Zero quebra de layout: Se a plataforma mudar a cor do botão ou a classe CSS do preço de .ad-price para .sc-price-new, o seu scraper tradicional quebra. A API estruturada tende a ser muito mais estável.

Custo Computacional Quase Zero: Fazer o parse de uma string JSON nativa com JSON.parse() é ordens de grandeza mais rápido do que construir e percorrer nós de DOM.

Onde tudo isso se conecta?
Todo esse processo de extração leve alimenta o pipeline do NaveIdeal.

Depois que esses dados brutos chegam sem peso na infraestrutura, eles entram em uma camada de normalização semântica, cruzam com a base histórica da Tabela FIPE e geram um Score de Oportunidade para filtrar veículos com real margem de desconto versus distorções de mercado.

Perguntas frequentes

Respostas institucionais sobre esta cobertura, fontes e limites editoriais.

Sobre o que trata “Web Scraping eficiente: Do Headless Browser às APIs ocultas”?
Quando você decide criar um agregador de dados em tempo real, a primeira ideia que vem à cabeça para coletar informações de grandes plataformas é: "Vou subir um Puppeteer, simular cliques humanos e pronto".Foi exatamente isso…
Por que Aprendizado & Cognição importa agora?
O tema impacta decisões e debates cotidianos ligados a Aprendizado & Cognição. A redação destaca fatos, datas e implicações práticas sem substituir orientação profissional personalizada.
Quem edita o conteúdo do Estrato Mente?
A cobertura é produzida e revisada pela equipe editorial do Estrato Mente, com editor-chefe responsável pela linha editorial. Conheça a redação em https://mente.estrato.cc/equipe/.
Quais fontes o Estrato prioriza?
Priorizamos fontes primárias (órgãos oficiais, balanços, estudos revisados, documentos públicos) e cruzamos informações antes da publicação, conforme a política editorial.
Como solicitar correção de uma matéria?
Envie o pedido pela página de Correções (https://mente.estrato.cc/correcoes/) ou Contato (https://mente.estrato.cc/contato/). Erros materiais são corrigidos com registro da atualização.
O conteúdo constitui aconselhamento profissional?
Não. As matérias têm caráter informativo e jornalístico. Decisões financeiras, de saúde, jurídicas ou educacionais devem considerar profissionais habilitados e a sua situação particular.
Onde acompanhar a política editorial do Estrato Mente?
Metodologia, ética e transparência estão em https://mente.estrato.cc/metodologia/, https://mente.estrato.cc/etica-editorial/ e https://mente.estrato.cc/politica-editorial/.
Como o Estrato trata temas sensíveis (YMYL)?
Temas que afetam dinheiro, saúde e bem-estar recebem revisão editorial reforçada, disclaimer visível e links para páginas institucionais de metodologia e correções. Portal: https://mente.estrato.cc/
WhatsApp X LinkedIn
Compartilhar: LinkedIn
Diego Amaral

Diego Amaral

Diego Amaral integra a equipe editorial do Estrato Mente, vertical da rede Estrato, na função de Repórter de Filosofia prática. O escopo permanente de cobertura inclui autoconhecimento e ética cotidiana, com atenção ao leitor brasileiro que busca contexto factual, datas oficiais e implicações práticas. Na produção diária, prioriza fontes primárias (órgãos públicos, balanços, papers e documentos oficiais), cruza pelo menos duas referências independentes quando o tema é contestado e evita manchetes que prometam certeza onde há incerteza. Critérios de qualidade: lead com o fato principal, atribuição clara de autoria da equipe Estrato, atualização com selo quando há mudança material e linguagem acessível sem simplificar demais o risco ou o contexto. Trabalha sob revisão da mesa editorial e do editor-chefe do portal. Matérias YMYL recebem segunda leitura antes da publicação e podem ser atualizadas quando surgem novos dados oficiais. Limites: este perfil descreve o papel editorial na marca Estrato. O conteúdo publicado é informativo e não constitui aconselhamento médico, financeiro, jurídico ou profissional personalizado. Transparência ao leitor: metodologia em /metodologia/, ética em /etica-editorial/, correções em /correcoes/, equipe em /equipe/ e canal em /contato/ ([email protected]). Na página-mãe da rede, a bio ampliada e o arquivo de matérias ficam em estrato.cc/blog/, com link para o arquivo do autor em cada portal.

One thought on “Web Scraping eficiente: Do Headless Browser às APIs ocultas”

Deixe um comentário