Python循环逐个发邮件时To Header叠加问题求助
解决批量单独发送邮件时收件人Header累积的问题
问题描述
我有如下邮件列表:
emails = ['a@a.a', 'b@b.b', 'c@c.c', 'd@d.d']
使用以下循环代码发送邮件:
for email in emails: message['To'] = email # ... 其他发送邮件的代码
但出现异常:第一个收件人的To头为a@a.a;第二个收件人的To头变成a@a.a, b@b.b;第三个则是a@a.a, b@b.b, c@c.c,无法实现给每个成员单独发送邮件。曾尝试通过文件存储收件人,但使用with open的w模式时会覆盖之前的内容,也未能解决问题。
问题根源(基于提供的完整代码)
核心问题是**MIMEMultipart对象在循环外创建,循环中仅修改To字段并重复添加邮件内容部件**:
- MIME消息的头部字段(如
To)重复赋值时不会覆盖原有值,而是会追加; - 每次循环都往同一个
message对象中attach文本部件,导致邮件内容也会累积重复。
解决方案
将邮件对象的创建、内容部件的添加逻辑全部放到循环内部,每次循环生成一个全新的MIMEMultipart实例,彻底避免旧内容残留。
修改后的完整代码
from smtplib import SMTP from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText import datetime import pathlib sender_email = 'myEmail@gmail.com' receiver_email = ['a@a.a', 'b@b.b', 'c@c.c'] password = 'myPass' html = '<p>an HTML code</p>' for receiver in receiver_email: # 每次循环创建全新的邮件对象 message = MIMEMultipart('alternative') message['Subject'] = 'Some Subject' message['From'] = sender_email message['To'] = receiver # 新对象的To字段不会有历史值累积 # 为当前邮件添加文本部件 part1 = MIMEText(html, 'plain') part2 = MIMEText(html, 'html') message.attach(part1) message.attach(part2) # 发送邮件 smtp = SMTP('smtp.gmail.com', 587) smtp.ehlo() smtp.starttls() smtp.ehlo() smtp.login(sender_email, password) smtp.sendmail(sender_email, receiver, message.as_string()) smtp.quit()
效率优化建议
每次循环重新建立SMTP连接会降低效率,可以将连接逻辑移到循环外,统一创建连接后批量发送,最后再关闭:
from smtplib import SMTP from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText import datetime import pathlib sender_email = 'myEmail@gmail.com' receiver_email = ['a@a.a', 'b@b.b', 'c@c.c'] password = 'myPass' html = '<p>an HTML code</p>' # 提前建立SMTP连接 smtp = SMTP('smtp.gmail.com', 587) smtp.ehlo() smtp.starttls() smtp.ehlo() smtp.login(sender_email, password) for receiver in receiver_email: message = MIMEMultipart('alternative') message['Subject'] = 'Some Subject' message['From'] = sender_email message['To'] = receiver part1 = MIMEText(html, 'plain') part2 = MIMEText(html, 'html') message.attach(part1) message.attach(part2) smtp.sendmail(sender_email, receiver, message.as_string()) # 所有邮件发送完成后关闭连接 smtp.quit()
内容的提问来源于stack exchange,提问作者Saeed
相关产品推荐
相关产品推荐

