Skip to content

Python SMTP 发送邮件

SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)是用于发送电子邮件的标准协议。Python 提供了 smtplib 模块来支持通过 SMTP 发送邮件。本章节将详细介绍如何在 Python 中使用 SMTP 发送邮件。

准备工作

1. 了解 SMTP 服务器

要发送邮件,需要使用 SMTP 服务器。常用的 SMTP 服务器包括:

  • Gmail SMTP 服务器:smtp.gmail.com,端口 587(TLS)或 465(SSL)
  • QQ 邮箱 SMTP 服务器:smtp.qq.com,端口 587(TLS)或 465(SSL)
  • 163 邮箱 SMTP 服务器:smtp.163.com,端口 587(TLS)或 465(SSL)
  • 公司/组织内部 SMTP 服务器:由 IT 部门提供

2. 开启 SMTP 服务

对于大多数公共邮箱(如 Gmail、QQ 邮箱、163 邮箱),需要先开启 SMTP 服务并获取授权码:

Gmail

  1. 登录 Gmail 账号
  2. 点击右上角的头像,选择 "管理您的 Google 账号"
  3. 点击左侧的 "安全性"
  4. 确保 "两步验证" 已开启
  5. 点击 "应用密码"
  6. 选择 "邮件" 作为应用,选择您的设备
  7. 生成并保存应用密码

QQ 邮箱

  1. 登录 QQ 邮箱
  2. 点击顶部的 "设置"
  3. 选择 "账户"
  4. 在 "POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV 服务" 部分,开启 "SMTP 服务"
  5. 按照提示发送短信验证
  6. 生成并保存授权码

163 邮箱

  1. 登录 163 邮箱
  2. 点击顶部的 "设置"
  3. 选择 "POP3/SMTP/IMAP"
  4. 开启 "SMTP 服务"
  5. 按照提示验证身份
  6. 生成并保存授权码

基本邮件发送

发送纯文本邮件

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

# 邮件配置
sender = 'your_email@example.com'  # 发件人邮箱
password = 'your_password'  # 发件人邮箱密码或授权码
receiver = 'recipient@example.com'  # 收件人邮箱
smtp_server = 'smtp.example.com'  # SMTP 服务器
smtp_port = 587  # SMTP 服务器端口(TLS)

# 创建邮件内容
message = MIMEText('这是一封测试邮件的正文内容。', 'plain', 'utf-8')
message['From'] = Header('发件人名称', 'utf-8')  # 发件人名称
message['To'] = Header('收件人名称', 'utf-8')  # 收件人名称
message['Subject'] = Header('测试邮件', 'utf-8')  # 邮件主题

try:
    # 连接 SMTP 服务器
    server = smtplib.SMTP(smtp_server, smtp_port)
    # 启动 TLS 加密
    server.starttls()
    # 登录邮箱
    server.login(sender, password)
    # 发送邮件
    server.sendmail(sender, receiver, message.as_string())
    print('邮件发送成功')
except Exception as e:
    print(f'邮件发送失败: {e}')
finally:
    # 关闭连接
    if 'server' in locals():
        server.quit()

发送 HTML 邮件

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

# 邮件配置
sender = 'your_email@example.com'
password = 'your_password'
receiver = 'recipient@example.com'
smtp_server = 'smtp.example.com'
smtp_port = 587

# 创建 HTML 内容
html_content = '''
<html>
  <body>
    <h1>测试邮件</h1>
    <p>这是一封 <b>HTML 格式</b> 的测试邮件。</p>
    <p>您可以在邮件中使用各种 HTML 标签,如:</p>
    <ul>
      <li>列表项 1</li>
      <li>列表项 2</li>
      <li>列表项 3</li>
    </ul>
    <p>还可以添加链接:<a href="https://www.example.com">访问示例网站</a></p>
  </body>
</html>
'''

# 创建邮件内容
message = MIMEText(html_content, 'html', 'utf-8')
message['From'] = Header('发件人名称', 'utf-8')
message['To'] = Header('收件人名称', 'utf-8')
message['Subject'] = Header('HTML 测试邮件', 'utf-8')

try:
    # 连接 SMTP 服务器
    server = smtplib.SMTP(smtp_server, smtp_port)
    server.starttls()
    server.login(sender, password)
    # 发送邮件
    server.sendmail(sender, receiver, message.as_string())
    print('HTML 邮件发送成功')
except Exception as e:
    print(f'邮件发送失败: {e}')
finally:
    # 关闭连接
    if 'server' in locals():
        server.quit()

发送带附件的邮件

发送单个附件

python
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.header import Header
import os

# 邮件配置
sender = 'your_email@example.com'
password = 'your_password'
receiver = 'recipient@example.com'
smtp_server = 'smtp.example.com'
smtp_port = 587

# 创建邮件对象
message = MIMEMultipart()
message['From'] = Header('发件人名称', 'utf-8')
message['To'] = Header('收件人名称', 'utf-8')
message['Subject'] = Header('带附件的测试邮件', 'utf-8')

# 添加正文
text_content = '这是一封带附件的测试邮件,请查收。'
message.attach(MIMEText(text_content, 'plain', 'utf-8'))

# 添加附件
attachment_path = 'example.txt'  # 附件路径
if os.path.exists(attachment_path):
    with open(attachment_path, 'rb') as f:
        # 创建附件对象
        attachment = MIMEApplication(f.read())
        # 设置附件头
        attachment.add_header('Content-Disposition', 'attachment', filename=os.path.basename(attachment_path))
        # 添加附件到邮件
        message.attach(attachment)
else:
    print(f'附件文件不存在: {attachment_path}')

try:
    # 连接 SMTP 服务器
    server = smtplib.SMTP(smtp_server, smtp_port)
    server.starttls()
    server.login(sender, password)
    # 发送邮件
    server.sendmail(sender, receiver, message.as_string())
    print('带附件的邮件发送成功')
except Exception as e:
    print(f'邮件发送失败: {e}')
finally:
    # 关闭连接
    if 'server' in locals():
        server.quit()

发送多个附件

python
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.header import Header
import os

# 邮件配置
sender = 'your_email@example.com'
password = 'your_password'
receiver = 'recipient@example.com'
smtp_server = 'smtp.example.com'
smtp_port = 587

# 创建邮件对象
message = MIMEMultipart()
message['From'] = Header('发件人名称', 'utf-8')
message['To'] = Header('收件人名称', 'utf-8')
message['Subject'] = Header('带多个附件的测试邮件', 'utf-8')

# 添加正文
text_content = '这是一封带多个附件的测试邮件,请查收。'
message.attach(MIMEText(text_content, 'plain', 'utf-8'))

# 添加多个附件
attachment_paths = ['example1.txt', 'example2.txt', 'example3.txt']
for path in attachment_paths:
    if os.path.exists(path):
        with open(path, 'rb') as f:
            attachment = MIMEApplication(f.read())
            attachment.add_header('Content-Disposition', 'attachment', filename=os.path.basename(path))
            message.attach(attachment)
        print(f'添加附件: {path}')
    else:
        print(f'附件文件不存在: {path}')

try:
    # 连接 SMTP 服务器
    server = smtplib.SMTP(smtp_server, smtp_port)
    server.starttls()
    server.login(sender, password)
    # 发送邮件
    server.sendmail(sender, receiver, message.as_string())
    print('带多个附件的邮件发送成功')
except Exception as e:
    print(f'邮件发送失败: {e}')
finally:
    # 关闭连接
    if 'server' in locals():
        server.quit()

发送带图片的邮件

内嵌图片到 HTML 邮件

python
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
from email.header import Header
import os

# 邮件配置
sender = 'your_email@example.com'
password = 'your_password'
receiver = 'recipient@example.com'
smtp_server = 'smtp.example.com'
smtp_port = 587

# 创建邮件对象
message = MIMEMultipart('related')  # 使用 related 类型支持内嵌资源
message['From'] = Header('发件人名称', 'utf-8')
message['To'] = Header('收件人名称', 'utf-8')
message['Subject'] = Header('带图片的测试邮件', 'utf-8')

# 创建 HTML 内容,引用图片
html_content = '''
<html>
  <body>
    <h1>测试邮件</h1>
    <p>这是一封带内嵌图片的 HTML 邮件。</p>
    <p>图片 1:</p>
    <img src="cid:image1" alt="图片 1">
    <p>图片 2:</p>
    <img src="cid:image2" alt="图片 2">
  </body>
</html>
'''

# 添加 HTML 正文
message.attach(MIMEText(html_content, 'html', 'utf-8'))

# 添加图片
image_paths = [('image1', 'example1.jpg'), ('image2', 'example2.png')]
for cid, path in image_paths:
    if os.path.exists(path):
        with open(path, 'rb') as f:
            image = MIMEImage(f.read())
            image.add_header('Content-ID', f'<{cid}>')
            message.attach(image)
        print(f'添加图片: {path}')
    else:
        print(f'图片文件不存在: {path}')

try:
    # 连接 SMTP 服务器
    server = smtplib.SMTP(smtp_server, smtp_port)
    server.starttls()
    server.login(sender, password)
    # 发送邮件
    server.sendmail(sender, receiver, message.as_string())
    print('带图片的邮件发送成功')
except Exception as e:
    print(f'邮件发送失败: {e}')
finally:
    # 关闭连接
    if 'server' in locals():
        server.quit()

发送给多个收件人

发送给多个收件人、抄送人和密送人

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

# 邮件配置
sender = 'your_email@example.com'
password = 'your_password'
receivers = ['recipient1@example.com', 'recipient2@example.com']  # 收件人列表
cc = ['cc1@example.com', 'cc2@example.com']  # 抄送列表
bcc = ['bcc1@example.com', 'bcc2@example.com']  # 密送列表
smtp_server = 'smtp.example.com'
smtp_port = 587

# 创建邮件内容
message = MIMEText('这是一封发送给多个收件人的测试邮件。', 'plain', 'utf-8')
message['From'] = Header('发件人名称', 'utf-8')
message['To'] = Header('; '.join(receivers), 'utf-8')  # 多个收件人用分号分隔
message['Cc'] = Header('; '.join(cc), 'utf-8')  # 多个抄送人用分号分隔
# 密送人不在邮件头中显示,只在 sendmail 的收件人列表中添加

# 合并所有收件人(收件人 + 抄送 + 密送)
all_receivers = receivers + cc + bcc

try:
    # 连接 SMTP 服务器
    server = smtplib.SMTP(smtp_server, smtp_port)
    server.starttls()
    server.login(sender, password)
    # 发送邮件
    server.sendmail(sender, all_receivers, message.as_string())
    print(f'邮件发送成功,共发送给 {len(all_receivers)} 个收件人')
except Exception as e:
    print(f'邮件发送失败: {e}')
finally:
    # 关闭连接
    if 'server' in locals():
        server.quit()

使用 SSL 连接

有些 SMTP 服务器要求使用 SSL 连接(端口通常为 465):

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

# 邮件配置
sender = 'your_email@example.com'
password = 'your_password'
receiver = 'recipient@example.com'
smtp_server = 'smtp.example.com'
smtp_port = 465  # SSL 端口

# 创建邮件内容
message = MIMEText('这是一封使用 SSL 连接发送的测试邮件。', 'plain', 'utf-8')
message['From'] = Header('发件人名称', 'utf-8')
message['To'] = Header('收件人名称', 'utf-8')
message['Subject'] = Header('SSL 测试邮件', 'utf-8')

try:
    # 连接 SMTP 服务器(使用 SSL)
    server = smtplib.SMTP_SSL(smtp_server, smtp_port)
    # 登录邮箱
    server.login(sender, password)
    # 发送邮件
    server.sendmail(sender, receiver, message.as_string())
    print('使用 SSL 连接发送邮件成功')
except Exception as e:
    print(f'邮件发送失败: {e}')
finally:
    # 关闭连接
    if 'server' in locals():
        server.quit()

邮件发送类

为了方便重用,可以创建一个邮件发送类:

python
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
import os

class EmailSender:
    """邮件发送类"""
    
    def __init__(self, sender, password, smtp_server, smtp_port, use_ssl=False):
        """初始化邮件发送器"""
        self.sender = sender
        self.password = password
        self.smtp_server = smtp_server
        self.smtp_port = smtp_port
        self.use_ssl = use_ssl
        self.server = None
    
    def connect(self):
        """连接到 SMTP 服务器"""
        try:
            if self.use_ssl:
                # 使用 SSL 连接
                self.server = smtplib.SMTP_SSL(self.smtp_server, self.smtp_port)
            else:
                # 使用普通连接,然后启动 TLS
                self.server = smtplib.SMTP(self.smtp_server, self.smtp_port)
                self.server.starttls()
            # 登录邮箱
            self.server.login(self.sender, self.password)
            print('成功连接到 SMTP 服务器')
            return True
        except Exception as e:
            print(f'连接 SMTP 服务器失败: {e}')
            return False
    
    def disconnect(self):
        """断开与 SMTP 服务器的连接"""
        if self.server:
            self.server.quit()
            print('已断开与 SMTP 服务器的连接')
    
    def send_text_email(self, receivers, subject, content, cc=None, bcc=None):
        """发送纯文本邮件"""
        return self._send_email(receivers, subject, content, 'plain', cc, bcc)
    
    def send_html_email(self, receivers, subject, html_content, cc=None, bcc=None):
        """发送 HTML 邮件"""
        return self._send_email(receivers, subject, html_content, 'html', cc, bcc)
    
    def send_email_with_attachments(self, receivers, subject, content, attachment_paths, cc=None, bcc=None):
        """发送带附件的邮件"""
        # 创建邮件对象
        message = MIMEMultipart()
        message['From'] = Header(self.sender.split('@')[0], 'utf-8')
        message['To'] = Header('; '.join(receivers), 'utf-8') if isinstance(receivers, list) else Header(receivers, 'utf-8')
        
        if cc:
            message['Cc'] = Header('; '.join(cc), 'utf-8') if isinstance(cc, list) else Header(cc, 'utf-8')
        
        message['Subject'] = Header(subject, 'utf-8')
        
        # 添加正文
        message.attach(MIMEText(content, 'plain', 'utf-8'))
        
        # 添加附件
        for path in attachment_paths:
            if os.path.exists(path):
                with open(path, 'rb') as f:
                    attachment = MIMEApplication(f.read())
                    attachment.add_header('Content-Disposition', 'attachment', filename=os.path.basename(path))
                    message.attach(attachment)
                print(f'添加附件: {path}')
            else:
                print(f'附件文件不存在: {path}')
        
        # 发送邮件
        return self._send_message(message, receivers, cc, bcc)
    
    def _send_email(self, receivers, subject, content, content_type, cc=None, bcc=None):
        """发送邮件的内部方法"""
        # 创建邮件对象
        message = MIMEText(content, content_type, 'utf-8')
        message['From'] = Header(self.sender.split('@')[0], 'utf-8')
        message['To'] = Header('; '.join(receivers), 'utf-8') if isinstance(receivers, list) else Header(receivers, 'utf-8')
        
        if cc:
            message['Cc'] = Header('; '.join(cc), 'utf-8') if isinstance(cc, list) else Header(cc, 'utf-8')
        
        message['Subject'] = Header(subject, 'utf-8')
        
        # 发送邮件
        return self._send_message(message, receivers, cc, bcc)
    
    def _send_message(self, message, receivers, cc=None, bcc=None):
        """发送邮件消息的内部方法"""
        try:
            # 确保已连接
            if not self.server:
                if not self.connect():
                    return False
            
            # 处理收件人列表
            if isinstance(receivers, str):
                receivers = [receivers]
            
            # 处理抄送列表
            if cc:
                if isinstance(cc, str):
                    cc = [cc]
            else:
                cc = []
            
            # 处理密送列表
            if bcc:
                if isinstance(bcc, str):
                    bcc = [bcc]
            else:
                bcc = []
            
            # 合并所有收件人
            all_receivers = receivers + cc + bcc
            
            # 发送邮件
            self.server.sendmail(self.sender, all_receivers, message.as_string())
            print(f'邮件发送成功,共发送给 {len(all_receivers)} 个收件人')
            return True
        except Exception as e:
            print(f'邮件发送失败: {e}')
            return False

# 使用示例
if __name__ == "__main__":
    # 配置邮件发送器
    sender = 'your_email@example.com'
    password = 'your_password'
    smtp_server = 'smtp.example.com'
    smtp_port = 587
    
    # 创建邮件发送器
    email_sender = EmailSender(sender, password, smtp_server, smtp_port)
    
    try:
        # 连接服务器
        email_sender.connect()
        
        # 发送纯文本邮件
        print('\n发送纯文本邮件:')
        email_sender.send_text_email(
            receivers=['recipient@example.com'],
            subject='测试邮件',
            content='这是一封测试邮件。'
        )
        
        # 发送 HTML 邮件
        print('\n发送 HTML 邮件:')
        html_content = '<h1>测试邮件</h1><p>这是一封 <b>HTML 格式</b> 的测试邮件。</p>'
        email_sender.send_html_email(
            receivers=['recipient@example.com'],
            subject='HTML 测试邮件',
            html_content=html_content
        )
        
        # 发送带附件的邮件
        print('\n发送带附件的邮件:')
        email_sender.send_email_with_attachments(
            receivers=['recipient@example.com'],
            subject='带附件的测试邮件',
            content='这是一封带附件的测试邮件,请查收。',
            attachment_paths=['example.txt', 'example.jpg']
        )
        
    finally:
        # 断开连接
        email_sender.disconnect()

实际应用示例

示例 1:自动发送报告邮件

python
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
from email.header import Header
import os
import datetime

class ReportSender:
    """报告发送类"""
    
    def __init__(self, sender, password, smtp_server, smtp_port):
        """初始化报告发送器"""
        self.sender = sender
        self.password = password
        self.smtp_server = smtp_server
        self.smtp_port = smtp_port
    
    def generate_daily_report(self):
        """生成每日报告"""
        today = datetime.date.today()
        report_date = today.strftime('%Y-%m-%d')
        
        # 生成报告内容
        report_content = f'''
每日报告 - {report_date}

1. 今日摘要
   - 完成了项目 A 的开发任务
   - 参加了团队会议
   - 解决了 3 个 bug

2. 明日计划
   - 开始项目 B 的设计
   - 代码审查
   - 编写文档

3. 遇到的问题
   - 无

4. 需要的支持
   - 无
        '''
        
        # 保存报告到文件
        report_filename = f'daily_report_{report_date}.txt'
        with open(report_filename, 'w', encoding='utf-8') as f:
            f.write(report_content)
        
        return report_filename, report_content
    
    def send_report(self, receivers, report_filename, report_content):
        """发送报告邮件"""
        today = datetime.date.today()
        report_date = today.strftime('%Y-%m-%d')
        
        # 创建邮件对象
        message = MIMEMultipart()
        message['From'] = Header(self.sender.split('@')[0], 'utf-8')
        message['To'] = Header('; '.join(receivers), 'utf-8')
        message['Subject'] = Header(f'每日报告 - {report_date}', 'utf-8')
        
        # 添加正文
        email_content = f'''
尊敬的领导:

您好!

附件是 {report_date} 的每日工作报告,请查收。

祝好!
        '''
        message.attach(MIMEText(email_content, 'plain', 'utf-8'))
        
        # 添加附件
        if os.path.exists(report_filename):
            with open(report_filename, 'rb') as f:
                attachment = MIMEApplication(f.read())
                attachment.add_header('Content-Disposition', 'attachment', filename=os.path.basename(report_filename))
                message.attach(attachment)
            print(f'添加附件: {report_filename}')
        else:
            print(f'报告文件不存在: {report_filename}')
            return False
        
        # 发送邮件
        try:
            # 连接 SMTP 服务器
            server = smtplib.SMTP(self.smtp_server, self.smtp_port)
            server.starttls()
            server.login(self.sender, self.password)
            
            # 发送邮件
            server.sendmail(self.sender, receivers, message.as_string())
            print(f'报告邮件发送成功,共发送给 {len(receivers)} 个收件人')
            server.quit()
            return True
        except Exception as e:
            print(f'邮件发送失败: {e}')
            return False
    
    def run(self, receivers):
        """运行报告生成和发送"""
        print('生成每日报告...')
        report_filename, report_content = self.generate_daily_report()
        
        print('发送报告邮件...')
        success = self.send_report(receivers, report_filename, report_content)
        
        # 清理报告文件
        if os.path.exists(report_filename):
            os.remove(report_filename)
            print(f'已删除报告文件: {report_filename}')
        
        return success

# 使用示例
if __name__ == "__main__":
    # 配置
    sender = 'your_email@example.com'
    password = 'your_password'
    smtp_server = 'smtp.example.com'
    smtp_port = 587
    receivers = ['manager@example.com', 'team@example.com']
    
    # 创建报告发送器
    report_sender = ReportSender(sender, password, smtp_server, smtp_port)
    
    # 运行
    report_sender.run(receivers)

示例 2:邮件通知系统

python
import smtplib
from email.mime.text import MIMEText
from email.header import Header
import configparser
import os

class EmailNotifier:
    """邮件通知系统"""
    
    def __init__(self, config_file='email_config.ini'):
        """初始化邮件通知器"""
        self.config_file = config_file
        self.config = self._load_config()
        
        # 从配置中读取邮件设置
        self.sender = self.config.get('Email', 'sender')
        self.password = self.config.get('Email', 'password')
        self.smtp_server = self.config.get('Email', 'smtp_server')
        self.smtp_port = self.config.getint('Email', 'smtp_port')
        self.use_ssl = self.config.getboolean('Email', 'use_ssl')
    
    def _load_config(self):
        """加载配置文件"""
        config = configparser.ConfigParser()
        
        # 如果配置文件不存在,创建默认配置
        if not os.path.exists(self.config_file):
            config['Email'] = {
                'sender': 'your_email@example.com',
                'password': 'your_password',
                'smtp_server': 'smtp.example.com',
                'smtp_port': '587',
                'use_ssl': 'False'
            }
            
            with open(self.config_file, 'w') as f:
                config.write(f)
            print(f'创建了默认配置文件: {self.config_file}')
        else:
            config.read(self.config_file)
        
        return config
    
    def send_notification(self, receivers, subject, message_content, is_html=False):
        """发送通知邮件"""
        # 创建邮件内容
        content_type = 'html' if is_html else 'plain'
        message = MIMEText(message_content, content_type, 'utf-8')
        message['From'] = Header(self.sender.split('@')[0], 'utf-8')
        message['To'] = Header('; '.join(receivers), 'utf-8') if isinstance(receivers, list) else Header(receivers, 'utf-8')
        message['Subject'] = Header(subject, 'utf-8')
        
        # 发送邮件
        try:
            # 连接 SMTP 服务器
            if self.use_ssl:
                server = smtplib.SMTP_SSL(self.smtp_server, self.smtp_port)
            else:
                server = smtplib.SMTP(self.smtp_server, self.smtp_port)
                server.starttls()
            
            # 登录邮箱
            server.login(self.sender, self.password)
            
            # 处理收件人列表
            if isinstance(receivers, str):
                receivers = [receivers]
            
            # 发送邮件
            server.sendmail(self.sender, receivers, message.as_string())
            print(f'通知邮件发送成功,共发送给 {len(receivers)} 个收件人')
            server.quit()
            return True
        except Exception as e:
            print(f'邮件发送失败: {e}')
            return False
    
    def send_alert(self, receivers, alert_message):
        """发送告警邮件"""
        subject = '[告警] 系统异常通知'
        content = f'''
尊敬的管理员:

您好!

系统检测到以下异常情况:

{alert_message}

请及时处理。

祝好!
系统自动通知
        '''
        return self.send_notification(receivers, subject, content)
    
    def send_success_notification(self, receivers, task_name, task_result):
        """发送成功通知邮件"""
        subject = f'[成功] {task_name} 执行完成'
        content = f'''
尊敬的用户:

您好!

任务 "{task_name}" 已成功执行完成,执行结果如下:

{task_result}

祝好!
系统自动通知
        '''
        return self.send_notification(receivers, subject, content)

# 使用示例
if __name__ == "__main__":
    # 创建邮件通知器
    notifier = EmailNotifier()
    
    # 发送告警通知
    print('发送告警通知:')
    notifier.send_alert(
        receivers=['admin@example.com'],
        alert_message='服务器 CPU 使用率超过 90%,当前值为 95%。'
    )
    
    # 发送成功通知
    print('\n发送成功通知:')
    notifier.send_success_notification(
        receivers=['user@example.com'],
        task_name='数据备份',
        task_result='备份成功,备份文件大小:1.2GB,备份时间:2024-01-01 12:00:00'
    )

邮件发送的最佳实践

1. 安全性

  • 保护密码:不要在代码中硬编码密码,使用配置文件或环境变量
  • 使用授权码:使用邮箱的授权码而不是登录密码
  • 加密连接:使用 TLS 或 SSL 加密连接
  • 验证收件人:验证收件人邮箱地址的格式

2. 可靠性

  • 错误处理:捕获并处理邮件发送过程中的异常
  • 重试机制:实现邮件发送失败后的重试逻辑
  • 超时设置:设置合理的连接超时时间
  • 日志记录:记录邮件发送的详细日志

3. 合规性

  • 避免垃圾邮件:确保邮件内容合法,不发送垃圾邮件
  • 添加退订选项:对于批量邮件,添加退订选项
  • 遵守法规:遵守当地的电子邮件法规,如 GDPR、CAN-SPAM 等

4. 性能

  • 批量发送:对于大量邮件,使用批量发送
  • 连接池:重用 SMTP 连接
  • 异步发送:使用异步方式发送邮件,避免阻塞主线程

5. 可用性

  • 备用服务器:配置多个 SMTP 服务器,当主服务器不可用时使用备用服务器
  • 监控:监控邮件发送的成功率
  • 报警:当邮件发送失败率过高时,触发报警

总结

本章节介绍了 Python 中使用 SMTP 发送邮件的方法,包括:

  1. 基本邮件发送:发送纯文本邮件和 HTML 邮件
  2. 高级邮件功能:发送带附件的邮件、带图片的邮件、发送给多个收件人
  3. 连接方式:使用 TLS 和 SSL 连接
  4. 邮件发送类:创建可重用的邮件发送类
  5. 实际应用示例:自动发送报告邮件、邮件通知系统
  6. 最佳实践:安全性、可靠性、合规性、性能、可用性

掌握 Python 中的邮件发送功能,对于自动化通知、报告生成、告警系统等场景非常重要。通过合理使用邮件发送功能,可以提高工作效率,及时传递重要信息。