今天百度学习了如何在python中使用SMTP发送邮件,包括带HTML格式和附件。
基本套路就是定义一个MIMEText(不带附件)或者MIMEMultipart(可带多个附件),然后再连接、登录邮件服务器并发送即可。(发送HTML格式的邮件与纯文本消息的邮件不同之处就是将MIMEText中_subtype设置为html。
)
套路如下:不带附件
from email.mime.text import MIMEText
import smtplib
mail = MIMEText('邮件正文') # 简单纯文本消息的邮件
# mail = MIMEText('邮件正文', _subtype='html', _charset='utf-8') # HTML格式的邮件
mail['Subject'] = '邮件主题'
mail['From'] = '发件人地址' # 需与邮件服务器的认证用户一致
mail['To'] = '收件人地址'
smtp = smtplib.SMTP('smtp.qq.com', port=25) # 设置邮件服务器地址与端口
smtp.login('帐号', '密码') # 登录邮件服务器
smtp.sendmail('发件人地址', '收件人地址', mail.as_string()) # 发送邮件
self.smtp.quit() # 关闭邮件服务器
带附件
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import smtplib
mail = MIMEMultipart()
mail.attach(MIMEText('邮件正文', _subtype='html', _charset='utf-8'))
# 构造附件att1,若是要带多个附件,可根据下边的格式构造
att1 = MIMEText(open('文件', 'rb').read(), 'base64', 'utf-8')
att1['Content-Type'] = 'application/octet-stream'
att1["Content-Disposition"] = 'attachment; filename="%s"' % 文件名
mail.attach(att1)
mail['Subject'] = '邮件主题'
mail['From'] = '发件人地址' # 需与邮件服务器的认证用户一致
mail['To'] = '收件人地址'
smtp = smtplib.SMTP('smtp.qq.com', port=25) # 设置邮件服务器地址与端口
smtp.login('帐号', '密码') # 登录邮件服务器
smtp.sendmail('发件人地址', '收件人地址', mail.as_string()) # 发送邮件
self.smtp.quit() # 关闭邮件服务器
我将其构造成一个类,以在构造类时是否传入file参数来判断是否要带附件。
说明:
- 需要在邮件服务器上设置打开smtp功能。
- SMTP服务器地址和端口可以在邮件服务器的设置里找到(在设置上边 1 时,应该就可以看到)
- 发件人与登录邮件服务器的认证用户应该一致,所以我把它写死在代码里了。(或许使用一个常量定义会更好?)
- 若是多个收件人则需在to_email参数中用逗号隔开。另外:MIMEText()["To"]的数据类型与sendmail(from_addrs,to_addrs,...)的to_addrs不同;前者为str类型,多个地址使用逗号分隔,后者为list类型。所以在sendmail()函数中使用split(',')来分离多个收件人。
代码如下:
# -*- coding:utf-8 -*-
""" 发送邮件 """
import smtplib, os, base64
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from datetime import datetime
class Email(object):
"""
特意将附件变量写成att1,是指若有多个附件,可用同样的格式再添加att2/att3:
att1 = MIMEText(f.read(), 'base64', 'utf-8')
att1['Content-Type'] = 'application/octet-stream'
att1["Content-Disposition"] = 'attachment; filename="%s"' % file_name
self.mail.attach(att1)
:param:to_email:收件人地址,多个收件人时用逗号隔开
:param:subject:邮件主题
:param:content:邮件内容
:param:file:附件地址
"""
def __init__(self, to_email, subject, content, file=None):
self.file = file
if (self.file is not None) and (not os.path.exists(self.file)):
raise Exception('附件不存在')
# 构造邮件
self.mail = MIMEMultipart()
self.mail.attach(MIMEText(content, _subtype='html', _charset='utf-8')) # 邮件内容
self.mail['Subject'] = subject # 主题
self.mail['From'] = '****@qq.com' # 发件人
self.mail['To'] = to_email # 收件人
self.smtp = None
def sent(self):
f = None
try:
# 构造附件并添加至邮件
if self.file is not None:
try:
with open(self.file, 'rb') as f:
att1 = MIMEText(f.read(), 'base64', 'utf-8')
except Exception as e:
raise Exception('附件读取错误')
else:
att1['Content-Type'] = 'application/octet-stream'
file_name = os.path.split(self.file)[-1]
# 下面一句是处理附件名为中文名
file_name = '=?utf-8?b?' + base64.b64encode(file_name.encode()).decode() + '?='
att1["Content-Disposition"] = 'attachment; filename="%s"' % file_name
self.mail.attach(att1)
self.smtp = smtplib.SMTP('smtp.qq.com', port=25) # 设置邮件服务器
self.smtp.login('****@qq.com', '****') # 登录邮件服务器
self.smtp.sendmail(self.mail['From'], self.mail['To'].split(','), self.mail.as_string()) # 发送邮件
self.smtp.quit() # 关闭邮件服务器
print('send seccess')
return True
except:
print('send fail')
return False
email = Email(
to_email='****@qq.com',
subject='Test',
content='''
<b>测试测试</b><br>
这是我的Email模块!
<center>send by python_mail</center>
''' + str(datetime.now())[:19]
# file='/1.png'
)
email.sent()
如果本文对您有帮助,请给我留个言。谢谢!