Зарегистрируйтесь и обратитесь в поддержку, чтобы получить 100 бесплатных проверок.Зарегистрироваться бесплатно
Иллюстрация процесса EmailCheckPro к статье «Проверка email на Python: проверка доставляемости из вашего кода»
Наглядная схема процесса, рассматриваемого в этой статье EmailCheckPro.

Руководство по проверке email на Python: локальная проверка формата, проверка доставляемости для одного или нескольких адресов, а также асинхронные пакетные задачи.

Проверка email на Python состоит из двух этапов. Сначала выполните локальную проверку формата с помощью поддерживаемой библиотеки, такой как email-validator, а затем проверьте доставляемость, вызвав API из вашего кода: POST /api/v1/check в EmailCheckPro для одного адреса, POST /api/v1/batch-check для 1–100 адресов в одном синхронном запросе или пакетную задачу (TXT/CSV), опрашиваемую не чаще чем раз в 30 секунд для целых файлов. Каждая завершенная проверка сообщает, является ли адрес доставляемым или недоставляемым на момент проверки; некоторые адреса остаются в статусе Не определено. Проверка не отправляет никаких сообщений на адрес.

Проверка формата против проверки доставляемости на Python

Большинство руководств по Python на эту тему смешивают три метода: регулярные выражения (Regex), DNS-запрос к домену и скрипт, который взаимодействует с почтовым сервером получателя. Они отвечают на разные вопросы, причем последний метод несет в себе реальные риски.

Метод Что он показывает Основное ограничение
Regex или библиотека валидации Ввод выглядит как полный адрес Ничего не говорит о почтовом ящике
DNS-запрос домена Домен настроен на получение почты Ничего не говорит о конкретном адресе
Самописный скрипт почтового сервера Иногда — принимается ли получатель Многие серверы принимают всё подряд или отказывают неизвестным отправителям, а ваш IP может попасть в черные списки
API проверки доставляемости Доставляемый или Недоставляемый на момент проверки, без отправки сообщений Некоторые адреса остаются в статусе Не определено

Практический конвейер на Python использует первую строку для каждого ввода, а последнюю — для важных адресов, таких как новые регистрации, импортированные данные или список перед рассылкой. Ссылки подтверждения остаются отдельным шагом для получения согласия и подтверждения владения.

Шаг 1: проверка формата с помощью email-validator

Пакет email-validator предоставляет понятные сообщения об ошибках и нормализованную форму адреса, что является лучшей отправной точкой, чем написанный вручную шаблон.

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

Здесь важны две детали:

  • Отключите DNS-шаг. По умолчанию библиотека делает DNS-запрос, чтобы узнать, может ли домен принимать почту. Это сигнал уровня домена, он увеличивает задержку, а API доставляемости отвечает на этот вопрос более прямо, поэтому check_deliverability=False позволяет этому слою работать быстро и локально.
  • Сохраняйте нормализованное значение. Библиотека приводит домен к нижнему регистру и нормализует Unicode, что предотвращает появление дубликатов с разным написанием.

Некорректный ввод должен быть возвращен пользователю или отправлен в список на исправление. Это не является результатом Недоставляемый, и рекомендации OWASP советуют избегать строгих пользовательских шаблонов, которые отклоняют валидные адреса.

Шаг 2: проверка доставляемости для одного адреса

Для формы регистрации или редактирования профиля вызывайте одиночный эндпоинт из серверного кода с помощью requests.

import os
import requests

API_BASE = os.environ["EMAILCHECK_API_BASE"]   # из документации API
session = requests.Session()
session.headers.update(build_headers())        # заголовки аутентификации в точности как в документации

def check_one(email: str) -> str:
    try:
        resp = session.post(f"{API_BASE}/api/v1/check",
                            data=build_check_body(email),   # тело запроса как в документации
                            timeout=(3.05, 10))
        return to_outcome(resp)  # "deliverable" | "undeliverable" | "undetermined"
    except requests.RequestException:
        return "not_completed"

build_headers, build_check_body и to_outcome — это небольшие вспомогательные функции, написанные на основе документации API EmailCheckPro, поэтому аутентификация и детали полей находятся в одном месте и соответствуют опубликованному контракту. Возврат простых строк делает остальную часть кодовой базы независимой от формата ответа.

Всегда устанавливайте тайм-аут. Документация Requests отмечает, что запросы не имеют тайм-аута по умолчанию, а кортеж задает отдельные лимиты на подключение и чтение. Выбирайте значения исходя из допустимого времени ожидания вашей страницы; приведенные выше числа — лишь примеры.

Затем используйте ветвление по четырем состояниям:

  • Доставляемый: продолжайте работу и сохраните дату проверки.
  • Недоставляемый: запросите другой адрес.
  • Не определено: например, для catch-all адреса. API в реальном времени возвращает бизнес-код вместо результата, и проверка не тарифицируется. Примите с соответствующим флагом.
  • Не завершено: тайм-аут или сетевая ошибка. Примите с флагом и повторите проверку позже из очереди.

Шаг 3: проверка до 100 адресов за запрос

Инструменты администратора, небольшие импорты и ночные задания часто содержат несколько десятков или сотен адресов. POST /api/v1/batch-check принимает 1–100 адресов и отвечает в одном запросе, с результатами в порядке ввода.

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)  # нет завершенного результата -> "undetermined"
    return outcomes

Поскольку порядок сохраняется, zip сопоставляет каждый элемент с адресом, который его создал. Каждый элемент также указывает, существует ли завершенный результат. Только элементы со значением 1 несут статус Доставляемый или Недоставляемый; всё остальное попадает в группу Не определено или Не завершено, но никогда в Недоставляемый.

Удалите дубликаты нормализованных адресов перед разбивкой на группы, чтобы один и тот же почтовый ящик не проверялся дважды за один запуск. Для нескольких сотен адресов без написания кода проверка в реальном времени в панели управления обрабатывает до 500 адресов за раз.

Шаг 4: выполнение пакетной задачи для целых файлов

Когда источником является экспорт, пакетная задача подходит лучше всего. Она асинхронна, поэтому запускайте её из скрипта, запланированного задания или воркера, такого как Celery, а не из веб-представления.

  1. Запишите файл. Создайте TXT или CSV с одним полным адресом на строку. Встроенных средств записи файлов Python достаточно для TXT; модуль csv помогает при работе с экспортом из электронных таблиц.
  2. Отправьте и сохраните ссылку на задачу в вашей базе данных, вместе с именем файла и временем, чтобы перезапущенный воркер мог продолжить работу.
  3. Опрашивайте с терпением с интервалом в 30 секунд или более:
import time

def run_bulk(path: str) -> str:
    task_ref = submit_file(path)           # POST /api/v1/bulk-tasks
    save_task(task_ref, path)              # для восстановления после перезапуска воркера
    while True:
        status = get_status(task_ref)      # GET /api/v1/bulk-tasks/{id}
        if status.finished:
            return status.result_link      # действует 12 часов
        time.sleep(30)                     # никогда не опрашивайте чаще
  1. Скачайте и объедините. Успешная задача возвращает один CSV по ссылке, которая действует 12 часов; запросите ту же задачу снова для получения свежей ссылки, если срок истек. Прочитайте его с помощью csv.DictReader и объедините по email-адресу, а не по номеру строки, так как невалидные и дублирующиеся строки удаляются во время подготовки.

CSV с результатами доставляемости связывает каждый адрес с его исходом. Для списков Gmail, Yandex и Mail.ru, Проверка аватара email добавляет столбцы аватаров; ссылка на аватар может быть пустой, даже если аватар присутствует. Лимиты задач для каждого продукта указаны в документации API.

Поддержание надежности интеграции на Python

  • Храните ключ вне кода. Читайте его из переменной окружения или хранилища секретов; он расходует баланс аккаунта, общий для веб-проверок, вызовов API, пакетных задач и доступа через MCP.
  • Повторно используйте Session. Это поддерживает соединения открытыми между вызовами, что помогает при циклах по группам из нескольких адресов.
  • Записывайте даты. Результат описывает адрес на момент проверки, поэтому сохраняйте дату и повторно проверяйте старые строки перед массовой рассылкой.
  • Ставьте повторные попытки в очередь. Проверки со статусом Не определено, с ошибкой или невалидные не тарифицируются, но немедленные повторные попытки редко меняют результат. Планируйте их с задержкой и ограничением количества.
  • Тестируйте ветвления. Создайте заглушку (mock) для вспомогательной функции, вызывающей API, и убедитесь, что каждое состояние достигает нужного сообщения или очереди.
  • AI-блокноты и ассистенты: эндпоинт MCP по адресу https://emailcheckpro.com/mcp поддерживает одиночные проверки и до 100 адресов; файловые задачи остаются на REST API.

Часто задаваемые вопросы

Какая библиотека Python лучше всего подходит для проверки формата email?

email-validator — это широко используемый выбор, поскольку она дает понятные сообщения об ошибках, поддерживает интернационализированные домены и возвращает нормализованный адрес. Какую бы библиотеку ни выбрала команда, главное — использовать один источник истины для форм, импортов и скриптов, а также отключать опциональные DNS-запросы, когда отдельная проверка доставляемости уже покрывает вопрос о том, может ли адрес получать почту.

Как команды могут проверить большой CSV-файл с адресами из Python?

Создайте файл TXT или CSV с одним полным адресом на строку, отправьте его как пакетную задачу и опрашивайте её статус из фонового задания не чаще чем раз в 30 секунд. Когда задача будет выполнена, скачайте единственный CSV с результатами в течение 12 часов или запросите задачу снова для получения свежей ссылки и объедините результаты по email-адресу.

Почему не стоит проверять почтовые ящики с помощью самописного скрипта почтового сервера на Python?

Многие почтовые серверы принимают всех получателей, задерживают неизвестных отправителей или блокируют повторяющиеся соединения, поэтому скрипты возвращают большую долю неубедительных ответов и могут привести к попаданию вашего IP в черные списки. Хостинговая проверка доставляемости возвращает статус Доставляемый или Недоставляемый без отправки чего-либо на адрес и помечает адреса, которые не удалось определить, как Не определено, вместо того чтобы гадать.

Узнать больше

Выберите информацию о продукте, которая соответствует следующему шагу в вашем рабочем процессе.

Источники