一.email - 电子邮件与 MIME 处理包
email
包是一个用于管理电子邮件消息的库。 它 并非 被设计为执行向 SMTP (RFC 2821), NNTP 或其他服务器发送电子邮件消息的操作;这些是 smtplib
和 nntplib
等模块的功能。 email
包试图尽可能遵循 RFC,支持 RFC 5233 和 RFC 6532,以及与 MIME 相关的各个 RFC 例如 RFC 2045, RFC 2046, RFC 2047, RFC 2183 和 RFC 2231。
email 包的总体结构可以分为三个主要部分,另外还有第四个部分用于控制其他部分的行为。
这个包的中心组件是代表电子邮件消息的“对象模型”。 应用程序主要通过在 message
子模块中定义的对象模型接口与这个包进行交互。 应用程序可以使用此 API 来询问有关现有电子邮件的问题、构造新的电子邮件,或者添加或移除自身也使用相同对象模型接口的电子邮件子组件。 也就是说,遵循电子邮件消息及其 MIME 子组件的性质,电子邮件对象模型是所有提供 EmailMessage
API 的对象所构成的树状结构。
这个包的另外两个主要组件是 parser
和 generator
。 parser 接受电子邮件消息的序列化版本(字节流)并将其转换为 EmailMessage
对象树。 generator 接受 EmailMessage
并将其转回序列化的字节流。 (parser 和 generator 还能处理文本字符流,但不建议这种用法,因为这很容易导致某种形式的无效消息。
控制组件是 policy
模块。 每一个 EmailMessage
、每一个 generator
和每一个 parser
都有一个相关联的 policy
对象来控制其行为。 通常应用程序只有在 EmailMessage
被创建时才需要指明控制策略,或者通过直接实例代 EmailMessage
来新建电子邮件,或者通过使用 parser
来解析输入流。 但是策略也可以在使用 generator
序列化消息时被更改。 例如,这允许从磁盘解析通用电子邮件消息,而在将消息发送到电子邮件服务器时使用标准 SMTP 设置对其进行序列化。
email 包会尽量地对应用程序隐藏各种控制类 RFC 的细节。 从概念上讲应用程序应当能够将电子邮件消息视为 Unicode 文本和二进制附件的结构化树,而不必担心在序列化时要如何表示它们。 但在实际中,经常有必要至少了解一部分控制类 MIME 消息及其结构的规划,特别是 MIME “内容类型” 的名称和性质以及它们是如何标识多部分文档的。 在大多数情况下这些知识应当仅对于更复杂的应用程序来说才是必需的,并且即便在那时它也应当仅是特定的高层级结构,而不是如何表示这些结构的细节信息。 由于 MIME 内容类型被广泛应用于现代因特网软件(而非只是电子邮件),因此这对许多程序员来说将是很熟悉的概念。
以下小节描述了 email
包的具体功能。 我们会从 message
对象模型开始,它是应用程序将要使用的主要接口,之后是 parser
和 generator
组件。 然后我们会介绍 policy
控制组件,它将完成对这个库的主要组件的处理。
接下来的三个小节会介绍这个包可能引发的异常以及 parser
可能检测到的缺陷(即与 RFC 不相符)。 然后我们会介绍 headerregistry
和 contentmanager
子组件,它们分别提供了用于更精细地操纵标题和载荷的工具。 这两个组件除了包含使用与生成非简单消息的相关特性,还记录了它们的可扩展性 API,这将是高级应用程序所感兴趣的内容。
在此之后是一组使用之前小节所介绍的 API 的基本部分的示例。
前面的内容是 email 包的现代(对 Unicode 支持良好)API。 从 Message
类开始的其余小节则介绍了旧式 compat32
API,它会更直接地处理如何表示电子邮件消息的细节。 compat32
API 不会 向应用程序隐藏 RFC 的相关细节,但对于需要进行此种层级操作的应用程序来说将是很有用的工具。 此文档对于因向下兼容理由而仍然使用 compat32
API 的应用程序也是很适合的。
email
包文档的内容:
- 19.1.1.
email.message
: 表示一封电子邮件信息 -
19.1.2.
email.parser
: 解析电子邮件信息 - 19.1.3.
email.generator
: 生成 MIME 文档 - 19.1.4.
email.policy
: 策略对象 - 19.1.5.
email.errors
: 异常和缺陷类 - 19.1.6.
email.headerregistry
: 自定义标头对象 -
19.1.7.
email.contentmanager
: 管理 MIME 内容 - 19.1.8.
email
: 示例
二.发送邮件简要概述
2.1 python发邮件所需要的基础包
python发送邮件需要用到python自带的两个模块,smtplib和email。直接import导入,无需下载。
python的smtplib提供了一种很方便的途径发送电子邮件,它对smtp协议进行了简单的封装。
2.2 smtplib的用法
smtplib用法相对来说很简单,就是分为两步。
- 创建SMTP的操作对象并连接smtp目标服务器,可以是163、QQ等
- 根据自己的账号登录目标服务器(自己的邮箱地址和邮箱授权码)
- 调用对象中的方法,发送邮件到目标地址
python与smtp服务器之间的具体交互的通用代码:
import smtplib
server = smtplib.SMTP(mailserver, port) # 发件人邮箱中的SMTP服务器,端口是25
server.login(sender, passwd) # 发件人邮箱账号、邮箱授权码
# msg.as_string()中as_string()是将msg(MIMEText或MIMEMultipart对象)变为str。
server.sendmail(sender, receive, msg.as_string())
server.quit()
具体的python连接目标服务器的代码如下:注:本文章用的是qq的smtp服务器。
常用邮箱的smtp服务器地址:
新浪邮箱:smtp.sina.com,搜狐邮箱:smtp.sohu.com,qq邮箱:smtp.qq.com
2.3 email模块的详细理解和使用
email模块下的mime模块下有常用的三个模块,三个模块中有三个大类。其实就是下边这三个了,说的很绕,下边为导入方式,一目了然。
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
简单说下他们的关系,如果构造一个MIMEText对象,就表示一个文本邮件对象,如果构造一个MIMEImage对象,就表示一个作为附件的图片对象,要把多个对象组合起来,就用MIMEMultipart对象,他代表的是整个邮件。这样说应该还不是很清晰,下边就分开来说,最后会总的总结,在最后边就是完整的代码(可以发送一切内容的代码)。
A.MIMEText对象中有三个需要我们设置的参数,一个是正文内容,一个是正文内容的类型,例如:”text/plain”和”text/html”,一个是正文内容的编码。
十.email案例
这里整理了一个发送邮件的案例。
包含发送html、图片、附件等。
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
import smtplib
# 配置邮箱及密码
from_mail = 'frommail@163.com'
from_mail_password = 'passwd'
to_mail = '2594398228@qq.com'
# 设置总的邮件体对象,对象类型为mixed
msg = MIMEMultipart('mixed')
# 邮件的发件人及收件人信息
msg['From'] = from_mail
msg['To'] = to_mail
# 邮件的主题
msg['Subject'] = 'python mail test'
# 构造文本内容
text_info = 'hello world'
text_sub = MIMEText(text_info, 'plain', 'utf-8')
msg.attach(text_sub)
# 构造超文本
url = "https://blog.csdn.net/u010520724"
html_info = """
<p>点击以下链接,你会去向一个更大的世界</p>
<p><a href="%s">click me</a></p>
<p>i am very galsses for you</p>
"""% url
html_sub = MIMEText(html_info, 'html', 'utf-8')
# 如果不加下边这行代码的话,上边的文本是不会正常显示的,会把超文本的内容当做文本显示
html_sub["Content-Disposition"] = 'attachment; filename="csdn.html"'
# 把构造的内容写到邮件体中
msg.attach(html_sub)
# 构造图片
image_file = open(r'E:\python\python.jpg', 'rb').read()
image = MIMEImage(image_file)
image.add_header('Content-ID', '<image1>')
# 如果不加下边这行代码的话,会在收件方方面显示乱码的bin文件,下载之后也不能正常打开,这个地方也可以对文件重命名
image["Content-Disposition"] = 'attachment; filename="red_people.png"'
msg.attach(image)
# 构造附件
txt_file = open(r'E:\python\test2.py', 'rb').read()
txt = MIMEText(txt_file, 'base64', 'utf-8')
txt["Content-Type"] = 'application/octet-stream'
#以下代码可以重命名附件为hello_world.txt
txt.add_header('Content-Disposition', 'attachment', filename='test.py')
msg.attach(txt)
try:
server = smtplib.SMTP('smtp.163.com')
server.docmd('ehol', from_mail)
server.starttls()
server.login(from_mail,from_mail_password)
server.sendmail(from_mail,to_mail,msg.as_string())
server.quit()
print('sendemail successful!')
except Exception as e:
print('sendemail failed next is the reason')
print(e)
查看发送记录:
参考:
1.https://docs.python.org/zh-cn/3.6/library/email.html
2.https://www.cnblogs.com/-wenli/p/10816927.html
3.https://blog.csdn.net/chinesepython/article/details/82465947