SMTP协议之发送邮件(纯文本,HTML以及附件邮件)

1.关于SMTP

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

1.1关于smtplib

使用Python的smtplib发送邮件十分简单,只要掌握了各种邮件类型的构造方法,正确设置好邮件头,就可以顺利发出。

构造一个邮件对象就是一个Messag对象,如果构造一个MIMEText对象,就表示一个文本邮件对象,如果构造一个MIMEImage对象,就表示一个作为附件的图片,要把多个对象组合起来,就用MIMEMultipart对象,而MIMEBase可以表示任何对象。它们的继承关系如下:

Message
± MIMEBase
± MIMEMultipart
± MIMENonMultipart
± MIMEMessage
± MIMEText
± MIMEImage

这种嵌套关系就可以构造出任意复杂的邮件。你可以通过email.mime文档查看它们所在的包以及详细的用法。

2.关于qq邮箱授权码

我使用的qq邮箱,是要开启qq授权码等功能才能登陆以及发送邮件。其它邮箱也应该是差不多的。这个自己直接百度一下就有详细教程了。

3.代码编写
3.1纯文本邮件
# -*- coding: utf-8 -*-
# @Time    : 2020/3/9 上午 10:36
# @Author  : lh
# @Email   : xx@lh.com
# @File    : test2.py
# @Software: PyCharm


import smtplib
from email.mime.text import MIMEText
from email.header import Header

qqAccout = 'XX@qq.com'  # 邮箱账号
qqCode = '**********'  # 授权码
smtp_server = 'smtp.qq.com'  # SMTP服务器地址:
smtp_port = 465  # 服务器端口

# 配置服务器以及登录(login()方法用来登录SMTP服务器,)
stmp = smtplib.SMTP_SSL(smtp_server, smtp_port)
stmp.set_debuglevel(1)  # 我们用set_debuglevel(1)就可以打印出和SMTP服务器交互的所有信息。
stmp.login(qqAccout, qqCode)

# 组装发送纯文本内容
message = MIMEText('33333没有什么实质作用的内容3333', 'plain', 'utf-8')  # 注意到构造MIMEText对象时,第一个参数就是邮件正文,第二个参数是MIME的subtype,传入'plain'表示纯文本,最终的MIME就是'text/plain',最后一定要用utf-8编码保证多语言兼容性。
message['From'] = Header("Python自动化监控系统", 'utf-8')  # 发件人
message['To'] = Header("有缘人", 'utf-8')  # 收件人
subject = 'Python SMTP 发送邮件测试'
message['Subject'] = Header(subject, 'utf-8')  # 邮件标题

try:
    # sendmail()方法就是发邮件,由于可以一次发给多个人,所以传入一个list,邮件正文是一个str,as_string()把MIMEText对象变成str
    stmp.sendmail(qqAccout, [qqAccout, ], message.as_string())  # 发件人,收件人,
    print('邮件发送成功')
except Exception as e:
    print('邮件发送失败--' + str(e))

注意到构造MIMEText对象时,第一个参数就是邮件正文,第二个参数是MIME的subtype,传入’plain’表示纯文本,最终的MIME就是’text/plain’,最后一定要用utf-8编码保证多语言兼容性。
运行程序:
在这里插入图片描述
这是一个自己发给自己的邮件。

3.2 HTML邮件

在构造MIMEText对象时,把HTML字符串传进去,再把第二个参数由plain变为html就可以了:

msg = MIMEText('<html><body><p>这是一个HTML邮件</p><a href="www.baidu.com">百度一下</a></body></html>', 'html', 'utf-8')
3.3 附件邮件

带附件的邮件可以看做包含若干部分的邮件:文本和各个附件本身,所以,可以构造一个MIMEMultipart对象代表邮件本身,然后往里面加上一个MIMEText作为邮件正文,再继续往里面加上表示附件的MIMEBase对象

# -*- coding: utf-8 -*-
# @Time    : 2020/3/12 上午 10:21
# @Author  : lh
# @Email   : xx@lh.com
# @File    : test5.py
# @Software: PyCharm

import smtplib
from email import encoders
from email.header import Header
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.utils import parseaddr, formataddr


def _format_addr(s):
    name, addr = parseaddr(s)
    return formataddr((Header(name, 'utf-8').encode(), addr))


from_addr = input('From: ')
password = input('Password: ')
to_addr = input('To: ')
smtp_server = input('SMTP server: ')

# 邮件对象
msg = MIMEMultipart()
msg['From'] = _format_addr('Python邮件测试<%s>' % from_addr)
msg['To'] = _format_addr('管理员 <%s>' % to_addr)
msg['Subject'] = Header('你是美团的吗,那么能送', 'utf-8').encode()

# 邮件正文是 MIMEText
msg.attach(MIMEText('发送文本邮件...', 'plain', 'utf-8'))

# 添加附件就是加上一个MIMEBase, 从本地读取一个图片
with open('test.html', 'rb') as f:
    # 设置附件的MIME和文件名, 这是一个html文件呢
    m = MIMEBase('file', 'html', filename='test.html')
    # 加上头信息
    m.add_header('Content-Disposition', 'attachment', filename='test.html')
    m.add_header('Content-ID', '<0>')
    m.add_header('X-Attachment-Id', '0')
    # 把附件的内容读取进来
    m.set_payload(f.read())
    # 使用Base64进行编码
    encoders.encode_base64(m)
    msg.attach(m)

    server = smtplib.SMTP(smtp_server, 25)
    server.set_debuglevel(1)
    server.login(from_addr, password)
    server.sendmail(from_addr, [to_addr], msg.as_string())
    server.quit()
3.4邮件中带图片

想要直接嵌套图片到邮件中的话需要,设置一下,因为一般邮件都会屏蔽掉我们带的外链的图片的。
按照发送附件的方式,先把邮件作为附件添加进去,然后,在HTML中通过引用src="cid:0"就可以把附件作为图片嵌入了。如果有多个图片,给它们依次编号,然后引用不同的cid:x即可。

上面代码加入MIMEMultipart的MIMEText从plain改为html,然后在适当的位置引用图片

# -*- coding: utf-8 -*-
# @Time    : 2020/3/12 上午 11:19
# @Author  : lh
# @Email   : xx@lh.com
# @File    : test6.py
# @Software: PyCharm

import smtplib
from email import encoders
from email.header import Header
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.utils import parseaddr, formataddr


def _format_addr(s):
    name, addr = parseaddr(s)
    return formataddr((Header(name, 'utf-8').encode(), addr))


from_addr = input('From: ')
password = input('Password: ')
to_addr = input('To: ')
smtp_server = input('SMTP server: ')

# 邮件对象
msg = MIMEMultipart()
msg['From'] = _format_addr('Python邮件测试<%s>' % from_addr)
msg['To'] = _format_addr('管理员 <%s>' % to_addr)
msg['Subject'] = Header('你是美团的吗,那么能送', 'utf-8').encode()

# 邮件正文是 MIMEText
msg.attach(MIMEText('<html><body><h1>Hello</h1>' +
                    '<p><img src="cid:0"></p>' +
                    '</body></html>', 'html', 'utf-8'))

# 添加附件就是加上一个MIMEBase, 从本地读取一个图片
with open('test.jpg', 'rb') as f:
    # 设置附件的MIME和文件名, 这是一个html文件呢
    m = MIMEBase('image', 'jpg', filename='test.jpg')
    # 加上头信息
    m.add_header('Content-Disposition', 'attachment', filename='test.jpg')
    m.add_header('Content-ID', '<0>')
    m.add_header('X-Attachment-Id', '0')
    # 把附件的内容读取进来
    m.set_payload(f.read())
    # 使用Base64进行编码
    encoders.encode_base64(m)
    msg.attach(m)

    server = smtplib.SMTP(smtp_server, 25)
    server.set_debuglevel(1)
    server.login(from_addr, password)
    server.sendmail(from_addr, [to_addr], msg.as_string())
    server.quit()
3.5降级查看邮件

收件人通过浏览器或者Outlook之类的软件是可以正常浏览邮件内容的,但是,如果收件人使用的设备太古老,查看不了HTML邮件的话,办法是在发送HTML的同时再附加一个纯文本,如果收件人无法查看HTML格式的邮件,就可以自动降级查看纯文本邮件。
利用MIMEMultipart就可以组合一个HTML和Plain,要注意指定subtype是alternative:

msg = MIMEMultipart('alternative')
msg['From'] = ...
msg['To'] = ...
msg['Subject'] = ...

msg.attach(MIMEText('hello', 'plain', 'utf-8'))
msg.attach(MIMEText('<html><body><h1>Hello</h1></body></html>', 'html', 'utf-8'))
# 正常发送msg对象...
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值