Extração de dados

Encontrando a API Por Trás da Página: Coletando de Endpoints JSON em Vez de HTML

Muitas páginas carregam seus dados como JSON. Como encontrar o endpoint que os carrega, por que ele costuma estar vinculado à sessão da página e como coletá-los de forma responsável.

Chris Collins

Chris Collins

30 de setembro de 2026 · 8 min de leitura

Abra uma página web moderna, observe a atividade de rede, e você frequentemente verá os dados que deseja chegarem como JSON antes da página desenhá-los. Os preços, listagens ou resultados que um scraper extrairia laboriosamente do HTML estão numa resposta limpa e estruturada que a própria página buscou.

Coletar a partir dessa resposta em vez da página renderizada pode ser menor, mais estável e muito mais fácil de analisar. Mas não é tão simples quanto copiar uma URL, e duas coisas surpreendem a maioria das equipes: quão pouco do JSON de uma página é realmente dado, e com que frequência o endpoint de dados se recusa a funcionar fora da página que o chamou. Este guia mostra como encontrar o endpoint certo, o que medimos em páginas reais, e como coletar dele sem ultrapassar limites.

Principais conclusões

  • A maior parte do JSON que uma página carrega não é dado. Na página de busca de voos de uma companhia aérea, as tarifas vieram em uma única resposta de 44.9 KB, cerca de 8% do JSON da página e cerca de 1.2% de seus 3.6 MB de transferência total.
  • Algumas páginas não têm API de dados alguma. Na página de previsão de um serviço nacional de meteorologia, toda resposta JSON pertencia à ferramenta de consentimento de cookies, e a previsão estava no HTML.
  • Encontre o endpoint pesquisando os corpos das respostas por um valor que você pode ver na página, não adivinhando a partir de URLs.
  • APIs de página frequentemente estão vinculadas à sessão da página. O endpoint de tarifas da companhia aérea funcionava dentro da página e retornava um HTTP 409 quando chamado diretamente.
  • Use apenas endpoints públicos que a página chama para visitantes anônimos, no ritmo em que uma pessoa navegando o faria, e prefira uma API oficial sempre que houver uma.

O que medimos

Carregamos duas páginas públicas em um navegador real em 30 de setembro de 2026 e registramos cada resposta.

Busca de voos de companhia aéreaPrevisão do tempo
Requisições6146
Total transferido3.62 MB2.57 MB
Respostas JSON15, 534 KB3, 1.04 MB
Respostas JSON contendo os dados1, 44.9 KB0
Onde os dados estavamUm endpoint de tarifasO HTML renderizado no servidor

Na página da companhia aérea, as maiores respostas JSON não eram tarifas de forma alguma. Um serviço de feature-flag de terceiros retornou a mesma resposta de 97 KB quatro vezes, e um pacote de tradução adicionou outros 92 KB. As tarifas chegaram em uma única resposta da própria API de reservas da companhia aérea.

Na página de meteorologia, todas as três respostas JSON vieram da ferramenta de gerenciamento de consentimento, uma delas uma lista de fornecedores de 860 KB, enquanto a própria previsão foi renderizada no HTML no servidor. “Coletar do JSON” não teria coletado nada útil.

Encontrando o endpoint que carrega os dados

O método confiável é pesquisar, não adivinhar. Escolha um valor que você pode ver na página, como um preço, um nome de produto ou um identificador, carregue a página em um navegador real, e encontre qual resposta JSON o contém.

Manualmente, isso é feito com as ferramentas de desenvolvedor do navegador: abra a aba Network, filtre para Fetch/XHR, recarregue, e pesquise os corpos das respostas pelo valor. De forma automatizada, é um script curto:

import { chromium } from 'playwright';

// Load a page once and report which JSON responses contain a value you can see on it.
export async function findEndpoint(url, needle, waitMs = 20000) {
  const browser = await chromium.launch({ headless: true });
  const page = await browser.newPage();
  const hits = [];
  page.on('response', async (response) => {
    const type = response.request().resourceType();
    const contentType = response.headers()['content-type'] || '';
    if (!['xhr', 'fetch'].includes(type) || !contentType.includes('json')) return;
    try {
      const body = await response.text();
      if (body.includes(needle)) {
        hits.push({
          method: response.request().method(),
          status: response.status(),
          bytes: Buffer.byteLength(body),
          url: response.url(),
        });
      }
    } catch {
      // Some responses (redirects, aborted requests) have no readable body.
    }
  });
  // Analytics beacons keep many pages from ever going network-idle,
  // so wait for the DOM, then until a match appears or the time runs out.
  await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 90000 });
  for (let waited = 0; waited < waitMs && hits.length === 0; waited += 500) {
    await page.waitForTimeout(500);
  }
  await page.waitForTimeout(1000);
  await browser.close();
  return hits;
}

Dada a página de voos da companhia aérea e uma tarifa visível nela, o script retornou exatamente uma correspondência entre 61 requisições: a resposta de disponibilidade da API de reservas. Observe a estratégia de espera. Nossa primeira versão esperava a página ficar ociosa na rede, o que nunca aconteceu, porque beacons de analytics continuavam disparando; ela expirou após 90 segundos. Esperar pelo DOM e depois por uma correspondência é mais confiável.

É possível chamá-lo diretamente?

Frequentemente não. Quando solicitamos o mesmo endpoint de disponibilidade da companhia aérea diretamente, sem a página, ele retornou HTTP 409 para requisições de seis países diferentes igualmente, enquanto a própria página o carregava sem problemas. APIs de página comumente dependem de coisas que a página configura primeiro: cookies de sessão, tokens embutidos no HTML, cabeçalhos de requisição, ou uma sequência de chamadas anteriores.

Isso deixa duas abordagens:

  • Deixe a página fazer a chamada. Carregue a página em um navegador e leia a resposta JSON conforme ela chega, como o script acima faz. Você obtém os dados limpos sem reconstruir a sessão, ao custo de executar um navegador.
  • Reproduza apenas endpoints simples e públicos. Alguns endpoints não precisam de nada além de uma URL. A mesma companhia aérea também publica um endpoint de tarifas público que responde a requisições simples, que usamos em um teste separado sobre se os preços mudam por país de saída. Onde um endpoint funciona de forma tão simples, é de longe a opção mais barata.

O que não se deve fazer é contornar a sessão: coletar tokens, forjar cabeçalhos ou reproduzir chamadas autenticadas para alcançar dados que o site não disponibilizou a visitantes anônimos. É aí que a coleta deixa de ser observação.

Por que o JSON vale a pena quando está disponível

Quando os dados de fato chegam como JSON, os ganhos são reais:

  • Tamanho. A resposta de tarifas tinha 44.9 KB contra 3.6 MB da página completa. Em coleta cobrada por largura de banda, essa diferença é a maior parte da conta, como mostra custo por registro limpo.
  • Estrutura. Os campos chegam nomeados e tipados, sem seletores para escrever ou manter.
  • Completude. As respostas frequentemente carregam mais do que a página exibe, como identificadores, todas as classes de tarifa ou sinalizadores de estoque.

As contrapartidas são igualmente reais. Endpoints não documentados mudam sem aviso, e uma resposta que muda de forma quebra seu parser silenciosamente, que é exatamente o problema para o qual existe o monitoramento de schema drift. Um número de versão no caminho, como o v4 na API de reservas da companhia aérea, é um sinal leve de estabilidade, não uma promessa.

Onde isso se encaixa entre as alternativas

FonteEstabilidadeEsforçoUse quando
API oficial e documentadaMais altaMais baixoSempre verifique primeiro
JSON-LD ou estado de página embutidoAltaBaixoA página o publica, veja pare de analisar HTML
Endpoints JSON próprios da páginaMédiaMédiaOs dados carregam depois da página, e o endpoint é público
HTML renderizado e seletoresMais baixaMais altoNada mais carrega os dados
Um modelo lendo a páginaVariaBaixo por site, alto por páginaMuitos templates, como em extração por LLM vs seletores

Colete de forma responsável

Os endpoints que uma página chama fazem parte do site, e as regras do site ainda se aplicam. Use apenas endpoints que a página chama para visitantes anônimos, ajuste o ritmo das requisições como uma pessoa navegando faria, respeite o robots.txt e os termos do site, e deixe de lado qualquer coisa atrás de um login ou token, a menos que você tenha permissão. Onde um site oferece uma API oficial, use-a; ela é mais estável, e é o que o site concordou em suportar. Os princípios mais amplos estão em robots.txt, opt-outs de IA e sinais de reserva.

Conclusão

Os dados por trás de uma página moderna frequentemente chegam como JSON, e quando isso acontece, coletá-los ali é menor, mais limpo e mais fácil de manter do que analisar HTML. Mas encontrá-lo exige uma pesquisa, não um palpite: nas páginas que medimos, o JSON útil era uma resposta entre muitas, e em uma página ele simplesmente não existia.

Pesquise os corpos das respostas por um valor que você pode ver, verifique se o endpoint funciona sozinho, deixe a página fazer a chamada quando não funcionar, e permaneça dentro do que o site oferece a qualquer visitante anônimo.

Fontes e referências

Pronto para começar?

Experimente os proxies residenciais da Shifter, mais de 205M IPs, mais de 195 países, a partir de $ 0,75/GB.

Começar