位置: 文档库 > Python > 分享Python实现SMTP发送邮件图文实例

分享Python实现SMTP发送邮件图文实例

天衣无缝 上传于 2020-08-29 20:39

YPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">

《分享Python实现SMTP发送邮件图文实例》

在现代信息化社会中,电子邮件作为重要的通信工具被广泛应用于个人交流、企业通知和系统自动化场景。Python凭借其简洁的语法和丰富的库支持,成为实现邮件发送功能的理想选择。本文将通过图文结合的方式,详细介绍如何使用Python的smtplib和email库实现SMTP协议邮件发送,涵盖基础文本邮件、带附件邮件及HTML格式邮件的完整实现流程。

一、SMTP协议基础与准备工作

SMTP(Simple Mail Transfer Protocol)是用于发送邮件的互联网标准协议。Python通过smtplib模块提供SMTP客户端功能,配合email库构建邮件内容。使用前需确认以下信息:

  • SMTP服务器地址(如QQ邮箱为smtp.qq.com)
  • 端口号(通常465/SSL或587/TLS)
  • 发件人邮箱账号及授权码(非邮箱密码)

获取授权码步骤(以QQ邮箱为例)

1. 登录QQ邮箱网页版

2. 进入「设置」→「账户」

3. 找到「POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务」

4. 开启「POP3/SMTP服务」并获取16位授权码

二、基础文本邮件发送实现

以下代码演示如何发送纯文本邮件:

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

# 邮件配置
smtp_server = 'smtp.qq.com'
port = 465
sender = 'your_email@qq.com'
password = 'your_authorization_code'  # 授权码
receiver = 'recipient@example.com'

# 创建邮件内容
message = MIMEText('这是通过Python SMTP发送的测试邮件', 'plain', 'utf-8')
message['From'] = Header('Python测试发件人')
message['To'] = Header('测试收件人')
message['Subject'] = Header('Python SMTP邮件测试')

try:
    # 建立SSL连接
    with smtplib.SMTP_SSL(smtp_server, port) as server:
        server.login(sender, password)
        server.sendmail(sender, [receiver], message.as_string())
    print("邮件发送成功")
except Exception as e:
    print(f"邮件发送失败: {e}")

代码解析

1. 使用MIMEText创建纯文本邮件对象

2. 通过Header设置邮件头信息(发件人、收件人、主题)

3. SMTP_SSL建立安全连接并登录

4. sendmail方法执行发送(收件人需为列表格式)

三、带附件邮件发送实现

发送附件需要使用MIMEMultipart组合多个MIME对象:

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

# 创建带附件的邮件容器
msg = MIMEMultipart()
msg['From'] = Header('Python附件发件人')
msg['To'] = Header('附件收件人')
msg['Subject'] = Header('带附件的Python邮件')

# 正文内容
text = MIMEText('这是包含附件的测试邮件', 'plain', 'utf-8')
msg.attach(text)

# 添加附件
with open('test.pdf', 'rb') as f:
    pdf = MIMEApplication(f.read())
    pdf.add_header('Content-Disposition', 'attachment', filename='test.pdf')
    msg.attach(pdf)

# 发送配置(同前)
try:
    with smtplib.SMTP_SSL('smtp.qq.com', 465) as server:
        server.login('your_email@qq.com', 'your_code')
        server.sendmail('your_email@qq.com', ['recipient@example.com'], msg.as_string())
    print("附件邮件发送成功")
except Exception as e:
    print(f"发送失败: {e}")

关键点说明

1. MIMEMultipart作为基础容器

2. MIMEApplication处理二进制附件

3. add_header设置附件显示名称

4. attach方法将各部分组合到邮件中

四、HTML格式邮件发送实现

HTML邮件支持富文本格式,适合包含样式和链接的场景:

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

# HTML内容
html_content = """
  
    

Python HTML邮件

这是一个Python官方的测试邮件

支持HTML格式和CSS样式

""" # 创建HTML邮件 msg = MIMEText(html_content, 'html', 'utf-8') msg['From'] = Header('HTML发件人') msg['To'] = Header('HTML收件人') msg['Subject'] = Header('Python HTML邮件测试') # 发送配置 try: with smtplib.SMTP_SSL('smtp.qq.com', 465) as server: server.login('your_email@qq.com', 'your_code') server.sendmail('your_email@qq.com', ['recipient@example.com'], msg.as_string()) print("HTML邮件发送成功") except Exception as e: print(f"发送失败: {e}")

注意事项

1. MIMEText的subtype参数设为'html'

2. HTML内容需符合标准格式

3. 部分邮箱客户端可能屏蔽外部样式

五、完整项目示例:多功能邮件发送器

综合实现文本、附件、HTML邮件的完整类:

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

class EmailSender:
    def __init__(self, smtp_server, port, sender, password):
        self.smtp_server = smtp_server
        self.port = port
        self.sender = sender
        self.password = password

    def send_text(self, receivers, subject, content):
        """发送纯文本邮件"""
        msg = MIMEText(content, 'plain', 'utf-8')
        msg['From'] = Header(self.sender)
        msg['To'] = Header(','.join(receivers))
        msg['Subject'] = Header(subject)
        self._send(msg, receivers)

    def send_html(self, receivers, subject, html_content):
        """发送HTML邮件"""
        msg = MIMEText(html_content, 'html', 'utf-8')
        msg['From'] = Header(self.sender)
        msg['To'] = Header(','.join(receivers))
        msg['Subject'] = Header(subject)
        self._send(msg, receivers)

    def send_attachment(self, receivers, subject, text_content, file_path):
        """发送带附件邮件"""
        msg = MIMEMultipart()
        msg['From'] = Header(self.sender)
        msg['To'] = Header(','.join(receivers))
        msg['Subject'] = Header(subject)

        # 添加正文
        msg.attach(MIMEText(text_content, 'plain', 'utf-8'))

        # 添加附件
        with open(file_path, 'rb') as f:
            part = MIMEApplication(f.read())
            part.add_header('Content-Disposition', 'attachment', 
                          filename=file_path.split('/')[-1])
            msg.attach(part)

        self._send(msg, receivers)

    def _send(self, msg, receivers):
        """内部发送方法"""
        try:
            with smtplib.SMTP_SSL(self.smtp_server, self.port) as server:
                server.login(self.sender, self.password)
                server.sendmail(self.sender, receivers, msg.as_string())
            print(f"邮件发送成功至: {','.join(receivers)}")
        except Exception as e:
            print(f"邮件发送失败: {e}")

# 使用示例
if __name__ == '__main__':
    sender = EmailSender(
        smtp_server='smtp.qq.com',
        port=465,
        sender='your_email@qq.com',
        password='your_code'
    )

    # 发送文本邮件
    sender.send_text(
        receivers=['recipient1@example.com', 'recipient2@example.com'],
        subject='测试文本邮件',
        content='这是通过EmailSender类发送的文本邮件'
    )

    # 发送HTML邮件
    html_content = """
    

HTML邮件测试

来自Python EmailSender类

""" sender.send_html( receivers=['recipient@example.com'], subject='HTML邮件测试', html_content=html_content ) # 发送附件邮件 sender.send_attachment( receivers=['recipient@example.com'], subject='带附件的邮件', text_content='请查收附件中的测试文件', file_path='test.pdf' )

六、常见问题解决方案

问题1:登录失败(535错误)

原因:授权码错误或未开启SMTP服务

解决:重新获取授权码并确认邮箱设置

问题2:连接超时

原因:网络问题或端口被屏蔽

解决:检查防火墙设置,尝试更换端口(如587)

问题3:附件乱码

原因:文件名编码问题

解决:显式设置文件名编码

part.add_header('Content-Disposition', 'attachment', 
              filename=('utf-8', '', '中文文件名.pdf'))

问题4:邮件进入垃圾箱

原因:发件人身份未验证

解决:配置SPF/DKIM记录,避免使用公共邮箱发送大量邮件

七、进阶应用场景

1. 批量邮件发送:结合数据库读取收件人列表

2. 邮件模板系统:使用Jinja2模板引擎生成动态内容

3. 异步发送:通过Celery实现异步邮件队列

4. 邮件追踪:在链接中添加唯一标识符统计打开率

示例:使用Jinja2模板的邮件发送

from jinja2 import Environment, FileSystemLoader

# 配置Jinja2环境
env = Environment(loader=FileSystemLoader('.'))
template = env.get_template('email_template.html')

# 渲染模板
html_content = template.render(
    title='个性化邮件',
    username='张三',
    link='https://example.com/confirm'
)

# 发送HTML邮件(同前)

八、安全注意事项

1. 永远不要在代码中硬编码密码,建议使用环境变量或配置文件

2. 对用户输入的内容进行HTML转义,防止XSS攻击

3. 限制邮件发送频率,避免被标记为垃圾邮件

4. 使用TLS 1.2及以上版本加密连接

示例:使用环境变量管理敏感信息

import os
from dotenv import load_dotenv

load_dotenv()  # 从.env文件加载环境变量

smtp_config = {
    'server': os.getenv('SMTP_SERVER'),
    'port': int(os.getenv('SMTP_PORT')),
    'user': os.getenv('SMTP_USER'),
    'password': os.getenv('SMTP_PASSWORD')
}

创建.env文件:

SMTP_SERVER=smtp.qq.com
SMTP_PORT=465
SMTP_USER=your_email@qq.com
SMTP_PASSWORD=your_code

九、总结与扩展

本文系统介绍了Python通过SMTP协议发送邮件的完整实现方案,涵盖了:

  • 基础文本邮件发送
  • 带附件邮件处理
  • HTML格式邮件构建
  • 封装为可复用类的实践
  • 常见问题解决方案
  • 安全最佳实践

实际应用中,可根据需求扩展以下功能:

  • 添加邮件发送日志记录
  • 实现邮件发送重试机制
  • 集成第三方邮件服务API(如SendGrid)
  • 开发Web界面管理邮件模板

掌握Python邮件发送技术后,可应用于自动化报告分发、系统警报通知、用户注册验证等多种业务场景,显著提升工作效率。

关键词:Python邮件发送、SMTP协议、smtplib库、email库、附件邮件、HTML邮件、邮件安全、Jinja2模板、环境变量管理

简介:本文详细介绍Python通过SMTP协议发送邮件的完整实现方案,涵盖基础文本邮件、带附件邮件、HTML格式邮件的代码实现,提供封装类示例和常见问题解决方案,同时强调安全实践和进阶应用场景,适合需要实现邮件自动化功能的开发者参考。