Для отправки электронной почты с использованием SMTP-модуля Python необходимо каким-то образом получить имя действующего почтового обменника (MX).Это либо локальный концентратор, либо ваш собственный интеллектуальный ретранслятор, или вы можете запросить DNS об общих записях MX для каждого целевого имени хоста / домена.
Это требование скрыто в документации.Это ужасное упущение в стандартных библиотеках Python - они не предоставляют простой способ запрашивать DNS для записи MX.(Существуют довольно приятные сторонние библиотеки Python DNS, такие как DNSPython и PyDNS с расширенной поддержкой гораздо большего количества DNS, чем нужно для всего, что связано с электронной почтой).
Как правило, вам лучше использовать список концентраторов или ретрансляторов из вашей собственной сети (или интернет-провайдера).Это связано с тем, что ваши попытки отправить почту непосредственно на опубликованные хосты MX могут столкнуться с различными попытками борьбы со спамом.(Например, это часто невозможно сделать из беспроводных сетей в кафе, отелях и через обычные бытовые кабельные и DSL-соединения; большинство этих диапазонов адресов перечислены в различных базах данных как потенциальные виды спама).В этом случае вы можете хранить и / или извлекать имена / адреса ваших локальных почтовых центров (или интеллектуальных ретрансляторов) любым удобным для вас способом.Это может быть файл .cfg (ConfigParser), или через LDAP или SQL-запрос, или даже (задыхаясь!), Жестко запрограммированный в ваших скриптах.
Если, однако, ваш код предназначен для запуска на подходящемсеть (например, в colo, или дата-центр), то вам придется сделать свое собственное разрешение MX.Вы можете установить один из вышеупомянутых пакетов PyPI.Если вам нужно ограничиться стандартными библиотеками, вы можете рассчитывать на общедоступную утилиту dig
, которая включена в большинство установок Linux, MacOS X, Solaris, FreeBSD и других хороших операционных систем.
В этом случае вы бы вызвали команду типа dig +short aol.com mx | awk '{print $NF}'
- subprocess.Popen()
, что можно сделать с помощью этого довольно уродливого однострочного:
mxers = subprocess.Popen("dig +short %s mx | awk '{print $NF}'"
% target_domain, stdout=subprocess.PIPE,
shell=True).communicate()[0].split()
Затем вы можете попытаться установить SMTP-соединение с каждымрезультирующих имен хостов по очереди.(Это нормально, если ваше значение "target_domain" должным образом очищено; не передавайте ненадежные данные через Popen()
с shell=True
).
Более безопасная версия выглядит еще более привлекательной:
mxers = subprocess.Popen(["dig", "+short", target_domain, "mx"],
stdout=subprocess.PIPE).communicate()[0].split()[1::2]
... где фрагмент / шаг в конце заменяет вызов на awk
и, таким образом, устраняет необходимость в shell=True