20.12. smtplibSMTP protocol client

源程序代码:Lib/smtplib.py


Smtplib模块定义了可用于将邮件发送到 SMTP 或 ESMTP 侦听器守护进程任何互联网机 SMTP 客户端会话对象。有关 SMTP 和 ESMTP 操作的详细信息,请参阅 RFC 821 (简单邮件传输协议) 和 RFC 1869 年(SMTP 服务扩展)。

class smtplib.SMTP([host[, port[, local_hostname[, timeout]]]])

SMTP实例封装一个 SMTP 连接。它具有支持 SMTP 和 ESMTP 操作完整剧目的方法。如果给出可选的主机和端口参数的信息,在初始化过程中使用这些参数调用时 SMTP connect ()方法。如果指定,则会将local_hostname用作 HELO/EHLO 命令中的本地主机的 FQDN。否则,使用socket.getfqdn(),找到了本地主机名称。如果使用 connect ()调用返回成功代码之外的任何内容,则会引发SMTPConnectError 可选的超时参数指定以秒计) 阻塞操作 (如连接尝试超时 (如果不指定,将使用全局默认超时设置)。如果在超时过期,则会引发socket.timeout

正常使用,您应该只需要初始化或连接, sendmail()quit ()方法。示例所示。

2.6 版本中的更改:添加了超时

class smtplib.SMTP_SSL([host[, port[, local_hostname[, keyfile[, certfile[, timeout]]]]]])

一个SMTP_SSL实例的行为完全相同的SMTP实例。 SMTP_SSL应该用于 SSL 要求从一开始的连接和使用starttls()并不适当情况。如果未指定主机,则使用本地主机。如果端口省略,则使用标准 SMTP 在 SSL 端口 (465)。local_hostname具有相同的含义一样SMTP类。密钥文件certfile也是可选的并且可以包含一个 PEM 格式私人密钥和证书链文件对于 SSL 连接。可选的超时参数指定以秒计) 阻塞操作 (如连接尝试超时 (如果不指定,将使用全局默认超时设置)。如果在超时过期,则会引发socket.timeout

在 2.6 版本新。

class smtplib.LMTP([host[, port[, local_hostname]]])

LMTP 协议,这是非常类似于 ESMTP,很大程度基于标准的 SMTP 客户端。它是共同的为 LMTP,使用 Unix 套接字,因此我们的connect ()方法必须支持,以及定期的主机: 端口服务器。local_hostname具有相同的含义一样SMTP类。若要指定一个 Unix 套接字,则必须使用以 '/' 开头的主机的绝对路径。

使用常规的 SMTP 机制,支持身份验证。当使用 Unix 套接字,LMTP 通常不支持或需要任何身份验证,但您的里程可能会有所不同。

在 2.6 版本新。

一些很有用的异常的定义:

exception smtplib.SMTPException

此模块提供的所有其他异常的基异常类。

exception smtplib.SMTPServerDisconnected

当服务器意外断开连接,或尝试连接到服务器之前使用的SMTP实例时,将引发此异常。

exception smtplib.SMTPResponseException

对于包括 SMTP 错误代码的所有异常的基类。在某些情况下会产生了这些异常,当 SMTP 服务器将返回一个错误代码。错误代码存储在smtp_code属性中的错误,和smtp_error属性设置为错误消息。

exception smtplib.SMTPSenderRefused

拒绝的发件人地址。属性设置所有SMTPResponseException异常时,此选项设置 SMTP 服务器拒绝的字符串 '发件人'。

exception smtplib.SMTPRecipientsRefused

拒绝所有的收件人地址。每个收件人的错误都可以访问通过属性的收件人,这是完全相同的排序一个字典,因为SMTP.sendmail()返回。

exception smtplib.SMTPDataError

SMTP 服务器拒绝接受的消息数据。

exception smtplib.SMTPConnectError

在建立与服务器的连接时出错。

exception smtplib.SMTPHeloError

服务器拒绝了我们的HELO消息。

exception smtplib.SMTPAuthenticationError

SMTP 身份验证出错。最有可能服务器不接受提供的用户名/密码组合。

请参见

RFC 821 - Simple Mail Transfer Protocol
Protocol definition for SMTP. This document covers the model, operating procedure, and protocol details for SMTP.
RFC 1869 - SMTP Service Extensions
Definition of the ESMTP extensions for SMTP. This describes a framework for extending SMTP with new commands, supporting dynamic discovery of the commands provided by the server, and defines a few additional commands.

20.12.1. SMTP Objects

SMTP实例都具有以下方法:

SMTP.set_debuglevel(level)

设置调试输出的级别。真正的价值,为一级的成果,在调试消息对于连接和所有邮件的发送到和接收到来自服务器。

SMTP.docmd(cmd[, argstring])

向服务器发送命令cmd可选参数argstring简单地连接到该命令,由空格分隔。

这将返回一个 2 元组组成的一个数值的响应代码和实际响应行 (多行响应联接成一个长行)。

在正常操作中它不应需要显式调用此方法。它用来实现其他的方法,并可用于测试私人扩展。

如果与服务器的连接丢失在等待答复时,将引发SMTPServerDisconnected

SMTP.connect([host[, port]])

连接到一个给定的端口上的主机。默认值是要连接到本地主机在标准 SMTP 端口 (25)。如果主机名以冒号结尾 (': ') 后跟一个数字,该后缀将剥离和数字解释为要使用的端口号。如果在实例化过程中指定的主机,该构造函数将自动调用此方法。返回的响应代码和在其连接响应服务器发送的消息 2 元组。

SMTP.helo([hostname])

向使用HELO的 SMTP 服务器标识自己。主机名参数默认为本地主机的完全限定的域名。作为对象的helo_resp属性存储由服务器返回的消息。

在正常操作中它不应需要显式调用此方法。它由sendmail()在必要时将隐式调用。

SMTP.ehlo([hostname])

向使用EHLOESMTP 服务器标识自己。主机名参数默认为本地主机的完全限定的域名。检查 ESMTP 选项响应并将它们用于存储由has_extn()此外将设置几种信息性属性: 由服务器返回的消息存储为ehlo_resp属性, does_esmtp被设置为 true 还是 false,具体取决于服务器是否支持 ESMTP,, esmtp_features将字典,它包含 SMTP 服务扩展此服务器支持和它们的参数 (如果有) 的名称。

除非你想要使用has_extn()在发送邮件之前,它不应需要显式调用此方法。它由sendmail()在必要时将隐式调用。

SMTP.ehlo_or_helo_if_needed()

此方法调用ehlo()helo()如果已经没有以前EHLOHELO命令此会话。它首次尝试 ESMTP EHLO

SMTPHeloError
The server didn’t reply properly to the HELO greeting.

在 2.6 版本新。

SMTP.has_extn(name)

如果名称是否则经由服务器,虚假的 SMTP 服务扩展集合中,则返回True 忽略大小写。

SMTP.verify(address)

请检查此服务器使用 SMTP VRFY上地址的有效性。返回一个元组组成的代码 250 及全套 RFC 822地址 (包括人类的名称),如果用户地址是有效的。400 或更大的 SMTP 错误代码和错误字符串 ; 否则返回。

很多网站禁用 SMTP VRFY以铝箔垃圾邮件制造者。

SMTP.login(user, password)

登录到 SMTP 服务器要求身份验证。论据是用户名和密码进行身份验证。如果这次会议已经没有以前的EHLOHELO命令,这种方法首先尝试 ESMTP EHLO 此方法将返回正常,如果身份验证成功,或可能会引发以下异常:

SMTPHeloError
The server didn’t reply properly to the HELO greeting.
SMTPAuthenticationError
The server didn’t accept the username/password combination.
SMTPException
No suitable authentication method was found.
SMTP.starttls([keyfile[, certfile]])

将 SMTP 连接放在 TLS (传输层安全性) 模式。遵循的所有 SMTP 命令将被都加密。然后,你应该再打电话ehlo()

如果提供了密钥文件certfile ,这些都传递给插座模块ssl()函数。

如果这次会议已经没有以前的EHLOHELO命令,这种方法首先尝试 ESMTP EHLO

在 2.6 版本中更改。

SMTPHeloError
The server didn’t reply properly to the HELO greeting.
SMTPException
The server does not support the STARTTLS extension.

在 2.6 版本中更改。

RuntimeError
SSL/TLS support is not available to your Python interpreter.
SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options])

发送邮件。必需的参数是 RFC 822从地址字符串,列表 RFC 822到地址字符串 (裸字符串将被视为具有 1 个地址的列表) 和消息字符串。调用方可能通过 ESMTP 选项 (如8bitmime) 的列表在邮件命令中用作mail_options应与所有RCPT命令一起使用的 ESMTP 选项 (例如DSN命令) 可以作为rcpt_options传递。(如果您需要使用不同的 ESMTP 选项给不同收件人您有使用mail () rcpt()data ()等的低级方法来发送消息。)

From_addrto_addrs参数用于构造由运输代理使用的邮件信封。 SMTP不修改任何方式中的邮件标题。

如果这次会议已经没有以前的EHLOHELO命令,这种方法首先尝试 ESMTP EHLO 如果服务器没有 ESMTP,邮件大小以及每个指定的选项将被传递给它 (如果该选项是在服务器广告的功能集)。如果EHLO失败,将尝试HELO和 ESMTP 选项抑制。

此方法将返回正常如果邮件将被接受为至少一个收件人。否则,它将引发异常。那就是,如果此方法不会引发异常,然后有人应收到你的邮件。如果此方法不会引发异常,它将返回一本字典,为被拒绝的每个收件人的一个条目。每个条目包含 SMTP 错误代码和相应的错误消息由服务器发送的元组。

该方法可能会引发以下异常:

SMTPRecipientsRefused
All recipients were refused. Nobody got the mail. The recipients attribute of the exception object is a dictionary with information about the refused recipients (like the one returned when at least one recipient was accepted).
SMTPHeloError
The server didn’t reply properly to the HELO greeting.
SMTPSenderRefused
The server didn’t accept the from_addr.
SMTPDataError
The server replied with an unexpected error code (other than a refusal of a recipient).

除非另行说明,否则连接将开放,即使在引发异常之后。

SMTP.quit()

终止 SMTP 会话,并关闭连接。返回 SMTP QUIT命令的结果。

2.6 版本中的更改:返回一个值。

低级的方法对应于标准的 SMTP/ESMTP 命令帮助,还支持RSET NOOP邮件 RCPT、 和数据通常这些不需要直接调用,所以他们未在此处。有关详细信息,请参阅模块代码。

20.12.2. SMTP Example

本示例提示用户输入需要在消息信封 ('到' 和 '从' 地址) 和要发送的消息的地址。注意要将包含在消息的标头必须包含在邮件中,当进入 ;此示例不做任何处理的 RFC 822邮件头。特别是,'到' 和 '从' 地址必须显式包含在邮件头中。

import smtplib

def prompt(prompt):
    return raw_input(prompt).strip()

fromaddr = prompt("From: ")
toaddrs  = prompt("To: ").split()
print "Enter message, end with ^D (Unix) or ^Z (Windows):"

# Add the From: and To: headers at the start!
msg = ("From: %s\r\nTo: %s\r\n\r\n"
       % (fromaddr, ", ".join(toaddrs)))
while 1:
    try:
        line = raw_input()
    except EOFError:
        break
    if not line:
        break
    msg = msg + line

print "Message length is " + repr(len(msg))

server = smtplib.SMTP('localhost')
server.set_debuglevel(1)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()

一般情况下,你会想要使用电子邮件软件包的功能来构建,然后转换为字符串,并通过sendmail(); 发送电子邮件请参阅电子邮件: 例子