Python使用smtplib库开发一个邮件自动发送工具

Python使用smtplib库开发一个邮件自动发送工具

在自动化办公、系统监控或任务提醒场景中,自动发送邮件是一项常见需求。本文将详细介绍如何使用 Python 的标准库 smtplibemail 开发一个功能完善的邮件自动发送工具,支持多邮箱服务商、附件发送、HTML内容和错误处理等功能,并提供完整的代码示例和使用说明。

1. 环境准备

1.1 安装依赖库

  • smtplib:Python 标准库,用于发送邮件。
  • email:Python 标准库,用于构建邮件内容。
  • 其他依赖(可选):
  • argparse:解析命令行参数(无需额外安装)。
  • tkinter:可选的图形化界面支持(无需额外安装)。

1.2 开发环境

  • 操作系统:Windows/macOS/Linux(通用性支持)。
  • Python版本:3.8 及以上(推荐使用最新稳定版)。

2. 功能需求分析

目标开发一个具备以下功能的邮件自动发送工具:

  1. 支持主流邮箱服务商:QQ邮箱、163邮箱、Gmail、Outlook 等。
  2. 发送邮件内容
  • 纯文本邮件。
  • HTML 格式邮件(支持富文本和超链接)。
  • 附件发送(支持多种文件类型)。
  1. 安全认证
  • 使用 SSL/TLS 加密连接。
  • 支持邮箱授权码(如 QQ 邮箱需使用授权码而非密码)。
  1. 错误处理
  • 捕获网络错误、认证失败、邮件发送失败等异常。
  1. 可扩展性
  • 通过配置文件或命令行参数自定义发送参数。

3. 核心代码实现

3.1 导入依赖库

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
import os
import argparse

3.2 邮箱服务商配置

# 邮箱服务商与 SMTP 服务器配置
SMTP_CONFIG = {
    "qq": {"server": "smtp.qq.com", "port": 465, "use_ssl": True},
    "163": {"server": "smtp.163.com", "port": 465, "use_ssl": True},
    "gmail": {"server": "smtp.gmail.com", "port": 465, "use_ssl": True},
    "outlook": {"server": "smtp.office365.com", "port": 587, "use_ssl": False},
}

3.3 构建邮件内容

def build_email(sender, password, recipients, subject, content, content_type="plain", attachments=None):
    """
    构建邮件内容
    :param sender: 发件人邮箱地址
    :param password: 邮箱密码/授权码
    :param recipients: 收件人列表(字符串或列表)
    :param subject: 邮件主题
    :param content: 邮件正文内容
    :param content_type: 内容类型(plain/html)
    :param attachments: 附件路径列表
    :return: 构建好的邮件对象
    """
    msg = MIMEMultipart()
    msg["From"] = sender
    msg["To"] = ", ".join(recipients) if isinstance(recipients, list) else recipients
    msg["Subject"] = subject

    # 添加正文内容
    msg.attach(MIMEText(content, content_type))

    # 添加附件
    if attachments:
        for file_path in attachments:
            if os.path.exists(file_path):
                with open(file_path, "rb") as f:
                    part = MIMEBase("application", "octet-stream")
                    part.set_payload(f.read())
                    encoders.encode_base64(part)
                    part.add_header("Content-Disposition", f"attachment; filename={os.path.basename(file_path)}")
                    msg.attach(part)
            else:
                raise FileNotFoundError(f"附件不存在: {file_path}")

    return msg

3.4 发送邮件

def send_email(sender, password, recipients, subject, content, content_type="plain", attachments=None, provider="qq"):
    """
    发送邮件
    :param sender: 发件人邮箱地址
    :param password: 邮箱密码/授权码
    :param recipients: 收件人列表
    :param subject: 邮件主题
    :param content: 邮件正文内容
    :param content_type: 内容类型(plain/html)
    :param attachments: 附件路径列表
    :param provider: 邮箱服务商(qq/163/gmail/outlook)
    """
    try:
        config = SMTP_CONFIG.get(provider.lower(), None)
        if not config:
            raise ValueError(f"不支持的邮箱服务商: {provider}")

        # 构建邮件对象
        msg = build_email(sender, password, recipients, subject, content, content_type, attachments)

        # 创建 SMTP 连接
        if config["use_ssl"]:
            server = smtplib.SMTP_SSL(config["server"], config["port"])
        else:
            server = smtplib.SMTP(config["server"], config["port"])
            server.starttls()

        # 登录邮箱并发送邮件
        server.login(sender, password)
        server.sendmail(sender, recipients, msg.as_string())
        server.quit()
        print("邮件发送成功!")

    except Exception as e:
        print(f"邮件发送失败: {e}")

4. 命令行参数支持(可选)

通过 argparse 提供命令行接口:

def parse_args():
    parser = argparse.ArgumentParser(description="Python 自动邮件发送工具")
    parser.add_argument("--sender", required=True, help="发件人邮箱地址")
    parser.add_argument("--password", required=True, help="邮箱密码/授权码")
    parser.add_argument("--recipients", nargs="+", required=True, help="收件人邮箱地址(多个用空格分隔)")
    parser.add_argument("--subject", required=True, help="邮件主题")
    parser.add_argument("--content", required=True, help="邮件正文内容")
    parser.add_argument("--type", choices=["plain", "html"], default="plain", help="内容类型(plain/html)")
    parser.add_argument("--attachments", nargs="+", help="附件路径(多个用空格分隔)")
    parser.add_argument("--provider", default="qq", help="邮箱服务商(qq/163/gmail/outlook)")
    return parser.parse_args()

5. 使用示例

5.1 命令行调用

python send_email.py \
  --sender example@qq.com \
  --password your_authorization_code \
  --recipients recipient1@example.com recipient2@example.com \
  --subject "测试邮件" \
  --content "这是一封自动发送的测试邮件。" \
  --attachments "report.pdf" "data.xlsx" \
  --provider qq

5.2 HTML 邮件示例

html_content = """
<h3>这是一封 HTML 邮件</h3>
<p>点击下面的链接访问官网:<a href="https://example.com">Example</a></p>
"""
send_email(
    sender="example@qq.com",
    password="your_code",
    recipients=["user@example.com"],
    subject="HTML 邮件示例",
    content=html_content,
    content_type="html",
    provider="qq"
)

6. 安全与注意事项

  1. 邮箱授权码
  • QQ邮箱、163邮箱等需在邮箱设置中生成授权码,禁止直接使用密码
  • Gmail 用户需开启“允许不够安全的应用”或使用应用专用密码。
  1. 敏感信息处理
  • 避免将密码硬编码在代码中,可通过环境变量或配置文件传递。
  1. 附件路径验证
  • 确保附件路径正确且文件可读。
  1. 错误处理
  • 捕获并记录异常(如网络中断、认证失败、文件不存在等)。
  1. 并发发送限制
  • 部分邮箱服务商对短时间内的发送频率有限制,避免触发反垃圾机制。

7. 扩展功能建议

  1. 图形化界面(GUI)
    使用 tkinterPyQt 开发简易界面,方便非技术用户操作。
  2. 批量发送
    从 CSV 文件读取收件人列表,实现邮件群发。
  3. 定时任务
    结合 scheduleAPScheduler 实现定时发送。
  4. 日志记录
    使用 logging 模块记录发送记录和错误信息。
  5. 模板邮件
    支持通过 Jinja2 模板动态生成邮件内容。

8. 总结

通过本文的实现,我们构建了一个基于 Python 的自动邮件发送工具,支持主流邮箱服务商、HTML 内容、附件发送和错误处理。该工具可广泛应用于自动化报告发送、系统告警通知、任务完成提醒等场景。结合命令行参数和扩展功能,用户能够灵活适配不同需求,显著提升工作效率。

© 版权声明
THE END
喜欢就支持一下吧
点赞11赞赏 分享