简介
SMTP是发送邮件的协议,Python内置对SMTP的支持,可以发送纯文本邮件、HTML邮件以及带附件的邮件。
Python对SMTP支持有smtplib和email两个模块,email负责构造邮件,smtplib负责发送邮件。
sample 1.发送文本邮件
构造MIMEText
1 |
|
注意到构造MIMEText对象时,第一个参数就是邮件正文,第二个参数是MIME的subtype,传入’plain’表示纯文本,最终的MIME就是’text/plain’,最后一定要用utf-8编码保证多语言兼容性。
使用smtp发送
1 |
|
编写了一个函数
_format_addr()
来格式化一个邮件地址。注意不能简单地传入name <addr@example.com>
,因为如果包含中文,需要通过Header
对象进行编码。msg['To']
接收的是字符串而不是list
,如果有多个邮件地址,用,分隔即可。用
set_debuglevel(1)
就可以打印出和SMTP服务器交互的所有信息。SMTP协议就是简单的文本命令和响应。login()
方法用来登录SMTP服务器,sendmail()
方法就是发邮件,由于可以一次发给多个人,所以传入一个list
,邮件正文是一个str
,as_string()
把MIMEText
对象变成str
。From
:发件人To
:收件人Cc
:抄送人Subject
:主题- 此处必须注意
smtplib.SMTP_SSL
和smtplib.SMTP
的区分,否则会报错提示连接失败。
这样我们就收到了一封测试邮件。
代码
1 |
|
samele 2.附件邮件
如果Email中要加上附件怎么办?带附件的邮件可以看做包含若干部分的邮件:文本和各个附件本身,所以,可以构造一个MIMEMultipart对象代表邮件本身,然后往里面加上一个MIMEText作为邮件正文,再继续往里面加上表示附件的MIMEBase对象即可:
1 |
|
sample 3.html 邮件
在构造MIMEText对象时,把HTML字符串传进去,再把第二个参数由plain变为html就可以了:
1 |
|
samele 3.图片邮件
要把图片嵌入到邮件正文中,我们只需按照发送附件的方式,先把邮件作为附件添加进去,然后,在HTML中通过引用src=”cid:0”就可以把附件作为图片嵌入了。如果有多个图片,给它们依次编号,然后引用不同的cid:x即可。
事实上,无论图片还是音频文件,使用方式都是一样的。1
2
3
4
5
6
7
8msgText = '<html><body><h1>Hello</h1>' + '<p><img src="cid:0"></p>' + '<p>send by <a href="http://www.mknight.cn">Python</a>...</p>' + '</body></html>'
with open('./hi.png', 'rb') as f:
FileApart = MIMEImage(f.read())
FileApart.add_header('Content-ID', '<0>')
msg.attach(FileApart)
全部代码如下: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#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
@author:medivh
@file: ex_send_mail.py
@time: 2019/02/24
"""
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.mime.image import MIMEImage
from email.header import Header
from email.utils import parseaddr, formataddr
def _format_addr(s):
name, addr = parseaddr(s)
return formataddr((Header(name, 'utf-8').encode(), addr))
# 输入Email地址和口令:
from_addr = xxx@x.com
password = xxxx
# 输入收件人地址:
to_addr = xx@xx.com
# 输入SMTP服务器地址,以QQ企业邮箱为例
smtp_server = 'smtp.exmail.qq.com'
msg = MIMEMultipart()
msg['From'] = _format_addr('Python爱好者 <%s>' % from_addr)
msg['To'] = _format_addr('管理员 <%s>' % to_addr)
msg['Subject'] = Header('来自SMTP的问候……', 'utf-8').encode()
msgText = '<html><body><h1>Hello</h1>' + '<p><img src="cid:0"></p>' + '<p>send by <a href="http://www.mknight.cn">Python</a>...</p>' + '</body></html>'
msg.attach(MIMEText(msgText, 'html', 'utf-8'))
# 添加附件就是加上一个MIMEImage,从本地读取一个图片:
with open('./hi.png', 'rb') as f:
# 设置附件的MIME和文件名,这里是png类型:
FileApart = MIMEImage(f.read())
FileApart.add_header('Content-ID', '<0>')
msg.attach(FileApart)
server = smtplib.SMTP_SSL(smtp_server, 465) # SMTP SSL协议默认端口是465,注意使用SMTP_SSL
server.set_debuglevel(3)
try:
server.login(from_addr, password)
server.sendmail(from_addr, [to_addr], msg.as_string())
server.quit()
except Exception as e:
print(e)
MIME 类型
通用类型
1 | class email.mime.application.MIMEApplication(_data, _subtype='octet-stream', _encoder=email.encoders.encode_base64, *, policy=compat32, **_params) |
音频类型
1 | class email.mime.audio.MIMEAudio(_audiodata, _subtype=None, _encoder=email.encoders.encode_base64, *, policy=compat32, **_params)¶ |
图片类型
1 | class email.mime.image.MIMEImage(_imagedata, _subtype=None, _encoder=email.encoders.encode_base64, *, policy=compat32, **_params) |
综上所述,如果想不起来啥类型就使用MIMEApplication
。