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.