原文链接:

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发送邮件的更多相关文章

  1. Python学习--21 电子邮件

    发送邮件 SMTP是发送邮件的协议,Python内置对SMTP的支持,可以发送纯文本邮件.HTML邮件以及带附件的邮件. Python对SMTP支持有smtplib和email两个模块,email负责 ...

  2. Python学习--21天Python基础学习之旅(Day08-Day21)

    Day08: Chapter 11 异常 1.1如果try代码块中代码运行没有问题,则运行时跳过except代码块.(有异常时执行except中的代码,没有异常则跳过except中的代码) try-e ...

  3. python实现基于smtp发送邮件

    [前言] 在某些项目中,我们需要实现发送邮件的功能,比如: 爬虫结束后,发送邮件通知 定时发送邮件提醒待办事项 某项业务逻辑触发邮件通知 今天我们就分享如何基于smtp借助163邮箱来发送邮件 [实现 ...

  4. Python中使用SMTP发送邮件以及POP收取邮件

    假设我们自己的电子邮件地址是from@163.com,对方的电子邮件地址是to@sina.com(这里的地址虚拟的),现在我们用Outlook或者Foxmail之类的软件写好邮件,填上对方的Email ...

  5. python中的SMTP发送邮件

    一. 介绍 python3中自带了smtplib模块和email模块 smtplib模块:负责与邮件服务器的交互 email模块:负责组织邮件内容 二. smtplib模块 smtplib模块:主要是 ...

  6. 吴裕雄--天生自然 PYTHON3开发学习:SMTP发送邮件

    import smtplib smtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] ) SMTP.sendmail(from_addr, ...

  7. Python学习--21天Python基础学习之旅(Day01、Day02)

    21天的python基础学习,使用<Python从入门到实践>,并且需要手敲书中的code,以下为整个学习过程的记录. Day01: 安装python时要选择复选框 Add Python ...

  8. python实战===使用smtp发送邮件的源代码,解决554错误码的问题,更新版!

    import smtplib from email.mime.text import MIMEText from email.header import Header import time #密文输 ...

  9. Python学习(21):Python函数(5):变量作用域与闭包

    转自 http://www.cnblogs.com/BeginMan/p/3179040.html 一.全局变量与局部变量 一个模块中,最高级别的变量有全局作用域. 全局变量一个特征就是:除非被删除, ...

随机推荐

  1. ifup,ifdown命令详解

    基础命令学习目录首页 原文链接:https://www.cnblogs.com/jing99/p/7881779.html ifup命令网络配置 ifup命令用于激活指定的网络接口.ifdown命令用 ...

  2. vim 多个文件切换 :b 命令

    MiniBufExplorer插件的使用 博客分类: vim vimMiniBufExplorer 快速浏览和操作Buffer -- 插件: MiniBufExplorer 下载地址 [http:// ...

  3. jquery-numberformatter插件

    项目地址:https://code.google.com/p/jquery-numberformatter/ 非jquery版:https://github.com/andrewgp/jsNumber ...

  4. nigix安装

    树莓派安装nginx,参考http://blog.csdn.net/zizi7/article/details/54347223 1. 下载PCRE 并安装. 主页地址: ftp://ftp.csx. ...

  5. iOS- 本地文本容错搜索引擎2-->如何实现英文(英文首字母,汉语拼音)对中文的搜索?

      1.前言 先闲说几句,最近北京的雾霾真是大,呛的我这攻城师都抗不住了.各位攻城师们一定要爱护好自己的身体!空气好时,少坐多动. 如果条件好的话,最好让你们BOSS搞个室内空气净化器.因为那几天一般 ...

  6. c# 判断两条线段是否相交(判断地图多边形是否相交)

    private void button1_Click(object sender, EventArgs e) { //var result = intersect3(point1, point2, p ...

  7. vue-Slot分发内容

    ①概述: 简单来说,假如父组件需要在子组件内放一些DOM,那么这些DOM是显示.不显示.在哪个地方显示.如何显示,就是slot分发负责的活. ②默认情况下 父组件在子组件内套的内容,是不显示的. 例如 ...

  8. JS单例模式在工作中的使用

    为了尽可能的减少全局变量的污染,在写js的时候可以采用单例模式,形式如下: 比如有一个js叫demo.js,那么我们可以在js里这样写: var demo = {} 这样做的目的是将整个js当成一个对 ...

  9. API的HTTP Status Code

    响应中的状态码 状态码 定义 说明 1xx 信息 接收到请求,继续处理 2xx 成功 操作成功地收到请求,理解和接受 3xx 重定向 为了完成请求,必须采取进一步擦措施 4xx 客户端错误 请求的语法 ...

  10. sourcetree git合并问题

    在使用sourcetree做多功能合并(合并不提交)的时候,有时按钮是灰色的,直接点击右上角命令行模式 git merge <branch1> --no-commit 转载请注明博客出处: ...