Cadastre-se e fale com o suporte para receber 100 verificações grátis.Cadastre-se grátis
Ilustração do fluxo de trabalho do EmailCheckPro para Verificação de e-mail em Python: verificando a entregabilidade a partir do seu código
Uma visão geral do fluxo de trabalho abordado neste artigo do EmailCheckPro.

Um guia em Python para verificação de e-mail: validação de formato local, verificações de entregabilidade para um ou vários endereços e tarefas em lote assíncronas.

A verificação de e-mail em Python consiste em duas partes. Valide o formato localmente com uma biblioteca mantida, como a email-validator, e depois verifique a entregabilidade chamando uma API a partir do seu código: o POST /api/v1/check do EmailCheckPro para um endereço, o POST /api/v1/batch-check para 1 a 100 endereços em uma única solicitação síncrona, ou uma tarefa em lote TXT/CSV consultada com um intervalo de pelo menos 30 segundos para arquivos completos. Cada verificação concluída informa se o endereço é Entregável ou Não entregável no momento da verificação, sendo que alguns endereços permanecem Indeterminado. A verificação não envia nada para o endereço.

Validação de formato vs. verificações de entregabilidade em Python

A maioria dos tutoriais em Python sobre este tópico mistura três técnicas: uma Regex, uma consulta DNS no domínio e um script que se comunica com o servidor de e-mail do destinatário. Eles respondem a perguntas diferentes, e a última opção traz riscos reais.

Técnica O que ela informa Limitação principal
Regex ou biblioteca de validação A entrada parece um endereço completo Não diz nada sobre a caixa de entrada
Consulta DNS de domínio O domínio parece configurado para receber e-mail Não diz nada sobre o endereço individual
Script de servidor de e-mail próprio Às vezes, se um destinatário é aceito Muitos servidores aceitam tudo ou recusam chamadores desconhecidos, e seu IP pode acabar em listas de bloqueio
API de verificação de entregabilidade Entregável ou Não entregável no momento da verificação, sem enviar nada Alguns endereços permanecem Indeterminado

Um pipeline prático em Python usa a primeira linha para cada entrada e a última linha para endereços importantes, como novos cadastros, importações ou uma lista prestes a receber um e-mail. Links de confirmação permanecem como uma etapa separada para consentimento e propriedade.

Passo 1: validar o formato com a email-validator

O pacote email-validator fornece mensagens de erro legíveis e uma forma normalizada do endereço, o que é um ponto de partida melhor do que um padrão escrito manualmente.

from email_validator import validate_email, EmailNotValidError

def screen_format(raw: str) -> str | None:
    try:
        result = validate_email(raw.strip(), check_deliverability=False)
        return result.normalized
    except EmailNotValidError:
        return None

Dois detalhes são importantes aqui:

  • Desative a etapa de DNS. Por padrão, a biblioteca consulta o DNS para verificar se o domínio pode receber e-mail. Esse é um sinal de nível de domínio, adiciona latência e a API de entregabilidade cobre a questão de forma mais direta, portanto, check_deliverability=False mantém essa camada rápida e offline.
  • Armazene o valor normalizado. A biblioteca coloca o domínio em minúsculas e normaliza o Unicode, o que evita que duplicatas entrem com grafias diferentes.

Uma entrada malformada deve retornar ao usuário ou ser enviada para uma lista de correção. Isso não é um resultado Não entregável, e a orientação da OWASP desaconselha padrões personalizados rígidos que rejeitam endereços válidos.

Passo 2: verificar a entregabilidade de um endereço

Para uma visualização de cadastro ou edição de perfil, chame o endpoint único a partir do código do servidor usando requests.

import os
import requests

API_BASE = os.environ["EMAILCHECK_API_BASE"]   # da documentação da API
session = requests.Session()
session.headers.update(build_headers())        # cabeçalhos de autenticação exatamente como documentado

def check_one(email: str) -> str:
    try:
        resp = session.post(f"{API_BASE}/api/v1/check",
                            data=build_check_body(email),   # corpo conforme documentado
                            timeout=(3.05, 10))
        return to_outcome(resp)  # "deliverable" | "undeliverable" | "undetermined"
    except requests.RequestException:
        return "not_completed"

build_headers, build_check_body e to_outcome são pequenos auxiliares escritos a partir da documentação da API do EmailCheckPro, para que a autenticação e os detalhes dos campos fiquem em um só lugar e correspondam ao contrato publicado. Retornar strings simples mantém o restante da base de código independente do formato de resposta.

Sempre defina um tempo limite (timeout). A documentação do Requests observa que as solicitações não expiram por padrão e que uma tupla define limites separados para conexão e leitura. Escolha valores de acordo com a tolerância da sua página; os números acima são exemplos.

Em seguida, ramifique em quatro estados:

  • Entregável: continue e salve a data da verificação.
  • Não entregável: solicite outro endereço.
  • Indeterminado: por exemplo, um endereço Catch-All. A API em tempo real retorna um código de negócio em vez de um resultado, e a verificação não é cobrada. Aceite com uma sinalização.
  • Não concluído: um tempo limite ou erro de rede. Aceite com uma sinalização e verifique novamente mais tarde a partir de uma fila.

Passo 3: verificar até 100 endereços por solicitação

Ferramentas administrativas, pequenas importações e tarefas noturnas geralmente contêm algumas dezenas ou centenas de endereços. O POST /api/v1/batch-check aceita de 1 a 100 endereços e responde na mesma solicitação, com os resultados na ordem de entrada.

def chunks(items, size=100):
    for start in range(0, len(items), size):
        yield items[start:start + size]

def check_many(emails: list[str]) -> dict[str, str]:
    outcomes = {}
    for group in chunks(emails):
        items = post_multi(group)          # POST /api/v1/batch-check
        for email, item in zip(group, items):
            outcomes[email] = item_outcome(item)  # sem resultado concluído -> "undetermined"
    return outcomes

Como a ordem é preservada, o zip mapeia cada item de volta ao endereço que o produziu. Cada item também informa se existe um resultado concluído. Apenas itens com um resultado positivo carregam Entregável ou Não entregável; qualquer outra coisa vai para o grupo Indeterminado ou Não concluído, nunca para Não entregável.

Remova duplicatas dos endereços normalizados antes de dividir em blocos, para que a mesma caixa de entrada não seja verificada duas vezes na mesma execução. Para algumas centenas de endereços sem código, a verificação em tempo real do painel lida com até 500 por vez.

Passo 4: executar uma tarefa em lote para arquivos inteiros

Quando a fonte é uma exportação, uma tarefa em lote é a melhor opção. Ela é assíncrona, portanto, execute-a a partir de um script, uma tarefa agendada ou um worker como o Celery, em vez de uma visualização web.

  1. Escreva o arquivo. Produza um TXT ou CSV com um endereço completo por linha. A escrita de arquivos nativa do Python é suficiente para TXT; o módulo csv ajuda quando você começa a partir de uma exportação de planilha.
  2. Envie e salve a referência da tarefa em seu banco de dados, com o nome do arquivo e a hora, para que um worker reiniciado possa retomar o processo.
  3. Consulte pacientemente em intervalos de 30 segundos ou mais:
import time

def run_bulk(path: str) -> str:
    task_ref = submit_file(path)           # POST /api/v1/bulk-tasks
    save_task(task_ref, path)              # sobreviver a reinicializações do worker
    while True:
        status = get_status(task_ref)      # GET /api/v1/bulk-tasks/{id}
        if status.finished:
            return status.result_link      # válido por 12 horas
        time.sleep(30)                     # nunca consulte mais rápido que isso
  1. Baixe e mescle. Uma tarefa bem-sucedida retorna um CSV em um link que dura 12 horas; consulte a mesma tarefa novamente para obter um novo link se ele expirar. Leia-o com csv.DictReader e junte pelo endereço de e-mail, não pelo número da linha, pois linhas inválidas e duplicadas são removidas durante a preparação.

O CSV de entregabilidade associa cada endereço ao seu resultado. Para listas do Gmail, Yandex e Mail.ru, a Verificação de avatar de e-mail em lote adiciona colunas de avatar; seu link de avatar pode estar vazio mesmo quando um avatar está presente. Os limites de tarefa por produto estão listados na documentação da API.

Mantendo a integração com Python confiável

  • Mantenha a chave fora do código. Leia-a de uma variável de ambiente ou armazenamento de segredos; ela consome o saldo da conta compartilhado por verificações web, chamadas de API, tarefas em lote e acesso MCP.
  • Reutilize uma Session. Ela mantém as conexões abertas entre as chamadas, o que ajuda em loops sobre blocos de vários endereços.
  • Registre datas. Um resultado descreve o endereço no momento da verificação, portanto, armazene a data e verifique novamente as linhas mais antigas antes de um envio grande.
  • Coloque novas tentativas na fila. Verificações Indeterminado, falhas e inválidas não são cobradas, mas novas tentativas imediatas raramente alteram o resultado. Agende-as com um atraso e um limite.
  • Teste as ramificações. Simule o auxiliar que chama a API e afirme que cada estado atinge a mensagem ou fila correta.
  • Notebooks e assistentes de IA: o endpoint MCP em https://emailcheckpro.com/mcp suporta verificações únicas e até 100 endereços; tarefas de arquivo permanecem na API REST.

Perguntas frequentes

Qual biblioteca Python é a melhor para validação de formato de e-mail?

A email-validator é uma escolha amplamente utilizada porque oferece mensagens de erro claras, suporta domínios internacionalizados e retorna um endereço normalizado. Independentemente da biblioteca que uma equipe escolha, o segredo é usar uma única fonte de verdade em formulários, importações e scripts, e desativar consultas DNS opcionais quando uma verificação de entregabilidade separada já cobre se o endereço pode receber e-mail.

Como as equipes podem verificar um grande CSV de endereços a partir do Python?

Escreva um arquivo TXT ou CSV com um endereço completo por linha, envie-o como uma tarefa em lote e consulte seu status a partir de um job em segundo plano com um intervalo de pelo menos 30 segundos. Quando for bem-sucedido, baixe o CSV de resultado único dentro de 12 horas, ou consulte a tarefa novamente para obter um novo link, e mescle os resultados de volta pelo endereço de e-mail.

Por que não verificar caixas de entrada com um script de servidor de e-mail Python caseiro?

Muitos servidores de e-mail aceitam todos os destinatários, atrasam chamadores desconhecidos ou bloqueiam conexões repetidas, portanto, os scripts retornam uma grande parcela de respostas inconclusivas e podem fazer com que o IP de envio seja colocado em listas de bloqueio. Uma verificação de entregabilidade hospedada retorna Entregável ou Não entregável sem enviar nada para o endereço, e marca os endereços que não consegue determinar como Indeterminado em vez de adivinhar.

Saiba mais

Escolha as informações do produto que se ajustam à próxima etapa do seu fluxo de trabalho.

Fontes