Outlook SMTP发信仅10封就触发554报错被限的原因及解决方法
问题根因
这个报错和SMTP配置、应用密码正确性无关,是你的发信逻辑触发了Outlook的动态反垃圾风控。所谓的100封/天是公开的静态限额,实际风控阈值会根据发信行为动态调整,你踩了两个最容易触发拦截的规则:
- 把SMTP连接、登录、断开流程写在了收件人遍历循环内,每发1封邮件就完成一次完整的认证、连接、断开流程,短时间高频次的认证请求会直接被判定为盗号批量发垃圾邮件的异常行为
- 邮件发送无任何间隔,瞬时连续发信的特征和垃圾邮件脚本完全匹配,哪怕发件量远低于公开限额也会被临时拦截
另外你贴的代码存在冗余逻辑:初始化smtplib.SMTP()时已经传入了主机和端口完成连接,后续又重复调用了一次connect()方法,会产生不必要的请求。
调整方案
按以下方式修改即可避开大部分风控拦截,达到账号对应的实际发信限额:
- 将SMTP连接、登录、断开逻辑移出收件人循环,整个批量发信任务只建立一次连接、完成一次认证,所有邮件发送完成后再断开连接,避免频繁重连认证
- 增加随机发送间隔,每发完1封邮件等待310秒再发下一封,模拟正常人工发信节奏;如果发送的是营销类推广内容,建议把间隔拉长到1030秒
- 优化邮件内容合规性:
- 避免所有收件人收到完全一致的内容,可在正文插入收件人称呼、专属标识等个性化字段,降低内容重复率
- 邮件主题避免使用过多营销敏感词、特殊符号
- 优先使用注册满1个月以上、有正常人工收发信记录的老账号发信,新注册账号的风控阈值极低,通常发5~20封就会被拦截
- 删除代码中重复的
connect()调用,减少不必要的服务器请求
修正后的参考代码
import time import random import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText selected_limit = limit_outlook content = outlook_content available_emails = list(outlook.keys()) # 邮件服务器配置 smtpHost = 'smtp-mail.outlook.com' smtpPort = 587 mailUname = details[0] mailPwd = details[1] fromEmail = details[0] mailSubject = "你的邮件主题" # 全局只建立一次SMTP连接 s = smtplib.SMTP(smtpHost, smtpPort) s.starttls() s.login(mailUname, mailPwd) try: for send_idx, recepient in enumerate(available_emails[:selected_limit]): # 单封邮件单独构建对象,避免收件人信息串扰 msg = MIMEMultipart() msg['From'] = fromEmail msg['To'] = recepient msg['Subject'] = mailSubject # 插入个性化内容降低重复率 personalized_content = HtmlContent(content).replace("{{username}}", recepient.split('@')[0]) msg.attach(MIMEText(personalized_content, 'html')) msgText = msg.as_string() err = s.sendmail(fromEmail, recepient, msgText) print(f"第{send_idx+1}封发送{'成功' if not err else '失败'},收件人:{recepient},错误信息:{err}") # 随机间隔3-8秒,避开频率检测 time.sleep(random.randint(3, 8)) finally: # 无论是否报错都正常断开连接 s.quit()
补充说明:如果账号已经被临时限制发信,先停止所有发信请求24小时等风控自动解除,解封后前10封建议把发送间隔拉到10秒以上,逐步提升发送节奏,不要刚解封就批量发信。免费Outlook账号的实际发信额度不是固定值,会根据账号年龄、历史发信信誉动态调整,信誉良好的老账号日发信量可到300封以上,新注册账号通常只有20~50封的初始额度。
内容的提问来源于stack exchange,提问作者Vaibhav Vishwakarma
相关产品推荐
相关产品推荐

