Python使用smtplib + yagmail进行自动化发送邮件
作者:张老师技术栈
这段文章详细介绍了使用Python自动化发送邮件的方法,包括准备工作、使用smtplib和yagmail库发送邮件、群发邮件、定时发送以及常见问题和解决方案,重点推荐了yagmail库,因其代码简洁且功能强大,适合日常办公邮件自动化需求,需要的朋友可以参考下
日常办公中最枯燥的重复劳动之一就是发邮件——给几十个人发通知、发周报、发附件。用 Python 自动化发邮件,一个是快,另一个是不会漏发或发错。
一、准备工作——开启邮箱的 SMTP 服务
发邮件需要开启邮箱的 SMTP 服务,获得一个授权码。 不是在代码里写你的登录密码。
常见邮箱的设置
| 邮箱 | SMTP 服务器 | 端口(SSL) | 开启方式 |
|---|---|---|---|
| QQ邮箱 | smtp.qq.com | 465 | 设置→账号→开启SMTP→生成授权码 |
| 163邮箱 | smtp.163.com | 465 | 设置→POP3/SMTP→开启→设置授权码 |
| Gmail | smtp.gmail.com | 465 | 需要开启两步验证+应用专用密码 |
| 企业微信 | smtp.exmail.qq.com | 465 | 管理员后台开启 |
授权码就是你的"邮箱密码",但只在代码里用,不要外传。
二、用 smtplib 发邮件(标准库)
smtplib 是 Python 内置库,不用安装,但代码写起来稍复杂。
1. 发送纯文本邮件
import smtplib
from email.mime.text import MIMEText
from email.header import Header
# 发件人配置
smtp_server = "smtp.qq.com"
smtp_port = 465
sender = "your_name@qq.com"
password = "你的授权码" # 不是QQ密码!
# 收件人
receiver = "someone@example.com"
# 构造邮件
subject = "本周工作汇报"
content = """
张老师,你好:
以下是本周工作总结:
1. 完成了秒杀系统的 Redis 集成
2. 发布了 5 篇 CSDN 技术文章
3. 正在准备考研数学复习
祝好!
"""
# 创建邮件对象
msg = MIMEText(content, "plain", "utf-8")
msg["From"] = Header(f"张政 <{sender}>")
msg["To"] = Header(f"{receiver}")
msg["Subject"] = Header(subject, "utf-8")
# 发送
try:
with smtplib.SMTP_SSL(smtp_server, smtp_port) as server:
server.login(sender, password)
server.sendmail(sender, [receiver], msg.as_string())
print("邮件发送成功!")
except Exception as e:
print(f"发送失败: {e}")
2. 发送 HTML 邮件
html_content = """
<h2>本周工作汇报</h2>
<table border="1" cellpadding="5">
<tr>
<th>项目</th>
<th>进度</th>
</tr>
<tr>
<td>秒杀系统</td>
<td style="color:green;">已完成</td>
</tr>
<tr>
<td>CSDN 文章</td>
<td>5 篇/周</td>
</tr>
<tr>
<td>考研复习</td>
<td>进行中</td>
</tr>
</table>
<p>祝好!</p>
"""
msg = MIMEText(html_content, "html", "utf-8")
3. 发送带附件的邮件
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
import os
def send_email_with_attachment(sender, password, receiver, subject, body, file_path):
"""发送带附件的邮件"""
# 创建 multipart 邮件对象
msg = MIMEMultipart()
msg["From"] = sender
msg["To"] = receiver
msg["Subject"] = subject
# 邮件正文
msg.attach(MIMEText(body, "plain", "utf-8"))
# 附件
with open(file_path, "rb") as f:
attachment = MIMEBase("application", "octet-stream")
attachment.set_payload(f.read())
encoders.encode_base64(attachment)
# 设置附件头(文件名)
filename = os.path.basename(file_path)
attachment.add_header(
"Content-Disposition",
f"attachment; filename={filename}"
)
msg.attach(attachment)
# 发送
with smtplib.SMTP_SSL("smtp.qq.com", 465) as server:
server.login(sender, password)
server.sendmail(sender, [receiver], msg.as_string())
print(f"邮件已发送(含附件: {filename})")
# 使用
send_email_with_attachment(
sender="your_name@qq.com",
password="授权码",
receiver="boss@company.com",
subject="季度报告",
body="请查收季度报告附件。",
file_path="季度报告.xlsx"
)
三、用 yagmail(推荐,代码精简很多)
pip install yagmail
import yagmail
# 连接邮箱(只需配置一次)
yag = yagmail.SMTP(
user="your_name@qq.com",
password="授权码",
host="smtp.qq.com",
port=465,
)
# 发送邮件(一行搞定)
yag.send(
to="someone@example.com",
subject="本周工作汇报",
contents="""
张老师,你好:
以下是本周工作总结:
1. 完成秒杀系统
2. 发了5篇CSDN
""",
)
# 发送带附件
yag.send(
to=["boss@company.com", "cc@company.com"], # 支持多个收件人和抄送
subject="季度报告",
contents="请查收附件。",
attachments=["季度报告.xlsx", "图表.png"], # 附件列表
)
print("发送成功!")
对比 smtplib: yagmail 代码量减少 60% 以上,不用手动构造 MIME 对象,附件自动处理。
四、群发邮件——逐人发送 vs 群发单显
1. 逐人发送(收件人互不可见)
import yagmail
import pandas as pd
yag = yagmail.SMTP("your_name@qq.com", "授权码", host="smtp.qq.com")
# 读取收件人列表(姓名+邮箱)
df = pd.read_excel("收件人名单.xlsx")
for _, row in df.iterrows():
content = f"""
{row['name']}老师,你好:
请查收本周的教学计划安排。
教学办
"""
yag.send(
to=row["email"],
subject="本周教学计划通知",
contents=content,
)
print(f"已发送给 {row['name']} ({row['email']})")
2. 带模板的群发
# 模板字符串
template = """
{name}老师,你好:
教务处通知:
{content}
请于 {deadline} 前提交。
教学办
"""
# 数据
data = [
{"name": "张三", "content": "请提交期末试卷", "deadline": "6月30日"},
{"name": "李四", "content": "请提交教学总结", "deadline": "7月5日"},
{"name": "王五", "content": "请确认下学期的课程安排", "deadline": "7月10日"},
]
yag = yagmail.SMTP("your_name@qq.com", "授权码")
for item in data:
content = template.format(**item)
# 这里需要每个人的邮箱,实际中可以从 Excel 或数据库获取
# yag.send(to=item['email'], subject='教务处通知', contents=content)
# print(f"已发送给{item['name']}")
五、定时发送
结合系统定时任务,可以实现每天 9 点自动发邮件:
Windows 定时任务
# send_daily_report.py
import yagmail
import datetime
def send_report():
today = datetime.date.today().strftime("%Y-%m-%d")
yag = yagmail.SMTP("your_name@qq.com", "授权码")
content = f"""
{today} 系统运行报告:
1. 服务器状态:正常
2. 数据库连接:正常
3. 日志数量:1256 条
"""
yag.send(
to="admin@company.com",
subject=f"系统日报 - {today}",
contents=content,
)
print(f"{today} 日报已发送")
if __name__ == "__main__":
send_report()
然后在 Windows 的任务计划程序中设置每天 9:00 执行此脚本。
六、常见问题
1. 发送失败:535 Error:登录失败
# 原因:不是用 QQ 密码,而是用授权码 # 解决:去 QQ 邮箱设置 → 账号 → 生成授权码 # 注意:授权码中间没有空格
2. 发送失败:554 被判定为垃圾邮件
# 原因:内容太短、太多链接、发送频率太高
# 解决:
# - 每封邮件的正文不要太雷同
# - 加收件人姓名个性化
# - 控制发送频率(每分钟不超过 10 封)
import time
for _, row in df.iterrows():
yag.send(...)
time.sleep(3) # 每封邮件间隔 3 秒
3. QQ邮箱发送上限
# QQ邮箱免费版:每天 500 封 # 企业邮箱:每天 2000 封 # 超过会被封号 24 小时,建议分多个邮箱发送
七、完整案例:自动发送周报
import yagmail
import pandas as pd
from datetime import datetime
class WeeklyReporter:
"""自动周报发送器"""
def __init__(self, sender_email, auth_code):
self.yag = yagmail.SMTP(sender_email, auth_code, host="smtp.qq.com")
def generate_report(self, name, tasks):
"""生成个性化周报"""
task_list = "\n".join([f" {i+1}. {t}" for i, t in enumerate(tasks)])
return f"""
{name}老师,你好:
以下是本周工作汇总:
本周完成任务:
{task_list}
祝工作顺利!
{datetime.now().strftime('%Y-%m-%d')}
"""
def send_batch(self, recipients):
"""批量发送周报"""
for r in recipients:
content = self.generate_report(r["name"], r["tasks"])
self.yag.send(
to=r["email"],
subject=f"【周报】{r['name']} - 本周工作总结",
contents=content,
)
print(f"✅ 已发送: {r['name']}")
time.sleep(2)
print(f"\n共发送 {len(recipients)} 封周报")
# 使用
reporter = WeeklyReporter("your_name@qq.com", "授权码")
# 收件人列表
recipients = [
{
"name": "张三",
"email": "zhangsan@company.com",
"tasks": ["完成了秒杀系统的Redis集成", "发布了3篇CSDN文章"],
},
{
"name": "李四",
"email": "lisi@company.com",
"tasks": ["完成了数据库设计文档", "修复了3个线上Bug"],
},
]
reporter.send_batch(recipients)
总结
简单发送 → yagmail(推荐,3行代码搞定) 带附件 → yagmail 自动处理 群发 → 循环发送 + 模板替换 定时 → 脚本 + 系统定时任务
工作中 90% 的邮件发送需求,用 yagmail 就够了。关键是把收件人和模板数据准备好,发送本身几行代码的事。
以上就是Python使用smtplib + yagmail进行自动化发送邮件的详细内容,更多关于Python smtplib + yagmail自动化发送邮件的资料请关注脚本之家其它相关文章!
