You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python循环发送个性化邮件仅向第一个收件人投递问题求助

问题根因
  • 最核心的问题是你将SMTP连接创建、登录的逻辑放在了for循环内部,每次循环都会重新建立连接并登录Gmail服务器。Gmail的SMTP安全机制会将短时间内的多次重复登录判定为异常操作,直接拦截后续的登录请求,因此只有第一次循环的邮件能发送成功。
  • 第二个可能的问题是代码没有做异常捕获,如果第二个及以后的收件人发送过程中出现报错(比如邮箱格式错误、内容违规拦截),程序会直接终止,不会继续执行后续的发送逻辑,表面上看也只会发第一个收件人。
  • 另外代码中直接使用了全局变量username和password,如果变量作用域出现问题,也可能导致第二次登录时校验失败。
修复方案
  1. 把SMTP连接、登录逻辑移到循环外部,全程只登录一次,避免触发风控
  2. 增加异常捕获逻辑,打印单条邮件发送失败的原因,保证循环不会被中断
  3. 建议将登录凭证作为参数传入函数,避免依赖全局变量

修复后代码

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 21:24:01