原文链接:
https://www.jianshu.com/p/369ec15bfe22
本文介绍python发送邮件模块smtplib以及相关MIME模块。
smtplib用于生成邮件发送的代理,发送邮件前需要通过MIMEText构造邮件内容。
发送纯文本邮件
下面是个发送纯文本邮件的例子。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
import smtplib from email.mime.text import MIMEText msg_from='XXXXX@163.com' passwd='XXXXX' msg_to='XXXXX@qq.com'
subject="python邮件测试" content="这是我使用python smtplib及email模块发送的邮件"
msg = MIMEText(content) msg['Subject'] = subject msg['From'] = msg_from msg['To'] = msg_to try: #s = smtplib.SMTP_SSL("smtp.163.com",465) s = smtplib.SMTP("smtp.163.com",25) s.login(msg_from, passwd) s.sendmail(msg_from, msg_to, msg.as_string()) print ("发送成功") except smtplib.SMTPException as e: print ("发送失败") finally: s.quit()
|
MIMEText实例化一个邮件对象,内容为content,对于邮件标题Subject,发件人From,以及收件人To
需要以字典形式指出,或者通过add_header(下文会给出)添加,否则对方看不到这些信息。
想要通过smtp发送邮件,需要打开指定邮箱的smtp协议,以及设置smtp授权密码。我设置的是163邮箱的。


设置好密码后,将上述代码中的passwd改为你的密码,msg_from改为你的邮箱。smtplib可以通过SMTP_SSL
发送,也可以采用普通形式直接初始化,对应的两个参数分别是授权的smtp服务器地址和端口号,因为我
设置的是163的,所以使用smtp.163.com服务器地址,端口号和服务器地址读者可以自己去查。通过生成的
smtp实例,一次调用login,sendemail就可以发送了。最后记得调用quit退出。
发送一封纯文本邮件,看一下效果

我们发现发件人标题显示的只有邮箱地址,没有昵称,可以采用parseaddr和formataddr对发件人信息完善。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
def _format_addr(s): name, addr = parseaddr(s) return formataddr((Header(name, 'utf-8').encode(), addr))
import smtplib from email.header import Header from email.mime.text import MIMEText from email.utils import parseaddr, formataddr
msg_from='XXXXX@163.com' passwd='XXXXX' msg_to='XXXXX@qq.com' receivers = ['XXXXX@qq.com']
subject="python邮件测试" content="这是我使用python smtplib及email模块发送的邮件"
msg = MIMEText(content,'plain','utf-8') msg['Subject'] = Header(subject,'utf-8').encode() msg['From'] = _format_addr('恋恋风辰 <%s>' %msg_from) msg['To'] = msg_to
try: #s = smtplib.SMTP_SSL("smtp.163.com",465) s = smtplib.SMTP("smtp.163.com",25) s.login(msg_from, passwd) s.sendmail(msg_from, receivers, msg.as_string()) print ("发送成功") except smtplib.SMTPException as e: print ("发送失败") finally: s.quit()
|
这样可以看到发件人的昵称了。我设置的是恋恋风辰。Header函数的作用是防止中文乱码。
Header对字符串按照utf-8方式编码。MIMEText中参数plain表示纯文本,utf-8表示纯文本
的编码方式。

发送html邮件
发送html邮件和之前发送纯文本类似,只需要将plain变为html,即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
def _format_addr(s): name, addr = parseaddr(s) return formataddr((Header(name, 'utf-8').encode(), addr))
import smtplib from email.header import Header from email.mime.text import MIMEText from email.utils import parseaddr, formataddr msg_from = 'XXXXXX@163.com' passwd = 'XXXXX' msg_to='XXXXXX@qq.com' receivers = ['XXXXXX@qq.com'] subject = 'python邮件测试html' content = '<html><body><h1>Hello</h1>' +\ '<p>send by <a href="http://www.python.org">Python</a>...</p>'
msg = MIMEText(content, 'html', 'utf-8') msg['Subject'] = Header(subject, 'utf-8').encode() msg['From'] = _format_addr('恋恋风辰 <%s>' %msg_from) msg['To'] = msg_to
try: s = smtplib.SMTP("smtp.163.com",25) s.login(msg_from, passwd) s.sendmail(msg_from, receivers, msg.as_string()) print('发送成功') except smtplib.SMTPException as e: print('发送失败') finally: s.quit()
|
看看效果:

发送带附件的邮件
发送带附件的邮件,和之前不同,需要通过MIMEMultipart创建邮件实例,
然后将文本,附件等通过attach方法绑定到邮件实例上,然后一起发送。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
|
import smtplib import email from email.header import Header from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.utils import parseaddr, formataddr from email.mime.base import MIMEBase
def _format_addr(s): name, addr = parseaddr(s) return formataddr((Header(name, 'utf-8').encode(), addr))
msg_from = 'XXXXX@163.com' passwd = 'XXXXX' msg_to='XXXXXX@qq.com' receivers = ['XXXX@qq.com'] subject = 'python邮件测试附件' content = '<html><body><h1>Hello</h1>' +\ '<p>send by <a href="http://www.python.org">Python</a>...</p>'
#附件邮件对象 msg = MIMEMultipart() msg['From'] = _format_addr('恋恋风辰 <%s>' %msg_from) msg['To'] = msg_to msg['Subject'] = Header(subject, 'utf-8').encode() #添加正文 text = MIMEText(content, 'html','utf-8') msg.attach(text) #添加附件就是创建一个MIMEBase对象,然后attach到msg上。 with open('./email.jpg','rb') as f: #设置附件名字 mime = MIMEBase('image', 'jpg', filename='text.jpg') #加上头信息 mime.add_header('Content-Disposition','attachment',filename='test.jpg') mime.add_header('Content-ID','<0>') mime.add_header('X-Attachment-Id','0') #读取内容放入附件 mime.set_payload(f.read()) #用Base64编码 email.encoders.encode_base64(mime) #添加到MIMEMultipart中 msg.attach(mime)
try: s = smtplib.SMTP("smtp.163.com",25) s.login(msg_from, passwd) s.sendmail(msg_from, receivers, msg.as_string()) print('发送成功') except smtplib.SMTPException as e: print('发送失败') finally: s.quit()
|
MIMEMultipart创建邮件实例msg,将收件人,发件人,主题设置到msg上。
然后通过MIMEText创建html文本内容,调用msg.attach方法将文本内容绑定
到邮件上。同样的道理,打开一个图片,通过MIMEBase创建一个附件实例,
设置文件名,文件类型,绑定的id等等,最后通过set_payload加载到附件,
然后msg.attach绑定到邮件实例上。后面的发送流程和之前一样。
看看效果:

发送带图片的html邮件
想要在html中添加图片,并且在邮件正文中显示,只需要在html文本中引用
图片id即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
|
import smtplib from email.header import Header from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.utils import parseaddr, formataddr from email.mime.base import MIMEBase from email.mime.image import MIMEImage
def _format_addr(s): name, addr = parseaddr(s) return formataddr((Header(name, 'utf-8').encode(), addr))
msg_from = 'XXXXXXXXXXXX@163.com' passwd = 'XXXXX' msg_to='XXXXXXXXX@qq.com' receivers = ['XXXXXXXXXX@qq.com'] subject = 'python邮件测试附件' content = '<b>Some <i>HTML</i> text</b> and an image.<br><img src="cid:image1"><br>good!'
#附件邮件对象 msg = MIMEMultipart() msg['From'] = _format_addr('恋恋风辰 <%s>' %msg_from) msg['To'] = msg_to msg['Subject'] = Header(subject, 'utf-8').encode() #添加正文 text = MIMEText(content, 'html','utf-8') msg.attach(text)
#添加附件就是创建一个MIMEBase对象,然后attach到msg上。 with open('./email.jpg','rb') as f: #设置附件名字 mime = MIMEImage(f.read()) #加上头信息 mime.add_header('Content-Disposition','attachment',filename='test.jpg') mime.add_header('Content-ID','`<image1>`')
#添加到MIMEMultipart中 msg.attach(mime)
try: s = smtplib.SMTP("smtp.163.com",25) s.login(msg_from, passwd) s.sendmail(msg_from, receivers, msg.as_string()) print('发送成功') except smtplib.SMTPException as e: print('发送失败') finally: s.quit()
|
mime.add_header(‘Content-ID’,'<image1>') 设置图片id为image1,
在html中引用image1就可以在邮件中文中显示图片了。
通过<img src="cid:image1">方式进行引用。
Messge类的继承和派生关系
1 2 3 4 5 6 7
|
Message +- MIMEBase +- MIMEMultipart +- MIMENonMultipart +- MIMEMessage +- MIMEText +- MIMEImage
|
MIMEBase继承于Message,MIMEMultipart继承于MIMEBase。
用MIMEText发送多种附件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
|
import smtplib from email.mime.text import MIMEText from email.header import Header from email.mime.multipart import MIMEMultipart from email.utils import parseaddr, formataddr import os
def _format_addr(s): name, addr = parseaddr(s) return formataddr((Header(name, 'utf-8').encode(), addr))
msg_from = 'XXXXXXXXX@163.com' passwd = 'XXXXXXXXXXX' msg_to='XXXXXXXXX@qq.com' receivers = ['XXXXXXXXXXX@qq.com'] subject = 'python邮件测试附件' content = '多种附件'
#附件邮件对象 msg = MIMEMultipart() msg['From'] = _format_addr('恋恋风辰 <%s>' %msg_from) msg['To'] = msg_to msg['Subject'] = Header(subject, 'utf-8').encode() #添加正文 text = MIMEText(content, 'html','utf-8') msg.attach(text)
os.chdir('./res') dir = os.getcwd()
for fn in os.listdir(dir): print(fn) with open(fn,'rb') as f: mime = MIMEText(f.read(), 'base64', 'utf-8') mime.add_header('Content-Disposition','attachment',filename = fn) mime.add_header('Content-Type', 'application/octet-stream') msg.attach(mime)
try: s = smtplib.SMTP("smtp.163.com",25) s.login(msg_from, passwd) s.sendmail(msg_from, receivers, msg.as_string()) print('发送成功') except smtplib.SMTPException as e: print('发送失败') finally: s.quit()
|
大体原理和之前一样,通过MIMEText可以实现多种附件的发送。
注意格式改为base64,编码用utf-8,可以实现多种附件发送。
效果如下:

通过MIMEApplication发送多种附件
同样可以通过MIMEApplication发送多种附件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
|
import smtplib from email.mime.text import MIMEText from email.mime.application import MIMEApplication from email.header import Header from email.mime.multipart import MIMEMultipart from email.utils import parseaddr, formataddr import os
def _format_addr(s): name, addr = parseaddr(s) return formataddr((Header(name, 'utf-8').encode(), addr))
msg_from = 'xxxxxxxxx@163.com' passwd = 'xxxxxxxxxx' msg_to='xxxxxxxxxxx@qq.com' receivers = ['xxxxxxxxx@qq.com'] subject = 'python邮件测试附件' content = '多种附件'
#附件邮件对象 msg = MIMEMultipart() msg['From'] = _format_addr('恋恋风辰 <%s>' %msg_from) msg['To'] = msg_to msg['Subject'] = Header(subject, 'utf-8').encode() #添加正文 text = MIMEText(content, 'html','utf-8') msg.attach(text)
os.chdir('./res') dir = os.getcwd()
for fn in os.listdir(dir): print(fn) with open(fn,'rb') as f: mime = MIMEApplication(f.read()) mime.add_header('Content-Disposition','attachment',filename = fn) mime.add_header('Content-Type', 'application/octet-stream') msg.attach(mime)
try: s = smtplib.SMTP("smtp.163.com",25) s.login(msg_from, passwd) s.sendmail(msg_from, receivers, msg.as_string()) print('发送成功') except smtplib.SMTPException as e: print('发送失败') finally: s.quit()
|
效果和之前的一样,这就是python中利用smtplib和MIME构造邮件发送的案例。
- Python学习--21 电子邮件
发送邮件 SMTP是发送邮件的协议,Python内置对SMTP的支持,可以发送纯文本邮件.HTML邮件以及带附件的邮件. Python对SMTP支持有smtplib和email两个模块,email负责 ...
- Python学习--21天Python基础学习之旅(Day08-Day21)
Day08: Chapter 11 异常 1.1如果try代码块中代码运行没有问题,则运行时跳过except代码块.(有异常时执行except中的代码,没有异常则跳过except中的代码) try-e ...
- python实现基于smtp发送邮件
[前言] 在某些项目中,我们需要实现发送邮件的功能,比如: 爬虫结束后,发送邮件通知 定时发送邮件提醒待办事项 某项业务逻辑触发邮件通知 今天我们就分享如何基于smtp借助163邮箱来发送邮件 [实现 ...
- Python中使用SMTP发送邮件以及POP收取邮件
假设我们自己的电子邮件地址是from@163.com,对方的电子邮件地址是to@sina.com(这里的地址虚拟的),现在我们用Outlook或者Foxmail之类的软件写好邮件,填上对方的Email ...
- python中的SMTP发送邮件
一. 介绍 python3中自带了smtplib模块和email模块 smtplib模块:负责与邮件服务器的交互 email模块:负责组织邮件内容 二. smtplib模块 smtplib模块:主要是 ...
- 吴裕雄--天生自然 PYTHON3开发学习:SMTP发送邮件
import smtplib smtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] ) SMTP.sendmail(from_addr, ...
- Python学习--21天Python基础学习之旅(Day01、Day02)
21天的python基础学习,使用<Python从入门到实践>,并且需要手敲书中的code,以下为整个学习过程的记录. Day01: 安装python时要选择复选框 Add Python ...
- python实战===使用smtp发送邮件的源代码,解决554错误码的问题,更新版!
import smtplib from email.mime.text import MIMEText from email.header import Header import time #密文输 ...
- Python学习(21):Python函数(5):变量作用域与闭包
转自 http://www.cnblogs.com/BeginMan/p/3179040.html 一.全局变量与局部变量 一个模块中,最高级别的变量有全局作用域. 全局变量一个特征就是:除非被删除, ...
随机推荐
- [linux] tmux终端复用神器 [转载]
转载https://www.cnblogs.com/kevingrace/p/6496899.html Tmux是一个优秀的终端复用软件,类似GNU Screen,但来自于OpenBSD,采用BSD授 ...
- TeamWork#3,Week5,Scrum Meeting 11.6, 11.7, 11.11, 11.12
11.6:到目前为止基本已完成相关知识的学习,各方面工作都开始进行,一开始进行比较慢. 11.7:项目遇到困难,需要补充相关知识,进度慢了下来. 11.11:各方面工作进展比较顺利,没有什么大问题. ...
- Java程序设计第四次实验报告
北京电子科技学院(BESTI) 实 验 报 告 课程:java程序设计 班级:1352 姓名:何伟钦 学号:20135223 成绩: 指导教师:娄嘉鹏 ...
- Chapter 5 软件工程中的形式化方法
从广义上讲,形式化方法是指将离散数学的方法用于解决软件工程领域的问题,主要包括建立精确的数学模型以及对模型的分析活动.狭义的讲,形式化方法是运用形式化语言,进行形式化的规格描述.模型推理和验证的方法. ...
- 微服务注册与发现 —— eureka
基础概念 在微服务系统中,服务的注册和发现是第一步,常用的有: Eureka:https://github.com/Netflix/eureka Zookeeper:https://zookeeper ...
- Python入门:逻辑判断与运算符
这是关于Python的第6篇文章,主要介绍下逻辑判断与运算符. (一) 逻辑判断: 如果要实现一个复杂的功能程序,逻辑判断必不可少.逻辑判断的最基本标准:布尔类型. 布尔类型只有两个值:True和Fa ...
- 关于vue项目管理项目的架构管理平台
关于vue项目管理项目的架构管理平台 https://panjiachen.github.io/vue-element-admin-site/#/zh-cn/faq 31.4k 次浏览 完整项目地址: ...
- 解决方案~Microsoft Security Client OOBE 程序错误
Microsoft Security Client OOBE 程序错误 适用于: Windows Windows 7 系统错误日志如下:会话"Microsoft Security Clien ...
- 2012r2 以及 2012r2 withupdate 已经安装更新的差异
0. 2012r2 不管带不带 update 1 他的版本号 都是 6.3.9600 如图示 2012r2的发布时间是 2013年 2012r2withupdate的发布时间是 2014年. 查看补丁 ...
- Log4j读取配置文件并使用
/** 设置配置路径从环境变量读取 * PropertyConfigurator类加载.properties文件的配置 * DOMConfigurator加载.xml文件的配置 ...