feat(extractor): implement multi-engine article content extractor

- Added scripts/extract_article_contents.py for batch scraping with stealth Foxcape and triple extraction (Trafilatura, Newspaper4k, Readability)
- Created unit, integration, and E2E test suite in tests/test_extract_article_contents.py (90/90 passing)
- Updated specs/003-article-content-extractor and README.md with usage documentation and CLI contracts
- Passed ruff linting/formatting and mypy type checking cleanly
This commit is contained in:
2026-08-20 19:22:20 -03:00
parent 6e3d57619b
commit 6a45368cb0
85 changed files with 18345 additions and 3897 deletions
@@ -0,0 +1,132 @@
# Tasks: Article Content Multi-Engine Extractor
**Feature**: `003-article-content-extractor`
**Spec**: [`specs/003-article-content-extractor/spec.md`](file:///c:/Users/aferr\Projects\AFTech\DunaMedia\TextNLPClassifierApp\specs\003-article-content-extractor\spec.md)
**Plan**: [`specs/003-article-content-extractor/plan.md`](file:///c:/Users/aferr\Projects\AFTech\DunaMedia\TextNLPClassifierApp\specs\003-article-content-extractor\plan.md)
**Status**: Completed
---
## Phase 1: Setup & Dependencies
**Purpose**: Garantir as dependências do ecossistema e a estrutura inicial do projeto.
- [X] T001 Atualizar dependências em `requirements.txt` incluindo `trafilatura`, `newspaper4k` e `readability-lxml`
- [X] T002 [P] Validar importação e disponibilidade das bibliotecas `foxcape`, `trafilatura`, `newspaper` e `readability` no ambiente Python
---
## Phase 2: Foundational (Estruturas e Modelos Base)
**Purpose**: Estruturas de dados, contratos de erro e classes base necessárias para todas as histórias de usuário.
- [X] T003 Definir modelos de dados e dataclasses (`InputArticle`, `TrafilaturaData`, `NewspaperData`, `ReadabilityData`, `ExtractedArticle`, `ExtractionBatchReport`) em `scripts/extract_article_contents.py`
- [X] T004 Implementar funções utilitárias de I/O para leitura segura de JSON de busca e gravação com UTF-8 em `scripts/extract_article_contents.py`
- [X] T005 [P] Criar suíte de testes base e fixtures de mock de HTML em `tests/test_extract_article_contents.py`
**Checkpoint**: Estruturas base e fixtures prontas para início do desenvolvimento das histórias de usuário.
---
## Phase 3: User Story 1 - Extração Completa e Consolidada de Artigos em Lote (Priority: P1) 🌟 MVP
**Goal**: Implementar a navegação headless stealth via Foxcape e os 3 motores de extração (Trafilatura, Newspaper4k, Readability) gerando o JSON consolidado.
**Independent Test**: Executar contra um HTML de teste ou URL mockada e verificar a extração de texto, títulos, metadados, autores, imagens e sumários NLP em um JSON sem raw HTML.
### Testes da User Story 1 (TDD)
- [X] T006 [P] [US1] Criar testes unitários para o parser `TrafilaturaExtractor` em `tests/test_extract_article_contents.py`
- [X] T007 [P] [US1] Criar testes unitários para o parser `NewspaperExtractor` (NLP, autores, imagens, resumo) em `tests/test_extract_article_contents.py`
- [X] T008 [P] [US1] Criar testes unitários para o parser `ReadabilityExtractor` (HTML limpo, títulos) em `tests/test_extract_article_contents.py`
- [X] T009 [US1] Criar teste de integração para o pipeline completo de extração multimotor em `tests/test_extract_article_contents.py`
### Implementação da User Story 1
- [X] T010 [P] [US1] Implementar classe `TrafilaturaExtractor` para extração máxima de metadados, categorias, tags e texto limpo em `scripts/extract_article_contents.py`
- [X] T011 [P] [US1] Implementar classe `NewspaperExtractor` com suporte a herança de idioma e métodos NLP (`parse`, `nlp`) em `scripts/extract_article_contents.py`
- [X] T012 [P] [US1] Implementar classe `ReadabilityExtractor` para higienização e extração do miolo textual em `scripts/extract_article_contents.py`
- [X] T013 [US1] Implementar gerenciador de sessão persistente do `Foxcape` (`with Foxcape(...)`) com espera de DOM (`domcontentloaded`) em `scripts/extract_article_contents.py`
- [X] T014 [US1] Implementar orquestrador de lote e consolidação de resultados (descartando HTML bruto da memória) em `scripts/extract_article_contents.py`
**Checkpoint**: MVP funcional — O sistema já é capaz de ler uma lista de URLs, navegar com Foxcape, extrair pelos 3 motores e salvar o JSON consolidado.
---
## Phase 4: User Story 2 - Resiliência e Isolamento de Falhas por Artigo e Motor (Priority: P2)
**Goal**: Garantir tolerância a falhas para que timeouts, erros 404, bloqueios ou quebras em um único motor não abortem o lote.
**Independent Test**: Executar contra uma lista contendo URLs válidas e inválidas, confirmando que a inválida recebe status `failed` e as válidas continuam normalmente.
### Testes da User Story 2 (TDD)
- [X] T015 [P] [US2] Criar teste para isolamento de erro em falha de navegação (timeout / 404) em `tests/test_extract_article_contents.py`
- [X] T016 [P] [US2] Criar teste para isolamento de erro quando um único motor falha em `tests/test_extract_article_contents.py`
### Implementação da User Story 2
- [X] T017 [US2] Implementar tratamento de exceções de rede e status HTTP individual por artigo em `scripts/extract_article_contents.py`
- [X] T018 [US2] Implementar tratamento de exceções defensivo e encapsulamento de erro por motor de extração em `scripts/extract_article_contents.py`
**Checkpoint**: Sistema 100% resiliente contra instabilidades de portais e erros pontuais de parsing.
---
## Phase 5: User Story 3 - Controle de Execução via CLI e Feedback Visual (Priority: P3)
**Goal**: Interface de linha de comando completa com flags descritivas, suporte a limites (`--limit`), modo silencioso (`--silent`) e logs em `stderr`.
**Independent Test**: Executar `python scripts/extract_article_contents.py -i out/river_plate.json --limit 2` e verificar os logs em `stderr` e a criação de `out/river_plate_extracted.json`.
### Testes da User Story 3 (TDD)
- [X] T019 [P] [US3] Criar testes de CLI para parsing de argumentos (`--input`, `--output`, `--limit`, `--language`, `--silent`, `--timeout`) em `tests/test_extract_article_contents.py`
- [X] T020 [P] [US3] Criar teste de validação de segregação de streams (`stderr` vs `stdout`) e exit codes em `tests/test_extract_article_contents.py`
### Implementação da User Story 3
- [X] T021 [US3] Implementar parser CLI (`argparse`) com todas as opções e convenção padrão de saída (`<stem>_extracted.json`) em `scripts/extract_article_contents.py`
- [X] T022 [US3] Implementar sistema de logging visual em tempo real com emojis e status direcionado exclusivamente para `sys.stderr` em `scripts/extract_article_contents.py`
- [X] T023 [US3] Implementar controle de códigos de saída (0 para sucesso, 1 para argumento inválido, 2 para erro de inicialização) em `scripts/extract_article_contents.py`
**Checkpoint**: Todas as histórias de usuário (US1, US2, US3) implementadas e integradas.
---
## Phase 6: Polish & Validação Final
**Purpose**: Verificação ponta a ponta, documentação e conformidade.
- [X] T024 [P] Executar suíte completa de testes automatizados com `pytest`
- [X] T025 Executar validação real de ponta a ponta contra `out/river_plate.json` gerando `out/river_plate_extracted.json`
- [X] T026 [P] Atualizar documentação de uso no `README.md`
- [X] T027 Executar `graphify update .` para manter o grafo de conhecimento do repositório sincronizado
---
## Dependencies & Execution Order
```mermaid
flowchart TD
P1[Phase 1: Setup & Dependencies\n T001, T002] --> P2[Phase 2: Foundational\n T003, T004, T005]
P2 --> P3[Phase 3: User Story 1 MVP\n T006-T014]
P3 --> P4[Phase 4: User Story 2 Resiliência\n T015-T018]
P4 --> P5[Phase 5: User Story 3 CLI & Logs\n T019-T023]
P5 --> P6[Phase 6: Polish & Validação\n T024-T027]
```
### Oportunidades de Execução Paralela
- **Phase 1**: `T002` pode rodar em paralelo após `T001`.
- **Phase 3 (Testes & Parsers)**: `T006`, `T007`, `T008` (testes unitários) e `T010`, `T011`, `T012` (implementações dos 3 parsers) podem ser desenvolvidos em paralelo por atuarem em classes isoladas.
- **Phase 4 & 5 (Testes)**: `T015`, `T016`, `T019`, `T020` podem ser implementados em paralelo antes das respectivas integrações no CLI.
---
## Implementation Strategy
### MVP First (User Story 1 Only)
1. Completar Fase 1 (Setup) e Fase 2 (Foundational).
2. Implementar Fase 3 (User Story 1).
3. **Validar MVP**: Testar extração de 1 artigo local com sucesso.
### Entrega Incremental
1. Setup + Foundational → Base pronta.
2. User Story 1 → Tripla extração funcional (MVP).
3. User Story 2 → Resiliência total contra falhas externas.
4. User Story 3 → Interface CLI rica e ergonômica.
5. Polish → Testes 100% passando e validação real em lote.