Scraping de Site Dinâmico
Sites dinâmicos carregam conteúdo usando JavaScript após o carregamento inicial da página. Este guia mostra como coletar dados desses sites usando o endpoint de navegador da FourA.
O problema
Quando você envia uma request HTTP padrão para um site com uso intenso de JavaScript, você obtém a estrutura HTML, mas não o conteúdo real. Os dados que você precisa (listagens de produtos, preços, resultados de busca) são carregados pelo JavaScript após a página renderizar em um navegador.
Isso é cada vez mais comum com frameworks modernos como React, Vue, Angular e Next.js.
A solução: Browser Requests
O endpoint de navegador da FourA (POST /api/browser/) abre sua URL em uma instância do navegador Chrome que:
- Carrega a página
- Executa todo o JavaScript
- Aguarda a renderização do conteúdo
- Retorna o HTML totalmente renderizado
Passo 1: Identifique o que você precisa
Antes de fazer a request, visite a página de destino no seu navegador e use o DevTools (F12) para encontrar um trecho de texto ou elemento que confirme que o conteúdo foi carregado. Por exemplo:
- Um nome de produto que aparece após o JS renderizar
- Uma classe CSS como
product-gridno HTML renderizado - Uma string de texto como "results" que só aparece quando os dados são carregados
Passo 2: Envie uma Browser Request
curl -X POST https://eu.api.foura.ai/api/browser/ \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/products",
"timeout_ms": 15000,
"checkText": "product-grid"
}'
A opção checkText instrui o FourA a verificar se "product-grid" está na página assim que o carregamento for concluído. Se não estiver, a request retorna como falha com checkText:product-grid not found, e uma request com falha não é cobrada. checkText não faz o FourA esperar mais tempo pelo texto.
Passo 3: Fazer o parse do HTML
A response contém o HTML totalmente renderizado no campo body. Faça o parse com sua biblioteca de preferência:
Python (BeautifulSoup)
import requests
from bs4 import BeautifulSoup
resp = requests.post("https://eu.api.foura.ai/api/browser/", headers={
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json"
}, json={
"url": "https://example.com/products",
"timeout_ms": 15000,
"checkText": "product-grid"
})
html = resp.json()["body"]
soup = BeautifulSoup(html, "html.parser")
for product in soup.select(".product-card"):
name = product.select_one(".product-name").text.strip()
price = product.select_one(".product-price").text.strip()
print(f"{name}: {price}")
Node.js (cheerio)
import * as cheerio from 'cheerio';
const resp = await fetch('https://eu.api.foura.ai/api/browser/', {
method: 'POST',
headers: { 'X-API-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' },
body: JSON.stringify({
url: 'https://example.com/products',
timeout_ms: 15000,
checkText: 'product-grid'
})
});
const { body: html } = await resp.json();
const $ = cheerio.load(html);
$('.product-card').each((i, el) => {
console.log($(el).find('.product-name').text(), $(el).find('.product-price').text());
});
Solução de problemas
Ainda está recebendo conteúdo vazio?
- Verifique se a página realmente usa renderização em JavaScript (compare "Exibir código-fonte da página" com o DevTools)
- Aumente
timeout_ms: algumas páginas demoram para carregar - Verifique se a página exige autenticação ou cookies (use o parâmetro
cookies)
Recebendo uma página de verificação?
- Para requests únicas/HTTP, mude para o endpoint de proxy (
POST /api/proxy/) para rotação automática de IP. - Para rotear um request de navegador por um proxy, passe o parâmetro
proxydo endpoint de navegador. O endpoint de proxy encapsula apenas requests únicas/HTTP, não requests de navegador.
O parâmetro proxy recebe o ID de proxy opaco retornado por uma response anterior, nunca um endereço de proxy próprio. Execute uma chamada POST /api/proxy/ (ou POST /api/auto/) primeiro, leia o campo proxy retornado e então fixe ele:
# Step 1: let FourA find a working exit. The response carries "proxy": "A1B2C3".
curl -X POST "https://eu.api.foura.ai/api/proxy/" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"maxTries": 5, "request": {"method": "GET", "url": "https://example.com/products"}}'
# Step 2: render through that same exit.
curl -X POST "https://eu.api.foura.ai/api/browser/" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/products", "proxy": "A1B2C3", "timeout_ms": 20000}'
Enviar um endereço em vez de um ID retorna como 400 Invalid proxy format. O padrão completo está em Reutilizar um Proxy Entre Requests.
Próximos Passos
- Escolhendo o Endpoint Certo: Quando usar browser vs. single
- Monitorar Preços da Concorrência: Tutorial completo de monitoramento de preços
- Sites protegidos: Lidar com sites protegidos
- Reutilizar um Proxy Entre Requests: Fixar uma saída durante todo o workflow