Empresa brasileira · Entrega automática · Suporte em português Seg a sex, 9h as 18h · PIX em reais
ProxyBox
Coleta de dados

Web scraping com Python na prática: do primeiro script ao coletor que aguenta

Como montar um coletor em Python com requests e BeautifulSoup, quando trocar por API, como respeitar limites e onde o proxy entra de verdade.

Por Redação ProxyBox · Editor técnico 6 min de leitura Python · web scraping · requests
Guia completo de Coleta de dados

Este artigo aprofunda um ponto do tema. Para a visão inteira, leia O que é web scraping: como funciona, quando é legal no Brasil e onde entra o proxy.

Um coletor em Python começa com cinco linhas que funcionam na primeira tentativa. O problema aparece depois: na semana três, quando o site muda uma div; no mês dois, quando começam a chegar respostas de erro; no mês seis, quando alguém pergunta de onde veio aquele dado.

Este artigo é sobre a segunda parte. Se você ainda está decidindo se precisa coletar, comece por o que é web scraping, que trata da base legal e de quando a fonte oficial resolve sem raspar nada.

Antes da primeira linha: existe API?

Continua sendo a pergunta que mais economiza trabalho. Um endpoint oficial devolve dado estruturado, não quebra quando o site muda de visual, consome uma fração do tráfego e não gera discussão sobre termos de uso.

No Brasil, boa parte do que as pessoas tentam raspar já está aberta: compras públicas, processos judiciais, cadastro de empresas, tabela de veículos. Vale conferir a fonte antes de escrever o coletor.

O par que resolve a maioria dos casos

Para página que já vem pronta no HTML, requests busca e BeautifulSoup extrai:

import requests
from bs4 import BeautifulSoup

sessao = requests.Session()
sessao.headers.update({
    "User-Agent": "MeuColetor/1.0 ([email protected])",
    "Accept-Language": "pt-BR,pt;q=0.9",
})

resposta = sessao.get("https://exemplo.com.br/produtos", timeout=20)
resposta.raise_for_status()

pagina = BeautifulSoup(resposta.text, "html.parser")
for item in pagina.select(".produto"):
    nome = item.select_one(".nome")
    preco = item.select_one(".preco")
    print(nome.get_text(strip=True), preco.get_text(strip=True))

Três detalhes desse trecho são o que separa script de coletor:

Session() em vez de requests.get solto. Reaproveita a conexão, o que reduz tempo e consumo. Em coleta grande, a diferença é grande.

User-Agent que identifica quem é. Um agente honesto, com forma de contato, é o que permite ao administrador do site falar com você em vez de simplesmente bloquear. É a diferença entre ser um parceiro chato e um problema anônimo.

timeout sempre. Sem ele, uma requisição pendurada trava o coletor por tempo indeterminado.

Selecione pelo que é estável

O motivo número um de coletor quebrado é seletor frágil. Classes geradas automaticamente mudam a cada publicação do site.

Prefira, nesta ordem: atributos de dado (data-produto-id), identificadores semânticos, estrutura de tabela, e só por último classe de estilo. E, muito antes disso, procure um bloco <script type="application/ld+json"> na página: muitos sites de comércio publicam ali o preço e o nome do produto em JSON limpo, prontos para ler sem nenhum seletor.

Devagar é mais rápido

A tentação é rodar tudo em paralelo. O resultado costuma ser bloqueio no primeiro dia.

import time, random

for url in urls:
    resposta = sessao.get(url, timeout=20)
    if resposta.status_code == 429:
        espera = int(resposta.headers.get("Retry-After", 60))
        time.sleep(espera)
        continue
    processa(resposta)
    time.sleep(random.uniform(1.5, 4.0))

O código acima faz duas coisas que quase todo coletor amador não faz: lê o Retry-After em vez de tentar de novo na hora, e varia o intervalo em vez de bater no relógio. O significado exato do 429 e a estratégia de espera crescente estão em erro 429 Too Many Requests.

Antes de qualquer coisa, leia o robots.txt do site e os termos de uso. Não é formalidade: é o que define se a sua coleta é aceitável.

Quando o navegador é necessário (e por que evitar)

Se o conteúdo só aparece depois do JavaScript rodar, requests não serve e entra um navegador automatizado. Antes de aceitar esse custo, abra as ferramentas de desenvolvedor na aba de rede e procure a chamada que a própria página faz: em muitos casos existe um endpoint JSON por trás, que devolve o mesmo dado sem renderizar nada.

Quando o navegador é inevitável, o custo muda de ordem: cada página carrega imagens, fontes e scripts, e o consumo de tráfego explode. A conta está em consumo de GB no scraping, e vale bloquear imagem e fonte no carregamento.

Onde o proxy entra de verdade

No começo, não entra. Coleta pequena, de páginas públicas, sai pela sua própria conexão sem problema nenhum.

Ele passa a fazer sentido em três situações:

  • O servidor conta por endereço. O volume cresceu e o limite passou a ser atingido. A saída é distribuir, sempre junto com a redução de frequência — nunca no lugar dela.
  • O conteúdo muda por origem. Preço, catálogo e resultado de busca variam conforme o país ou a cidade de quem pede. Aí um endereço brasileiro não é otimização: é requisito de correção do dado.
  • A coleta precisa manter login. Caso em que trocar de endereço no meio da sessão é justamente o que dispara alerta, e o correto é um endereço fixo.

A configuração em requests, httpx e aiohttp, com usuário e senha e o tratamento de senha com caractere especial, está no guia de proxy em Python. A escolha entre endereço fixo, por sessão ou por requisição está em proxy rotativo.

Vale medir antes de contratar: rode cem itens, meça o tráfego consumido e projete. A página de proxy para web scraping mostra os produtos por cenário.

O checklist do coletor que dura

  1. Conferiu se existe API ou dado aberto na fonte.
  2. Leu robots.txt e os termos de uso.
  3. Definiu base legal se houver dado pessoal.
  4. Usa Session, timeout e User-Agent identificável.
  5. Seleciona por atributo estável, não por classe de estilo.
  6. Respeita Retry-After e varia o intervalo.
  7. Registra a taxa de erro e avisa quando ela sobe.
  8. Só então avalia proxy, pelo tipo de limite que apareceu.

Coletor montado nessa ordem custa menos em tráfego, quebra menos quando o site muda e não coloca ninguém em situação difícil.

Perguntas frequentes

Qual biblioteca usar para web scraping em Python?
Para a maioria dos casos, requests para buscar e BeautifulSoup para extrair. Scrapy compensa quando há muitas páginas e regras de fila. Navegador automatizado só quando o conteúdo depende de JavaScript, porque custa muito mais em tempo e em tráfego.
Preciso de proxy para fazer scraping em Python?
No começo, quase nunca. O proxy entra quando o volume cresce e o servidor passa a contar requisições por endereço, ou quando o conteúdo muda conforme o país de origem.
Como evitar o erro 429 em Python?
Reduza a frequência, respeite o cabeçalho Retry-After quando ele vier e faça a espera crescer a cada nova falha. Só depois disso pense em distribuir as requisições entre endereços.
Web scraping com Python é legal?
A linguagem não muda a resposta. O que define é a fonte, os termos de uso do site, o tipo de dado coletado e a base legal quando há dado pessoal. Coletar página pública com moderação é diferente de copiar base protegida.

Quer aplicar isso na sua operação?

Preço público em reais, PIX e credenciais no painel em minutos. Se não souber qual tipo escolher, descreva a operação no WhatsApp — indicamos o mais barato que resolve.

Este conteúdo é informativo. Proxy é infraestrutura de rede: controlamos origem, exclusividade e geolocalização do IP. Aprovação ou restrição de contas depende também de comportamento de uso, impressão digital do navegador e das políticas internas de cada plataforma. Consulte a política de uso aceitável.

Suporte em português Fale no WhatsApp