Skip to content

Arquitetura do MercoDocs Scraper

O MercoDocs usa Scrapy com scrapy-playwright para coletar documentação pública do Mercosul. O portal do Mercosul utiliza iframes e conteúdo dinâmico (JavaScript), exigindo renderização via browser.

start_requests()
parse_list(response) ← Página principal com iframe
├─ Localiza iframe de documentos.mercosur.int
├─ Itera pelos órgãos (dropdown #organo) [actas spider]
├─ Extrai linhas da tabela (headers + cells)
├─ Identifica detail_url e acta_urls
├─ Gerencia paginação (botão "next")
parse_details(response, item) ← Página de detalhes do documento
├─ Extrai metadados (tabelas, dt/dd, painéis)
├─ Extrai arquivos (links para PDFs, docs, etc.)
├─ Identifica URLs de atas
_extract_links_from_browser_url() ← Navegação Playwright
├─ Acessa URL da ata via page.goto()
├─ Tratamento de Cloudflare (retry com backoff)
├─ _extract_acta_structured() ← Dados da ata
│ ├─ Dados básicos (.box kv aprimorado: Versión, Fecha Versión)
│ ├─ Reunião (assistentes integral, datas, localização)
│ ├─ Arquivos da ata (links)
│ ├─ Sistematização (links)
│ └─ Anexos (tabela + modal "Ver Anexo")
│ └─ _extract_anexo_modal_structured()
│ └─ Documentos relacionados (links estruturados: Directivas, etc.)
└─ Recursão para links de anexo (depth ≤ 1)
BaseMercosurSpider (scraper/spiders/base.py)
├── Carregamento incremental (load_existing_data)
├── Log de falhas (log_failed_item)
├── Helpers de dedup (_append_arquivo, _append_detail)
├── Detecção (_is_document_candidate, _is_anexo_link, _is_challenge_page)
├── Parsing HTML (_extract_box_kv, _extract_links_from_box, _parse_link_meta)
├── Extração estruturada (_extract_acta_structured, _extract_anexo_modal_structured)
└── Navegação Playwright (_extract_links_from_browser_url)
├── MercosurActasSpider (mercosur_actas_y_anexos.py)
│ └── Multi-órgão (dropdown), simplified ver_detalles
├── MercosurDeclaracionesSpider (mercosur_declaraciones_presidenciales.py)
│ └── Declarações presidenciais
├── MercosurSpider (mercosur_comunicados_presidenciales.py)
│ └── Comunicados presidenciais (mais simples)
└── MercosurNormativaSpider (mercosur_normativa.py)
└── Normativa via API interna (CSRF + POST)

Todos os spiders produzem itens JSONL. A estrutura pode variar levemente por spider (ex: Atas foca na extração profunda), mas segue este padrão:

{
"source_list_url": "https://www.mercosur.int/documentos/...",
"detail_url": "https://documentos.mercosur.int/public/...",
"Órgano": "CMC (opcional, presente em actas)",
"Título": "Título do documento",
"Número": "01/2024",
"ver_detalles": {
"metadados": { "chave": "valor (opcional)" },
"arquivos": [
{ "url": "...", "descricao": "...", "texto_link": "..." }
],
"ver_actas": [
{
"acta_url": "...",
"dados_basicos": {
"Tipo": "Acta",
"Versión": "(Corrigendum 1)",
"Fecha Versión": "27/02/2026"
},
"reuniao": {
"Asistentes": "Órgão A / Órgão B | Depende de: X"
},
"arquivos_ata": [],
"sistematizacao": [],
"anexos": [
{
"numero": "IV",
"titulo": "Directivas aprobadas",
"ver_anexo": {
"dados_basicos": {},
"arquivos": [],
"documentos_relacionados": {
"texto": "...",
"links": [
{
"tipo": "Directiva",
"numero": "212/2025",
"titulo": "...",
"url": "...",
"texto_link": "Ver Directiva"
}
]
}
}
}
]
}
]
},
"access_attempts": [
{ "type": "ver_detalles", "url": "...", "has_challenge": false, "ok": true }
]
}

O portal do Mercosul usa Cloudflare. O scraper adota estas estratégias:

  1. Stealth: playwright-stealth para mascarar automação
  2. User-Agent real: Chrome 121 no settings.py
  3. Delays humanos: human_delay() e human_scroll() simulam comportamento real
  4. Retry com backoff: 3 tentativas com espera crescente (5s, 10s, 20s)
  5. Storage State: Permite reaproveitar cookies de sessão autenticada

Veja .env.example para a lista completa.