Python

python 使用SMTP发送邮件[HTML格式,带附件]

2018-09-05  本文已影响0人  cz_布衣

今天百度学习了如何在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参数来判断是否要带附件。

说明:
  1. 需要在邮件服务器上设置打开smtp功能。
  2. SMTP服务器地址和端口可以在邮件服务器的设置里找到(在设置上边 1 时,应该就可以看到)
  3. 发件人与登录邮件服务器的认证用户应该一致,所以我把它写死在代码里了。(或许使用一个常量定义会更好?)
  4. 若是多个收件人则需在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()

如果本文对您有帮助,请给我留个言。谢谢!

上一篇 下一篇

猜你喜欢

热点阅读