Scarnox · Blog

Como fazer scraping de sites renderizados com JavaScript

Muitos sites modernos enviam um documento HTML quase vazio e constroem o conteúdo no navegador com JavaScript. Se o seu scraper busca a página e não encontra produtos, preços nem texto de artigo, o conteúdo existe, mas chega depois. Este guia mostra como identificar qual tipo de página você tem, como encontrar um caminho mais rápido do que um navegador quando ele existe e como fazer scraping de páginas renderizadas com Playwright em Python. Termina com uma nota sobre o que fazer quando uma página renderizada mostra um captcha.

Passo 1: verifique se o conteúdo está no HTML

Abra a página com view-source: no seu navegador, ou busque-a com uma requisição HTTP simples, e procure no código-fonte um trecho de texto que você consegue ver na tela. Três resultados são comuns:

Passo 2: chame o endpoint JSON, se existir um

Quando uma página busca os dados de um endpoint, chamar esse endpoint diretamente costuma ser a melhor opção. Ele é menor, mais rápido e mais estável do que a página renderizada. Copie a URL da requisição, verifique quais cabeçalhos o site exige e teste a partir de um script. Faça isso apenas quando os termos do site permitirem, e respeite quaisquer limites de taxa ou autenticação que o site espera. Um endpoint não documentado pode mudar sem aviso, então escreva o seu parser para falhar de forma explícita quando a estrutura da resposta mudar.

Passo 3: renderize a página quando for necessário

Se o conteúdo realmente exige o navegador, use um navegador headless. O Playwright é uma boa escolha para Python. O exemplo abaixo abre uma listagem de produtos, espera o conteúdo aparecer e lê o texto de cada cartão:

from playwright.sync_api import sync_playwright

URL = "https://example.com/products"  # uma página que você tem permissão para raspar

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()
    page.goto(URL, wait_until="domcontentloaded", timeout=60_000)
    # Espere pelo elemento que prova que os dados chegaram.
    page.wait_for_selector(".product-card", timeout=30_000)
    titles = page.locator(".product-card h2").all_inner_texts()
    browser.close()

for title in titles:
    print(title)

Esperar por um seletor específico é muito mais confiável do que um sleep fixo. Uma pausa fixa é curta demais em um dia lento ou desperdiça tempo em um dia rápido. Escolha o elemento que só aparece depois que os dados carregaram.

Passo 4: trate rolagem infinita e paginação

Algumas páginas carregam mais itens conforme você rola. Role até o fim, espere a contagem de itens crescer e pare quando ela não crescer mais. Páginas com paginação numerada são mais simples: encontre o link da próxima página, siga-o e pare na última. Defina sempre um número máximo de páginas ou rolagens, para que um bug não mantenha o seu crawler rodando para sempre.

def scroll_until_done(page, selector: str, max_rounds: int = 20) -> int:
    previous = -1
    for _ in range(max_rounds):
        count = page.locator(selector).count()
        if count == previous:
            break
        previous = count
        page.mouse.wheel(0, 4000)
        page.wait_for_timeout(1500)  # dê tempo para o próximo lote carregar
    return previous

Passo 5: mantenha o navegador econômico

Renderizar é caro. Bloqueie imagens, fontes e mídias de que você não precisa, e reutilize um único navegador para muitas páginas, em vez de iniciar um novo a cada vez. Feche páginas e contextos quando terminar, para que a memória não cresça ao longo de uma execução longa.

def block_heavy_assets(route):
    if route.request.resource_type in ("image", "font", "media"):
        route.abort()
    else:
        route.continue_()

page.route("**/*", block_heavy_assets)

Passo 6: quando uma página renderizada mostra um captcha

Às vezes a página renderizada apresenta um captcha antes de mostrar qualquer conteúdo. Se esse captcha for PopularCaptcha, o tipo de captcha ativo na Scarnox, você lê o sitekey da página, solicita um token e coloca o token no campo de formulário que o site espera. O guia de PopularCaptcha em Python percorre essa etapa. Outros widgets ainda não estão ativos, então confira tipos de captcha explicados antes de planejar em cima de um deles.

Tenha cuidado com o próprio navegador. Um navegador headless que parece claramente automatizado pode disparar mais verificações, e não menos. Leia detecção de navegador headless para os sinais a observar, e prefira menos carregamentos de página, mais lentos.

Faça scraping com responsabilidade

Próximos passos

Comece com crédito de teste grátis, sem cartão: crie uma conta e teste o fluxo de PopularCaptcha em uma página sua. Para as tarifas atuais, veja a página de preços.