– SMTP协议客户端 – Internet协议和支持(Python教程)(参考资料)
smtplib– SMTP协议客户端
源代码: Lib / smtplib.py
smtplib模块定义了一个可用于发送邮件的SMTP客户端会话对象到具有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操作。如果给出了可选的主机和端口参数,则在初始化期间使用这些参数调用SMTPconnect()方法。如果指定,则local_hostname用作HELO / EHLO命令中本地主机的FQDN。否则,使用socket.getfqdn()找到本地主机名。如果connect()调用返回除成功代码之外的任何内容,则会引发SMTPConnectError。可选timeout参数指定阻塞操作(如连接尝试)的超时(以秒为单位)(如果未指定,将使用全局默认超时设置)。如果超时到期,则socket.timeoutisraised。可选的source_address参数允许绑定到具有多个网络接口的机器中的某个特定源地址,和/或某个特定源TCP端口。它需要一个2元组(主机,端口),以便在连接之前将套接字绑定为其源地址。如果省略(或主机或端口分别为""和/或0),将使用OS默认行为.对于正常使用,您应该只需要初始化/连接,
sendmail()和SMTP.quit()方法。下面有一个例子.SMTP类支持with语句。像这样使用时,QUIT语句退出时会自动发出SMTPwith命令。例如:>>> from smtplib import SMTP>>> with SMTP("domain.org") as smtp:... smtp.noop()...(250, b"Ok")>>>在版本3.3中更改:添加了对
with语句的支持.在版本3.3中更改:添加了source_address参数.
- 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,则使用本地主机。如果port为零,则使用标准的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.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非常相似,严重依据标准SMTP客户端。对于LMTP使用Unix套接字是很常见的,所以我们的
connect()方法必须支持它以及常规主机:portserver。可选参数local_hostname和source_address具有与SMTP类中相同的含义。要指定Unixsocket,必须使用host的绝对路径,以’/’开头.使用常规SMTP机制支持身份验证。当使用unix套接字时,LMTP通常不支持或要求任何身份验证,但你的里程可能会有所不同.
也定义了很好的异常选择:
- exception
smtplib.SMTPException -
的子类
OSError这是该模块提供的所有其他异常的基本异常类.版本3.4更改:SMTPException成为
OSError
- 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身份验证出错了。很可能服务器不接受提供的用户名/密码组合.
参见
SMTP对象
SMTP实例有以下方法:
SMTP.set_debuglevel(level)-
设置调试输出级别。对于
True,值为1或level导致连接的调试消息以及发送到服务器和从服务器接收的所有消息。level导致这些消息被加上时间戳在版本3.5中更改:添加了debuglevel 2.
SMTP.docmd(cmd, args=””)-
向服务器发送命令cmd。可选参数args简单地与命令相连,用空格分隔.
这将返回一个由数字响应代码和实际响应行组成的2元组(多行响应连接成一条长行。)
在正常操作中,没有必要显式调用此方法。它用于实现其他方法,可能对测试privateextensions有用.
如果在等待回复时丢失了与服务器的连接,则
SMTPServerDisconnected将被抬起.
SMTP.connect(host=”localhost”, port=0 )-
连接到给定端口上的主机。默认设置是连接到标准SMTP端口(25)的localhost。如果主机名以冒号结尾(
":")后跟一个数字,该后缀将被剥离,并将该数字解释为要使用的端口号。如果在实例化期间指定了主机,则构造函数会自动调用此方法。返回服务器在其连接响应中发送的响应代码和消息的a2元组.
SMTP.helo(name=””)-
使用
HELO。hostname参数默认为本地主机的完全限定域名。服务器返回的消息存储为对象的helo_resp属性.在正常操作中,没有必要明确地调用这个方法。必要时会被
sendmail()隐式调用.
SMTP.ehlo(name=””)-
使用
EHLO。hostname参数默认为本地主机的完全限定域名。检查ESMTP选项的响应并将其存储以供has_extn()。还设置了几个信息属性:服务器返回的消息存储为ehlo_resp属性,does_esmtp设置为true或false,具体取决于服务器是否支持ESMTP,esmtp_features将是一个字典,其中包含此服务器支持的SMTP服务扩展名及其参数(如果有).除非您想使用
has_extn()在发送邮件之前,不必明确地调用此方法。它会被sendmail()必要时。
SMTP.ehlo_or_helo_if_needed()-
这个方法叫
ehlo()和/或helo()如果有一个不太明显的EHLO或HELO指挥本次会议。它尝试了ESMTPEHLO第一个SMTPHeloError- 服务器没有正确回复
HELO问候
SMTP.has_extn(name)-
返回
True如果name在服务器返回的SMTP服务扩展集中,False除此以外。案件被忽略了
SMTP.verify(address)-
使用SMTP
VRFY。返回包含代码250和完整 RFC 822 如果用户地址有效,则为地址(包括人名)。否则返回一个400或更大的SMTP错误代码和一个错误字符串.注意
许多网站禁用SMTP
VRFY为了欺骗垃圾邮件发送者.
SMTP.login(user, password, *, initial_response_ok=True)-
登录需要验证的SMTP服务器。参数是用于进行身份验证的用户名和密码。如果以前没有
EHLO或HELO命令此会话,此方法首先尝试ESMTPEHLO。如果验证成功,此方法将正常返回,或者可能引发以下异常:SMTPHeloError- 服务器没有正确回复
HELOgreeting. SMTPAuthenticationError- 服务器不接受用户名/密码组合.
SMTPNotSupportedErrorAUTH服务器不支持命令.SMTPException- 没有找到合适的身份验证方法.
如果它们被广告宣传为服务器支持,则
smtplib支持的每种身份验证方法都会被尝试。见auth()获取支持的身份验证方法列表。initial_response_ok通过auth().可选关键字参数initial_response_ok指定支持它的forauthentication方法, RFC 4954 中指定的“初始响应”是否可以与
AUTH命令,而不是要求挑战/响应.版本3.5改变:
SMTPNotSupportedError可能会被提升,并且initial_response_ok参数被添加了
SMTP.auth(mechanism, authobject, *, initial_response_ok=True/)-
发一个
SMTPAUTH命令用于指定的验证mechanism,并通过authobject.mechanism处理质询响应,指定哪个验证机制用作
AUTH命令;authesmtp_features.authobject元素中列出的有效值必须是一个可调用的对象,它带有一个可选的单个参数:
data = authobject(challenge = None)如果可选的关键字参数initial_response_ok为true,则
authobject()将首先调用,不带参数。它可以返回 RFC 4954 “初始响应”ASCIIstr,它将被编码并与AUTH命令如下。如果authobject()不支持初始响应(例如因为它需要一个挑战),它应该在None调用时返回challenge=None。如果initial_response_ok是假的,那么authobject()不会先用None.如果初始响应检查返回
None, 或者如果 initial_response_ok是的,authobject()将被调用来处理服务器的challengeresponse;challenge它传递的参数将是bytes。它应该返回ASCIIstrdata,它将被base64编码并发送到服务器.SMTPclass为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()again.如果keyfile和certfile提供,它们用于创建
ssl.SSLContext.可选context参数是
ssl.SSLContext对象;这是使用密钥文件和证书文件的替代方法,如果指定keyfile和certfile应该是None.如果以前没有
EHLO或HELO命令这个会话,这个方法首先尝试ESMTPEHLO.自版本3.6以后删除:keyfile和certfile不赞成使用context。请用
ssl.SSLContext.load_cert_chain()相反,或者让ssl.create_default_context()为您选择系统的可信任CA证书.SMTPHeloError- 服务器没有正确回复
HELOgreeting. SMTPNotSupportedError- 服务器不支持STARTTLS扩展.
RuntimeError- 您的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=())-
发送邮件。所需的参数是 RFC 822 from-address字符串, RFC 822 列表到地址字符串(一个简单的字符串将是被视为具有1address的列表)和消息字符串。调用者可以传递一个ESMTP选项列表(例如
8bitmime)以在MAIL FROM命令中使用mail_options.ESMTP选项(例如DSN命令))应该与所有RCPT命令一起使用,可以作为rcpt_options传递。(如果需要对不同的收件人使用不同的ESMTPoptions,则必须使用低级方法,如mail(),rcpt()和data()来发送邮件。)注意
from_addr和to_addrs参数用于构造传输代理使用的messageenvelope。
sendmail不会以任何方式修改themessage标题.msg可以是包含ASCII范围内的字符或字节串的字符串。使用ascii编解码器将字符串编码为字节,并将单独的
\r和\n字符转换为\r\n字符。字节串没有被修改.如果以前没有
EHLO或HELO命令这个会话,这个方法首先尝试ESMTPEHLO。如果服务器执行ESMTP,则会将消息大小和指定选项的每个传递给它(如果该选项位于服务器通告的特征集中)。如果EHLO失败,HELO将被尝试并且ESMTP选项被抑制.如果邮件被至少一个接收者接受,则此方法将正常返回。否则会引发异常。也就是说,如果此方法不会引发异常,那么有人应该收到您的邮件。如果此方法不引发异常,则返回一个字典,每个被拒绝的一个条目都有一个条目。每个条目都包含一个SMTP错误代码元组和服务器发送的随附错误消息.
如果
SMTPUTF8包含在mail_options中,服务器支持它,from_addr和to_addrs可能包含非ASCII字符.此方法可能会引发以下异常:
SMTPRecipientsRefused- 所有收件人都被拒绝了。没有人收到邮件。异常对象的
recipients属性是一个字典,其中包含有关已注入的收件人的信息(如至少有一个收件人被收到时返回的那个). SMTPHeloError- 服务器没有正确回复
HELO问候 SMTPSenderRefused- 服务器不接受from_addr.
SMTPDataError- 服务器回复了一个意外的错误代码(除了拒绝接受者).
SMTPNotSupportedErrorSMTPUTF8在mail_options中给出但服务器不支持.
除非另有说明,否则即使在异常情况下连接也会打开.
在版本3.2中更改:msg可能是一个字节串.
在版本3.5中更改:
SMTPUTF8支持补充,和SMTPNotSupportedError如果指定了SMTPUTF8但是服务器不支持它可以进行评估.
SMTP.send_message(msg, from_addr=None, to_addrs=None, mail_options=(), rcpt_options=())-
这是一个方便的方法来调用
sendmail()由email.message.Message宾语。这些论点与sendmail()的含义相同,除了msg是Messageobject.如果from_addr是
None或to_addrs是None,send_message使用从msg在中指定RFC 5322 :from_addr设置为Sender字段,如果它存在,否则到From领域。to_addrs结合To,Cc的Bcc和msg字段的值(如果有的话)。如果消息中只出现一对Resent-*标题,则忽略常规标题和Resent-*使用标题。如果消息包含多个Resent-*标题集,则会引发ValueError,因为无法明确地检测到最新的Resent-集合headers.send_message序列化msg使用BytesGenerator和\r\n作为linesep,并调用sendmail()来传输结果消息。无论from_addr和to_addrs,send_message的值如何都不传送任何Bcc或Resent-Bcc可能出现在msg的标题。如果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: break if not line: break msg = msg + lineprint("Message length is", len(msg))server = smtplib.SMTP("localhost")server.set_debuglevel(1)server.sendmail(fromaddr, toaddrs, msg)server.quit()
注意
一般来说,你会想要使用email包的功能包括一个电子邮件消息,然后您可以发送send_message();看电子邮件:例子.
评论被关闭。