feat(extractor): add Google News headlines extractor with Foxcape headless and URL resolution
- Add standalone CLI script scripts/extract_google_news.py for Google News RSS scraping - Integrate foxcape in headless mode as primary stealth anti-bot engine - Implement parallel article URL resolution using googlenewsdecoder and ThreadPoolExecutor - Support language and regional locale mapping (-l, --lang, --locale) - Implement real-time progress logging in stderr and --silent flag - Add unit, integration, and live E2E tests in tests/test_extract_google_news.py - Add full SpecKit documentation (specs/002-google-news-extractor/) - Create comprehensive README.md covering both NLP Classifier and Google News Extractor
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
# Implementation Plan: Google News Headlines Extractor
|
||||
|
||||
**Branch**: `002-google-news-extractor` | **Date**: 2026-08-20 | **Spec**: [spec.md](./spec.md)
|
||||
|
||||
**Input**: Feature specification from `specs/002-google-news-extractor/spec.md`
|
||||
|
||||
## Summary
|
||||
|
||||
Implementar um script CLI Python simples, robusto e autônomo ([`scripts/extract_google_news.py`](file:///c:/Users/aferr/Projects/AFTech/DunaMedia/TextNLPClassifierApp/scripts/extract_google_news.py)) para extrair manchetes do Google News RSS por assunto, idioma e região geográfica (*locale*). A solução utiliza a biblioteca [`foxcape`](https://pypi.org/project/foxcape/) em modo `headless=True` para garantir evasão anti-bot stealth, a biblioteca [`googlenewsdecoder`](https://pypi.org/project/googlenewsdecoder/) para resolver automaticamente as URLs intermediárias para os links finais dos portais de notícias em paralelo (`ThreadPoolExecutor`), e logging em tempo real via `sys.stderr`.
|
||||
|
||||
## Technical Context
|
||||
|
||||
**Language/Version**: Python >= 3.10 (3.11 / 3.12 / 3.13 / 3.14)
|
||||
**Primary Dependencies**:
|
||||
* `foxcape>=0.1.1` (scraping stealth & evasão anti-bot Camoufox em modo headless)
|
||||
* `googlenewsdecoder>=0.1.7` (decodificação de URLs intermediárias do Google News)
|
||||
* `selectolax>=0.3.27` (parser ultra-rápido de nós e atributos)
|
||||
* `beautifulsoup4>=4.12.0` (limpeza HTML e higienização de resumos/snippets)
|
||||
* `argparse` (parser CLI na biblioteca padrão)
|
||||
* `concurrent.futures` (resolução paralela em pool de threads)
|
||||
|
||||
**Storage**: N/A (stateless; saída via `stdout` ou arquivo especificado por flag `-o / --output`)
|
||||
**Testing**: `pytest` com fixtures de feeds RSS, testes unitários mockados e testes End-to-End (E2E) ao vivo
|
||||
**Target Platform**: Multiplataforma (Windows / Linux / macOS)
|
||||
**Project Type**: Standalone CLI script + módulo utilitário de scripts
|
||||
**Constraints**: Separação estrita de streams (`stdout` para JSON e `stderr` para logs informativos/erros)
|
||||
|
||||
## Architecture & Pipeline
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[SearchQuery CLI] --> B[Foxcape Headless Fetch]
|
||||
B --> C[parse_google_news_rss XML/HTML]
|
||||
C --> D[ThreadPoolExecutor URL Resolution]
|
||||
D --> E[ExtractionResult JSON Output]
|
||||
E --> F[stdout / File Output]
|
||||
```
|
||||
|
||||
1. **Ingestão & Validação**: `SearchQuery` valida palavra-chave não-vazia, idioma e limites de páginas (1 a 10).
|
||||
2. **Coleta RSS via Foxcape**: `Foxcape.fetch(url, config=FoxcapeConfig(headless=True))` busca o feed com evasões anti-bot.
|
||||
3. **Higienização XML/HTML**: `parse_google_news_rss` extrai nós, limpa resumos com `BeautifulSoup` e deduplica subtítulos redundantes.
|
||||
4. **Decodificação de Links**: `resolve_articles_urls` decodifica as URLs intermediárias do Google News em paralelo via `googlenewsdecoder`.
|
||||
5. **Emissão Estruturada**: JSON formatado no `stdout` ou gravado em arquivo (`--output`).
|
||||
|
||||
## Project Structure
|
||||
|
||||
### Documentation (this feature)
|
||||
|
||||
```text
|
||||
specs/002-google-news-extractor/
|
||||
├── spec.md # Especificação de requisitos da feature
|
||||
├── plan.md # Este plano de implementação
|
||||
├── research.md # Pesquisa técnica e decisões de design
|
||||
├── data-model.md # Entidades, DTOs e esquema JSON
|
||||
├── contracts/
|
||||
│ └── cli_contract.md # Contrato de argumentos CLI e I/O streams
|
||||
├── quickstart.md # Guia rápido de execução e validação
|
||||
└── checklists/
|
||||
├── requirements.md # Checklist de qualidade dos requisitos
|
||||
└── readiness.md # Checklist de prontidão e completude
|
||||
```
|
||||
|
||||
### Source Code
|
||||
|
||||
```text
|
||||
scripts/
|
||||
├── __init__.py # Identificador de pacote Python
|
||||
└── extract_google_news.py # Script CLI principal e lógica de extração
|
||||
|
||||
tests/
|
||||
├── fixtures/
|
||||
│ └── google_news_sample.xml # Amostra de feed RSS para testes offline
|
||||
└── test_extract_google_news.py# Testes unitários, integração e E2E ao vivo
|
||||
```
|
||||
Reference in New Issue
Block a user