Práticas responsáveis de raspagem
Conformidade com robots.txt, cabeçalhos de agente do usuário, atrasos entre requisições e cache.
Práticas responsáveis de raspagem é uma aula grátis de AI Agents no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de AI Agents, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de AI Agents inclui 4 aulas no total.
Por que a raspagem responsável é importante
A raspagem da web pode sobrecarregar servidores, violar termos de serviço e fazer com que o IP do seu agente seja banido. Ferramentas de raspagem responsáveis respeitam limites de frequência, identificam-se e seguem as regras publicadas pelos sites.
Esta lição aborda as ferramentas e técnicas para fazer raspagem de maneira ética e sustentável.
Verificando robots.txt
Todo site pode publicar um arquivo robots.txt especificando quais caminhos os agentes automatizados podem ou não acessar. A biblioteca padrão do Python inclui urllib.robotparser para analisar esse arquivo.
Verifique sempre o robots.txt antes de fazer raspagem em um site.
import urllib.robotparser
rp = urllib.robotparser.RobotFileParser()
rp.set_url('https://example.com/robots.txt')
rp.read()
# Check if our bot can fetch a specific path
can_fetch = rp.can_fetch('MyAgent/1.0', 'https://example.com/public-data')
print(f'Can fetch: {can_fetch}') # True or False
cannot_fetch = rp.can_fetch('*', 'https://example.com/private/admin')
print(f'Admin allowed: {cannot_fetch}') # Often FalseConfigurando um agente do usuário descritivo
O cabeçalho HTTP User-Agent identifica quem está fazendo uma solicitação. Um agente do usuário honesto permite que os administradores do site saibam o que é o seu robô e como entrar em contato com você caso haja problemas. Disfarçar-se de navegador para evitar bloqueios gera preocupações éticas.
import httpx
headers = {
# Honest, descriptive User-Agent
'User-Agent': 'MyResearchBot/1.0 (contact: me@example.com; purpose: academic research)'
}
response = httpx.get(
'https://example.com/data',
headers=headers,
timeout=10.0
)
print(response.status_code)Limitando a taxa com time.sleep()
Enviar centenas de solicitações por segundo pode sobrecarregar um servidor e muitas vezes é considerado um ataque de negação de serviço. Adicione atrasos entre as solicitações usando time.sleep(). Use random.uniform() para tornar o atraso menos robótico e mais parecido com o comportamento humano.
import time
import random
import httpx
urls = [
'https://example.com/page/1',
'https://example.com/page/2',
'https://example.com/page/3'
]
for url in urls:
response = httpx.get(url, timeout=10.0)
print(f'Fetched {url}: {response.status_code}')
# Wait between 1 and 3 seconds before the next request
delay = random.uniform(1, 3)
print(f'Sleeping {delay:.1f}s...')
time.sleep(delay)Respeitando os cabeçalhos de nova tentativa
Quando um servidor responde com 429 Too Many Requests, geralmente inclui um cabeçalho Retry-After que especifica quantos segundos aguardar. Seu agente deve ler esse valor e respeitá-lo, em vez de tentar novamente imediatamente.
import time
import httpx
def fetch_with_retry(url: str) -> httpx.Response:
while True:
response = httpx.get(url, timeout=10.0)
if response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 5))
print(f'Rate limited. Waiting {retry_after}s...')
time.sleep(retry_after)
continue # retry
response.raise_for_status()
return responseArmazenando respostas em cache para evitar novas buscas
requests-cache armazena automaticamente respostas HTTP em cache no disco. Se o seu agente precisar buscar a mesma URL várias vezes (por exemplo, durante o desenvolvimento ou em novas execuções), as respostas armazenadas em cache serão retornadas instantaneamente sem acessar o servidor.
# pip install requests-cache
import requests_cache
# Install the cache globally — cached responses expire after 1 hour
requests_cache.install_cache(
'agent_cache',
backend='sqlite',
expire_after=3600 # seconds
)
import requests
# First call: fetches from network and caches
response = requests.get('https://api.example.com/data')
print(response.from_cache) # False
# Second call: returns cached result instantly
response2 = requests.get('https://api.example.com/data')
print(response2.from_cache) # TrueArmazenamento manual em cache baseado em arquivos com httpx
Se preferir não usar requests-cache, um cache simples baseado em arquivos funciona bem. Armazene as respostas como arquivos JSON identificados pelo hash da URL e recarregue-os se o arquivo ainda for recente o suficiente.
import hashlib
import json
import os
import time
import httpx
CACHE_DIR = '/tmp/agent_cache'
os.makedirs(CACHE_DIR, exist_ok=True)
def cached_get(url: str, ttl_seconds: int = 3600) -> dict:
key = hashlib.md5(url.encode()).hexdigest()
cache_file = os.path.join(CACHE_DIR, key + '.json')
if os.path.exists(cache_file):
age = time.time() - os.path.getmtime(cache_file)
if age < ttl_seconds:
with open(cache_file) as f:
return json.load(f)
response = httpx.get(url, timeout=10.0)
response.raise_for_status()
data = response.json()
with open(cache_file, 'w') as f:
json.dump(data, f)
return dataLendo os termos de serviço
Antes de fazer raspagem em qualquer site, leia os respectivos Termos de Serviço. Muitos proíbem explicitamente o acesso automatizado ou o uso comercial dos dados. Violar os Termos de Serviço pode resultar em medidas legais, não apenas em um bloqueio de IP.
Se existir uma API oficial, prefira-a sempre à raspagem do HTML — ela é mais rápida, mais estável e juridicamente mais segura.
Recuo exponencial após erros
Quando uma solicitação falhar, não tente novamente imediatamente. Use um recuo exponencial: aguarde 1 s, depois 2 s, depois 4 s etc. Isso evita sobrecarregar um servidor com dificuldades e é um padrão profissional em agentes de produção.
import time
import httpx
def fetch_with_backoff(url: str, max_retries: int = 4) -> dict:
for attempt in range(max_retries):
try:
response = httpx.get(url, timeout=10.0)
response.raise_for_status()
return response.json()
except (httpx.HTTPStatusError, httpx.RequestError) as e:
if attempt == max_retries - 1:
raise
wait = 2 ** attempt # 1, 2, 4, 8 seconds
print(f'Attempt {attempt+1} failed: {e}. Retrying in {wait}s...')
time.sleep(wait)
return {}Fazendo raspagem apenas do que você precisa
Minimize a carga no servidor buscando apenas o que o seu agente realmente precisa. Evite baixar páginas inteiras quando um pequeno endpoint de API retorna os mesmos dados. Use solicitações HEAD para verificar se um recurso foi alterado antes de buscar o corpo completo.
import httpx
def has_page_changed(url: str, last_etag: str = None) -> bool:
headers = {}
if last_etag:
headers['If-None-Match'] = last_etag
response = httpx.head(url, headers=headers, timeout=5.0)
if response.status_code == 304: # Not Modified
return False
new_etag = response.headers.get('ETag')
print(f'New ETag: {new_etag}')
return TrueResumo das regras para uma raspagem responsável
Uma lista de verificação rápida antes que seu agente faça raspagem em qualquer site:
- Verifique
robots.txte respeite as regras de desativação - Configure um
User-Agenthonesto e descritivo - Adicione atrasos aleatórios entre as solicitações (
time.sleep(random.uniform(1,3))) - Respeite os cabeçalhos
Retry-Afternas respostas 429 - Armazene as respostas em cache para evitar novas buscas desnecessárias
- Leia os Termos de Serviço do site
- Prefira APIs oficiais à raspagem de HTML quando disponíveis
Verificação de conhecimentos: raspagem responsável
Teste sua compreensão das práticas éticas e responsáveis de raspagem.
Recapitulação: práticas de raspagem responsável
Agora você tem um conjunto completo de ferramentas para fazer raspagem de maneira responsável:
robotparserpara verificar o que você tem permissão para acessar- Cabeçalhos
User-Agentdescritivos que identificam o seu robô time.sleep(random.uniform(1,3))entre as solicitaçõesrequests-cacheou armazenamento manual em cache para evitar buscas duplicadas- Recuo exponencial para o tratamento de erros
- Consciência jurídica: verifique sempre os Termos de Serviço
A raspagem responsável contribui para uma web mais saudável e mantém seus agentes em execução sem bloqueios.
Perguntas Frequentes
A aula “Práticas responsáveis de raspagem” é grátis?
Sim — o texto completo de “Práticas responsáveis de raspagem” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de AI Agents, atualize para CoddyKit PRO. O curso de AI Agents inclui 4 aulas no total.
O que vou aprender em “Práticas responsáveis de raspagem”?
Conformidade com robots.txt, cabeçalhos de agente do usuário, atrasos entre requisições e cache. Você pratica AI Agents com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar AI Agents?
Nenhuma experiência prévia é necessária. AI Agents no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.
Quanto tempo leva a aula “Práticas responsáveis de raspagem”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de AI Agents?
Sim. Cada aula de AI Agents inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Clientes HTTP para agentes: httpx e requests
- Analisando HTML com BeautifulSoup
- Lidando com paginação e conteúdo dinâmico
- Práticas responsáveis de raspagem