# Etapa 05 — Pool de proxies e anti-bloqueio ## Objetivo Implementar o módulo `proxy/` e integrar rotação de proxies, delays humanizados e detecção de bloqueio ao motor de scraping da etapa 03, conforme `ARQUITETURA-SCHEMA.md` seção 6. ## Contexto Esta etapa assume que a tabela `proxies` já existe (etapa 02) e que o motor de scraping básico já funciona (etapa 03). Aqui o foco é blindar o motor contra bloqueio, não mudar a lógica de extração em si. ## Tarefas 1. Criar `proxy/ProxyPoolService`: - Selecionar um proxy `ativo` disponível, priorizando os com `ultima_utilizacao` mais antiga (distribuição de uso mais uniforme) - Marcar o proxy como "em uso" durante a execução de uma busca (para não ser selecionado concorrentemente por outra busca simultânea) - Ao final da busca, atualizar `ultima_utilizacao` 2. Criar `proxy/BloqueioDetector`: - Verificar, após cada navegação, se a página retornada é uma página de captcha/"unusual traffic" (por texto/seletor característico) - Se detectar bloqueio: incrementar `total_bloqueios` do proxy, mudar status para `degradado` (ou `bloqueado` se ultrapassar um limite configurável de bloqueios), e sinalizar para o orchestrator tentar novamente com outro proxy 3. Criar `proxy/BackoffService`: - Implementar backoff exponencial: se buscas consecutivas falharem por bloqueio, aumentar o intervalo de espera antes da próxima tentativa - Expor uma configuração de limite de buscas por hora por proxy (auto-throttling), configurável via `application.yml` 4. Criar `scraper/DelayHumanizadoService`: - Gerar intervalos aleatórios (dentro de faixas configuráveis) entre ações: digitação, scroll, troca de busca - Aplicar scroll em passos pequenos e variáveis, nunca um salto direto 5. Integrar fingerprint variável por sessão: - Configurar o contexto do Playwright (`BrowserContext`) com User-Agent, viewport e timezone variáveis por sessão de busca, coerentes com a região do proxy usado 6. Integrar todos os módulos acima ao `BuscaOrchestrator` da etapa 03, sem alterar a lógica de extração de dados em si 7. Atualizar `Busca` para gravar `proxy_id` usado e, em caso de erro, o `detalhe_erro` ## Critérios de aceite - [ ] Proxy é selecionado do pool e liberado corretamente ao final de cada busca - [ ] Bloqueio é detectado e o proxy correspondente é marcado como `degradado`/`bloqueado` automaticamente - [ ] Backoff exponencial ativa após falhas consecutivas, sem exigir intervenção manual - [ ] Delays e scroll não seguem padrão fixo (validar observando os logs/tempos entre execuções) - [ ] Fingerprint (User-Agent, viewport, timezone) varia entre sessões de busca - [ ] `busca.proxy_id` e `busca.detalhe_erro` são preenchidos corretamente