python:smtplib --- SMTP 协议客户端

  • 简介
  • SMTP 对象
  • SMTP 示例

简介

smtplib 模块定义了一个 SMTP 客户端会话对象,该对象可将邮件发送到互联网上任何带有 SMTP 或 ESMTP 监听程序的计算机。 关于 SMTP 和 ESMTP 操作的更多细节请参阅 RFC 821 (简单邮件传输协议) 和 RFC 1869 (SMTP 服务扩展)。
class smtplib.SMTP(host=‘’, port=0, local_hostname=None, [timeout, ]source_address=None)
SMTP 实例是对 SMTP 连接的封装。 它提供了支持各种 SMTP 和 ESMTP 操作的方法。 如果给出了可选的 host 和 port 形参,则会在初始化期间调用 SMTP connect() 方法并附带这些形参。 如果指定了 local_hostname,它将在 HELO/EHLO 命令中被用作本地主机的 FQDN。 在其他情况下,会使用 socket.getfqdn() 来找到本地主机名。 如果 connect() 调用返回了表示成功的代码以外的信息,则会引发 SMTPConnectError。 可选的 timeout 形参指定了阻塞操作如连接尝试的超时秒数(如果未指定,则将使用全局默认超时设置)。 如果达到超时限制,则会引发 TimeoutError。 可选的 source_address 形参允许在在有多张网卡的计算机中绑定到某些特定的源地址,和/或绑定到某些特定的源 TCP 端口。 它接受一个 2 元组 (host, port) 作为在连接之前所绑定作为其源地址的套接字。 如果省略(或者如果 host 或 port 为 ‘’ 和/或分别为 0)则将使用 OS 的默认行为。

正常使用时,只需要初始化或 connect 方法,sendmail() 方法,再加上 SMTP.quit() 方法即可。下文包括了一个示例。

SMTP 类支持 with 语句。当这样使用时,with 语句一退出就会自动发出 SMTP QUIT 命令。例如:

>>>
from smtplib import SMTP
with SMTP("domain.org") as smtp:smtp.noop()(250, b'Ok')
>>>

引发一个 审计事件 smtplib.send,附带参数 self, data。

在 3.3 版更改: 添加了对 with 语句的支持。

在 3.3 版更改: 添加了 source_address 参数。

3.5 新版功能: 现在已支持 SMTPUTF8 扩展 (RFC 6531)。

在 3.9 版更改: 如果 timeout 形参被设为零,则它将引发 ValueError 来阻止创建非阻塞的套接字

class smtplib.SMTP_SSL(host=‘’, port=0, local_hostname=None, keyfile=None, certfile=None, [timeout, ]context=None, source_address=None)
SMTP_SSL 实例与 SMTP 实例的行为完全相同。在开始连接就需要 SSL,且 starttls() 不适合的情况下,应该使用 SMTP_SSL。如果未指定 host,则使用 localhost。如果 port 为 0,则使用标准 SMTP-over-SSL 端口(465)。可选参数 local_hostname、timeout 和 source_address 的含义与 SMTP 类中的相同。可选参数 context 是一个 SSLContext 对象,可以从多个方面配置安全连接。请阅读 安全考量 以获取最佳实践。

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 证书。

在 3.9 版更改: 如果 timeout 形参被设为零,则它将引发 ValueError 来阻止创建非阻塞的套接字

class smtplib.LMTP(host=‘’, port=LMTP_PORT, local_hostname=None, source_address=None[, timeout])
LMTP 协议与 ESMTP 非常相似,它很大程度上基于标准的 SMTP 客户端。将 Unix 套接字用于 LMTP 是很常见的,因此 connect() 方法支持 Unix 套接字,也支持常规的 host:port 服务器。可选参数 local_hostname 和 source_address 的含义与 SMTP 类中的相同。要指定 Unix 套接字,host 必须使用绝对路径,以 ‘/’ 开头。

支持使用常规的 SMTP 机制来进行认证。 当使用 Unix 套接字时,LMTP 通常不支持或要求任何认证,但你的情况可能会有所不同。

在 3.9 版更改: 添加了可选的 timeout 形参。

同样地定义了一组精心选择的异常:

exception smtplib.SMTPException
OSError 的子类,它是本模块提供的所有其他异常的基类。

在 3.4 版更改: SMTPException 已成为 OSError 的子类

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

exception smtplib.SMTPResponseException
包括 SMTP 错误代码的所有异常的基类。 这些异常会在 SMTP 服务器返回错误代码时在实例中生成。 错误代码存放在错误的 smtp_code 属性中,并且 smtp_error 属性会被设为错误消息。

exception smtplib.SMTPSenderRefused
发送方地址被拒绝。 除了在所有 SMTPResponseException 异常上设置的属性,还会将 ‘sender’ 设为代表拒绝方 SMTP 服务器的字符串。

exception smtplib.SMTPRecipientsRefused
所有接收方地址被拒绝。 每个接收方的错误可通过属性 recipients 来访问,该属性是一个字典,其元素顺序与 SMTP.sendmail() 所返回的一致。

exception smtplib.SMTPDataError
SMTP 服务器拒绝接收消息数据。

exception smtplib.SMTPConnectError
在建立与服务器的连接期间发生了错误。

exception smtplib.SMTPHeloError
服务器拒绝了我们的 HELO 消息。

exception smtplib.SMTPNotSupportedError
尝试的命令或选项不被服务器所支持。

3.5 新版功能.

exception smtplib.SMTPAuthenticationError
SMTP 认证出现问题。 最大的可能是服务器不接受所提供的用户名/密码组合。

参见
RFC 821 - 简单邮件传输协议
SMTP 的协议定义。 该文件涵盖了 SMTP 的模型、操作程序和协议细节。

RFC 1869 - SMTP 服务扩展
定义了 SMTP 的 ESMTP 扩展。 这描述了一个用新命令扩展 SMTP 的框架,支持动态发现服务器所提供的命令,并定义了一些额外的命令。

SMTP 对象

一个 SMTP 实例拥有以下方法:

SMTP.set_debuglevel(level)
设置调试输出级别。 如果 level 的值为 1 或 True ,就会产生连接的调试信息,以及所有发送和接收服务器的信息。 如果 level 的值为 2 ,则这些信息会被加上时间戳。

在 3.5 版更改: 添调试级别 2 。

SMTP.docmd(cmd, args=‘’)
向服务器发送一条命令 cmd 。 可选的参数 args 被简单地串联到命令中,用一个空格隔开。

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

在正常操作中,应该没有必要明确地调用这个方法。它被用来实现其他方法,对于测试私有扩展可能很有用。

如果在等待回复的过程中,与服务器的连接丢失, SMTPServerDisconnected 将被触发。

SMTP.connect(host=‘localhost’, port=0)
连接到某个主机的某个端口。默认是连接到 localhost 的标准 SMTP 端口(25)上。如果主机名以冒号 (‘:’) 结尾,后跟数字,则该后缀将被删除,且数字将视作要使用的端口号。如果在实例化时指定了 host,则构造函数会自动调用本方法。返回包含响应码和响应消息的 2 元组,它们由服务器在其连接响应中发送。

触发一个 auditing event smtplib.connect,其参数为 self , host , port 。

SMTP.helo(name=‘’)
使用 HELO 向 SMTP 服务器表明自己的身份。 hostname 参数默认为本地主机的完全合格域名。服务器返回的消息被存储为对象的 helo_resp 属性。

在正常操作中,应该没有必要明确调用这个方法。它将在必要时被 sendmail() 隐式调用。

SMTP.ehlo(name=‘’)
使用 EHLO 向 ESMTP 服务器表明自己的身份。 hostname 参数默认为本地主机的完全合格域名。 检查 ESMTP 选项的响应,并存储它们供 has_extn() 使用。同时设置几个信息属性:服务器返回的消息被存储为 ehlo_resp 属性, does_esmtp 根据服务器是否支持 ESMTP 被设置为 True 或 False ,而 esmtp_features 将是一个字典,包含这个服务器支持的 SMTP 服务扩展的名称,以及它们的参数(如果有)。

除非你想在发送邮件前使用 has_extn() ,否则应该没有必要明确调用这个方法。 它将在必要时被 sendmail() 隐式调用。

SMTP.ehlo_or_helo_if_needed()
如果这个会话中没有先前的 EHLO 或 HELO 命令,该方法会调用 ehlo() 和/或 helo() 。它首先尝试 ESMTP EHLO 。

SMTPHeloError
服务器没有正确回复 HELO 问候。

SMTP.has_extn(name)
如果 name 在服务器返回的 SMTP 服务扩展集合中,返回 True ,否则为 False 。大小写被忽略。

SMTP.verify(address)
使用 SMTP VRFY 检查此服务器上的某个地址是否有效。 如果用户地址有效则返回一个由代码 250 和完整 RFC 822 地址(包括人名)组成的元组。 否则返回 400 或更大的 SMTP 错误代码以及一个错误字符串。

备注 许多网站都禁用 SMTP VRFY 以阻止垃圾邮件。
SMTP.login(user, password, *, initial_response_ok=True)
登录到一个需要认证的 SMTP 服务器。 参数是用于认证的用户名和密码。 如果会话在之前没有执行过 EHLO 或 HELO 命令,此方法会先尝试 ESMTP EHLO。 如果认证成功则此方法将正常返回,否则可能引发以下异常:

SMTPHeloError
服务器没有正确回复 HELO 问候。

SMTPAuthenticationError
服务器不接受所提供的用户名/密码组合。

SMTPNotSupportedError
服务器不支持 AUTH 命令。

SMTPException
未找到适当的认证方法。

smtplib 所支持的每种认证方法只要被服务器声明支持就会被依次尝试。 请参阅 auth() 获取受支持的认证方法列表。 initial_response_ok 会被传递给 auth()。

可选的关键字参数 initial_response_ok 对于支持它的认证方法,是否可以与 AUTH 命令一起发送 RFC 4954 中所规定的“初始响应”,而不是要求回复/响应。

在 3.5 版更改: 可能会引发 SMTPNotSupportedError,并添加 initial_response_ok 形参。

SMTP.auth(mechanism, authobject, *, initial_response_ok=True)
为指定的认证机制 mechanism 发送 SMTP AUTH 命令,并通过 authobject 处理回复响应。

mechanism 指定要使用何种认证机制作为 AUTH 命令的参数;可用的值是在 esmtp_features 的 auth 元素中列出的内容。

authobject 必须是接受一个可选的单独参数的可调用对象:

data = authobject(challenge=None)

如果可选的关键字参数 initial_response_ok 为真值,则将先不带参数地调用 authobject()。 它可以返回 RFC 4954 “初始响应” ASCII str,其内容将被编码并使用下述的 AUTH 命令来发送。 如果 authobject() 不支持初始响应(例如由于要求一个回复),它应当将 None 作为附带 challenge=None 调用的返回值。 如果 initial_response_ok 为假值,则 authobject() 将不会附带 None 被首先调用。

如果初始响应检测返回了 None,或者如果 initial_response_ok 为假值,则将调用 authobject() 来处理服务器的回复响应;它所传递的 challenge 参数将为一个 bytes。 它应当返回用 base64 进行编码的 ASCII str data 并发送给服务器。

SMTP 类提供的 authobjects 针对 CRAM-MD5, PLAIN 和 LOGIN 等机制;它们的名称分别是 SMTP.auth_cram_md5, SMTP.auth_plain 和 SMTP.auth_login。 它们都要求将 user 和 password 这两个 SMTP 实例属性设为适当的值。

用户代码通常不需要直接调用 auth,而是调用 login() 方法,它将按上述顺序依次尝试上述每一种机制。 auth 被公开以便辅助实现 smtplib 没有(或尚未)直接支持的认证方法。

3.5 新版功能.

SMTP.starttls(keyfile=None, certfile=None, context=None)
将 SMTP 连接设为 TLS (传输层安全) 模式。 后续的所有 SMTP 命令都将被加密。 你应当随即再次调用 ehlo()。

如果提供了 keyfile 和 certfile,它们会被用来创建 ssl.SSLContext。

可选的 context 形参是一个 ssl.SSLContext 对象;它是使用密钥文件和证书的替代方式,如果指定了该形参则 keyfile 和 certfile 都应为 None。

如果这个会话中没有先前的 EHLO or HELO 命令,该方法会首先尝试 ESMTP EHLO。

3.6 版后已移除: keyfile 和 certfile 已弃用并转而推荐 context。 请改用 ssl.SSLContext.load_cert_chain() 或让 ssl.create_default_context() 为你选择系统所信任的 CA 证书。

SMTPHeloError
服务器没有正确回复 HELO 问候。

SMTPNotSupportedError
服务器不支持 STARTTLS 扩展。

RuntimeError
SSL/TLS 支持在你的 Python 解释器上不可用。

在 3.3 版更改: 增加了 context。

在 3.4 版更改: 此方法现在支持使用 SSLContext.check_hostname 和 服务器名称指示符 (参见 HAS_SNI) 进行主机名检查。

在 3.5 版更改: 因缺少 STARTTLS 支持而引发的错误现在是 SMTPNotSupportedError 子类而不是 SMTPException 基类。

SMTP.sendmail(from_addr, to_addrs, msg, mail_options=(), rcpt_options=())
发送邮件。必要参数是一个 RFC 822 发件地址字符串,一个 RFC 822 收件地址字符串列表(裸字符串将被视为含有 1 个地址的列表),以及一个消息字符串。调用者可以将 ESMTP 选项列表(如 8bitmime)作为 mail_options 传入,用于 MAIL FROM 命令。需要与所有 RCPT 命令一起使用的 ESMTP 选项(如 DSN 命令)可以作为 rcpt_options 传入。(如果需要对不同的收件人使用不同的 ESMTP 选项,则必须使用底层的方法来发送消息,如 mail(), rcpt() 和 data()。)

备注 from_addr 和 to_addrs 形参被用来构造传输代理所使用的消息封包。 sendmail 不会以任何方式修改消息标头。
msg 可以是一个包含 ASCII 范围内字符的字符串,或是一个字节串。 字符串会使用 ascii 编解码器编码为字节串,并且单独的 \r 和 \n 字符会被转换为 \r\n 字符序列。 字节串则不会被修改。

如果在此之前本会话没有执行过 EHLO 或 HELO 命令,此方法会先尝试 ESMTP EHLO。 如果服务器执行了 ESMTP,消息大小和每个指定的选项将被传递给它(如果指定的选项属于服务器声明的特性集)。 如果 EHLO 失败,则将尝试 HELO 并屏蔽 ESMTP 选项。

如果邮件被至少一个接收方接受则此方法将正常返回。 在其他情况下它将引发异常。 也就是说,如果此方法没有引发异常,则应当会有人收到你的邮件。 如果此方法没有引发异常,它将返回一个字典,其中的条目对应每个拒绝的接收方。 每个条目均包含由服务器发送的 SMTP 错误代码和相应错误消息所组成的元组。

如果 SMTPUTF8 包括在 mail_options 中,并且被服务器所支持,则 from_addr 和 to_addrs 可能包含非 ASCII 字符。

此方法可能引发以下异常:

SMTPRecipientsRefused
所有收件人都被拒绝。 无人收到邮件。 该异常的 recipients 属性是一个字典,其中有被拒绝收件人的信息(类似于至少有一个收件人接受邮件时所返回的信息)。

SMTPHeloError
服务器没有正确回复 HELO 问候。

SMTPSenderRefused
服务器不接受 from_addr。

SMTPDataError
服务器回复了一个意外的错误代码(而不是拒绝收件人)。

SMTPNotSupportedError
在 mail_options 中给出了 SMTPUTF8 但是不被服务器所支持。

除非另有说明,即使在引发异常之后连接仍将被打开。

在 3.2 版更改: msg 可以为字节串。

在 3.5 版更改: 增加了 SMTPUTF8 支持,并且如果指定了 SMTPUTF8 但是不被服务器所支持则可能会引发 SMTPNotSupportedError。

SMTP.send_message(msg, from_addr=None, to_addrs=None, mail_options=(), rcpt_options=())
本方法是一种快捷方法,用于带着消息调用 sendmail(),消息由 email.message.Message 对象表示。参数的含义与 sendmail() 中的相同,除了 msg,它是一个 Message 对象。

如果 from_addr 为 None 或 to_addrs 为 None,那么send_message将根据 RFC 5322,从 msg 头部提取地址填充下列参数:如果头部存在 Sender 字段,则用它填充 from_addr,不存在则用 From 字段填充 from_addr。to_addrs 组合了 msg 中的 To, Cc 和 Bcc 字段的值(字段存在的情况下)。如果一组 Resent-* 头部恰好出现在 message 中,那么就忽略常规的头部,改用 Resent-* 头部。如果 message 包含多组 Resent-* 头部,则引发 ValueError,因为无法明确检测出哪一组 Resent- 头部是最新的。

send_message 使用 BytesGenerator 来序列化 msg,且将 \r\n 作为 linesep,并调用 sendmail() 来传输序列化后的结果。无论 from_addr 和 to_addrs 的值为何,send_message 都不会传输 msg 中可能出现的 Bcc 或 Resent-Bcc 头部。如果 from_addr 和 to_addrs 中的某个地址包含非 ASCII 字符,且服务器没有声明支持 SMTPUTF8,则引发 SMTPNotSupported 错误。如果服务器支持,则 Message 将按新克隆的 policy 进行序列化,其中的 utf8 属性被设置为 True,且 SMTPUTF8 和 BODY=8BITMIME 被添加到 mail_options 中。

3.2 新版功能.

3.5 新版功能: 支持国际化地址 (SMTPUTF8)。

SMTP.quit()
终结 SMTP 会话并关闭连接。 返回 SMTP QUIT 命令的结果。

与标准 SMTP/ESMTP 命令 HELP, RSET, NOOP, MAIL, RCPT 和 DATA 对应的低层级方法也是受支持的。 通常不需要直接调用这些方法,因此它们没有被写入本文档。 相关细节请参看模块代码。

SMTP 示例

这个例子提示用户输入消息封包所需的地址 (‘To’ 和 ‘From’ 地址),以及所要封包的消息。 请注意包括在消息中的标头必须包括在输入的消息中;这个例子不对 RFC 822 标头进行任何处理。 特别地,‘To’ 和 ‘From’ 地址必须显式地包括在消息标头中。

import smtplibdef 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:breakif not line:breakmsg = msg + lineprint("Message length is", len(msg))server = smtplib.SMTP('localhost')
server.set_debuglevel(1)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()

python:smtplib --- SMTP 协议客户端相关推荐

  1. smtplib python_smtplib —SMTP协议客户端

    ### 导航 - [索引](../genindex.xhtml "总目录") - [模块](../py-modindex.xhtml "Python 模块索引" ...

  2. python应用系列教程——python使用smtp协议发送邮件:html文本邮件、图片邮件、文件附件邮件

    全栈工程师开发手册 (作者:栾鹏) python教程全解 python使用smtp协议发送电子邮件.包含发送html文本邮件.包含图片附件的邮件,包含其他文件附件的邮件.可设置邮件的收发人,主题,内容 ...

  3. python smtplib.SMTP()发送邮件报“UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0xba in position 0: i

    python smtplib.SMTP()发送邮件报"UnicodeDecodeError: 'utf-8' codec can't decode byte 0xba in position ...

  4. python邮件客户端_python3之模块SMTP协议客户端与email邮件MIME对象

    1.smtplib模块的常用类与方法 smtplib模块实现邮件的发送功能,模拟一个stmp客户端,通过与smtp服务器交互来实现邮件发送的功能,可以理解成Foxmail的发邮件功能,在使用之前我们需 ...

  5. Python 使用SMTP协议发送邮件

    引言 问题基于<计算机网络自定向下>第二章的课后套接字编程作业:邮件客户 题目的下载链接:python 压缩包 题目如下: 这个实验结束时,您将能够更好地了解SMTP协议.您还将获得使用P ...

  6. python无限制邮件群发软件_收藏 - 使用Python通过SMTP协议群发/单发邮件方法

    由于可能需要的功能,寻找可以群发邮件的办法,寻找过几个免费和付费平台,但是均不是特别满意.于是老唐同学说可以用Python结合阿里云邮件推送服务.这里把可以实现的Python SMTP脚本整理出来,脚 ...

  7. Python——Python使用POP3协议客户端poplib登录邮箱并解压缩zip、rar压缩包

    文章目录 1. 项目背景 2. poplib模块 3. 邮箱登录 4. 获取邮件内容 1. 获取邮件基本信息 2. 获取邮件中的附件 5. 解压zip/rar压缩包 1. 打开zip/rar压缩包 2 ...

  8. 【Python学习笔记】(十)邮件处理:email模块;SMTP协议(smtplib模块);POP3协议(poplib模块);IMAP协议(imaplib模块)

    电子邮件,简称电邮,是指一种由寄件人将数字信息发送给一个人或者多个人的信息交换方式. 电邮包括三个部分:消息的"信封".邮件标头.邮件内容. 电邮的格式:用户名@主机名(域名).电 ...

  9. 深入理解SMTP协议之邮件客户端

    本文将使用Python从零实现一个简易的邮件客户端,通过本文你将对SMTP协议有更深入的了解,同时掌握使用Python实现标准协议的经验. 我们将开发一个简单的邮件客户端,将邮件发送给任意收件人.我们 ...

最新文章

  1. ACM-ICPC历届世界总冠军名单1977-2015
  2. golang中的strings.Index
  3. 【学习笔记】2、Python - Jupyter Notebook界面基础
  4. Python安装错误 building 'statsmodels. extensionerror: Microsoft Visual C++ 14.0 is
  5. 配置Django实现数据库读写分离
  6. Spring AOP EXPRESSION
  7. HiKey960 开发板 android 编译
  8. 计算机一级上机考试试题题库,2016年计算机一级上机考试题库
  9. asp.net页面绑定数据的方式-----未完待续
  10. jQuery BreakingNews 间歇滚动
  11. 从0-1背包问题学习回溯法、分支界限法、动态规划
  12. 解题: SDOI 2011 染色
  13. 设计模式:策略模式(C++)【诸葛亮的锦囊妙计】
  14. QTableView修改数据后弹出是否保存的提示框。
  15. 计算机二级关系模式知识点,2013年计算机二级VFP关系模式知识点详解
  16. listview控件在php的使用方法,VBA窗体之ListView控件的基本应用 | VBA实例教程
  17. 字符串与整型的相互转换
  18. 荣耀60 SE参数配置
  19. 计算机桌面图标不可以移动怎么调,win10电脑桌面图标不能移动怎么办,win10桌面图标移动不了的解决方法...
  20. 电子实训与毕业设计开放式训练装置

热门文章

  1. 中高端投影仪当贝X3、极米H3S和坚果J10S哪个好?哪个值得买?
  2. AutoCAD .Net 遍历组
  3. 表达式和内部函数(运算符/连接符/数字函数/字符串函数/日期函数/转换函数/format函数)
  4. source命令相当于(.)命令
  5. 【力扣日记】018 四数之和
  6. 北理宋文杰:时空域下智能车辆未知区域自主导航技术
  7. 卫士处刑者冠军css3边,装备_流放之路3.9卫士流血BD_3.9冠军流血弓刷图BD攻略_3DM网游...
  8. 支付宝对接-查询对账单下载地址接口 遇到的坑
  9. 神经网络架构搜索(NAS)基础
  10. excel怎么设置打印区域_Excel2019怎么设置打印区域?Excel2019打印区域设置方法