Python循环发送个性化邮件仅向第一个收件人投递问题求助
问题根因
- 最核心的问题是你将SMTP连接创建、登录的逻辑放在了for循环内部,每次循环都会重新建立连接并登录Gmail服务器。Gmail的SMTP安全机制会将短时间内的多次重复登录判定为异常操作,直接拦截后续的登录请求,因此只有第一次循环的邮件能发送成功。
- 第二个可能的问题是代码没有做异常捕获,如果第二个及以后的收件人发送过程中出现报错(比如邮箱格式错误、内容违规拦截),程序会直接终止,不会继续执行后续的发送逻辑,表面上看也只会发第一个收件人。
- 另外代码中直接使用了全局变量
username和password,如果变量作用域出现问题,也可能导致第二次登录时校验失败。
修复方案
- 把SMTP连接、登录逻辑移到循环外部,全程只登录一次,避免触发风控
- 增加异常捕获逻辑,打印单条邮件发送失败的原因,保证循环不会被中断
- 建议将登录凭证作为参数传入函数,避免依赖全局变量
修复后代码
from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText import smtplib import time def send(recipients, subject, message, username, password): # 把SMTP连接移到循环外,仅登录一次 with smtplib.SMTP(host="smtp.gmail.com", port=587) as smtp: smtp.ehlo() smtp.starttls() smtp.login(username, password) for name, email in recipients.items(): try: edited_subject = subject.replace("<>", name) edited_message = message.replace("<>", name) mail = MIMEMultipart() mail['from'] = 'Tomas' mail['to'] = email mail['subject'] = edited_subject mail.attach(MIMEText(edited_message, "plain")) smtp.send_message(mail) print(f"已成功向{name} <{email}> 发送邮件") # 收件人多的话可加延迟降低限流风险 # time.sleep(1) except Exception as e: print(f"向{name} <{email}> 发送邮件失败,错误信息:{str(e)}")
额外注意事项
- 如果你使用的是Gmail普通账号,需要先开启应用专用密码登录,避免被安全机制拦截
- 如果收件人数量超过20个,建议在每次发送之间加1秒左右的延迟,进一步降低触发限流的概率
内容的提问来源于stack exchange,提问作者Tomas
相关产品推荐
相关产品推荐

