robotparser no Python: leia robots.txt

Publicado em: 20/08/2026
Tempo de leitura: 5 minutos
Código HTML em uma tela representando crawling responsável com robotparser no Python

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.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Desenvolvedor configurando servidor HTTPS e certificado TLS com Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    HTTPSServer: crie servidor HTTPS local no Python

    Aprenda HTTPSServer no Python para servir HTTPS localmente, configurar certificados, usar threads e entender limites de segurança.

    Ler mais

    Tempo de leitura: 5 minutos
    08/10/2026
    Arquivos protegidos representando extração segura de TAR com Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    tarfile extraction_filter: extraia TAR com segurança

    Aprenda tarfile extraction_filter no Python para extrair arquivos TAR com validação, segurança e controle de caminhos.

    Ler mais

    Tempo de leitura: 6 minutos
    08/10/2026
    Código Python exibindo avisos controlados com catch_warnings
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    catch_warnings: capture warnings em testes Python

    Aprenda catch_warnings no Python para capturar, testar e controlar avisos com filtros específicos e segurança.

    Ler mais

    Tempo de leitura: 5 minutos
    07/10/2026
    Código Python representando referências persistentes do pickle
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    pickle persistent_id: serialize referências externas

    Aprenda pickle persistent_id no Python para serializar referências externas com IDs estáveis, validação, segurança e compatibilidade.

    Ler mais

    Tempo de leitura: 5 minutos
    07/10/2026
    Código binário representando buffers e memória no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    memoryview.count: conte valores sem copiar buffers

    Aprenda memoryview.count no Python para contar bytes e valores em buffers sem cópias, com formatos, limites e boas práticas.

    Ler mais

    Tempo de leitura: 6 minutos
    06/10/2026
    Código Python com anotações de tipos
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    annotationlib: evite imports circulares em anotações

    Aprenda annotationlib no Python para ler anotações adiadas, evitar imports circulares e criar ferramentas de introspecção seguras.

    Ler mais

    Tempo de leitura: 6 minutos
    06/10/2026