O módulo urllib.robotparser interpreta arquivos robots.txt e responde se um user-agent pode acessar determinada URL. Ele é uma ferramenta importante para crawlers, indexadores, monitores e automações responsáveis, porque centraliza regras de Allow, Disallow, atraso entre requisições, taxa sugerida e sitemaps.
Respeitar robots.txt não é a única obrigação de um crawler. O arquivo não concede autorização, não substitui termos de uso, não protege conteúdo privado e não garante que uma coleta seja ética ou legal. Este guia mostra como usar RobotFileParser, tratar falhas de rede, atualizar regras, combinar limites e evitar sobrecarga.
O que é robots.txt?
Um site pode publicar /robots.txt na raiz da origem, por exemplo https://example.com/robots.txt. O arquivo associa grupos de regras a nomes de user-agent. Um crawler identifica-se e consulta se um caminho pode ser buscado.
User-agent: MinhaColetaBot
Disallow: /admin/
Allow: /admin/documentacao-publica/
Crawl-delay: 5
Sitemap: https://example.com/sitemap.xml
As regras são específicas da combinação de esquema, hostname e porta. O arquivo de um subdomínio não controla automaticamente outro. A sintaxe e o comportamento básico são padronizados pelo RFC 9309.
Primeiro uso de RobotFileParser
from urllib.robotparser import RobotFileParser
robots_url = "https://example.com/robots.txt"
parser = RobotFileParser(robots_url)
parser.read()
allowed = parser.can_fetch(
"MinhaColetaBot",
"https://example.com/artigos/python",
)
print(allowed)
read() baixa o arquivo e o envia ao parser. Para controlar timeout, tamanho, status e TLS com mais precisão, é melhor buscar o conteúdo usando um cliente HTTP e chamar parse(lines).
O guia de urllib.request no Python mostra como fazer downloads com timeout, limite e validação.
Parsing manual com limite
from urllib.request import Request, urlopen
from urllib.robotparser import RobotFileParser
MAX_ROBOTS_BYTES = 512 * 1024
USER_AGENT = "MinhaColetaBot/1.0 (+https://example.org/bot)"
request = Request(
"https://example.com/robots.txt",
headers={"User-Agent": USER_AGENT},
)
with urlopen(request, timeout=10) as response:
raw = response.read(MAX_ROBOTS_BYTES + 1)
if len(raw) > MAX_ROBOTS_BYTES:
raise ValueError("robots.txt excedeu o limite")
text = raw.decode("utf-8", errors="replace")
parser = RobotFileParser()
parser.set_url(request.full_url)
parser.parse(text.splitlines())
parser.modified()
O RFC define detalhes de encoding e tamanho que crawlers completos devem considerar. Para uma automação controlada, um limite conservador impede consumo excessivo por respostas inesperadas.
Escolha o user-agent correto
Use o mesmo identificador ao baixar o arquivo, consultar can_fetch() e fazer as requisições reais. Um nome claro ajuda administradores a entender o tráfego e entrar em contato.
USER_AGENT_TOKEN = "MinhaColetaBot"
HTTP_USER_AGENT = "MinhaColetaBot/1.0 (+mailto:bot@example.org)"
if not parser.can_fetch(USER_AGENT_TOKEN, target_url):
raise PermissionError("URL bloqueada pelo robots.txt")
Não use * apenas para obter regras mais permissivas quando existe um grupo específico para seu bot. Não imite Googlebot, navegador ou outro crawler.
can_fetch() e URLs completas
can_fetch(useragent, url) compara o caminho da URL com as regras aplicáveis. Passe uma URL devidamente construída e validada.
from urllib.parse import urljoin, urlsplit
base = "https://example.com/"
target = urljoin(base, "/produtos?page=2")
parts = urlsplit(target)
if parts.scheme != "https" or parts.hostname != "example.com":
raise ValueError("Destino inesperado")
if parser.can_fetch(USER_AGENT_TOKEN, target):
print("Pode buscar")
Veja o guia de urllib.parse no Python para evitar redirects e combinações de URL perigosas.
Crawl-delay
crawl_delay() devolve o número de segundos sugerido entre requisições, ou None quando não há uma diretiva válida.
delay = parser.crawl_delay(USER_AGENT_TOKEN)
if delay is None:
delay = 2.0
delay = max(delay, 1.0)
Mesmo sem diretiva, aplique uma taxa conservadora. O atraso deve ser coordenado entre todas as workers que acessam a mesma origem; dormir isoladamente em cada thread pode multiplicar a taxa total.
Request-rate
request_rate() retorna uma tupla com quantidade de requisições e janela em segundos.
rate = parser.request_rate(USER_AGENT_TOKEN)
if rate:
interval = rate.seconds / rate.requests
print(f"intervalo médio mínimo: {interval:.2f}s")
Uma implementação real deve usar token bucket ou outro limitador compartilhado. Combine crawl-delay, request-rate, respostas 429 e limites próprios, escolhendo a regra mais conservadora.
Sitemaps
site_maps() retorna URLs declaradas na diretiva Sitemap.
for sitemap_url in parser.site_maps() or []:
print(sitemap_url)
Sitemaps ajudam a descobrir páginas públicas sem percorrer todos os links, reduzindo tráfego. Ainda assim, valide cada URL, limite o tamanho, trate compressão e aplique as políticas de coleta.
Atualização e cache
mtime() informa quando o arquivo foi obtido, e modified() atualiza esse momento. Caches evitam baixar robots.txt antes de cada página.
import time
REFRESH_SECONDS = 6 * 60 * 60
if time.time() - parser.mtime() > REFRESH_SECONDS:
refresh_robots(parser)
Não mantenha regras indefinidamente. Use cache por origem, atualização periódica e sincronização para impedir que várias workers façam a mesma consulta simultaneamente.
Falhas ao obter robots.txt
A política para 404, 401, 403, timeout e erros 5xx deve ser definida explicitamente. Um crawler responsável costuma ser conservador diante de falha temporária: reduz ou pausa a coleta até confirmar as regras.
Não trate toda exceção como “permitido”. Isso transforma uma indisponibilidade momentânea em autorização ampla. Registre o status e aplique retry com backoff, sem sobrecarregar o servidor.
robots.txt não é segurança
As regras são públicas e voluntárias. Elas não impedem um cliente malicioso de acessar um caminho. Conteúdo privado precisa de autenticação e autorização no servidor. Não liste segredos esperando escondê-los; o arquivo pode revelar caminhos interessantes.
Redirects e mudança de origem
Ao seguir links ou redirects, recalcule a origem. Uma nova combinação de esquema, host ou porta exige outro parser e outro cache. Nunca aplique as regras de example.com a cdn.example.net.
Identificação, contato e logs
Use um user-agent com nome, versão e página ou e-mail de contato. Registre URL, decisão de robots, atraso aplicado, status, bytes e duração. Não registre dados pessoais coletados sem necessidade.
O artigo de logging no Python ajuda a estruturar logs e correlação.
Integração com um crawler
def may_fetch(url: str, origin_cache: dict[str, RobotFileParser]) -> bool:
origin = origin_from_url(url)
parser = origin_cache.get(origin)
if parser is None or is_stale(parser):
parser = load_robots(origin)
origin_cache[origin] = parser
return parser.can_fetch(USER_AGENT_TOKEN, url)
Depois da decisão, o crawler ainda precisa limitar concorrência, respeitar 429 e Retry-After, evitar ciclos, canonicalizar URLs, deduplicar conteúdo e proteger-se contra SSRF.
Web scraping responsável
O guia de web scraping com Python mostra extração de dados, paginação e práticas responsáveis. Antes de coletar, pergunte se existe API, feed ou exportação oficial que reduza carga e ambiguidade.
Erros comuns
Os erros frequentes são baixar robots a cada URL, consultar com user-agent diferente do usado no HTTP, ignorar crawl-delay, tratar falha como permissão, aplicar regras a outra origem, usar robots como autorização, não limitar o arquivo e executar muitas workers sem rate limiter compartilhado.
Boas práticas
Mantenha um parser por origem, faça cache com atualização, use identificação verdadeira, aplique a regra mais conservadora de taxa, valide sitemaps e redirects, limite respostas e pause diante de falhas. Respeite termos de uso, privacidade, direitos autorais e solicitações dos administradores mesmo quando o arquivo permite a URL.
Conclusão
urllib.robotparser oferece uma interface simples para interpretar robots.txt, mas um crawler responsável precisa de muito mais: cache, limites compartilhados, tratamento conservador de falhas, identificação, validação de URLs e decisões éticas. Use o módulo como uma camada de respeito operacional, não como autorização ou garantia jurídica.
Consulte a documentação oficial de urllib.robotparser e o RFC 9309 sobre o Robots Exclusion Protocol.







