- 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
3.5 KiB
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
foxcapecomFoxcapeConfig(headless=True, humanize=False)como motor de requisição primário. - Rationale:
foxcapeintegra 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çãoheadless=Truegarante que a execução ocorra 100% em segundo plano sem abrir janelas gráficas no sistema. - Alternatives Considered:
curl_cffi+beautifulsoup4manual: Boa alternativa, mas exige orquestração manual de impersonação de TLS e headers.requestspadrã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.
- Scraping direto da interface HTML do Google News (
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-BRes→hl=es-419,gl=AR,ceid=AR:es-419en→hl=en-US,gl=US,ceid=US:en-USde→hl=de,gl=DE,ceid=DE:defr→hl=fr,gl=FR,ceid=FR:frit→hl=it,gl=IT,ceid=IT:it- Customizado: se fornecido
--locale MX, sobrescreve ogle ajustaceid={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 comconcurrent.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] ...) parasys.stderre reservarsys.stdoutexclusivamente 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 comojqou redirecionamentos de arquivo.