Как проверить запись MX для домена в python?

У меня есть большое количество адресов электронной почты для проверки. Сначала я разбираю их с регулярным выражением, чтобы выбросить абсолютно сумасшедшие. Я остался с теми, кто выглядит разумным, но все же может содержать ошибки.

Я хочу найти, какие адреса имеют действительные домены, поэтому дайте мне [email protected] Я хочу знать, можно ли даже отправлять электронные письма на abcxyz.com.

Я хочу проверить это, чтобы убедиться, что он соответствует действительной записи A или MX - есть ли простой способ сделать это, используя только стандартную библиотеку Python? Я бы предпочел не добавлять дополнительную зависимость к моему проекту только для поддержки этой функции.

Ответы

Ответ 1

В стандартной библиотеке отсутствует интерфейс DNS, поэтому вам придется либо перевернуть свой собственный, либо использовать стороннюю библиотеку.

Это не быстро меняющаяся концепция, поэтому внешние библиотеки стабильны и хорошо протестированы.

Тот, который я использовал успешно для той же задачи, что и ваш вопрос, PyDNS.

Очень грубый эскиз моего кода выглядит примерно так:

import DNS, smtplib

DNS.DiscoverNameServers()
mx_hosts = DNS.mxlookup(hostname)

# Just doing the mxlookup might be enough for you,
# but do something like this to test for SMTP server
for mx in mx_hosts:
    smtp = smtplib.SMTP()
    #.. if this doesn't raise an exception it is a valid MX host...
    try:
        smtp.connect(mx[1])
    except smtplib.SMTPConnectError:
        continue # try the next MX server in list

Другая библиотека, которая может быть лучше/быстрее, чем PyDNS, dnsmodule, хотя похоже, что с 2002 года она не имела никакой активности, по сравнению с последним обновлением PyDNS в августе 2008 года.

Изменить. Я также хотел бы отметить, что адреса электронной почты не могут быть легко проанализированы с помощью регулярного выражения. Вам лучше использовать функцию parseaddr() в стандартном модуле library.utils библиотеки (см. Мой ответ на этот вопрос).

Ответ 2

Простым способом сделать это НЕ в стандартной библиотеке является использование validate_email package:

from validate_email import validate_email
is_valid = validate_email('[email protected]', check_mx=True)

Для получения более быстрых результатов для обработки большого количества адресов электронной почты (например, списка emails, вы можете зашифровать домены и выполнять check_mx только в том случае, если домен отсутствует. Что-то вроде:

emails = ["[email protected]", "[email protected]_domain", "[email protected]", ...]
verified_domains = set()
for email in emails:
    domain = email.split("@")[-1]
    domain_verified = domain in verified_domains
    is_valid = validate_email(email, check_mx=not domain_verified)
    if is_valid:
        verified_domains.add(domain)