杰瑞科技汇

Python如何用mimetext实现群发邮件?

核心概念

在开始之前,我们需要理解几个核心概念:

Python如何用mimetext实现群发邮件?-图1
(图片来源网络,侵删)
  1. MIME (Multipurpose Internet Mail Extensions):这是一种扩展邮件标准,允许邮件不仅仅包含纯文本,还可以包含 HTML、图片、音频、视频、附件等二进制或非文本数据,我们使用 email.mime 模块下的类来构建这些不同类型的邮件内容。
  2. email.mime.text.MIMEText:这是最基础的 MIME 类,用于创建纯文本或 HTML 格式的邮件正文,它的构造函数是 MIMEText(_text, _subtype='plain', _charset='utf-8')
    • _text: 邮件正文内容。
    • _subtype: 子类型,可以是 'plain' (纯文本) 或 'html' (HTML)。
    • _charset: 字符编码,强烈建议使用 'utf-8' 以支持中文等非英文字符。
  3. smtplib:这是 Python 的标准库,用于发送邮件,它封装了 SMTP (Simple Mail Transfer Protocol) 协议,让我们可以用 Python 代码连接到邮件服务器并发送邮件。
  4. 邮件结构:一封完整的邮件(特别是群发邮件)通常包含:
    • 发件人
    • 收件人 (一个或多个)
    • 抄送 (可选)
    • 主题
    • 邮件正文 (可以是纯文本、HTML 或两者兼备)
    • 附件 (可选)

准备工作(获取邮件服务器信息)

在写代码之前,你需要准备以下信息,这些信息通常可以从你的邮箱服务商(如 QQ、163、Gmail、Outlook 等)的帮助页面找到:

  • SMTP 服务器地址:QQ邮箱是 smtp.qq.com,163邮箱是 smtp.163.com
  • SMTP 端口:通常是 465 (SSL 加密) 或 587 (STARTTLS 加密),使用 465 更简单,因为它在整个连接过程中都是加密的。
  • 你的邮箱地址
  • 授权码注意,这通常不是你的邮箱登录密码!为了安全,邮箱服务商(尤其是国内的)会提供一个“授权码”或“专用密码”用于第三方登录,请务必在邮箱设置中开启 SMTP 服务并获取授权码。

安装必要的库

Python 的 emailsmtplib 都是标准库,无需额外安装,你只需要确保你的 Python 环境正确配置即可。

# 通常不需要执行,因为它们是标准库
# pip install secure-smtplib  # 一个更现代的第三方库,可选

编写 Python 代码

下面我们从一个最简单的例子开始,逐步构建一个功能完善的邮件群发器。

示例 1:发送一封简单的纯文本邮件

这是最基础的用法,直接使用 MIMEText

Python如何用mimetext实现群发邮件?-图2
(图片来源网络,侵删)
import smtplib
from email.mime.text import MIMEText
from email.header import Header
# --- 1. 准备邮件内容 ---
# 邮件主题
subject = "Python邮件测试"(纯文本)
plain_text_content = "你好,\n\n这是一封通过Python发送的测试邮件,\n\n祝好!"
# 创建一个MIMEText对象,指定内容为纯文本
# _subtype='plain' 表示纯文本,'html' 表示HTML
# _charset='utf-8' 非常重要,防止中文乱码
msg = MIMEText(plain_text_content, 'plain', 'utf-8')
# --- 2. 设置邮件头 ---
# 邮件主题,需要用 Header 处理,以防主题中有中文等特殊字符
msg['Subject'] = Header(subject, 'utf-8')
# 发件人
msg['From'] = "your_email@qq.com" # 替换成你的邮箱
# 收件人 (可以是一个或多个,用逗号隔开)
msg['To'] = "recipient1@example.com, recipient2@example.com" # 替换成收件人邮箱
# --- 3. 连接邮件服务器并发送邮件 ---
# 请替换成你自己的邮箱信息
sender_email = "your_email@qq.com"
sender_password = "your_authorization_code" # 替换成你的授权码
smtp_server = "smtp.qq.com"
smtp_port = 465 # SSL端口
try:
    # 使用 with 语句可以确保连接被正确关闭
    # smtplib.SMTP_SSL() 用于创建一个使用SSL加密的SMTP连接
    with smtplib.SMTP_SSL(smtp_server, smtp_port) as server:
        # 登录邮箱
        server.login(sender_email, sender_password)
        # 发送邮件
        # 发送时,第二个参数是收件人列表,可以是一个字符串(多个收件人用逗号隔开)或一个列表
        server.sendmail(sender_email, msg['To'].split(','), msg.as_string())
        print("邮件发送成功!")
except Exception as e:
    print(f"邮件发送失败,错误信息: {e}")

示例 2:发送一封包含附件和HTML正文的邮件

群发邮件通常需要更丰富的内容,比如HTML格式的正文和附件,这时我们需要使用 MIMEMultipart 作为邮件容器,然后把 MIMETextMIMEImageMIMEApplication 等作为部件添加进去。

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
# --- 1. 准备邮件内容 ---
# 邮件主题
subject = "重要通知:月度报告"
# 创建一个 MIMEMultipart 对象,作为邮件容器
# 'mixed' 表示邮件包含多个部分,如文本、附件等
msg = MIMEMultipart('mixed')
# --- 2. 设置邮件头 ---
msg['Subject'] = Header(subject, 'utf-8')
msg['From'] = "your_email@qq.com"
# 收件人列表,使用列表更规范
to_addrs = ["recipient1@example.com", "recipient2@example.com"]
msg['To'] = ", ".join(to_addrs)
# --- 3. 添加邮件正文 ---
# 添加HTML正文
html_content = """
<html>
  <head></head>
  <body>
    <h1>月度报告</h1>
    <p>您好,</p>
    <p>请查收附件中的 <b>月度销售报告</b>。</p>
    <p>如有任何问题,请随时联系。</p>
    <p>谢谢!</p>
  </body>
</html>
"""
# 创建一个HTML格式的MIMEText对象
html_part = MIMEText(html_content, 'html', 'utf-8')
# 将HTML部分添加到邮件容器中
msg.attach(html_part)
# 添加纯文本正文(作为HTML无法显示时的备选)
plain_text_content = "您好,\n\n请查收附件中的月度销售报告,\n\n谢谢!"
plain_part = MIMEText(plain_text_content, 'plain', 'utf-8')
# 将纯文本部分也添加进去,放在HTML部分之前
# msg.attach(plain_part) # 如果只想发HTML,可以注释掉这一行
# --- 4. 添加附件 ---
# 假设我们有一个名为 "report.pdf" 的文件在当前目录下
attachment_path = "report.pdf" # 替换成你的附件路径
if os.path.exists(attachment_path):
    # 创建一个MIMEApplication对象,用于处理二进制附件
    with open(attachment_path, 'rb') as f:
        # MIMEApplication 的第一个参数是附件的二进制数据
        # _subtype 指定附件类型,这里用 'octet-stream' 表示通用二进制流
        # _encoder 设置为 'base64' 表示使用Base64编码
        part = MIMEApplication(f.read(), Name=os.path.basename(attachment_path))
    # 添加附件头
    part['Content-Disposition'] = f'attachment; filename="{os.path.basename(attachment_path)}"'
    # 将附件添加到邮件容器中
    msg.attach(part)
    print(f"附件 '{os.path.basename(attachment_path)}' 添加成功。")
else:
    print(f"警告:附件文件 '{attachment_path}' 未找到,将不添加附件。")
# --- 5. 连接并发送邮件 ---
sender_email = "your_email@qq.com"
sender_password = "your_authorization_code"
smtp_server = "smtp.qq.com"
smtp_port = 465
try:
    with smtplib.SMTP_SSL(smtp_server, smtp_port) as server:
        server.login(sender_email, sender_password)
        # 发送邮件,收件人使用列表
        server.sendmail(sender_email, to_addrs, msg.as_string())
        print("邮件群发成功!")
except Exception as e:
    print(f"邮件发送失败,错误信息: {e}")

代码解析与最佳实践

  1. 使用 MIMEMultipart 作为容器:当邮件需要包含正文和附件时,MIMEMultipart 是最佳选择,它像一个信封,可以把信(MIMEText)、照片(MIMEImage)等所有东西都装进去。
  2. 字符编码:所有涉及中文的地方,如主题、发件人、收件人、正文,都建议使用 Header 类进行包装,并统一使用 'utf-8' 编码,这是避免乱码最可靠的方法。
    msg['Subject'] = Header("我的邮件主题", 'utf-8')
  3. 收件人列表:群发时,将收件人邮箱地址存储在一个列表中,然后在 sendmail 方法中直接传入这个列表,比用逗号隔开的字符串更清晰、更不容易出错。
  4. 附件处理
    • 使用 os.path.exists() 检查文件是否存在,避免因文件缺失导致程序崩溃。
    • 使用 with open(...) as f: 的方式打开文件,可以确保文件在读取后自动关闭,防止资源泄露。
    • MIMEApplication 适用于所有类型的二进制文件(PDF, DOC, ZIP等)。MIMEImage 专门用于图片,MIMEAudio 用于音频。
    • Content-Disposition 头部字段是告诉邮件客户端这是一个附件,并指定了下载时默认的文件名。
  5. 安全性
    • 永远不要将邮箱密码或授权码直接硬编码在代码中,尤其是当你要把代码上传到 GitHub 等公开平台时,更好的做法是使用环境变量或配置文件来管理这些敏感信息。
    • 始终使用 SMTP_SSLSMTP(..., port=587).starttls() 来加密你的邮件连接,防止密码和邮件内容在传输过程中被窃听。

通过以上示例,你已经掌握了使用 Python 群发邮件的核心技术:

  • MIMEText: 创建纯文本或HTML正文。
  • MIMEMultipart: 构建包含多部分(正文+附件)的复杂邮件。
  • smtplib.SMTP_SSL: 安全地连接到邮件服务器并发送邮件。
  • Header: 正确处理邮件头中的非ASCII字符。

你可以基于这些基础代码,自由组合和扩展,创建出满足你各种需求的邮件群发工具。

Python如何用mimetext实现群发邮件?-图3
(图片来源网络,侵删)
分享:
扫描分享到社交APP
上一篇
下一篇