Python邮件群发 从Excel读取收件人列表
用Python openpyxl读取Excel里的收件人列表,循环调用smtplib群发邮件,自动跳过空行、记录成功失败,附完整可运行代码。
场景痛点
公司要给500个客户发通知,手工在邮箱里一个个粘贴收件人,粘完一抬头半小时过去了,还容易漏人、重复发。把收件人邮箱放在Excel里,Python读出来循环发,跑完自动记录哪些成功哪些失败。
用到的库
pip install openpyxl
完整代码
# -*- coding: utf-8 -*-
import smtplib
import time
from email.mime.text import MIMEText
from email.header import Header
from openpyxl import load_workbook
SMTP_SERVER = "smtp.qq.com"
SMTP_PORT = 465
SENDER = "your_account@qq.com"
AUTH_CODE = "your_smtp_auth_code"
def load_receivers(excel_path):
"""从Excel读取收件人邮箱,假定第一列是邮箱地址,第一行是表头"""
wb = load_workbook(excel_path, read_only=True)
ws = wb.active
emails = []
for row in ws.iter_rows(min_row=2, values_only=True):
if row and row[0]:
email = str(row[0]).strip()
if "@" in email:
emails.append(email)
wb.close()
return emails
def send_batch(emails, subject, body):
# 用同一条SMTP连接循环发,不用每次重新登录
server = smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT)
server.login(SENDER, AUTH_CODE)
success, failed = [], []
for email in emails:
try:
msg = MIMEText(body, "plain", "utf-8")
msg["From"] = Header(f"通知 <{SENDER}>", "utf-8")
msg["To"] = Header(email, "utf-8")
msg["Subject"] = Header(subject, "utf-8")
server.sendmail(SENDER, [email], msg.as_string())
success.append(email)
print(f"[OK] {email}")
except Exception as e:
failed.append((email, str(e)))
print(f"[FAIL] {email}: {e}")
# 每发一封停0.5秒,避免被限流
time.sleep(0.5)
server.quit()
print(f"完成:成功{len(success)},失败{len(failed)}")
if __name__ == "__main__":
receivers = load_receivers("recipients.xlsx")
send_batch(
receivers,
"月度账单通知",
"您好,本月账单已出,请登录系统查看。"
)
代码讲解
load_workbook(..., read_only=True):只读模式打开大Excel更快,不需要写回。iter_rows(min_row=2, values_only=True):从第2行开始读,跳过表头;values_only=True直接拿值,不用操作cell对象。- 把SMTP连接提到循环外面:登录一次连接发完所有邮件,比每封邮件重新登录快几十倍。
time.sleep(0.5):发太快容易被SMTP服务器判定为垃圾邮件批量发送而临时封号,500封以内建议每封间隔0.3~1秒。
运行结果
控制台逐行打印[OK] 邮箱或[FAIL] 邮箱: 原因,最后汇总成功和失败数量。失败的可以单独挑出来重试。
注意事项
- QQ邮箱每天群发上限大概500封,163邮箱类似,超量会被临时禁止发信,大批量要分几天或用企业邮箱。
- 邮件内容里不要出现"中奖""免费""点击"这类高频垃圾词,否则容易进对方垃圾箱。
- Excel里邮箱前后可能有空格、大小写混着,读取时要
strip(),大小写SMTP不区分但最好统一小写。 - 失败原因常见:授权码错、端口被封、对方邮箱不存在、发送频率超限。

更新时间:2026-09-14 21:10:47