Files
TextNLPClassifierApp/specs/002-google-news-extractor/research.md
T
andreferraro 6e3d57619b 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
2026-08-20 11:50:16 -03:00

3.5 KiB

Research: Google News Headlines Extractor

1. Technical Decisions & Tradeoffs

Decision 1: Motor de Requisição e Scraping com foxcape em Modo Headless

  • Decision: Adotar o pacote foxcape com FoxcapeConfig(headless=True, humanize=False) como motor de requisição primário.
  • Rationale: foxcape integra Camoufox e BeautifulSoup com evasões de fingerprinting TLS, runtime JS e headers avançados, impedindo bloqueios (429/403/Captchas) frequentes do Google News. A configuração headless=True garante que a execução ocorra 100% em segundo plano sem abrir janelas gráficas no sistema.
  • Alternatives Considered:
    • curl_cffi + beautifulsoup4 manual: Boa alternativa, mas exige orquestração manual de impersonação de TLS e headers.
    • requests padrão: Alto risco de bloqueio anti-bot pelo Google News.
    • Foxcape padrão sem configuração (headless=False): Abre janela visual do Firefox indesejada em execuções CLI e servidores.

Decision 2: Endpoint RSS do Google News vs. Scraping de DOM

  • Decision: Utilizar o endpoint oficial de busca RSS do Google News: https://news.google.com/rss/search?q={query}&hl={hl}&gl={gl}&ceid={gl}:{hl}.
  • Rationale: Formato estruturado em XML padrão, com carregamento rápido e direto de todos os metadados necessários (title, link, pubDate, description), sem necessidade de lidar com seletores CSS voláteis da interface web renderizada.
  • Alternatives Considered:
    • Scraping direto da interface HTML do Google News (news.google.com/search): Classes CSS ofuscadas e alteradas frequentemente pelo Google, quebrando facilmente a extração.

Decision 3: Mapeamento de Idioma e Locale (hl, gl, ceid)

  • Decision: Tabela de mapeamento determinística com fallback dinâmico.
    • pt → hl=pt-BR, gl=BR, ceid=BR:pt-BR
    • es → hl=es-419, gl=AR, ceid=AR:es-419
    • en → hl=en-US, gl=US, ceid=US:en-US
    • de → hl=de, gl=DE, ceid=DE:de
    • fr → hl=fr, gl=FR, ceid=FR:fr
    • it → hl=it, gl=IT, ceid=IT:it
    • Customizado: se fornecido --locale MX, sobrescreve o gl e ajusta ceid={gl}:{hl}.
  • Rationale: Garante notícias contextualmente adequadas por país sem que o usuário precise memorizar os códigos técnicos internos do Google News.

Decision 4: Resolução de URLs do Google News via googlenewsdecoder

  • Decision: Resolver automaticamente as URLs intermediárias (news.google.com/rss/articles/CBMi...) para os links originais dos veículos de imprensa em lote com concurrent.futures.ThreadPoolExecutor(max_workers=5).
  • Rationale: Os links gerados pelo Google News contêm tokens RPC intermediários que dificultam a leitura e ingestão direta. A decodificação em lote resolve até 50 URLs em menos de 1 segundo sem sobrecarga.
  • Alternatives Considered:
    • Resolução via Playwright headless para cada link: Muito lenta para listas de 20 a 50 notícias (demora 30 a 60 segundos).
    • Manter apenas a URL do Google News: Prejudica o usuário e sistemas downstream que precisam do domínio e link real do portal de notícias.

Decision 5: Logging em Tempo Real no stderr e Segregação de Streams

  • Decision: Enviar mensagens de status ([INFO] ...) para sys.stderr e reservar sys.stdout exclusivamente para o JSON.
  • Rationale: Permite que o operador acompanhe o progresso em tempo real no terminal (Consultando..., Decodificando URLs..., Arquivo salvo...) sem quebrar a interoperabilidade com ferramentas de pipe como jq ou redirecionamentos de arquivo.