Voltar ao blog

Como fazer scraping de sites de notícias sem bloqueios: configuração de proxy e contorno de proteção

Guia completo para configurar o scraping de sites de notícias: escolha do tipo de proxy, contorno de sistemas anti-bot, configuração de rotação de IP e exemplos de código em Python.

📅7 de março de 2026
```html

Sites de notícias são um dos recursos mais protegidos na internet. Cloudflare, limitação de taxa, bloqueios por IP — tudo isso torna o parsing de notícias um sério desafio técnico. Neste guia, vamos discutir como configurar corretamente proxies para coleta estável de dados de portais de notícias, qual tipo de proxy escolher para diferentes tarefas e como contornar os modernos sistemas de proteção.

Por que sites de notícias bloqueiam parsers

Portais de notícias são especialmente sensíveis à coleta automática de dados por várias razões. Em primeiro lugar, o conteúdo é seu principal ativo, que monetizam através de publicidade e assinaturas. O parsing em massa permite que concorrentes copiem materiais e reduz o tráfego único. Em segundo lugar, a alta carga de bots aumenta os custos com servidores e CDN.

Sites de notícias modernos utilizam proteção em múltiplas camadas:

  • Cloudflare e similares — verificam JavaScript, impressões TLS do navegador, padrões comportamentais
  • Limitação de taxa — limitam o número de solicitações de um único IP (geralmente 10-50 solicitações por minuto)
  • Bloqueio por User-Agent — banem cabeçalhos padrão de bibliotecas (Python-requests, curl)
  • CAPTCHA — exibem em caso de atividade suspeita
  • Geobloqueios — alguns portais de notícias estão disponíveis apenas de determinados países

Sinais típicos pelos quais sites de notícias detectam parsers: o mesmo IP faz muitas solicitações consecutivas, ausência de JavaScript, ordem não padrão dos cabeçalhos HTTP, velocidade de solicitações muito rápida (um humano não consegue abrir 10 páginas por segundo), ausência de cookies e referrer.

Importante: O parsing de sites de notícias está em uma zona cinzenta. Sempre verifique o robots.txt e os Termos de Serviço do recurso alvo. Para uso comercial dos dados, recomenda-se utilizar APIs oficiais ou firmar acordos de parceria.

Qual tipo de proxy escolher para parsing de notícias

A escolha do tipo de proxy depende da escala da tarefa, do orçamento e do nível de proteção dos sites-alvo. Vamos considerar três opções principais e sua aplicabilidade para parsing de notícias.

Tipo de proxy Velocidade Custo Quando usar
Proxies de data center Alta (50-100 ms) Baixa Sites sem Cloudflare, grande volume de dados, testes
Proxies residenciais Média (200-500 ms) Alta Sites com Cloudflare, proteção rigorosa, geotargeting
Proxies móveis Média (300-600 ms) Muito alta Máxima proteção, versões móveis de sites de notícias

Proxies de data center para parsing de notícias

Adequados para parsing de sites de notícias sem proteção séria: publicações regionais, blogs, pequenos portais de informação. Vantagens: alta velocidade (importante ao fazer parsing de centenas de fontes), baixo custo (é possível alugar um pool de 50-100 IPs), conexão estável.

Desvantagens: facilmente detectáveis por ASN (pertencimento a data center), frequentemente já estão na lista negra de grandes sites, não passam pelo Cloudflare Challenge em 70% dos casos. Use proxies de data center para parsing em massa de feeds RSS, sitemap.xml, endpoints de API ou para coleta de metadados (títulos, datas de publicação) sem carregar o conteúdo completo.

Proxies residenciais — o padrão ouro

Proxies residenciais são endereços IP de usuários domésticos reais, fornecidos por provedores de internet. Para sites de notícias, eles se parecem com visitantes normais, o que é crítico ao trabalhar com recursos protegidos.

Quando os proxies residenciais são obrigatórios: parsing de grandes portais de notícias (CNN, BBC, Reuters, RBK, Kommersant), sites atrás do Cloudflare ou proteção similar, coleta de dados de determinados países (geotargeting), sessões longas com autenticação. Proxies residenciais passam nos testes de JavaScript do Cloudflare, têm uma boa reputação de IP, suportam sessões fixas (fixação de IP por 10-30 minutos).

Dica prática: use proxies residenciais com rotação por tempo (sessões fixas), e não por solicitações. Por exemplo, um IP funciona por 10 minutos, coleta 20-30 artigos e depois muda. Isso parece mais natural do que mudar o IP a cada solicitação.

Proxies móveis para casos especiais

Proxies móveis utilizam IPs de operadoras móveis (MTS, Beeline, Tele2). Eles têm a máxima confiança, pois milhões de pessoas usam a internet móvel para ler notícias. Utilize-os para parsing de versões móveis de sites de notícias (geralmente têm proteção simplificada), sites com proteção extremamente rigorosa, páginas AMP do Google News.

Característica dos proxies móveis: o IP muda automaticamente com frequência (as operadoras móveis usam CGNAT), um IP pode ser compartilhado por centenas de usuários ao mesmo tempo, o que torna o bloqueio inútil. Desvantagem — alto custo, portanto, use-os pontualmente, apenas para os objetivos mais protegidos.

Contornando o Cloudflare e outros sistemas anti-bot

O Cloudflare é o principal inimigo dos parsers de sites de notícias. Cerca de 40% dos grandes portais de notícias usam o Cloudflare para proteção contra bots. Bibliotecas padrão (requests, urllib) não passam na verificação, pois o Cloudflare analisa a impressão TLS, a execução de JavaScript, a ordem dos cabeçalhos HTTP, padrões comportamentais.

Estratégias para contornar o Cloudflare

1. Navegadores headless (Selenium, Playwright, Puppeteer)

Emulam um navegador real com execução de JavaScript. O Cloudflare vê a impressão TLS correta do Chrome/Firefox e permite a solicitação. Desvantagens: lento (2-5 segundos por página), requer muitos recursos (RAM, CPU).

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

# Configuração do proxy para Selenium
chrome_options = Options()
chrome_options.add_argument('--proxy-server=http://username:password@proxy.example.com:8080')
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-blink-features=AutomationControlled')

driver = webdriver.Chrome(options=chrome_options)
driver.get('https://news-site.com/article')

# Aguardamos o carregamento do JavaScript
driver.implicitly_wait(10)
html = driver.page_source
driver.quit()

2. Bibliotecas com TLS-fingerprinting (curl_cffi, tls-client)

Imitam a impressão TLS de um navegador real sem iniciar um navegador headless. Funcionam de 10 a 20 vezes mais rápido que o Selenium, mas não executam JavaScript. Adequadas para sites com verificação básica do Cloudflare (sem JS-challenge).

from curl_cffi import requests

proxies = {
    'http': 'http://username:password@proxy.example.com:8080',
    'https': 'http://username:password@proxy.example.com:8080'
}

response = requests.get(
    'https://news-site.com/article',
    proxies=proxies,
    impersonate='chrome110'  # Imitando a impressão TLS do Chrome 110
)

print(response.text)

3. Serviços de contorno do Cloudflare (scraperapi, scrapingbee)

APIs pagas que contornam automaticamente o Cloudflare. Você envia a URL, eles retornam o HTML pronto. Vantagens: não é necessário entender os detalhes técnicos, rotação automática de proxies, tratamento de CAPTCHA. Desvantagens: caro em grandes volumes (a partir de $50/mês por 100K solicitações).

Cabeçalhos HTTP corretos

Mesmo com proxies, é importante enviar cabeçalhos corretos, caso contrário, o site detectará o bot por um User-Agent não padrão ou pela ausência de Accept-Language.

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Accept-Language': 'pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7',
    'Accept-Encoding': 'gzip, deflate, br',
    'DNT': '1',
    'Connection': 'keep-alive',
    'Upgrade-Insecure-Requests': '1',
    'Sec-Fetch-Dest': 'document',
    'Sec-Fetch-Mode': 'navigate',
    'Sec-Fetch-Site': 'none',
    'Cache-Control': 'max-age=0'
}

Atualize periodicamente o User-Agent — use versões atuais dos navegadores. Você pode verificar sua impressão em sites como whoer.net ou browserleaks.com.

Configuração de rotação de IP e gerenciamento de solicitações

A rotação correta de proxies é a chave para um parsing estável sem bloqueios. Sites de notícias monitoram a frequência de solicitações de um único IP, e exceder o limite resulta em banimento temporário ou permanente.

Tipos de rotação de proxies

Rotação por solicitações — cada solicitação passa por um novo IP. Adequada para parsing rápido de um grande número de sites diferentes, minimiza o risco de banimento por frequência de solicitações. Desvantagens: não é adequada para sites com sessões (cookies, autenticação), pode parecer suspeita para algumas proteções.

Rotação por tempo (sessões fixas) — um IP é usado por um tempo fixo (5-30 minutos), depois muda. Adequada para parsing de um único portal de notícias com várias páginas, mantém cookies e sessões, parece o comportamento de um usuário real. Recomendada para a maioria das tarefas de parsing de notícias.

Rotação por geolocalização — troca de IP de diferentes países/cidades. Usada para parsing de conteúdo geodependente (notícias regionais), contornando geobloqueios.

Frequência ideal de solicitações

Mesmo com rotação de proxies, não se deve fazer solicitações com muita frequência. Intervalos seguros para diferentes tipos de sites:

  • Grandes portais de notícias (RBK, Kommersant, Vedomosti) — 2-5 segundos entre solicitações de um único IP
  • Sites médios — 1-3 segundos
  • Blogs pequenos e publicações regionais — 0.5-1 segundo

Adicione atrasos aleatórios (randomization) para que o padrão de solicitações pareça natural:

import time
import random

def fetch_article(url, proxies):
    response = requests.get(url, proxies=proxies, headers=headers)
    
    # Atraso aleatório de 2 a 5 segundos
    delay = random.uniform(2, 5)
    time.sleep(delay)
    
    return response.text

Exemplo de rotação de proxies de um pool

Se você tem uma lista de proxies, pode implementar uma rotação simples manualmente:

import itertools
import requests

# Pool de proxies
proxy_list = [
    'http://user:pass@proxy1.example.com:8080',
    'http://user:pass@proxy2.example.com:8080',
    'http://user:pass@proxy3.example.com:8080',
]

# Criando um iterador infinito
proxy_pool = itertools.cycle(proxy_list)

def get_next_proxy():
    proxy = next(proxy_pool)
    return {'http': proxy, 'https': proxy}

# Uso
urls = ['https://news1.com/article', 'https://news2.com/article']

for url in urls:
    proxies = get_next_proxy()
    response = requests.get(url, proxies=proxies, headers=headers)
    print(f'Fetched {url} via {proxies["http"]}')

Exemplos de código: Python + Scrapy + proxies

Scrapy é um framework profissional para parsing que suporta proxies, middleware, rotação e tratamento de erros desde o início. Vamos considerar um exemplo completo de um parser de site de notícias com rotação de proxies.

Instalação de dependências

pip install scrapy scrapy-rotating-proxies

Configuração do Scrapy com proxies (settings.py)

# settings.py

# Ativando middleware para rotação de proxies
ROTATING_PROXY_LIST = [
    'http://user:pass@proxy1.example.com:8080',
    'http://user:pass@proxy2.example.com:8080',
    'http://user:pass@proxy3.example.com:8080',
]

DOWNLOADER_MIDDLEWARES = {
    'rotating_proxies.middlewares.RotatingProxyMiddleware': 610,
    'rotating_proxies.middlewares.BanDetectionMiddleware': 620,
}

# Configurações para contornar bloqueios
CONCURRENT_REQUESTS = 8  # Não mais que 8 solicitações simultâneas
DOWNLOAD_DELAY = 2  # Atraso de 2 segundos entre solicitações
RANDOMIZE_DOWNLOAD_DELAY = True  # Atraso aleatório

# User-Agent
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'

# Tentativas de repetição em caso de erros
RETRY_TIMES = 3
RETRY_HTTP_CODES = [500, 502, 503, 504, 408, 429]

Spider para parsing de notícias

# news_spider.py

import scrapy
from datetime import datetime

class NewsSpider(scrapy.Spider):
    name = 'news_parser'
    
    # Lista de sites de notícias para parsing
    start_urls = [
        'https://example-news.com/latest',
    ]
    
    def parse(self, response):
        # Fazendo parsing da lista de artigos na página principal
        articles = response.css('article.news-item')
        
        for article in articles:
            article_url = article.css('a.title::attr(href)').get()
            
            if article_url:
                # Acessando a página do artigo
                yield response.follow(article_url, callback=self.parse_article)
    
    def parse_article(self, response):
        # Extraindo dados do artigo
        yield {
            'url': response.url,
            'title': response.css('h1.article-title::text').get(),
            'date': response.css('time.published::attr(datetime)').get(),
            'author': response.css('span.author::text').get(),
            'text': ' '.join(response.css('div.article-body p::text').getall()),
            'tags': response.css('a.tag::text').getall(),
            'scraped_at': datetime.now().isoformat(),
        }

Executando o parser

# Salvando em JSON
scrapy crawl news_parser -o news_data.json

# Salvando em CSV
scrapy crawl news_parser -o news_data.csv

Parser simples com requests + BeautifulSoup

Se não for necessária uma lógica complexa, você pode usar a combinação requests + BeautifulSoup:

import requests
from bs4 import BeautifulSoup
import time
import random

# Configuração do proxy
proxies = {
    'http': 'http://user:pass@proxy.example.com:8080',
    'https': 'http://user:pass@proxy.example.com:8080'
}

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}

def parse_news_article(url):
    try:
        response = requests.get(url, proxies=proxies, headers=headers, timeout=10)
        response.raise_for_status()
        
        soup = BeautifulSoup(response.text, 'html.parser')
        
        # Extraindo dados (seletores dependem do site)
        title = soup.find('h1', class_='article-title').text.strip()
        date = soup.find('time', class_='published')['datetime']
        text = ' '.join([p.text for p in soup.find_all('p', class_='article-text')])
        
        return {
            'url': url,
            'title': title,
            'date': date,
            'text': text
        }
    
    except Exception as e:
        print(f'Erro ao fazer parsing de {url}: {e}')
        return None

# Fazendo parsing da lista de artigos
urls = [
    'https://news-site.com/article-1',
    'https://news-site.com/article-2',
]

for url in urls:
    article_data = parse_news_article(url)
    if article_data:
        print(article_data)
    
    # Atraso entre solicitações
    time.sleep(random.uniform(2, 4))

Erros comuns ao fazer parsing de notícias

Mesmo com a configuração correta do proxy, os parsers frequentemente recebem bloqueios devido a erros técnicos. Vamos discutir os problemas mais comuns e suas soluções.

Erro 1: Frequência de solicitações muito alta

Sintomas: HTTP 429 (Too Many Requests), banimentos temporários de IP, CAPTCHA. Causa: o parser faz 10-50 solicitações por segundo de um único IP. Solução: adicione atrasos (time.sleep()), use DOWNLOAD_DELAY no Scrapy, limite CONCURRENT_REQUESTS.

Erro 2: Uso de um único proxy para todas as solicitações

Sintomas: o proxy é rapidamente banido, mesmo com atrasos. Causa: um único IP faz centenas de solicitações a um site. Solução: use um pool de proxies com rotação, para sites grandes — no mínimo 10-20 proxies, para sessões fixas mude o IP a cada 10-15 minutos.

Erro 3: Ignorando cookies

Muitos sites de notícias definem cookies na primeira visita e verificam sua presença em solicitações subsequentes. A ausência de cookies é um sinal de bot. Solução: use requests.Session() para salvar cookies automaticamente, no Scrapy ative COOKIES_ENABLED = True.

import requests

session = requests.Session()
session.proxies = {'http': 'http://proxy.com:8080', 'https': 'http://proxy.com:8080'}

# Primeira solicitação — obtendo cookies
response1 = session.get('https://news-site.com')

# Solicitações subsequentes enviam cookies automaticamente
response2 = session.get('https://news-site.com/article')

Erro 4: Tratamento incorreto de redirecionamentos

Sites de notícias frequentemente usam redirecionamentos (301, 302) para versões móveis, subdomínios regionais, páginas AMP. Se o parser não seguir os redirecionamentos, ele recebe uma página vazia. Solução: em requests, isso está ativado por padrão (allow_redirects=True), verifique a URL final através de response.url.

Erro 5: Parsing de conteúdo dinâmico sem JavaScript

Muitos sites de notícias modernos carregam conteúdo através de JavaScript (React, Vue). A biblioteca requests obtém um esqueleto HTML vazio sem artigos. Solução: use Selenium/Playwright para executar JavaScript, verifique a aba Network nas DevTools — talvez os dados estejam sendo carregados através de API (pode-se fazer parsing diretamente do JSON).

Escalonamento: parsing de centenas de fontes

Quando é necessário fazer parsing não de um único site de notícias, mas de centenas de fontes simultaneamente (agregadores de notícias, monitoramento de mídia), é necessária uma arquitetura escalável.

Parsing distribuído com Scrapy Cloud

Scrapy Cloud (dos criadores do Scrapy) permite executar parsers na nuvem com escalonamento automático. Vantagens: não é necessário ter servidores próprios, rotação automática de proxies, monitoramento e logs. Custo: a partir de $9/mês pelo plano básico.

Filas de tarefas (Celery + Redis)

Para implantação autônoma, use o Celery — um sistema de tarefas distribuídas. Arquitetura: o Redis armazena a fila de URLs para parsing, vários workers (servidores) retiram tarefas da fila e fazem parsing em paralelo, cada worker usa seu próprio pool de proxies.

# tasks.py

from celery import Celery
import requests

app = Celery('news_parser', broker='redis://localhost:6379/0')

@app.task
def parse_article(url, proxy):
    proxies = {'http': proxy, 'https': proxy}
    response = requests.get(url, proxies=proxies, timeout=10)
    # Parsing e salvamento de dados
    return response.text

# Adicionando tarefas à fila
urls = ['https://news1.com/article', 'https://news2.com/article']
proxies = ['http://proxy1.com:8080', 'http://proxy2.com:8080']

for url in urls:
    proxy = random.choice(proxies)
    parse_article.delay(url, proxy)  # Execução assíncrona

Monitoramento e tratamento de erros

Ao fazer parsing em grande escala, o monitoramento é crucial: quantas URLs foram processadas, quantos erros, quais proxies foram banidos. Use o Sentry para rastreamento de erros em Python, Grafana + Prometheus para métricas (solicitações por segundo, tempo de resposta), logging no ELK Stack (Elasticsearch, Logstash, Kibana).

Dica: Crie um sistema de verificação automática de proxies. A cada 5-10 minutos, envie uma solicitação de teste através de cada proxy para whoer.net ou httpbin.org. Se o proxy não responder ou estiver banido — exclua-o do pool e adicione um novo.

Otimização de custos com proxies

Ao fazer parsing de centenas de fontes, os custos com proxies podem chegar a milhares de dólares por mês. Estratégias de otimização: use proxies de data center para sites simples (RSS, API), proxies residenciais — apenas para protegidos, cache de dados — não faça parsing do mesmo artigo duas vezes, faça parsing em horários não pico (à noite a carga nos sites é menor, menor risco de banimento).

Exemplo: para fazer parsing de 500 sites de notícias, você pode usar 80% de proxies de data center (para RSS e sites simples) e 20% de proxies residenciais (para os 100 principais portais protegidos). Isso reduzirá os custos em 3-5 vezes.

Conclusão

O parsing de sites de notícias é uma tarefa tecnicamente complexa, que requer a escolha correta de proxies, configuração de rotação e contorno de sistemas anti-bot. Principais conclusões do artigo: para portais de notícias protegidos (Cloudflare, limitação de taxa rigorosa), use proxies residenciais com sessões fixas; para parsing em massa de centenas de fontes, proxies de data center com rotação rápida são adequados; sempre adicione atrasos entre solicitações (2-5 segundos) e cabeçalhos HTTP corretos; para contornar o Cloudflare, use navegadores headless (Selenium, Playwright) ou bibliotecas com TLS-fingerprinting.

Ao escalar, use sistemas distribuídos (Celery, Scrapy Cloud) e monitore erros. Lembre-se de que o parsing deve ser ético — respeite o robots.txt, não crie carga excessiva nos servidores e respeite os direitos autorais sobre o conteúdo.

Se você planeja fazer parsing de grandes portais de notícias com proteção Cloudflare, recomendamos usar proxies residenciais — eles oferecem um alto nível de confiança e risco mínimo de bloqueios. Para tarefas onde a velocidade e o volume de dados são importantes (parsing de RSS, endpoints de API), proxies de data center são adequados.

```