Voltar ao blogue
A ciência da extração de dados da Web
Raluca PenciucLast updated on May 13, 202614 min read

HTTP Headers Web Scraping: Deixar de ser bloqueado

HTTP Headers Web Scraping: Deixar de ser bloqueado
Resumo: Os cabeçalhos HTTP são, normalmente, a razão pela qual o seu scraper recebe um erro 403, enquanto o seu navegador carrega a mesma URL sem problemas. Este guia mostra quais os cabeçalhos que os sistemas anti-bot realmente analisam, como capturar o conjunto de cabeçalhos de um navegador real a partir das Ferramentas do Desenvolvedor, como enviá-los e alterná-los corretamente em Python e Node.js, e quando o ajuste manual deixa de valer a pena e uma API de scraping gerida é a melhor opção.

A maioria dos scrapers bloqueados não o é devido ao seu IP. São bloqueados pela solicitação que enviam antes mesmo de o corpo da solicitação começar. O web scraping com cabeçalhos HTTP consiste em fazer com que os metadados do seu cliente pareçam os de um navegador real, em vez de uma biblioteca padrão do Python ou do Node.js, e é a alavanca mais barata e subutilizada que tem contra a deteção anti-bot.

Em HTTP, um cabeçalho é um par nome-valor separado por dois pontos que transporta metadados sobre o pedido ou a resposta: a identidade do cliente, idiomas aceites, codificação, cookies, contexto de segurança e muito mais. A referência MDN sobre cabeçalhos HTTP e a RFC 9110 definem a semântica canónica. Os sistemas de deteção comparam o conjunto de cabeçalhos do seu scraper com a impressão digital de uma sessão real do Chrome ou do Firefox, e qualquer discrepância nos valores, presença, maiúsculas/minúsculas ou ordem pode sinalizar a solicitação.

Este guia destina-se a engenheiros de backend, dados e operações cujos scrapers estão a devolver 403, 429, corpos vazios ou uma página diferente daquela que o navegador vê. Ao terminar, saberá quais os cabeçalhos que importam, como lê-los a partir do DevTools e reproduzi-los em Python ou Node.js, como lidar com a ordem dos cabeçalhos e as impressões digitais TLS, e quando parar de ajustar e transferir a camada de pedidos para um serviço gerido.

Cabeçalhos HTTP Web Scraping 101: Cabeçalhos vs. Cookies, Atualizado

Comece por entender bem o modelo. Um cabeçalho de solicitação é um metadado que o seu cliente anexa a uma solicitação de saída: quem você é, o que aceita, de onde veio. Um cabeçalho de resposta é um metadado que o servidor envia de volta: dicas de status, tipo de conteúdo, regras de cache e Set-Cookie diretivas.

Os cookies não são um protocolo separado; são um cabeçalho com estado. O servidor distribui-os através de Set-Cookie, e o seu cliente repete-os num Cookie cabeçalho em todas as solicitações seguintes. De acordo com a RFC 6265, essa troca mantém as sessões ativas, transporta tokens de autenticação, fixa a localização geográfica e armazena buckets A/B.

Para a extração de dados da Web com cabeçalhos HTTP, ambas as camadas são importantes. Se falhar em qualquer uma delas, o seu cliente parecerá novo a cada acesso, que é exatamente o que a deteção de bots procura. O nosso explicador de cookies HTTP aborda a mecânica subjacente.

Que cabeçalhos os sistemas anti-bot realmente monitorizam

Os servidores não avaliam todos os cabeçalhos da mesma forma. Uma pequena lista faz o trabalho pesado em pilhas reais de identificação, e os mesmos nomes aparecem em todos os fornecedores de detecção. Os H3s abaixo abordam esses cabeçalhos aproximadamente por ordem de impacto para a extração de dados da Web com cabeçalhos HTTP, desde aquele que quase todos erram (User-Agent) até dicas do cliente e cookies por sessão.

User-Agent: O cabeçalho mais verificado e mais falsificado

User-Agent identifica o software do cliente, o sistema operativo e o motor do navegador, e é o primeiro cabeçalho que os sistemas anti-bot testam. Valores predefinidos como python-requests/2.x ou o padrão do axios são bloqueados instantaneamente porque nenhum visitante real os envia. O perfil mais comum no mundo real é o Chrome no Windows, pelo que esse é o alvo mais seguro para imitar.

Dois padrões falham com certeza. O primeiro é reutilizar um único UA em milhões de pedidos. O segundo é editar manualmente um UA real, alterando um dígito e acabando com uma versão que nenhum navegador real alguma vez lançou. No momento da redação, verifique em relação a uma versão atual do Chrome ou do Firefox, em vez de copiar uma cadeia de versão de qualquer tutorial, incluindo este.

Accept, Accept-Language e Accept-Encoding

Estes três indicam que tipo de conteúdo o seu cliente consegue processar. Accept enumera tipos MIME, Accept-Language enumera configurações regionais, tais como en-US,en;q=0.9, e Accept-Encoding lista algoritmos de compressão (gzip, deflate, br). Os navegadores reais enviam valores ricos e ordenados aqui, e as cadeias de caracteres exatas diferem entre o Chrome e o Firefox.

As armadilhas são subtis. Um IP residencial dos EUA emparelhado com Accept-Language: ru é uma incompatibilidade de impressão digital. Enviar br (Brotli), mas depois não conseguir descodificar um corpo Brotli, parece exatamente como um bot. Faça corresponder Accept-Language com a localização geográfica do seu proxy e anuncie apenas formatos de compressão que o seu cliente HTTP realmente descompacta de forma transparente.

Referer e Origin

Referer indica ao servidor qual a página que encaminhou o utilizador para este URL. Uma visita a uma página de produto específica sem Referer parece suspeito, porque os visitantes reais geralmente chegam a partir de um motor de busca, de uma lista de categorias ou de um link interno. Defina uma origem plausível Referer , como uma pesquisa no Google ou a própria página de categorias do site.

Origin é o seu equivalente mais restrito: os navegadores anexam-no a pedidos POST e fetch/XHR de origem cruzada. Se estiver a reproduzir uma chamada de API que observou no DevTools, copie o Origin cabeçalho na íntegra, ou o servidor tratará a solicitação como falsificada.

Sec-Fetch e Client Hints (Sec-CH-UA)

Os navegadores Chromium modernos anexam uma família de cabeçalhos de contexto de segurança que os guias de scraping mais antigos ignoram: Sec-Fetch-Site, Sec-Fetch-Mode, Sec-Fetch-Dest, e Sec-Fetch-User. Estes descrevem se a solicitação é uma navegação de nível superior, um recurso incorporado ou um XHR de origem cruzada. O carregamento direto de uma página a partir de um separador novo envia normalmente Sec-Fetch-Site: none, Sec-Fetch-Mode: navigate, e Sec-Fetch-Dest: document.

Client hints (Sec-CH-UA, Sec-CH-UA-Mobile, Sec-CH-UA-Platform) repetem o seu perfil de UA de forma estruturada. A verificação da impressão digital é simples: se o seu User-Agent afirma ser o Chrome no Windows, mas o seu Sec-CH-UA-Platform diz "macOS", você é sinalizado. Sempre indique a fonte User-Agent, Sec-CH-UAe Sec-CH-UA-Platform a partir da mesma captura real do navegador para que se mantenham internamente consistentes.

Cookies e cabeçalhos de sessão

Após a primeira solicitação, Cookie torna-se o cabeçalho com mais identidade que envias. Os sistemas anti-bot utilizam-no para rastrear se uma sessão está aquecida, se aceitaste um banner de consentimento e se o teu token CSRF veio da mesma renderização que o formulário que estás a enviar. Se eliminares os cookies entre pedidos, parecerás um visitante totalmente novo de cada vez.

Cabeçalhos personalizados como x-csrf-token, x-api-key, e Authorization aparecem em pontos finais XHR por trás de SPAs modernas. Retire-os do HTML ou de uma resposta JSON anterior e, em seguida, anexe-os à chamada de dados real. Sem esse passo, a API retorna 401 ou resultados vazios.

Capture cabeçalhos reais do navegador a partir do DevTools

Deixe de adivinhar os valores dos cabeçalhos. Abra o site de destino numa sessão normal do Chrome ou Firefox, clique com o botão direito do rato e selecione Inspecionar, depois mude para o separador Rede. Recarregue a página, clique na primeira solicitação de documento (o HTML) e abra o painel Cabeçalhos. A secção Cabeçalhos da solicitação é a sua referência.

Dois truques poupam tempo. Clique com o botão direito do rato na solicitação e escolha «Copiar como cURL» para descarregar a chamada completa, incluindo cabeçalhos, cookies e corpo, num comando pronto para o shell. E antes de reproduzir, elimine valores específicos da sessão, como Cookie, x-client-datae quaisquer tokens CSRF de uso único.

Valida a reprodução apontando-a para httpbin.org/headers, que devolve exatamente o que o teu cliente enviou. Se a resposta não corresponder à captura do DevTools, a tua biblioteca HTTP está a reescrever dados. O nosso guia de cabeçalhos de resposta cURL aborda táticas de inspeção mais aprofundadas.

Enviar cabeçalhos personalizados em Python e Node.js

O padrão é o mesmo em todos os clientes HTTP: crie um dicionário de nomes e valores de cabeçalhos, anexe-o à solicitação e reutilize uma sessão para que os cookies persistam. As duas seções específicas para cada linguagem abaixo mostram as armadilhas que surgem em grande escala.

Python (requests e httpx)

Com requests, passa um headers dict para gete use um Session para que os cookies persistam entre chamadas:

import requests

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                  "AppleWebKit/537.36 (KHTML, like Gecko) "
                  "Chrome/<current> Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.9",
    "Accept-Encoding": "gzip, deflate, br",
    "Sec-Fetch-Site": "none",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-Dest": "document",
}

with requests.Session() as s:
    s.headers.update(headers)
    r = s.get("https://httpbin.org/headers")
    print(r.json())

O problema: requests não preserva a ordem dos cabeçalhos de forma fiável, o que é uma fraqueza conhecida em termos de identificação digital. Para web scraping de cabeçalhos HTTP em grande escala, prefira httpx, que mantém a ordem exata de inserção do seu dicionário e suporta HTTP/2. Construa o dicionário na mesma ordem que o DevTools mostrou, e a imagem da transmissão permanecerá consistente.

Node.js (axios e fetch)

No Node.js, tanto axios e o nativo fetch aceitam um headers objeto. Reutilize uma instância do axios para partilhar valores predefinidos e utilize um cookie jar (axios-cookiejar-support ou similar) para que as sessões sobrevivam entre pedidos:

import axios from "axios";

const client = axios.create({
  headers: {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
                  "AppleWebKit/537.36 (KHTML, like Gecko) " +
                  "Chrome/<current> Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.9",
    "Sec-Fetch-Site": "none",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-Dest": "document",
  },
});

const { data } = await client.get("https://httpbin.org/headers");
console.log(data);

Tenha cuidado com predefinições do axios como X-Requested-With: XMLHttpRequest, que expõem a biblioteca. Substitua-os ou elimine-os explicitamente. A nossa análise aprofundada dos cabeçalhos do axios aborda padrões de detecção e evasão na camada de pedidos.

Ordem dos cabeçalhos, maiúsculas/minúsculas e impressões digitais TLS

Os nomes dos cabeçalhos não diferenciam maiúsculas de minúsculas de acordo com a RFC, mas a sua maiúscula/minúscula e ordem são, em grande medida, uma impressão digital. O Chrome real envia User-Agent com exatamente essa maiúscula/minúscula num slot específico relativo a Accept e Sec-Fetch-*. O Python requests historicamente coloca os nomes em minúsculas e não garante a ordem; httpx preserva o que quer que lhe forneça; o axios é geralmente fiel, mas adiciona os seus próprios valores predefinidos se não os remover.

Isso é apenas metade da história. Mesmo com um conjunto de cabeçalhos perfeito, o seu handshake TLS é a sua própria impressão digital. O JA3 e o mais recente JA4 calculam o hash das suites de encriptação, extensões e curvas elípticas que o seu cliente oferece. Uma pilha TLS em Python que alega ser do Chrome, mas que oferece a ordem de encriptação do OpenSSL, é uma mentira óbvia; consulte tlsfingerprint.io para ver como isso é detetável.

Medidas de mitigação: use um cliente compatível com HTTP/2 com configurações TLS realistas (curl_cffi, tls-client em Python; undici com TLS personalizado no Node), ou recorra a um proxy oculto ou a uma API gerida que controle a camada TLS por si.

Rote e atualize conjuntos de cabeçalhos em escala

Em escala, a rotação de cabeçalhos HTTP para web scraping funciona ao nível da sessão, não ao nível do pedido. Mantenha um conjunto de cabeçalhos realista durante a validade dos seus cookies e só troque quando iniciar uma nova identidade. Trocar User-Agent a meio da sessão é, por si só, um sinal de deteção.

Crie um conjunto de centenas de conjuntos de cabeçalhos reais a partir das versões atuais do Chrome, Firefox, Edge e Safari. Atualize-o à medida que os navegadores forem atualizados; caso contrário, irá destacar-se por utilizar o UA do ano passado. Combine a rotação de cabeçalhos com a rotação de proxies para que nem o IP nem os cabeçalhos, isoladamente, se tornem uma chave estável. O nosso guia para evitar bloqueios de IP e o tutorial sobre proxies para requests em Python abordam a parte dos proxies.

Cabeçalhos padrão da biblioteca a remover antes de enviar

Antes de qualquer pedido ser enviado, verifique o que a sua biblioteca está a enviar sem que lhe seja pedido. Indícios comuns:

  • User-Agent: python-requests/<version> ou o UA padrão do axios
  • X-Requested-With: XMLHttpRequest do axios
  • Accept: */* em vez de uma lista MIME real
  • Connection: close quando os navegadores reais mantêm a ligação
  • Injetado por proxy Via, X-Forwarded-For, e Forwarded

Substitua os primeiros quatro por valores realistas e teste o seu proxy contra httpbin.org/headers para capturar o último grupo.

Depuração de bloqueios baseados em cabeçalhos: uma lista de verificação

O ciclo de depuração para a extração de dados de cabeçalhos HTTP é curto. Quando obtiver um 403, 429 ou um corpo vazio, mas o navegador renderizar corretamente, siga esta lista por ordem:

  1. Compare os cabeçalhos. Compare a captura do DevTools com httpbin.org/headers linha a linha.
  2. Altere o User-Agent para uma string diferente do Chrome ou Firefox atual e tente novamente.
  3. Verifique o Accept-Encoding. Se indicar br, confirma se o teu cliente o descomprime; caso contrário, descarta-o.
  4. Verifique os cookies. Confirme se Cookie corresponde à sessão que preparou.
  5. Reproduza com o cURL a partir de Copy as cURL. Se o cURL funcionar e o seu código não, a diferença está no seu cliente. Se o cURL também falhar, o problema está no IP ou no TLS, e não nos cabeçalhos.

Quando mudar de cabeçalhos manuais para uma API de scraping gerida

A extração de dados da Web com cabeçalhos HTTP manuais tem um limite. Escale quando atingir qualquer uma destas situações:

  • Bloqueios TLS ou JA3/JA4 que resistem a cabeçalhos perfeitos. A solução está abaixo de HTTP.
  • Concorrência acima de algumas centenas de sessões, onde novos conjuntos de UA e armazenamentos de cookies se tornam um serviço próprio.
  • Custo de rotação em horas de engenheiro que excede o que um endpoint gerido cobra por sucesso.
  • Alvos difíceis por trás da gestão de bots empresariais que associam as sessões a uma impressão digital completa do navegador.

Uma API de scraper gerida ou um proxy furtivo controla cabeçalhos, TLS, IPs e tentativas de repetição por trás de um único ponto de extremidade, para que o seu código mantenha a lógica de análise. O nosso guia de 2026 sobre web scraping sem ser bloqueado abrange todo o percurso de escalonamento.

Pontos-chave

  • Os cabeçalhos da biblioteca padrão são a pista mais evidente. Substitua python-requests/x.y UAs, os padrões do axios e X-Requested-With antes de mais nada.
  • Capture, não invente. Obtenha conjuntos de cabeçalhos a partir do DevTools ou Copy as cURL, remova valores específicos da sessão e valide em relação a httpbin.org/headers.
  • A consistência interna supera o puro realismo. User-Agent, Sec-CH-UA, Sec-CH-UA-Platform, e Accept-Language todos devem descrever o mesmo navegador, SO e localização geográfica.
  • A ordem e o TLS são tão importantes quanto os valores. Prefira httpx em vez de requests em Python e utilize um cliente compatível com TLS (ou uma API gerida) quando a identificação JA3/JA4 estiver em jogo.
  • Alterne por sessão, não por solicitação. Mantenha um conjunto de cabeçalhos durante a validade do cookie, atualize o conjunto à medida que os navegadores são atualizados e combine-o com a rotação de proxy.

Perguntas frequentes

Por que razão as minhas solicitações continuam a ser bloqueadas depois de ter copiado os cabeçalhos exatos do Chrome?

Normalmente porque os cabeçalhos não são o único sinal. O seu handshake TLS (JA3/JA4), a ordenação de frames HTTP/2, a reputação do IP e a falta de cookies de sessão criam, todos eles, uma impressão digital do seu cliente de forma independente. Mesmo cabeçalhos com bytes perfeitos falham quando a pilha TLS subjacente diz «Python» em vez de «Chrome». Repita a solicitação com o cURL: se o cURL for bem-sucedido e o seu código não, a falha está abaixo da camada de cabeçalhos.

Com que frequência devo alternar as cadeias User-Agent e os conjuntos completos de cabeçalhos entre pedidos?

Alterne por sessão, não por pedido. Um visitante real mantém o mesmo navegador durante toda a visita, por isso uma sessão que troca User-Agent a meio do percurso é, por si só, suspeita. Mantenha um conjunto de cabeçalhos durante o tempo de vida do seu conjunto de cookies e, em seguida, escolha um novo para a próxima sessão. Atualize o conjunto subjacente a cada poucas semanas, à medida que o Chrome e o Firefox lançam novas versões estáveis.

Ainda preciso definir cabeçalhos HTTP se estiver a usar um navegador sem interface gráfica, como o Playwright ou o Puppeteer?

Sim, parcialmente. Um navegador sem interface gráfica envia cabeçalhos realistas automaticamente, incluindo Sec-CH-UA e Sec-Fetch-*, pelo que pode saltar a maior parte do trabalho manual. Ainda precisa de substituir o modo sem interface User-Agent (que muitas vezes inclui HeadlessChrome), definir um Accept-Language para a localização geográfica do seu proxy e desativar o navigator.webdriver sinalizador através de um plugin stealth ou de um sinalizador de inicialização.

Uma API de scraping gerida ou um proxy inteligente podem gerir cabeçalhos HTTP automaticamente por mim?

Sim. As APIs de scraping geridas e as redes de proxies furtivos selecionam um conjunto de cabeçalhos realista por alvo, associam-no a um IP residencial e a um perfil TLS, e alternam tudo em sincronia. Você envia o URL de destino, eles devolvem o HTML ou JSON. A contrapartida é o custo por pedido versus o tempo de engenharia necessário para construir e manter a sua própria pilha de cabeçalhos, proxies e impressões digitais.

Como posso saber se um bloqueio é causado por cabeçalhos, por IP ou por uma impressão digital TLS?

Isola uma variável de cada vez. Primeiro, repete a tua solicitação exata com curl --resolve a partir do mesmo IP; se o cURL for bem-sucedido, o problema está nos cabeçalhos ou na ordem do seu cliente HTTP. Em seguida, mude para um IP residencial diferente com os mesmos cabeçalhos; se o bloqueio desaparecer, o IP foi sinalizado. Se nenhuma das opções ajudar, o handshake TLS é o culpado mais provável.

Conclusão

A extração de cabeçalhos HTTP não é a parte mais glamorosa da criação de um scraper, mas é a que oferece o maior retorno com um mínimo de trabalho. Capture cabeçalhos reais do navegador, envie-os na ordem em que o navegador os utilizou e mantenha User-Agent, Sec-CH-UAe Accept-Language internamente consistentes, alterne por sessão em vez de por pedido e elimine os padrões da biblioteca que gritam automação. Esse conjunto de hábitos elimina a maioria dos 403 e 429 fáceis antes mesmo de recorrer a um proxy.

Para além disso, o ajuste manual chega a um impasse. Impressões digitais JA3/JA4, gestão de bots empresariais e grande simultaneidade empurram todo o trabalho para além da camada de cabeçalhos, e esse é o momento certo para parar de fazer tudo manualmente e deixar que um serviço gerido trate disso. Se a sua pilha de tecnologias estiver nesse ponto, a API Scraper da WebScrapingAPI gere cabeçalhos, perfis TLS, IPs residenciais e tentativas de repetição por trás de um único ponto de extremidade, para que possa manter a lógica de análise e abandonar a corrida às impressões digitais. Comece por aí quando os cabeçalhos manuais deixarem de ser a opção mais económica.

Sobre o autor
Raluca Penciuc, Desenvolvedor Full-Stack @ WebScrapingAPI
Raluca PenciucDesenvolvedor Full-Stack

Raluca Penciuc é programadora Full Stack na WebScrapingAPI, onde desenvolve scrapers, aperfeiçoa estratégias de evasão e procura formas fiáveis de reduzir a deteção nos sites-alvo.

Comece a construir

Pronto para expandir a sua recolha de dados?

Junte-se a mais de 2.000 empresas que utilizam a WebScrapingAPI para extrair dados da Web à escala empresarial, sem quaisquer custos de infraestrutura.