Metodologia, Auditoria de Sites de Candidatos, Eleições Gerais 2026

Última atualização: conforme data do commit no controle de versão. Autor: análise conduzida com apoio de assistente de IA (Claude), a pedido do responsável pelo repositório.

1. Objetivo

Verificar, para o universo de candidaturas registradas nas Eleições Gerais 2026, a hospedagem em território brasileiro dos sites próprios declarados à Justiça Eleitoral.

2. Base legal considerada

Este documento reproduz o entendimento da legislação tal como apresentado ao autor do projeto (inclusive via uma busca com resposta de IA, usada como ponto de partida). Não substitui parecer jurídico formal, antes de qualquer comunicação oficial ao TSE, recomenda-se validação por profissional do Direito Eleitoral quanto à redação exata vigente de cada dispositivo.

3. Fonte de dados

Toda a coleta usa exclusivamente a API pública do painel "Divulgação de Candidaturas e Contas Eleitorais" (https://divulgacandcontas.tse.jus.br/divulga/), a mesma que alimenta o site oficial de consulta do TSE. Não há uso de nenhuma base paga, vazada ou não pública.

Endpoints usados (descobertos por engenharia reversa das chamadas de rede feitas pela própria SPA oficial do TSE, navegando manualmente pela interface):

EndpointUso
GET /rest/v1/eleicao/eleicao-atual?idEleicao={id}Estrutura nacional: todas as UFs, cargos e contagem de candidatos
GET /rest/v1/candidatura/listar/{ano}/{uf}/{id}/{cargo}/candidatosLista de candidatos de um cargo/UF
GET /rest/v1/candidatura/buscar/{ano}/{uf}/{id}/candidato/{idCandidato}Detalhe do candidato, incl. campo sites (endereços declarados)

3.1. Obstáculo técnico, bloqueio de automação pelo WAF do TSE

O domínio divulgacandcontas.tse.jus.br (e também www.tse.jus.br e dadosabertos.tse.jus.br) está atrás de um WAF que retorna HTTP 403 "Access Denied" para qualquer cliente que não seja um navegador real renderizando a página, isso inclui curl, a biblioteca requests do Python, e também o Playwright/Selenium rodando em modo headless (mesmo com IP residencial brasileiro, mesmo mascarando navigator.webdriver).

Testes realizados (ver histórico do projeto) mostraram que:

Conclusão prática: o bloqueio não é por IP/rede, é por alguma característica de fingerprinting específica do modo headless do Chromium (comum em soluções de bot management como Akamai/Cloudflare Bot Manager). A solução adotada foi rodar um Chromium com interface gráfica (headless=False) e fazer as chamadas de API via fetch() dentro da própria página carregada, replicando exatamente o comportamento de um usuário navegando pelo site. Ver scripts/tse_client.py.

Essa exigência tem uma implicação prática importante: os crawlers deste projeto não podem rodar num servidor CI/CD puramente headless sem um display virtual (Xvfb ou equivalente), precisam de um ambiente com sessão gráfica disponível.

4. Etapa 1, descoberta de candidatos e sites declarados

Script: scripts/discover_candidatos.py

  1. Busca a estrutura nacional da eleição 2026 (28 "UEs": as 27 Unidades da Federação + "BR" para a chapa presidencial).
  2. Para cada combinação UF × cargo (governador, vice, senador, 1º e 2º suplentes, deputado federal, deputado estadual/distrital, e presidente/vice para "BR"), lista todos os candidatos.
  3. Para cada candidato, busca o detalhe completo e extrai o campo sites, a lista de endereços eletrônicos que o próprio candidato comunicou à Justiça Eleitoral (nos termos do art. 57-B, I).
  4. Salva incrementalmente em data/raw/candidatos_sites.csv, um registro por candidato. Execução é resumível: candidatos já presentes no CSV de saída são pulados numa nova execução.

Universo coberto: 20.965 candidaturas nacionais nas Eleições Gerais 2026 (contagem obtida diretamente da API do TSE em 15/09/2026).

5. Etapa 2, classificação e análise de hospedagem

Script: scripts/analisar_sites.py (usa site_classifier.py e hosting_analysis.py)

5.1. Classificação (site próprio vs. rede social vs. outros)

O campo sites do TSE é um campo de texto livre por candidato, mistura links de redes sociais (Instagram, Facebook, X/Twitter, TikTok, YouTube, Kwai, Threads, LinkedIn, Telegram, WhatsApp, Discord), agregadores de link (Linktree e similares), plataformas de financiamento coletivo (QueroApoiar, Vakinha etc.) e, eventualmente, um domínio próprio do candidato.

A regra de hospedagem no Brasil (art. 57-B) diz respeito ao "sítio do candidato", um domínio sobre o qual o candidato tem controle/escolha de hospedagem, não aos perfis hospedados por terceiros (Meta, Google, X etc.), cuja infraestrutura não é decisão do candidato. Por isso a etapa de classificação (site_classifier.py) separa essas categorias antes de aplicar a análise de hospedagem, evitando falsos positivos ("Instagram não hospedado no Brasil" não é uma violação imputável ao candidato).

5.2. Verificação de hospedagem no Brasil

Para cada "site próprio":

  1. Resolve o domínio via DNS para um endereço IP.
  2. Geolocaliza o IP via API pública gratuita (ip-api.com), obtendo país, ISP/organização e ASN.
  3. Marca hospedado_no_brasil = True se o código de país for BR.

Limitação crítica: geolocalização de IP não revela o servidor de origem quando o site está atrás de um CDN/proxy global (Cloudflare, Akamai, Fastly, Amazon CloudFront, Sucuri/Imperva etc.), o IP resolvido é o do ponto de presença (PoP) mais próximo do requisitante, não o do servidor real. Isso é extremamente comum em sites de campanha, já que Cloudflare oferece plano gratuito e proteção contra DDoS. Exemplo real encontrado durante o desenvolvimento deste projeto, lula.com.br resolve para um IP da Cloudflare geolocalizado no Canadá, o que, tomado ingenuamente, sugeriria hospedagem fora do Brasil, mas na verdade só reflete a rede de borda da Cloudflare, sem qualquer relação com onde o servidor de origem realmente está.

Por isso, hosting_analysis.py detecta a organização/ISP do IP contra uma lista de provedores conhecidos de CDN/proxy e, quando identificado, não afirma hospedado_no_brasil = False, marca o campo como indeterminado (None) e sinaliza atras_de_cdn_proxy com o nome do provedor. Só é reportado hospedado_no_brasil = False com confiança quando o IP resolvido pertence claramente a um provedor de hospedagem comum (não um CDN de borda) fora do Brasil. Mesmo assim, casos limítrofes precisam de checagem manual (ex.: histórico de DNS para tentar identificar a origem real por trás do CDN) antes de qualquer conclusão a ser comunicada ao TSE.

6. Limitações gerais do projeto

7. Reprodutibilidade

Todo o código está no repositório no GitHub. Os dados brutos e processados (CSV) ficam versionados em data/, permitindo auditoria externa de cada etapa. Ver README.md para instruções de execução.