On this page
smtplib — SMTP 协议 Client 端
源代码: Lib/smtplib.py
smtplib模块定义 SMTPClient 端会话对象,该对象可用于pass SMTP 或 ESMTP 侦听器守护程序将邮件发送到任何 Internet 计算机。有关 SMTP 和 ESMTP 操作的详细信息,请参阅 RFC 821(简单邮件传输协议)和 RFC 1869(SMTP 服务扩展)。
-
- class *
smtplib.
SMTP
(* host ='', port = 0 , local_hostname = None *,[* timeout *,] * source_address = None *)
- SMTP实例封装了 SMTP 连接。它具有支持 SMTP 和 ESMTP 操作的全部Function的方法。如果给出了可选的主机和端口参数,则在初始化期间将使用这些参数调用 SMTP connect()方法。如果指定,* local_hostname 用作 HELO/EHLO 命令中 localhost 的 FQDN。否则,使用socket.getfqdn()找到 localhost 名。如果connect()调用返回成功代码以外的任何内容,则会引发SMTPConnectError。可选的 timeout *参数以秒为单位指定用于阻止诸如连接try之类的操作的超时(如果未指定,将使用全局默认超时设置)。如果超时到期,则socket.timeout被提高。可选的 source_address 参数允许绑定到具有多个网络接口的计算机中的某些特定源地址和/或某些特定源 TCP 端口。连接之前,套接字需要两个 Tuples(主机,端口)绑定为其源地址。如果Ellipsis(或者主机或端口分别为
''
和/或 0),则将使用 os 默认行为。
- class *
对于正常使用,您只需要初始化/连接,sendmail()和SMTP.quit()方法。下面包括一个示例。
SMTP类支持with语句。像这样使用时,with
语句退出时,会自动发出 SMTP QUIT
命令。例如。:
>>> from smtplib import SMTP
>>> with SMTP("domain.org") as smtp:
... smtp.noop()
...
(250, b'Ok')
>>>
所有命令都将引发带有参数self
和data
的auditing event smtplib.SMTP.send
,其中data
是将要发送到远程主机的字节。
在版本 3.3 中进行了更改:添加了对with语句的支持。
在版本 3.3 中更改:添加了 source_address 参数。
版本 3.5 中的新增Function:现在支持 SMTPUTF8extensions( RFC 6531)。
-
- class *
smtplib.
SMTP_SSL
(* host ='', port = 0 , local_hostname = None , keyfile = None , certfile = None *,[* timeout *,] * context = None , source_address = None *)
- SMTP_SSL实例的行为与SMTP实例完全相同。 SMTP_SSL应该用于从连接开始就需要 SSL 且不适合使用
starttls()
的情况。如果未指定* host ,则使用 localhost。如果 port 为零,则使用标准的 SSL 上的 SMTP 端口(465)。可选参数 local_hostname , timeout 和 source_address *具有与SMTP类相同的含义。 * context *(也是可选的)可以包含SSLContext并允许配置安全连接的各个方面。请阅读Security considerations以获得最佳做法。
- class *
- keyfile 和 certfile 是 context *的遗留替代品,它们可以指向 PEM 格式的私钥和证书链文件以进行 SSL 连接。
在版本 3.3 中更改:添加了* context *。
在版本 3.3 中更改:添加了 source_address 参数。
在版本 3.4 中进行了更改:该类现在支持使用ssl.SSLContext.check_hostname和服务器名称指示(请参阅ssl.HAS_SNI)检查主机名。
从 3.6 版开始不推荐使用:* keyfile 和 certfile 不再推荐使用 context *。请改用ssl.SSLContext.load_cert_chain(),或让ssl.create_default_context()为您选择系统的受信任 CA 证书。
-
- class *
smtplib.
LMTP
(* host ='', port = LMTP_PORT , local_hostname = None , source_address = None *)
- LMTP 协议与 ESMTP 非常相似,它很大程度上基于标准的 SMTPClient 端。对于 LMTP,通常使用 Unix 套接字,因此我们的
connect()
方法必须支持该套接字以及常规的 host:port 服务器。可选参数 local_hostname 和 source_address 具有与SMTP类相同的含义。要指定 Unix 套接字,必须为* host *使用绝对路径,以'/'开头。
- class *
使用常规 SMTP 机制支持身份验证。使用 Unix 套接字时,LMTP 通常不支持或不需要任何身份验证,但是您的里程可能会有所不同。
还定义了一个很好的 exception 选择:
- exception
smtplib.
SMTPException
- OSError的子类,它是此模块提供的所有其他异常的基本异常类。
在版本 3.4 中进行了更改:SMTPException 成为OSError的子类
exception
smtplib.
SMTPServerDisconnected
- 如果服务器意外断开连接,或者在将其连接到服务器之前try使用SMTP实例,则会引发此异常。
exception
smtplib.
SMTPResponseException
- 所有包含 SMTP 错误代码的异常的 Base Class。在某些情况下,当 SMTP 服务器返回错误代码时,会生成这些异常。错误代码存储在错误的
smtp_code
属性中,并且smtp_error
属性设置为错误消息。
- 所有包含 SMTP 错误代码的异常的 Base Class。在某些情况下,当 SMTP 服务器返回错误代码时,会生成这些异常。错误代码存储在错误的
exception
smtplib.
SMTPSenderRefused
- 发件人地址被拒绝。除了在所有SMTPResponseExceptionexception 中设置的属性外,这还将'sender'设置为 SMTP 服务器拒绝的字符串。
exception
smtplib.
SMTPRecipientsRefused
- 所有收件人地址均被拒绝。每个收件人的错误都可以pass属性
recipients
进行访问,该属性是与SMTP.sendmail()返回类型完全相同的字典。
- 所有收件人地址均被拒绝。每个收件人的错误都可以pass属性
exception
smtplib.
SMTPDataError
- SMTP 服务器拒绝接受邮件数据。
exception
smtplib.
SMTPConnectError
- 与服务器构建连接期间发生错误。
exception
smtplib.
SMTPHeloError
- 服务器拒绝了我们的
HELO
消息。
- 服务器拒绝了我们的
exception
smtplib.
SMTPNotSupportedError
- 服务器不支持try的命令或选项。
3.5 版中的新Function。
- exception
smtplib.
SMTPAuthenticationError
- SMTP 验证出错。服务器很可能不接受提供的用户名/密码组合。
See also
SMTP Objects
SMTP实例具有以下方法:
SMTP.
set_debuglevel
(级别)- 设置调试输出级别。 * level *的值为 1 或
True
会导致连接的调试消息以及发送到服务器和从服务器接收的所有消息。 * level *的值 2 导致这些消息带有时间戳。
- 设置调试输出级别。 * level *的值为 1 或
在版本 3.5 中进行了更改:添加了调试级别 2.
SMTP.
docmd
(* cmd , args =''*)- 向服务器发送命令* cmd 。可选参数 args *仅连接到命令,并用空格分隔。
这将返回一个由数字响应代码和实际响应行组成的 2Tuples(多行响应合并为一条长行.)
在正常操作中,不必显式调用此方法。它用于实现其他方法,可能对测试私有扩展有用。
如果在 await 答复时与服务器的连接丢失,则将引发SMTPServerDisconnected。
SMTP.
connect
(* host ='localhost', port = 0 *)- 连接到给定端口上的主机。默认设置是在标准 SMTP 端口(25)上连接到 localhost。如果主机名以冒号(
':'
)后跟数字结尾,则将删除该后缀,并将该数字解释为要使用的端口号。如果在实例化期间指定了主机,则构造方法会自动调用此方法。返回由服务器在其连接响应中发送的响应代码和消息的 2Tuples。
- 连接到给定端口上的主机。默认设置是在标准 SMTP 端口(25)上连接到 localhost。如果主机名以冒号(
用参数self
,host
,port
引发auditing event smtplib.connect
。
SMTP.
helo
(* name =''*)- 使用
HELO
将自己标识为 SMTP 服务器。 hostname 参数默认为 localhost 的标准域名。服务器返回的消息存储为对象的helo_resp
属性。
- 使用
在正常操作中,不必显式调用此方法。必要时它将由sendmail()隐式调用。
SMTP.
ehlo
(* name =''*)- 使用
EHLO
将自己标识为 ESMTP 服务器。 hostname 参数默认为 localhost 的标准域名。检查 ESMTP 选项的响应,并存储它们供has_extn()使用。还设置了一些信息属性:服务器返回的消息存储为ehlo_resp
属性,根据服务器是否支持 ESMTP 将does_esmtp
设置为 true 或 false,并且esmtp_features
将是一个包含该服务器 SMTP 服务 extensions 的字典。支持及其参数(如果有)。
- 使用
除非您希望在发送邮件之前使用has_extn(),否则不必显式调用此方法。必要时它将由sendmail()隐式调用。
SMTP.
ehlo_or_helo_if_needed
( )-
- 服务器未正确回复
HELO
问候。
- 服务器未正确回复
SMTP.
has_extn
(* name *)SMTP.
verify
(地址)- 使用 SMTP
VRFY
检查此服务器上地址的有效性。如果用户地址有效,则返回一个由代码 250 和完整的 RFC 822地址(包括人名)组成的 Tuples。否则,返回 SMTP 错误代码 400 或更高以及错误字符串。
- 使用 SMTP
Note
许多站点禁用 SMTP VRFY
来阻止垃圾邮件发送者。
SMTP.
login
(* user , password ,**,* initial_response_ok = True *)- 登录需要身份验证的 SMTP 服务器。参数是用于验证的用户名和密码。如果此会话没有先前的
EHLO
或HELO
命令,则此方法首先try ESMTPEHLO
。如果身份验证成功,此方法将正常返回,或者可能引发以下异常:
- 登录需要身份验证的 SMTP 服务器。参数是用于验证的用户名和密码。如果此会话没有先前的
-
服务器未正确回复
HELO
问候。-
- 服务器不接受用户名/密码组合。
-
- 服务器不支持
AUTH
命令。
- 服务器不支持
-
- 找不到合适的身份验证方法。
如果smtplib支持的每种身份验证方法被公布为服务器支持,则依次try。有关支持的身份验证方法的列表,请参见auth()。 * initial_response_ok *传递给auth()。
可选关键字参数* initial_response_ok *指定对于支持它的身份验证方法,是否可以与AUTH
命令一起发送 RFC 4954中指定的“初始响应”,而不是要求质询/响应。
在版本 3.5 中更改:可能引发SMTPNotSupportedError,并添加了* initial_response_ok *参数。
SMTP.
auth
(机制,* authobject ,**,* initial_response_ok = True *)- 发出用于指定身份验证机制的
SMTP
AUTH
命令,并pass* authobject *处理质询响应。
- 发出用于指定身份验证机制的
“机制”指定将哪种身份验证机制用作AUTH
命令的参数;有效值是esmtp_features
的auth
元素中列出的值。
- authobject *必须是带有可选单个参数的可调用对象:
Note
数据= authobject(挑战=无)
如果可选关键字参数* initial_response_ok 为 true,则authobject()
将首先被调用而没有参数。它可以返回 RFC 4954“初始响应” ASCII str
,它将使用AUTH
命令进行编码和发送,如下所示。如果authobject()
不支持初始响应(例如,因为它需要质询),则在使用challenge=None
调用时应返回None
。如果 initial_response_ok *为 false,则不会先使用None
调用authobject()
。
如果初始响应检查返回None
,或者* initial_response_ok 为 false,则将调用authobject()
来处理服务器的质询响应;传递给它的 challenge *参数是bytes
。它应该返回 ASCII str
* data *,它将被 base64 编码并发送到服务器。
SMTP
类为CRAM-MD5
,PLAIN
和LOGIN
机制提供authobjects
;它们分别命名为SMTP.auth_cram_md5
,SMTP.auth_plain
和SMTP.auth_login
。它们都要求将SMTP
实例的user
和password
属性设置为适当的值。
用户代码通常不需要直接调用auth
,而可以调用login()方法,该方法将按列出的 Sequences 依次try上述每种机制。公开auth
以便于实现smtplib不直接(或尚未)支持的身份验证方法。
3.5 版中的新Function。
SMTP.
starttls
(* keyfile = None , certfile = None , context = None *)- 将 SMTP 连接置于 TLS(传输层安全性)模式下。随后的所有 SMTP 命令将被加密。然后,您应该再次致电ehlo()。
如果提供了* keyfile 和 certfile *,它们将用于创建ssl.SSLContext。
可选的* context 参数是ssl.SSLContext对象;这是使用密钥文件和证书文件的替代方法,并且如果指定了 keyfile 和 certfile *都应为None
。
如果此会话没有先前的EHLO
或HELO
命令,则此方法首先try ESMTP EHLO
。
从 3.6 版开始不推荐使用:* keyfile 和 certfile 不再推荐使用 context *。请改用ssl.SSLContext.load_cert_chain(),或让ssl.create_default_context()为您选择系统的受信任 CA 证书。
-
服务器未正确回复
HELO
问候。-
- 服务器不支持 STARTTLS 扩展。
-
- 您的 Python 解释器不提供 SSL/TLS 支持。
在版本 3.3 中更改:添加了* context *。
在版本 3.4 中进行了更改:该方法现在支持使用SSLContext.check_hostname
和* Server Name Indicator *(请参阅HAS_SNI)检查主机名。
在版本 3.5 中进行了更改:由于缺少 STARTTLS 支持而引发的错误现在是SMTPNotSupportedError子类,而不是基础SMTPException。
SMTP.
sendmail
(* from_addr , to_addrs , msg , mail_options =(), rcpt_options =()*)
Note
- from_addr 和 to_addrs *参数用于构造传输代理使用的消息信封。
sendmail
不会以任何方式修改邮件头。
- msg *可以是包含 ASCII 范围内字符的字符串,也可以是字节字符串。使用 ascii 编解码器将字符串编码为字节,并将单独的
\r
和\n
字符转换为\r\n
字符。字节字符串未修改。
如果此会话没有先前的EHLO
或HELO
命令,则此方法首先try ESMTP EHLO
。如果服务器使用 ESMTP,则将向其传递邮件大小和每个指定的选项(如果该选项在服务器发布的Function集中)。如果EHLO
失败,将tryHELO
并抑制 ESMTP 选项。
如果至少一个收件人接受了该邮件,则此方法将正常返回。否则会引发异常。也就是说,如果此方法未引发异常,则应该有人收到您的邮件。如果此方法没有引发异常,它将返回一个字典,其中每个拒绝的接收者都有一个条目。每个条目都包含一个 SMTP 错误代码的 Tuples 以及服务器发送的附带错误消息。
如果SMTPUTF8
包含在* mail_options 中,并且服务器支持它,则 from_addr 和 to_addrs *可能包含非 ASCII 字符。
此方法可能会引发以下异常:
-
所有收件人均被拒绝。没有人收到邮件。异常对象的
recipients
属性是一本字典,其中包含有关被拒绝的收件人的信息(例如,当至少一个收件人被接受时返回的字典)。-
- 服务器未正确回复
HELO
问候。
- 服务器未正确回复
-
- 服务器不接受* from_addr *。
-
- 服务器回复了意外的错误代码(拒绝接收者除外)。
-
SMTPUTF8
已在* mail_options *中给出,但服务器不支持。
除非另有说明,否则即使出现异常也将打开连接。
在版本 3.2 中更改:* msg *可能是字节字符串。
在版本 3.5 中更改:添加了SMTPUTF8
支持,如果指定了SMTPUTF8
但服务器不支持,则可能引发SMTPNotSupportedError。
SMTP.
send_message
(* msg , from_addr = None , to_addrs = None , mail_options =(), rcpt_options =()*)- 这是使用email.message.Message对象表示的消息调用sendmail()的一种便捷方法。这些参数与sendmail()的含义相同,除了* msg *是
Message
对象。
- 这是使用email.message.Message对象表示的消息调用sendmail()的一种便捷方法。这些参数与sendmail()的含义相同,除了* msg *是
如果* from_addr 为None
或 to_addrs 为None
,则send_message
用从 RFC 5322中指定的从 msg 头中提取的地址填充这些参数: from_addr 设置为 Sender 字段(如果存在),并且否则为 From 字段。 * to_addrs 组合 msg 中 To , Cc 和 Bcc 字段的值(如果有)。如果消息中仅出现一组 Resent- Headers,则常规 Headers 将被忽略,而使用 Resent- Headers 代替。如果邮件包含多个* Resent- Headers 集,则会引发ValueError,因为无法明确检测到最新的 Resent- *Headers 集。
send_message
使用BytesGenerator并将\r\n
作为* linesep 序列化 msg ,并调用sendmail()传输结果消息。无论 from_addr 和 to_addrs 的值如何,send_message
都不会传输 msg 中可能出现的任何 Bcc 或 Resent-Bcc Headers。如果 from_addr 和 to_addrs 中的任何地址包含非 ASCII 字符,并且服务器未宣传SMTPUTF8
支持,则会引发SMTPNotSupported
错误。否则,将Message
与其policy的克隆(其utf8属性设置为True
)进行序列化,并将SMTPUTF8
和BODY=8BITMIME
添加到 mail_options *。
3.2 版中的新Function。
版本 3.5 中的新Function:支持国际化地址(SMTPUTF8
)。
SMTP.
quit
( )- 终止 SMTP 会话并关闭连接。返回 SMTP
QUIT
命令的结果。
- 终止 SMTP 会话并关闭连接。返回 SMTP
还支持与标准 SMTP/ESMTP 命令HELP
,RSET
,NOOP
,MAIL
,RCPT
和DATA
对应的低级方法。通常,这些不需要直接调用,因此这里没有记录。有关详细信息,请查阅模块代码。
SMTP Example
本示例提示用户 Importing 邮件信封中所需的地址(“收件人”和“发件人”地址)以及要传递的邮件。请注意,要包含在消息中的 Headers 必须包含在 Importing 的消息中;本示例不对 RFC 822Headers 进行任何处理。特别是,“收件人”和“发件人”地址必须明确包含在消息头中。
import smtplib
def prompt(prompt):
return 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 True:
try:
line = input()
except EOFError:
break
if not line:
break
msg = msg + line
print("Message length is", len(msg))
server = smtplib.SMTP('localhost')
server.set_debuglevel(1)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()
Note
通常,您将需要使用email软件包的Function来构造电子邮件,然后可以passsend_message()发送该电子邮件;参见email: Examples。