邮件发送脚本怎写?

wen 实用脚本 43

邮件发送脚本怎么写?从零到一构建自动化邮件系统实战指南

目录导读

  1. 为什么需要邮件发送脚本?
  2. Python vs Shell vs 其他语言:哪种更适合你?
  3. 核心知识:SMTP协议与邮件发送原理
  4. 手把手教你写一个Python邮件发送脚本
  5. 进阶技巧:批量发送、附件、HTML模板
  6. 常见错误与排查方法(问答环节)
  7. 安全与合规:避免被标记为垃圾邮件
  8. 实战案例:监控告警邮件自动发送
  9. 总结与最佳实践

为什么需要邮件发送脚本?

在日常工作中,无论是系统运维监控、用户注册通知、定时报告推送,还是营销邮件群发,手动发送邮件都是低效且容易出错的,邮件发送脚本能帮你实现:

邮件发送脚本怎写?

  • 自动化:按预设规则自动发送,无需人工干预
  • 批量处理:同时向数百甚至数千人发送个性化内容
  • 定时触发:结合cron或任务调度器实现周期性发送
  • 集成能力:无缝对接监控系统、数据库、API等

根据Stack Overflow 2024年开发者调查,超过60%的后端开发者需要编写邮件发送程序,掌握这项技能,你将能快速构建报警系统、订阅通知、客户联系等实用功能。


Python vs Shell vs 其他语言:哪种更适合你?

语言/工具 适用场景 优势 劣势
Python 通用、复杂逻辑 库丰富(smtplib/email),代码易读 需安装Python环境
Shell 简单发送、Linux环境 原生支持mail/sendmail命令 功能有限,附件处理麻烦
Node.js 前端/全栈项目 异步非阻塞,npm包丰富 回调地狱,内存占用较高
Go 高性能、并发场景 编译为单文件,部署简便 语法稍复杂,生态不如Python成熟

对于大多数用户,Python是最平衡的选择——门槛低、文档多、能处理复杂需求,本文将以Python为主进行演示。


核心知识:SMTP协议与邮件发送原理

1 SMTP是什么?

简单邮件传输协议(SMTP)是互联网上发送邮件的标准协议,当你通过脚本发送邮件时,实际上是在与SMTP服务器通信(如smtp.gmail.com、smtp.qq.com等)。

2 发送流程

你的脚本 → SMTP服务器 → 收件方邮件服务器 → 收件人收件箱

3 关键术语

  • 发件人地址:用于身份验证,通常需要用户名和密码
  • 收件人地址:可以设置To、Cc(抄送)、Bcc(密送)
  • 邮件头:包含Subject(主题)、From、To、Date等
  • 邮件体:可以是纯文本或HTML格式

4 端口选择

  • 587:TLS加密端口(推荐,如Gmail、QQ邮箱)
  • 465:SSL加密端口(部分服务商仍使用)
  • 25:非加密端口(需自行配置加密,不建议)

手把手教你写一个Python邮件发送脚本

1 准备工作

  1. 开启邮箱的SMTP服务(以QQ邮箱为例):
    • 登录QQ邮箱 → 设置 → 账户 → 开启“POP3/IMAP/SMTP服务”
    • 生成一个授权码(不是登录密码)
  2. 安装Python(如未安装,从python.org下载)

2 基础脚本:发送一封纯文本邮件

import smtplib
from email.mime.text import MIMEText
from email.header import Header
# 配置信息
smtp_server = "smtp.qq.com"          # 发件人邮箱SMTP地址
port = 587                              # 端口(QQ邮箱使用587)
sender = "your_email@qq.com"           # 发件人邮箱
password = "your_authorization_code"    # QQ邮箱授权码(不是登录密码)
receiver = "receiver@example.com"       # 收件人邮箱
# 构建邮件内容
message = MIMEText("这是一封由Python发送的测试邮件。", "plain", "utf-8")
message["From"] = Header("脚本小助手", "utf-8")  # 发件人显示名称
message["To"] = Header("亲爱的用户", "utf-8")    # 收件人显示名称
message["Subject"] = Header("Python邮件测试", "utf-8")
try:
    # 连接SMTP服务器并发送
    server = smtplib.SMTP(smtp_server, port)
    server.starttls()                   # 启用TLS加密
    server.login(sender, password)
    server.sendmail(sender, [receiver], message.as_string())
    print("✅ 邮件发送成功!")
except Exception as e:
    print(f"❌ 发送失败:{e}")
finally:
    server.quit()

运行方法:将上述代码保存为send_mail.py,在终端执行python send_mail.py


进阶技巧:批量发送、附件、HTML模板

1 批量发送(带个性化内容)

import smtplib
from email.mime.text import MIMEText
# 收件人列表(姓名+邮箱)
recipients = [
    {"name": "张三", "email": "zhangsan@example.com"},
    {"name": "李四", "email": "lisi@example.com"},
]
for person in recipients:
    content = f"""
    尊敬的{person['name']}:
    您好!您的账户已验证成功。
    此致
    敬礼
    """
    msg = MIMEText(content, "plain", "utf-8")
    msg["Subject"] = f"验证通知 - {person['name']}"
    msg["From"] = sender
    msg["To"] = person["email"]
    # 发送逻辑同上(可复用连接)
    server.sendmail(sender, [person["email"]], msg.as_string())
print("批量发送完成!")

2 添加附件

from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
msg = MIMEMultipart()
msg["Subject"] = "含有附件的邮件"
msg["From"] = sender
msg["To"] = receiver
body = MIMEText("请查收附件。", "plain", "utf-8")
msg.attach(body)
# 添加附件(如:report.pdf)
filename = "report.pdf"
attachment = open(filename, "rb")
part = MIMEBase("application", "octet-stream")
part.set_payload(attachment.read())
encoders.encode_base64(part)
part.add_header("Content-Disposition", f"attachment; filename= {filename}")
msg.attach(part)
# 发送
server.sendmail(sender, [receiver], msg.as_string())

3 使用HTML模板(推荐)

html_template = """
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <style>
        body { font-family: Arial, sans-serif; }
        .btn { background-color: #4CAF50; color: white; padding: 10px 20px; text-decoration: none; }
    </style>
</head>
<body>
    <h2>尊敬的用户,您好!</h2>
    <p>请点击下方按钮验证您的邮箱:</p>
    <a class="btn" href="https://your-domain.com/verify?token=abc123">验证邮箱</a>
    <p>如果按钮无法点击,请复制以下链接到浏览器:</p>
    <p>https://your-domain.com/verify?token=abc123</p>
</body>
</html>
"""
msg = MIMEText(html_template, "html", "utf-8")

常见错误与排查方法(问答环节)

Q1:收到“535 Authentication failed”错误?

A:最常见的原因是SMTP用户名或密码错误,注意:

  • 密码不是邮箱登录密码,而是授权码(需单独生成)
  • 部分邮箱(如163)需使用“客户端授权码”而非登录密码

Q2:为什么发送成功但收件人没收到?(进入垃圾箱)

A:可能是被SPF/DKIM验证拦截,解决方案:

  • 发件人域名配置SPF记录(DNS中添加TXT记录)
  • 避免使用过于营销性的词汇(如“免费”“折扣”)
  • 控制发送频率,单次别超过100封

Q3:遇到“Connection refused”怎么办?

A:检查:

  • SMTP服务器地址是否写对(如QQ邮箱是smtp.qq.com)
  • 端口是否被防火墙屏蔽(尝试587或465)
  • 网络是否能访问外部SMTP服务器

Q4:如何发送定时邮件?

A:结合系统调度工具:

  • Linux/Mac:使用crontab,例如每天早8点运行:0 8 * * * /usr/bin/python3 /path/to/your_script.py
  • Windows:使用“任务计划程序”设置定时执行

安全与合规:避免被标记为垃圾邮件

1 通用安全准则

  • 不要硬编码密码:使用环境变量或配置文件
  • 加日志记录:记录每次发送的收件人、时间、状态
  • 设置发送频率限制:每5分钟发送不超过50封

2 腾讯云/阿里云邮件推送(替代方案)

对于较大规模发送(>100封/天),建议使用邮件推送服务:

  • 阿里云邮件推送:提供高可用API,自动处理退回/投诉
  • 腾讯云邮件推送:支持模板管理、统计分析

3 域名授权

在DNS中添加以下TXT记录可提升送达率:

v=spf1 include:spf.your-email-provider.com ~all

同时开启DKIM签名(多数服务商有向导)。


实战案例:监控告警邮件自动发送

假设你的服务器磁盘使用率超过85%,需要自动发送告警:

import subprocess
import smtplib
from email.mime.text import MIMEText
def check_disk_usage():
    result = subprocess.run(["df", "-h", "/"], capture_output=True, text=True)
    lines = result.stdout.split("\n")
    if len(lines) > 1:
        usage_percent = lines[1].split()[4].rstrip("%")
        return int(usage_percent)
    return 0
def send_alert(usage):
    if usage > 85:
        msg = MIMEText(f"⚠️ 磁盘使用率已达到 {usage}%,请立即清理!", "plain", "utf-8")
        msg["Subject"] = f"服务器磁盘告警: {usage}%"
        server.sendmail(sender, [admin_email], msg.as_string())
# 在主程序中调用
usage = check_disk_usage()
send_alert(usage)

将此脚本加入crontab(每5分钟执行一次):

*/5 * * * * python3 /path/to/disk_alert.py

总结与最佳实践

1 核心关键点

  • SMTP配置:正确提供服务器地址、端口、账号密码是关键
  • 代码结构:将配置与逻辑分离,使用config.py或环境变量
  • 测试先行:先用[test@yourserver.com]测试,再扩展到真实用户
  • 日志记录:每次发送写入日志,便于排查问题

2 推荐阅读与工具

  • Python官方文档:smtplibemail模块
  • 在线测试工具:smtpbucket.com(测试邮件发送,不实际投递)
  • 开源项目:yagmail(简化邮件发送)、flask-mail(集成Flask框架)

3 下一步学习

  • 集成HTML模板引擎(如Jinja2)提升邮件美观度
  • 使用异步框架(如aiofiles + aiosmtplib)提升批量发送性能
  • 学习邮件营销规范:退订链接、真实发件人、内容许可

邮件发送脚本不仅仅是技术实现,更是可靠性与合规性的平衡,从一个小脚本开始,逐步构建你的自动化通信系统吧!

抱歉,评论功能暂时关闭!