# Operação do scraper e do banco ## 1. Arquitetura atual Estrutura esperada: ```text dfimoveis_data/ ├── dfimoveis.sqlite3 ├── photos/ │ └── / ├── raw/ │ ├── listing/ │ └── search/ └── browser-profile/ ``` O SQLite é a fonte estruturada. Fotos e HTML bruto são evidências complementares essenciais. --- ## 2. Funções já previstas no scraper - múltiplas pesquisas; - paginação com `pagina=N`; - requisições assíncronas; - concorrência controlada; - retentativas; - extração de páginas de anúncio; - download de todas as fotos; - armazenamento em SQLite; - observações históricas e mudanças; - HTML bruto comprimido; - marcação de anúncios removidos ou inativos; - fallback opcional por Playwright. Não simplificar o scraper de modo a perder histórico, fotos ou HTML bruto. --- ## 3. Cloudflare e 403 Foi confirmado desafio JavaScript do Cloudflare, com referências a `challenges.cloudflare.com` e `cf-ray` associado a GRU. Consequências: - `httpx` isolado não resolve desafio JavaScript; - trocar apenas User-Agent, aumentar retries ou reduzir concorrência não garante acesso; - o scraper deve tentar o cliente HTTP normal e usar Playwright como fallback quando houver 403 ou challenge. ### Playwright Configuração operacional: - Chromium visível no primeiro uso; - perfil persistente em `dfimoveis_data/browser-profile`; - reutilização de cookies e sessão; - resolução manual do challenge quando necessário; - depois, possibilidade de execução automatizada enquanto a sessão permanecer válida; - não usar modo headless no primeiro desafio. O objetivo é usar uma sessão legítima do navegador, não tentar derrotar ou explorar mecanismos de proteção. Respeitar termos aplicáveis, limites de requisição e carga do site. --- ## 4. User-Agent e sessão - usar `DFIMOVEIS_USER_AGENT` configurável; - preservar cookies e perfil local; - não gravar credenciais no repositório; - não compartilhar o diretório `browser-profile`; - incluir perfis e cookies no `.gitignore`. --- ## 5. Banco em análise Caminho: ```text dfimoveis_data/dfimoveis.sqlite3 ``` Abrir em modo somente leitura: ```python connection = sqlite3.connect( "file:dfimoveis_data/dfimoveis.sqlite3?mode=ro", uri=True, ) connection.execute("PRAGMA query_only = ON") ``` Não executar análises que escrevam no banco. Para transformações: - exportar Parquet/CSV; - criar `data/derived/analytics.sqlite`; - ou trabalhar em uma cópia consistente. --- ## 6. Snapshot de 22/07/2026 - 162 anúncios; - 637 observações históricas; - 7.457 registros de foto: 3.521 da galeria primária e 3.936 evidências legadas excluídas da análise; - Mangueiral: 95 anúncios acumulados, 78 ativos e 17 inativos; - Cruzeiro Novo: 67 acumulados, 63 ativos e 4 inativos; - coleta entre 13 e 22/07/2026; - a partir da execução 21, somente o Mangueiral permanece no arquivo de buscas. A cobertura é curta. Não inferir liquidez, sazonalidade ou tendência de preço. O histórico legado contém mudanças infladas por campos textuais instáveis. O schema v2 usa `stable_content_hash`, exclui ruído de interface e registra mudanças materiais futuras em `listing_change_events`. ### Migração v2 - backup anterior: `dfimoveis_data/backups/dfimoveis_before_schema_v2_20260722.sqlite3`; - migração idempotente: `python scripts/migrate_dfimoveis_schema_v2.py`; - nunca apagar fotos legadas: usar `v_primary_photos` ou `is_primary_gallery=1` nas análises; - usar `creci_normalized`, `address_normalized` e `neighborhood_normalized`, preservando os campos brutos; - consultar `v_listing_current_availability` e `v_open_data_quality_issues` para triagem; - futuras execuções registram buscas e configuração em `crawl_runs`. --- ## 7. Qualidade e deduplicação O scraper e a análise devem preservar três níveis: - anúncio; - observação histórica; - imóvel físico provável. Sinais de duplicidade: - imagens iguais ou muito semelhantes; - mesma implantação; - texto quase idêntico; - mesmo endereço; - mesmos quartos, área e preço; - anúncios de corretores diferentes. Não apagar duplicatas. Registrar grupos, confiança e anúncio de referência. --- ## 8. Disponibilidade e “vendido” Auditar: - primeira foto; - descrição; - status estruturado; - atividade na coleta. Estados sugeridos: - ativo; - inativo; - vendido visualmente indicado; - negócio fechado declarado; - republicado; - duplicata provável; - status desconhecido. Selo visual é evidência operacional. Não prova transação registral. --- ## 9. Observabilidade Cada execução deve registrar: - início e fim; - versão do scraper; - configuração; - pesquisas executadas; - páginas solicitadas e concluídas; - status HTTP; - desafios Cloudflare; - anúncios vistos; - fotos baixadas; - erros; - tempo de execução; - número de anúncios marcados inativos. Diferenciar falha de coleta de redução real de estoque. --- ## 10. Segurança operacional - não versionar banco, fotos, HTML bruto, cookies ou perfil de navegador; - não expor tokens e sessões; - limitar concorrência; - usar backoff; - evitar coleta agressiva; - não remover dados históricos; - manter backup antes de migrações; - testar mudanças em banco de desenvolvimento; - nunca migrar o banco original durante uma análise.