Como evitar captchas no scraping (sem quebrar as regras)
A maioria dos captchas durante o scraping é uma reação a um tráfego que parece automatizado. A forma mais barata de lidar com eles é parar de disparar esses captchas. Isso significa primeiro procurar uma fonte de dados legítima, verificar o que as regras do site permitem, enviar menos requisições e mais espaçadas, e não buscar a mesma página duas vezes. Resolver o captcha é o plano B para os casos que você não consegue evitar, não o plano principal.
Procure primeiro uma API ou feed oficial
Muitos sites que sofrem scraping já oferecem uma forma de obter os mesmos dados sem captcha: uma API pública, uma exportação de dados, um feed RSS ou sitemap, ou um programa de parceria. Uma fonte oficial é mais confiável, tem menos chance de mudar sem aviso e dá ao dono do site controle sobre como os dados são usados. Procure por:
- uma seção para desenvolvedores ou API no rodapé do site,
- o
sitemap.xmlcom a lista de páginas, - links RSS ou Atom no
<head>da página, - uma página de "dados" ou "download" para exportações em massa.
Se alguma dessas opções atender à sua necessidade, use-a. Você evitará a maioria dos captchas simplesmente por não solicitar HTML.
Respeite o robots.txt e o intervalo que ele pede
O robots.txt informa quais caminhos os clientes automatizados podem acessar e, às vezes, quanto tempo esperar entre as requisições. A biblioteca padrão do Python pode lê-lo para você:
import time
from urllib.robotparser import RobotFileParser
import requests
USER_AGENT = "ExampleBot/1.0 (+https://example.com/bot)"
parser = RobotFileParser()
parser.set_url("https://example.com/robots.txt")
parser.read()
delay = parser.crawl_delay(USER_AGENT) or 5 # usa 5 segundos como valor conservador padrão
urls = [
"https://example.com/products?page=1",
"https://example.com/products?page=2",
]
last_request = 0.0
for url in urls:
if not parser.can_fetch(USER_AGENT, url):
print("skipped by robots.txt:", url)
continue
wait = delay - (time.monotonic() - last_request)
if wait > 0:
time.sleep(wait)
resp = requests.get(url, headers={"User-Agent": USER_AGENT}, timeout=30)
last_request = time.monotonic()
print(url, resp.status_code)
Se o robots.txt proibir um caminho, a resposta honesta é deixá-lo de lado ou pedir autorização ao dono. Contornar isso com um navegador não muda o que o site pediu.
Desacelere e espalhe as requisições
Um ritmo constante e moderado raramente dispara um captcha, enquanto uma rajada quase sempre dispara. Alguns hábitos fazem muita diferença:
- Defina uma taxa de requisições por site e mantenha-a, em vez de rodar na velocidade máxima.
- Adicione um jitter aleatório para que o intervalo não seja perfeitamente regular.
- Pare e espere um pouco quando vir um 429 ou uma página de captcha.
- Rode os jobs em horários de baixo movimento se a carga do site for uma preocupação.
Use cache e não busque de novo
Cada requisição que você não faz é uma requisição que o site não precisa atender. Guarde as páginas que você busca com a data e um hash do corpo, e só busque de novo quando o conteúdo provavelmente tiver mudado. Requisições condicionais com os cabeçalhos If-Modified-Since ou ETag permitem que o servidor responda "não modificado" de forma barata, quando ele oferece suporte a isso.
Reaproveite sessões e envie cabeçalhos comuns
Uma sessão que mantém os cookies entre as requisições se comporta mais como um visitante do que um script que começa do zero toda vez. Use requests.Session() para cada site e envie um User-Agent claro e honesto, que identifique seu bot e um contato. Não se passe por um navegador para burlar uma regra. Se um site precisar de JavaScript para mostrar o conteúdo, use uma ferramenta de navegador apenas para essas páginas e mantenha os mesmos limites de taxa.
Quando um captcha ainda aparecer
Alguns sites vão mostrar um captcha não importa o quanto você se comporte com cuidado. Detecte isso no código e pare aquele job, em vez de martelar a página. A detecção e a resolução opcional para o PopularCaptcha estão explicadas em captchas em web scraping.
Planeje o crawl antes de começar
Um crawl que busca tudo todos os dias é a forma mais fácil de disparar um captcha. Planeje o trabalho primeiro:
- Priorize. Decida quais páginas mudam com frequência e quais raramente mudam. Faça o crawl das frequentes com mais vezes e das demais com menos.
- Use as datas do sitemap. Muitos sitemaps incluem um valor
lastmod. Pule as URLs que não mudaram desde a sua última visita. - Faça crawl incremental. Guarde a última busca bem-sucedida de cada URL e retome dali, em vez de recomeçar da página um depois de uma falha.
- Distribua a carga. Divida uma lista grande em lotes e rode-os ao longo do dia, não todos de uma vez.
Um plano assim reduz o número de requisições, que é a maior alavanca que você tem.
Registre o plano em um arquivo de configuração curto ou em uma tabela: os sites, as seções, o intervalo de atualização e o orçamento diário de requisições de cada um. Quando o orçamento acabar, o job para até a próxima janela. Tratar o orçamento como um limite rígido, e não como uma sugestão, é o que impede o crawler de passar para o padrão de tráfego que dispara captchas. Revise o orçamento a cada poucas semanas, porque um site que cresce também pode crescer o tráfego, e o que era educado no trimestre passado pode não ser educado agora.
Faça scraping com responsabilidade
- Verifique o
robots.txte os termos de uso antes de começar e respeite o que eles dizem. - Mantenha a taxa de requisições baixa e pare quando o site sinalizar que está com dificuldades.
- Não colete dados pessoais sem motivo para tê-los, e apague-os quando não precisar mais.
- Não republique conteúdo protegido por direitos autorais em massa. Use os dados para análise, comparação ou no seu próprio produto, e dê crédito à fonte quando for apropriado.
- Entre em contato com o dono do site se precisar de um volume maior. Ele pode oferecer um feed.