批量发送邮件失败:首封后因RFC 5322重复标头被Gmail拦截
问题分析与解决
错误原因
你收到的550 5.7.1 duplicate headers错误,核心问题有两个:
- 邮件对象
mesaj在循环外创建,每次循环重复给它设置From、To、Subject头,还重复添加正文内容,导致邮件头重复,违反RFC5322规范,被Gmail拦截。 - 代码存在索引错误:你的
mails.txt格式是Name,Surname,name@gmail.com,按逗号分割后邮箱是第三个元素(索引2),但你用了kisi[1],实际取的是姓氏,会导致收件人错误。
修复后的代码
import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText import sys # 提前建立SMTP连接并登录,避免重复创建连接 try: mail = smtplib.SMTP("smtp.gmail.com", 587) mail.ehlo() mail.starttls() mail.login("my mail", "my mail app password here") except Exception as e: sys.stderr.write(f"SMTP连接失败: {str(e)}") sys.stderr.flush() sys.exit(1) with open("mails.txt", "r", encoding="utf-8") as file: mailler = file.readlines() for i in mailler: try: # 跳过空行 if not i.strip(): continue kisi = i.strip().split(",") # 确保分割后有3个有效元素 if len(kisi) != 3: print(f"无效行: {i}") continue # 每次循环创建新的邮件对象,避免重复头和内容 mesaj = MIMEMultipart() mesaj["From"] = "MY MAİL HERE" mesaj["To"] = kisi[2].strip() # 修正:取第三个元素作为邮箱 mesaj["Subject"] = "SMTP Toplu Mail Denemesi" yazı = f"{kisi[0]} Bu Maili Görmezden Gelin" icerik = MIMEText(yazı, "plain") mesaj.attach(icerik) mail.sendmail(mesaj["From"], mesaj["To"], mesaj.as_string()) print(f"{kisi[0]} Adlı Kişiye Mail Başarıyla Gönderildi") except Exception as e: sys.stderr.write(f"{kisi[0]} Adlı Kişiye Mail Gönderilemedi: {str(e)}\n") sys.stderr.flush() # 最后统一关闭连接 mail.close()
关键修改点
- 邮件对象移到循环内:每次循环创建新的
MIMEMultipart(),确保每封邮件的头和内容独立,不会重复叠加。 - 修正收件人索引:从
kisi[1]改为kisi[2].strip(),正确获取邮箱地址并去除换行符。 - SMTP连接复用:把连接、登录逻辑提到循环外,只执行一次,提升发送效率。
- 增加异常与格式校验:捕获具体异常信息方便排查,同时跳过空行、无效格式的行,避免程序崩溃。
内容的提问来源于stack exchange,提问作者muratkavak
相关产品推荐
相关产品推荐

