发送电子邮件
从古代的八百里加急,到现在的电子邮件,邮件的发展见证了上下五千年的发展史,这些当然是废话,只是要说说邮件的重要性。
可常规的通信手段相比,尤其是在现在,电话、QQ、微信等等各种社交软件的兴起,比传统的邮件和现在的电子邮件都快捷了很多;那为什么电子邮件还是显得那么重要呢~
电子邮件,目前来说在不同的行业中还是占据着非常重要的办公需求的地位的,常规情况下公司的任务分配、沟通、协作等等都是通过电子邮件进行处理的;同时,电子邮件本身的功能【邮件发送、群发、抄送、附件】让它更加社和较为正式的办公场合和日常较大数据的沟通;所以电子邮件的操作在各种编程语言中都有涉及和扩展;也是我们必须掌握的技能之一
1. 电子邮件的传输过程
我们回顾一下传统的邮件的发送过程(说白了就是写信),写信的过程如下图所示:
写好信件 -> 投递到邮筒 -> 邮局揽收所有的邮件 -> XX地区邮局 -> 传送到XX地区邮局 -> 投递 -> 个人邮筒 -> 看到信件
电子邮件的传输过程和传统的模式有点类似,也是我们自己有写邮件的电子邮件软件,写好的邮件点击发送,发送到邮件服务器,某邮件服务器将邮件通过网络传送到另一个邮件服务器,邮件服务器将邮件投递到目标用户的投递服务区,目标用户从投递服务区收取邮件。
电子邮件发送流程及术语解释
邮件发送处理过程:用户A发送邮件给用户B/C/D
术语解释:
MUA:Mail User Agent,邮件用户代理,我们可以简单的理解成我们使用的发送邮件的软件,如Foxmail、outlook、gmail等等,这样的软件可以编辑邮件,发送/收取邮件
MTA:Mail Transfer Agent,邮件传输代理,我们通常情况下,注册的邮箱都是属于某一个运营商的,如xx@qq.com这是腾讯的邮箱、xx@163.com这是网易的邮箱等等,通常运营商会有自己的服务器专门用于邮件的网络传输的,这里的MTA指代的就是运营商服务器
MDA:Mail Delivery Agent,邮件投递代理,我们发送的邮件,会默认保存在目标服务器中的投递服务区,需要目标用户从投递服务区中提取邮件(收取邮件)。
完成流程如下
邮件 -> MUA -> MTA -> … n个MTA -> MDA <- MUA <- 邮件
那我们程序中,如果要实现发送邮件和接收邮件的功能,就需要自己开发程序完成从MUA-> MTA发送的过程来完成发邮件的功能;同样需要完成从MUA->MDA收取邮件的过程完成收邮件的功能
2. SMTP发送邮件
smtp是发送邮件的一种常见的协议,python已经内置了smtp协议的支持,可以发送常规的邮件内容(文本、附件、网页等)
2.1. 模块简介
在邮件发送模块中,主要使用如下两个模块进行处理
- email模块:用于构建电子邮件对象的服务模块
- smtplib模块:用于电子邮件发送的服务模块
接下来,我们先了解一个简单的邮件发送程序
import email,smtplib
from email.mime.text import MIMEText
# 发送邮件服务器
smtp_server = "smtp.qq.com"
# 邮箱账号+密码
email_user = "xxxxxxxxx@qq.com"
email_pass = "qq用户请填写授权码"
# 发件人收件人信息
sender = email_user
receiver = "xxxxxx@xxxx.com"
# 发送的消息设置,plain表示文本,utf-8表示数据编码格式
msg = MIMEText("这是一份自动发送的测试邮件", "plain", "utf-8")
# 连接邮件服务器,用户登录, 发送邮件
server = smtplib.SMTP_SSL(smtp_server, 465)
server.set_debuglevel(1)
server.login(email_user, email_pass)
server.sendmail(sender, receiver, msg.as_string())
server.quit();
print("邮件发送结束")
上述代码是通过qq邮箱发送邮件的案例
使用QQ邮箱发送邮件时需要注意,如果正常情况下,需要开启smtp等服务,然后使用正确的登录账号和登录密码,如果一旦设置了QQ安全中心之类的,就需要通过设置授权码进行登录
打开网页版QQ邮箱,进入[设置]选项->进入[账户]选项,操作如下内容:
设置完上述内容之后,运行程序,我们在目标邮箱中就收到了对应的邮件
2.2. 发送完整邮件
上面的邮件我们已经看出来了,在收件箱中看到的邮件,只是包含了发件人邮箱和邮件的文本内容;邮件的标题、发件人名称、收件人名称、邮件的格式等等都没有进行处理。
在python的email模块中,可以通过设置Subject
设置邮箱标题,设置From
设置发件人信息,设置To
设置收件人信息
通常情况下,我们会将标题中的中文,使用email.header模块中的Header()方法进行编码以保证数据传输的正确性;
在常规邮箱处理过程中,收件人和发件人这两个信息的展示格式是类似于姓名 <xxxx@mail.com>
这样的格式,这种格式在python中通过email.utils模块中的parseaddr()
方法和formataddr()
方法进行处理的
# 导入需要的模块
import email, smtplib
from email.mime.text import MIMEText
from email.header import Header
from email.utils import parseaddr, formataddr
# 定义连接邮箱服务器的信息
smtp_server = "smtp.qq.com"
smtp_user = "xxxxxxxx@qq.com"
smtp_pass = "qq用户如果设置了安全策略的话这里要写授权码"
# 设置发件人、收件人
sender = smtp_user
receiver = "xxxxxx@xxxx.com"
# 定义用于编码发件人和收件人格式的方法
def _format_addr(user):
name, addr = parseaddr(user)
return formataddr((Header(name, "utf-8").encode(), addr))
# 开始发送邮件
# 连接服务器
server = smtplib.SMTP_SSL(smtp_server, 465)
# 登录服务器
server.login(smtp_user, smtp_pass)
# 设置内容,标题,发件人,收件人
msg = MIMEText("这是一个自动发送的邮件", "plain", "utf-8")
msg["subject"] = Header("来自大牧莫邪的问候")
msg["from"] = _format_addr("大牧莫邪 <%s>" % sender)
msg["to"] = _format_addr("牟文斌 <%s>" % receiver)
# 发送邮件
server.sendmail(sender, receiver, msg.as_string())
print("邮件发送成功")
可以看到,上面的代码中,我们对标题进行了编码设置,对发件人和收件人的格式进行了处理;[注意:现在的邮箱服务器,某些情况下不通过Header编码也可以正常识别中文,但是我们还是在代码中进行规范,防止出现中文乱码的BUG]
正确接收邮件:
2.3. 发送HTML格式的文件
在上面的内容中,我们已经看到了,发送邮件的内容,是通过MIMEText()函数进行规范的,如果设置了plain
选项表示发送文本邮件,如果我们设置html
就是发送的HTML格式的邮件,HTML标签需要被解析出来,请上干货:
import email, smtplib
from email.mime.text import MIMEText
from email.header import Header
from email.utils import parseaddr, formataddr
# 定义连接邮箱服务器的信息
smtp_server = "smtp.qq.com"
smtp_user = "1007821300@qq.com"
smtp_pass = "kyecgawxkkupbegh"
# 设置发件人、收件人
sender = smtp_user
receiver = "muwenbin@qikux.com"
# 设置对发件人、收件人格式化处理的方法
def _format_addr(user):
name, addr = parseaddr(user)
return formataddr((Header(name, "utf-8").encode(), addr))
# 设置连接邮箱服务器
server = smtplib.SMTP_SSL(smtp_server)
# 登录账号
server.login(smtp_user, smtp_pass)
# 设置邮箱标题、发件人、收件人、内容信息
msg = MIMEText("<h1>Hello 你好</h1>这是一封自动发送的测试邮件", "html", "utf-8")
msg["subject"] = Header("来自大牧莫邪的问候")
msg["from"] = _format_addr("大牧莫邪 <%s>" % sender)
msg["to"] = _format_addr("木木 <%s>" % receiver)
# 发送邮件
server.sendmail(sender, receiver, msg.as_string())
print("邮件发送完成")
邮件发送完成,收件箱中查看邮件
这里有人可能会有问题,谁TM没事干,写一个邮件写那么多的HTML标签进去呀,它疯了啊!
这里需要给大家普及一个前端的知识点,我们通常在网页中输入内容时,会添加富文本编辑器,如百度的UEditor,富文本编辑器中会带各种各样的格式,这些格式底层其实就是HTML标签,我们将用户在富文本编辑器中写的内容进行发送的时候,发送的就是HTML格式的文本数据
2.4. 邮件中添加附件
上面介绍了常规的邮件发送的处理手段,这里我们接着介绍一种非常常用的邮件内容的处理方式:添加附件
添加了附件的邮件,我们就需要对邮件进行拆分和组合的处理了。说简单一点就是将邮件内容和附件分别用对象表示,然后将不同的对象组合在一起作为一个完整的邮件即可
在python中,用MIMEText()服务类表示普通的邮件内容,用MIMEBase()服务类来表示我们的附件对象,然后将邮件内容和附件包装在MIMEMultipart()中形成一个完整的邮件进行发送
废话少说,上干货
# 导入需要的模块
import email, smtplib
from email import encoders
from email.utils import parseaddr, formataddr
from email.header import Header
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
# 定义连接邮箱服务器的信息
smtp_server = "smtp.qq.com"
smtp_user = "xxxxxxxxx@qq.com"
smtp_pass = "qq用户如果设置了安全验证,这里请填写您的授权码"
# 设置发件人、收件人
sender = smtp_user
receiver = "xxxxxx@xxxx.com"
# 设置收件人,发件人格式的方法
def _format_addr(user):
name, addr = parseaddr(user)
return formataddr((Header(name, "utf-8").encode(), addr))
# 连接服务器
server = smtplib.SMTP_SSL(smtp_server)
# 登录服务器
server.login(smtp_user, smtp_pass)
# 设置邮件内容[可以包装邮件内容和附件的MIMEMultipart对象]
msg = MIMEMultipart()
msg["subject"] = Header("来自大牧的问候", "utf-8")
msg["from"] = _format_addr("大牧来了 <%s>" % sender)
msg["to"] = _format_addr("牟文斌 <%s>" % receiver)
# 1.设置邮件正文内容
content = MIMEText("这是邮件正文内容部分", "plain", "utf-8")
# 将正文内容添加到包装对象中
msg.attach(content)
# 2.设置附件内容<使用本地的图片作为附件>
with open("d:/my.jpg", "rb") as f:
# 设置MIMEBase对象包装附件
attachment = MIMEBase("image", "jpg", filename="header.jpg")
# 设置附件信息
attachment.add_header("Content-Disposition", "attachment", filename="header.jpg")
attachment.add_header("Content-ID", "<0>")
attachment.add_header("X-Attachment-Id", "0")
# 读取附件内容
attachment.set_payload(f.read())
# 编码文件
encoders.encode_base64(attachment)
# 添加附件到包装对象中
msg.attach(attachment)
# 发送邮件
server.sendmail(sender, receiver, msg.as_string())
print("邮件发送成功")
运行上述程序之后,收件箱中,收到对应的邮件内容如下:
这里需要注意几个问题
- MIMEMultipart()对象也是一种邮件对象,可以包含多个组成部分
- MIMEText()对象主要用于进行邮件正文内容的设置,可以是纯文本,可以是HTML格式
- MIMEBase()对象主要用于进行附件的添加,常规情况下以独立文件对象的形式作为邮件内容的一部分而存在
完成的邮件格式是包含邮件正文内容和附件的
MIMEMultipart()
对象
2.5. 邮件中显示的图片
如果我们要在邮件中添加显示的图片应该怎么做呢~
按照我们常规的理解,可以通过将邮件内容修改为HTML,这样的话,图片就可以通过
标签插入进入了,难道不是吗?
邮件服务商们发现了一个问题,如果在邮件中可以任意添加链接的话,很容易让邮件作为一个犯罪的桥梁,把指向恶意网站或者服务的超链接带入我们的PC,所以常规情况下,邮件中会自动屏蔽带外链接图片的。
那应该怎么做呢?
其实邮件中的图片在python中处理的比较简单,邮件中需要的图片,通过附件的形式上传到邮件服务器,然后根据附件的顺序使用cid:num
添加就可以了,语法类似![](cid:0)
这是在正文中使用附件中的第一个图片
上干货:
# 导入需要的模块
import email, smtplib
from email import encoders
from email.utils import parseaddr, formataddr
from email.header import Header
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
# 定义连接邮箱服务器的信息
smtp_server = "smtp.qq.com"
smtp_user = "xxxxxxxxx@qq.com"
smtp_pass = "qq用户如果设置了安全验证,这里请填写您的授权码"
# 设置发件人、收件人
sender = smtp_user
receiver = "xxxxxx@xxxx.com"
# 设置收件人,发件人格式的方法
def _format_addr(user):
name, addr = parseaddr(user)
return formataddr((Header(name, "utf-8").encode(), addr))
# 连接服务器
server = smtplib.SMTP_SSL(smtp_server)
# 登录服务器
server.login(smtp_user, smtp_pass)
# 设置邮件内容[可以包装邮件内容和附件的MIMEMultipart对象]
msg = MIMEMultipart()
msg["subject"] = Header("来自大牧的问候", "utf-8")
msg["from"] = _format_addr("大牧来了 <%s>" % sender)
msg["to"] = _format_addr("牟文斌 <%s>" % receiver)
# 1.设置邮件正文内容
content = MIMEText("<h2>这是邮件正文内容部分</h2>![](cid:0)", "html", "utf-8")
# 将正文内容添加到包装对象中
msg.attach(content)
# 2.设置附件内容<使用本地的图片作为附件>
with open("d:/my.jpg", "rb") as f:
# 设置MIMEBase对象包装附件
attachment = MIMEBase("image", "jpg", filename="header.jpg")
# 设置附件信息
attachment.add_header("Content-Disposition", "attachment", filename="header.jpg")
attachment.add_header("Content-ID", "<0>")
attachment.add_header("X-Attachment-Id", "0")
# 读取附件内容
attachment.set_payload(f.read())
# 编码文件
encoders.encode_base64(attachment)
# 添加附件到包装对象中
msg.attach(attachment)
# 发送邮件
server.sendmail(sender, receiver, msg.as_string())
print("邮件发送成功")
上述代码执行完成后,在我们的收件箱中,赤果果个的就出现了下面的结果
附录:常见发送邮件服务器
| 邮箱|smtp服务器 |端口|
常用的邮箱服务器(SMTP、POP3)地址、端口
sina.com:
POP3服务器地址:pop3.sina.com.cn(端口:110)
SMTP服务器地址:smtp.sina.com.cn(端口:25)
sinaVIP:
POP3服务器:pop3.vip.sina.com (端口:110)
SMTP服务器:smtp.vip.sina.com (端口:25)
sohu.com:
POP3服务器地址:pop3.sohu.com(端口:110)
SMTP服务器地址:smtp.sohu.com(端口:25)
126邮箱:
POP3服务器地址:pop.126.com(端口:110)
SMTP服务器地址:smtp.126.com(端口:25)
139邮箱:
POP3服务器地址:POP.139.com(端口:110)
SMTP服务器地址:SMTP.139.com(端口:25)
163.com:
POP3服务器地址:pop.163.com(端口:110)
SMTP服务器地址:smtp.163.com(端口:25)
QQ邮箱
POP3服务器地址:pop.qq.com(端口:110)
SMTP服务器地址:smtp.qq.com (端口:25)
QQ企业邮箱
POP3服务器地址:pop.exmail.qq.com (SSL启用 端口:995)
SMTP服务器地址:smtp.exmail.qq.com(SSL启用 端口:587/465)
yahoo.com:
POP3服务器地址:pop.mail.yahoo.com
SMTP服务器地址:smtp.mail.yahoo.com
yahoo.com.cn:
POP3服务器地址:pop.mail.yahoo.com.cn(端口:995)
SMTP服务器地址:smtp.mail.yahoo.com.cn(端口:587
HotMail
POP3服务器地址:pop3.live.com (端口:995)
SMTP服务器地址:smtp.live.com (端口:587)
gmail(google.com)
POP3服务器地址:pop.gmail.com(SSL启用 端口:995)
SMTP服务器地址:smtp.gmail.com(SSL启用 端口:587)
263.net:
POP3服务器地址:pop3.263.net(端口:110)
SMTP服务器地址:smtp.263.net(端口:25)
263.net.cn:
POP3服务器地址:pop.263.net.cn(端口:110)
SMTP服务器地址:smtp.263.net.cn(端口:25)
x263.net:
POP3服务器地址:pop.x263.net(端口:110)
SMTP服务器地址:smtp.x263.net(端口:25)
21cn.com:
POP3服务器地址:pop.21cn.com(端口:110)
SMTP服务器地址:smtp.21cn.com(端口:25)
Foxmail:
POP3服务器地址:POP.foxmail.com(端口:110)
SMTP服务器地址:SMTP.foxmail.com(端口:25)
china.com:
POP3服务器地址:pop.china.com(端口:110)
SMTP服务器地址:smtp.china.com(端口:25)
tom.com:
POP3服务器地址:pop.tom.com(端口:110)
SMTP服务器地址:smtp.tom.com(端口:25)
etang.com:
POP3服务器地址:pop.etang.com
SMTP服务器地址:smtp.etang.com
接收电子邮件
通过SMTP协议发送邮件,我们通过POP3协议接收邮件
回顾一下邮件发送的过程
电子邮件 -> MUA -> MTA -> …MTA -> MDA <- MUA <- 电子邮件
我们发送邮件主要实现的是MUA->MTA的过程
使用的模块如下
smtplib
email.header.Header
email.utils.parseaddr/formataddr
email.mime.mutipart.MIMEMultipart
email.mime.base.MMEBase
email.mime.text.MIMEText
- POP3协议简介
- 收取邮件
1. POP3协议简介
1.1简介
POP3协议,全名为Post Office Protocol - Vesion 3,邮局协议 版本3
POP3协议是TCP/IP协议族中的一种,由RFC1939定义
协议主要用于支持使用客户端远程管理在服务器上的电子邮件
提供了SSL加密的POP3协议被称为POP3S
POP协议主持离线有限处理,通常情况下邮件发送到服务器上,电子邮件客户端将邮件从邮件服务器获取到个人终PC上,邮件服务器上的邮件会被删除;目前POP3邮件服务器大部分可以获取邮件的同时不删除服务器上的邮件
1.2特性
默认端口:110
默认传输协议:TCP
使用的软件结构:C/S
访问模式:离线访问
1.3 POP3常见命令码
1.4 python中使用POP3
python中提供了poplib模块用于进行POP3协议的支持
核心的处理过程主要是如下两个步骤
- 使用poplib模块接收邮件
- 使用email模块解析邮件
2. POP3读取邮箱信息
常规操作步骤:
- 定义连接pop3服务器的信息
- 连接pop3服务器
- 登录pop3服务器
- 获取邮件服务器中邮件的信息【数量、大小、列表等等】
import poplib
# 服务器连接信息
pop_user = "xxxxxxxxx@qq.com"
pop_pass = "这里请使用您的授权码"
pop_server = "pop.qq.com"
# 连接到pop3服务器
print("开始连接pop3服务器")
server = poplib.POP3_SSL(pop_server)
print("连接服务器成功")
# 设置打印调试信息
server.set_debuglevel(1)
# 设置打印pop3服务欢迎文字
print(server.getwelcome().decode("utf-8"))
# 登录服务器
print("准备登录POP服务器")
server.user(pop_user)
server.pass_(pop_pass)
print("登录身份验证成功,准备获取邮件信息")
# stat()返回邮件数量和占用空间
print("邮件数量:%s, 大小:%s" % server.stat())
print("~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~")
# 返回邮件详细列表信息mails
resp, mails, octets = server.list()
print(resp)
print(mails)
print(octets)
# 退出服务器
server.quit()
上述代码执行完成后,会出现如下结果:
注意:下面出现cmd字样的是调试信息,其中出现的类似USER/PASS等都是POP3的命令码,可以参考前面的命令码部分了解一下
开始连接pop3服务器
连接服务器成功
+OK QQMail POP3 Server v1.0 Service Ready(QQMail v2.0)
准备登录POP服务器
cmd ‘USER 1007821300@qq.com’
cmd ‘PASS kyecgawxkkupbegh’
登录身份验证成功,准备获取邮件信息
cmd ‘STAT’
stat [b’+OK’, b’105’, b’3796095’]
邮件数量:105, 大小:3796095
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
cmd ‘LIST’
b’+OK’
[b’1 36817’, b’2 27060’, b’3 1860’, b’4 63794’, b’5 73282’, b’6 5360’, b’7 35188’, b’8 19933’, b’82 7118’,·······b’100 2329’, b’101 36325’, b’102 28107’, b’103 28090’, b’104 29170’, b’105 28088’]
984
cmd ‘QUIT’
3. POP3读取最新的一封普通文本邮件
我们使用上一节中的发送邮件的代码发送一份纯文本的或者带了HTML标签的邮件,然后在下面的代码中接收一下这份邮件
# 引入需要的模块
import email, poplib
from email.parser import Parser
from email.utils import parseaddr
from email.header import decode_header
# 服务器连接信息
pop_server = "pop.qq.com"
pop_user = "xxxxxxxx@qq.com"
pop_pass = "此处请使用授权码"
# 连接pop服务器
server = pop.POP3_SSL(pop_server)
# 登录pop服务器,进行身份验证
server.user(pop_user)
server.pass_(pop_pass)
# 获取邮件服务器上的邮件的信息
email_msg = server.stat()
# 获取最新的一份邮件
# 注意:接收的邮件是按照索引进行排序的,这里的索引是1开始的
resp, lines, octets = server.retr(email_msg[0])
# 拼接完整邮件
email_content = b"\r\n".join(lines).decode("UTF-8")
# 解析邮件标题
title = email_content.get("Subject")
if title :
value, charset = decode_header(title)[0]
if charset:
title = value.decode(charset)
# 解析发件人信息
sender = email_content.get("From")
if sender:
value, addr = parseaddr(sender)
name, charset = decode_header(value)
if charset:
name = ame.decode(charset)
sender = u"%s <%s>" % (name, addr)
# 解析收件人信息
receiver = email_content.get("To")
if receiver:
value, addr = parseaddr(receiver)
name, charset = decode_header(value)
if charset:
name = name.decode(charset)
receiver = u"%s <%s>" % (name, addr)
# 解析邮件内容
content = email_content.get_payload(decode=True)
content = content.decode("UTF-8")
# 打印邮件内容
print("邮件标题:%s" % title)
print("发件人:%s" % sender)
print("收件人:%s" % receiver)
print("邮件内容:%s" % content)
# 退出邮件服务器
server.quit()
执行上述代码,运行结果如下:
邮件标题:来自大牧莫邪的问候
发件人: 大牧莫邪 xxxxxxxx@qq.com
收件人:木木 xxxxxxxxx@qq.com
邮件内容:Hello 你好,这是一封自动发送的测试邮件
我们针对上面的代码最一下简单的了解
邮件的标题、发件人、收件人,对应的是邮件内容中的Subject,From,To,这三个数据我们在学习完发送邮件部分之后已经了解到,是通过编码进行处理过的,所以我们要对这样的编码进行解码,解码的过程比较简单,通过如下的代码就可以进行解码的处理:
# 引入解码需要的模块
>from email.header import decode_header
from email.utils import parseaddr
> # 定义一个函数,用于解析邮件内容
>def decode_msg(msg)
# 解析邮件标题、发件人、收件人
> for info in ["Subject", "From", "To"]:
value = msg.get(info)
# 解析邮件标题
if info == "Subject":
# 标题不含特殊格式,直接解码
name, charset = decode_header(value)[0]
value = name.decode(charset)
else:
# 发件人、收件人格式特殊,使用parseaddr解析之后再进行解码
value, addr = parseaddr(msg)
name, charset = decode_header(value)[0]
value = name.decode_header(charset)
接下来就是内容的解析了,关于邮件内容的处理,我们从前面的发送邮件就知道,邮件内容主要是普通文本邮件包装的服务类MIMEText或者是带了附件的混合服务类MIMEMultipart,针对邮件的处理,只需要将邮件内容解析为Message对象,在后续处理过程中就可以方便的进行格式化,解析非常简单
# 引入解析需要的模块
from email.parser import Parser
# 解析邮件内容
content = Parse().parsestr(email_content)
4. POP3读取最新的带附件的邮件
某些情况下,我们的邮件内容是带附件的,是通过MIMEMultipart对象包含的邮件内容和附件,我们通常情况下,需要对MIMEMultipart对象进行遍历,对其中的MIMEText对象表示的邮件内容和MIMEBase对象表示的附件内容进行分别解析。
废话不多说,上干货:
第一步:分清楚什么是邮件标题、发件人、收件人;什么是邮件内容;什么是邮件附件
通过is_multipart()
函数来区分邮件是否是混合邮件
通过get_content_type()
函数来区分邮件是否是内容/附件
# 引入需要的模块
import email, poplib
from email.parser import Parser
from email.utils import parseaddr
from email.header import decode_header
# 定义解析邮件内容的函数
def decode_mail(msg):
# 解析邮件标题、发件人、收件人信息
for info in ["Subject", "From", "To"]:
value = msg.get(info)
if info == "Subject":# 解析邮件标题
title = decode_info(value)
else:# 解析发件人、收件人信息
name, addr = parseaddr(value)
sender = decode_info(name)
sender = "%s <%s>" % (name, addr)
# 如果邮件是MIMEMultipart混合内容,执行递归处理
if(msg.is_multipart()):
parts = msg.get_payload()
for n, part in enumerate(parts):
print(n, part)
# 递归解析邮件
decode_mail(part)
else:
# 获取邮件编码格式
content_type = msg.get_content_type();
# 判断编码并解码
if content_type == "text/plain" or content_type == "text/html":
content = "这是邮件内容"
else:
content = "这是邮件附件"
# decode_header解码操作函数
def decode_info(info):
name, charset = decode_header(info)
if charset:
name = name.decode(charset)
return name
上面的代码中,我们定义了函数
decode_mail(msg)
来进行邮件内容的解析处理
主要包含三部分内容
1.首先解析邮件标题、发件人、收件人这样的特殊的信息
2.根据is_multipart()
函数区分是否混合邮件
3.根据msg.get_content_type()
函数进行邮件内容和附件的区分处理
来源:https://www.jianshu.com/p/d5b648c0d901
https://www.jianshu.com/p/148d69995dcf