Verificación de correo electrónico en Python: comprobación de entregabilidad desde su código
Valide el formato de direcciones con una biblioteca mantenida y compruebe la entregabilidad desde Python para una dirección, 100 a la vez o archivos completos.

Una guía de Python para la verificación de correo electrónico: validación de formato local, comprobaciones de entregabilidad para una o varias direcciones y tareas masivas asíncronas.
La verificación de correo electrónico en Python consta de dos partes. Valide el formato localmente con una biblioteca mantenida como email-validator y, a continuación, compruebe la entregabilidad llamando a una API desde su código: POST /api/v1/check de EmailCheckPro para una dirección, POST /api/v1/batch-check para 1–100 direcciones en una solicitud síncrona, o una tarea masiva TXT/CSV que se consulta como máximo cada 30 segundos para archivos completos. Cada comprobación completada informa si es Entregable o No entregable en el momento de la comprobación, y algunas direcciones permanecen como Indeterminado. La comprobación no envía nada a la dirección.
Validación de formato vs. comprobaciones de entregabilidad en Python
La mayoría de los tutoriales de Python sobre este tema mezclan tres técnicas: una Regex, una búsqueda DNS en el dominio y un script que se comunica con el servidor de correo del destinatario. Responden a preguntas diferentes y la última conlleva riesgos reales.
| Técnica | Qué le indica | Limitación principal |
|---|---|---|
| Regex o biblioteca de validación | La entrada parece una dirección completa | No dice nada sobre el buzón |
| Búsqueda DNS de dominio | El dominio parece configurado para recibir correo | No dice nada sobre la dirección individual |
| Script de servidor de correo propio | A veces si un destinatario es aceptado | Muchos servidores aceptan todo o rechazan llamadas desconocidas, y su IP puede terminar en listas de bloqueo |
| API de comprobación de entregabilidad | Entregable o No entregable en el momento de la comprobación, sin enviar nada | Algunas direcciones permanecen como Indeterminado |
Un flujo de trabajo práctico en Python utiliza la primera fila para cada entrada y la última fila para las direcciones importantes, como nuevos registros, importaciones o una lista que está a punto de recibir un envío. Los enlaces de confirmación siguen siendo un paso independiente para el consentimiento y la propiedad.
Paso 1: validar el formato con email-validator
El paquete email-validator ofrece mensajes de error legibles y una forma normalizada de la dirección, lo cual es un mejor punto de partida que un patrón escrito a mano.
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
Dos detalles son importantes aquí:
- Desactive su paso de DNS. Por defecto, la biblioteca consulta el DNS para ver si el dominio puede recibir correo. Esa es una señal a nivel de dominio, añade latencia y la API de entregabilidad cubre la pregunta de forma más directa, por lo que
check_deliverability=Falsemantiene esta capa rápida y sin conexión. - Almacene el valor normalizado. La biblioteca convierte el dominio a minúsculas y normaliza Unicode, lo que evita que se cuelen duplicados con diferentes grafías.
Una entrada mal formada debe devolverse al usuario o incluirse en una lista de corrección. No es un resultado No entregable, y la guía de OWASP desaconseja el uso de patrones personalizados estrictos que rechacen direcciones válidas.
Paso 2: comprobar la entregabilidad de una dirección
Para una vista de registro o una edición de perfil, llame al endpoint individual desde el código del servidor utilizando requests.
import os
import requests
API_BASE = os.environ["EMAILCHECK_API_BASE"] # de la documentación de la API
session = requests.Session()
session.headers.update(build_headers()) # encabezados de autenticación exactamente como se documenta
def check_one(email: str) -> str:
try:
resp = session.post(f"{API_BASE}/api/v1/check",
data=build_check_body(email), # cuerpo como se documenta
timeout=(3.05, 10))
return to_outcome(resp) # "deliverable" | "undeliverable" | "undetermined"
except requests.RequestException:
return "not_completed"
build_headers, build_check_body y to_outcome son pequeños asistentes escritos a partir de la documentación de la API de EmailCheckPro, por lo que los detalles de autenticación y campos residen en un solo lugar y coinciden con el contrato publicado. Devolver cadenas de texto simples mantiene el resto del código base independiente del formato de respuesta.
Establezca siempre un tiempo de espera (timeout). La documentación de Requests señala que las solicitudes no tienen tiempo de espera por defecto y que una tupla establece límites separados para la conexión y la lectura. Elija valores según la tolerancia de su propia página; los números anteriores son ejemplos.
A continuación, bifurque según cuatro estados:
- Entregable: continúe y guarde la fecha de la comprobación.
- No entregable: solicite otra dirección.
- Indeterminado: por ejemplo, una dirección Catch-All. La API en tiempo real devuelve un código de negocio en lugar de un resultado, y la comprobación no tiene coste. Acéptela con una marca.
- No completado: un tiempo de espera o error de red. Acéptela con una marca y vuelva a comprobarla más tarde desde una cola.
Paso 3: comprobar hasta 100 direcciones por solicitud
Las herramientas de administración, las importaciones pequeñas y los trabajos nocturnos a menudo contienen unas pocas docenas o cientos de direcciones. POST /api/v1/batch-check acepta de 1 a 100 direcciones y responde en la misma solicitud, con los resultados en el orden 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) # sin resultado completado -> "undetermined"
return outcomes
Debido a que se conserva el orden, zip asigna cada elemento a la dirección que lo produjo. Cada elemento también indica si existe un resultado completado. Solo los elementos con un resultado llevan Entregable o No entregable; cualquier otra cosa va al grupo de Indeterminado o No completado, nunca a No entregable.
Elimine los duplicados de las direcciones normalizadas antes de dividirlas en grupos, para que el mismo buzón no se compruebe dos veces en una misma ejecución. Para unos pocos cientos de direcciones sin código, la comprobación en tiempo real del panel de control gestiona hasta 500 a la vez.
Paso 4: ejecutar una tarea masiva para archivos completos
Una vez que la fuente es una exportación, una tarea masiva es la opción más adecuada. Es asíncrona, por lo que debe ejecutarse desde un script, un trabajo programado o un trabajador como Celery en lugar de una vista web.
- Escriba el archivo. Produzca un TXT o CSV con una dirección completa por línea. La escritura de archivos integrada de Python es suficiente para TXT; el módulo csv ayuda cuando se parte de una exportación de hoja de cálculo.
- Envíe y guarde la referencia de la tarea en su base de datos, con el nombre del archivo y la hora, para que un trabajador reiniciado pueda reanudarla.
- Consulte con paciencia a intervalos de 30 segundos o más:
import time
def run_bulk(path: str) -> str:
task_ref = submit_file(path) # POST /api/v1/bulk-tasks
save_task(task_ref, path) # sobrevive a reinicios del trabajador
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 más rápido que esto
- Descargue y combine. Una tarea exitosa devuelve un CSV en un enlace que dura 12 horas; vuelva a consultar la misma tarea para obtener un enlace nuevo si caduca. Léalo con
csv.DictReadery únalo por la dirección de correo electrónico, no por el número de fila, ya que las líneas no válidas y duplicadas se eliminan durante la preparación.
El CSV de entregabilidad empareja cada dirección con su resultado. Para listas de Gmail, Yandex y Mail.ru, la Verificación de avatar de correo masiva añade columnas de avatar; su enlace de avatar puede estar vacío incluso cuando hay un avatar presente. Los límites de tareas por producto se enumeran en la documentación de la API.
Mantener la integración con Python fiable
- Mantenga la clave fuera del código. Léala desde una variable de entorno o un almacén de secretos; consume el saldo de la cuenta compartido por comprobaciones web, llamadas a la API, tareas masivas y acceso MCP.
- Reutilice una
Session. Mantiene las conexiones abiertas entre llamadas, lo que ayuda en los bucles sobre grupos de varias direcciones. - Registre las fechas. Un resultado describe la dirección en el momento de la comprobación, así que guarde la fecha y vuelva a comprobar las filas antiguas antes de un envío grande.
- Ponga en cola los reintentos. Las comprobaciones Indeterminado, fallidas y no válidas no tienen coste, pero los reintentos inmediatos rara vez cambian el resultado. Prográmelos con un retraso y un límite.
- Pruebe las bifurcaciones. Simule el asistente que llama a la API y asegúrese de que cada estado llegue al mensaje o cola correctos.
- Cuadernos de notas y asistentes de IA: el endpoint MCP en
https://emailcheckpro.com/mcpadmite comprobaciones individuales y de hasta 100 direcciones; las tareas de archivo permanecen en la API REST.
Preguntas frecuentes
¿Qué biblioteca de Python es mejor para la validación de formato de correo electrónico?
email-validator es una opción muy utilizada porque ofrece mensajes de error claros, admite dominios internacionalizados y devuelve una dirección normalizada. Independientemente de la biblioteca que elija un equipo, la clave es utilizar una única fuente de verdad en formularios, importaciones y scripts, y deshabilitar las búsquedas DNS opcionales cuando una comprobación de entregabilidad independiente ya cubre si la dirección puede recibir correo.
¿Cómo pueden los equipos comprobar un CSV grande de direcciones desde Python?
Escriba un archivo TXT o CSV con una dirección completa por línea, envíelo como una tarea masiva y consulte su estado desde un trabajo en segundo plano no más de una vez cada 30 segundos. Cuando tenga éxito, descargue el CSV de resultados único en un plazo de 12 horas, o vuelva a consultar la tarea para obtener un enlace nuevo, y combine los resultados por dirección de correo electrónico.
¿Por qué no verificar buzones con un script de servidor de correo propio en Python?
Muchos servidores de correo aceptan a todos los destinatarios, retrasan a los emisores desconocidos o bloquean conexiones repetidas, por lo que los scripts devuelven una gran cantidad de respuestas no concluyentes y pueden hacer que la IP de envío sea incluida en listas de bloqueo. Una comprobación de entregabilidad alojada devuelve Entregable o No entregable sin enviar nada a la dirección, y marca las direcciones que no puede determinar como Indeterminado en lugar de adivinar.
Más información
Elija la información del producto que se ajuste al siguiente paso de su flujo de trabajo.