【发布时间】:2010-06-09 18:36:42
【问题描述】:
我是这样写代码的
import smtplib
server=smtplib.SMTP('localhost')
然后它引发了类似的错误
错误:[Errno 10061] 由于目标机器主动拒绝,无法建立连接
我是 SMTP 新手,您能说出具体的问题吗?
【问题讨论】:
-
您使用的是什么操作系统?什么 SMTP 服务器?
我是这样写代码的
import smtplib
server=smtplib.SMTP('localhost')
然后它引发了类似的错误
错误:[Errno 10061] 由于目标机器主动拒绝,无法建立连接
我是 SMTP 新手,您能说出具体的问题吗?
【问题讨论】:
听起来您尝试此操作的计算机上未设置 SMTP。尝试使用您的 ISP 的邮件服务器(通常类似于 mail.example.com)或确保您在本地安装了 SMTP 服务器。
【讨论】:
您可以在控制台上设置一个简单的 smtp 服务器,而不是尝试在本地安装 smtp 库。
这样做:
python -m smtpd -n -c DebuggingServer localhost:1025
所有邮件都会打印到控制台。
【讨论】:
import smtplib server=smtplib.SMTP('localhost',1025)
要使用 Python SMTP 模块发送电子邮件,您需要以某种方式获取有效邮件交换器 (MX) 的名称。这可以是您自己的本地集线器或智能中继,也可以查询 DNS 以获取每个目标主机/域名的公共 MX 记录。
文档中忽略了此要求。 Python 的标准库中一个可怕的遗漏是它们没有提供一种简单的方法来查询 DNS 以获取 MX 记录。 (有相当不错的第三方 Python DNS 库,例如 DNSPython 和 PyDNS,它们对 DNS 的广泛支持比您对与电子邮件相关的任何东西所需要的要多得多)。
一般来说,您最好使用您自己的网络(或 ISP)中的集线器或中继器列表。这是因为您将邮件直接发送到已发布的 MX 主机的努力可能会与各种打击垃圾邮件的尝试发生冲突。 (例如,咖啡店、酒店的无线网络以及普通的家庭电缆和 DSL 连接通常无法实现;这些地址范围中的大多数在各种数据库中被列为潜在的垃圾邮件类型)。在这种情况下,您可以通过任何您喜欢的方式存储和/或检索本地邮件集线器(或智能中继)的名称/地址。它可以是 .cfg 文件 (ConfigParser),或者通过 LDAP 或 SQL 查询,甚至(喘气!)硬编码到您的脚本中。
但是,如果您的代码打算在合适的网络上运行(例如,在 colo 或数据中心),那么您必须自己进行 MX 解析。您可以安装上述 PyPI 软件包之一。如果您需要将自己限制在标准库中,那么您可能可以依赖常用的dig 实用程序,该实用程序包含在大多数 Linux、MacOS X、Solaris、FreeBSD 和其他优秀操作系统的安装中。
在这种情况下,您可以通过subprocess.Popen() 调用像dig +short aol.com mx | awk '{print $NF}' 这样的命令,这可以通过这个相当丑陋的单线来完成:
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
【讨论】: