Python自动发送多人多附件邮件实战:解决授权码与退信问题

陆景行
陆景行
发布时间:2026-10-13 | 2人浏览过
原创

本文详解使用Python实现定时向多人发送带多附件邮件的方法。重点解决smtplib.SMTPAuthenticationError授权失败及163邮箱554 DT:SPM退信问题,提供完整代码示例与调试技巧,适用于Windows及Linux环境。

近期公司部分数据统计与分析报表的定时发送配置被误删,需重新恢复该功能。原方案基于Linux Shell脚本实现,操作繁琐且维护困难,因此决定改用Python重构。鉴于网上现有资料往往未经整理,存在如仅支持单收件人、附件路径硬编码等不灵活问题,本文旨在提供一份经过优化的实现记录。

在实现过程中,主要需解决以下关键问题:

1、smtplib.SMTPAuthenticationError: (550, b'User has no permission')

2、smtplib.SMTPAuthenticationError: (535, b'Error: authentication failed')

上述两类错误通常由未使用邮箱授权码引起。请自行通过邮箱服务商后台生成并配置正确的授权码。

3、554 DT:SPM 163 smtp5

此为网易邮箱的反垃圾邮件检测机制所致,可能与发送频率较高有关。作者在测试中曾遇到此问题,后续通过添加一个网易邮箱作为收件人后发送成功,具体成因尚不明确。如有知情者,欢迎私信或评论补充说明。

前期准备:检查系统Python版本号,

若显示如图版本信息,则表明环境已就绪。

2、核心实现代码(本代码在Windows IDLE环境下编辑测试,若迁移至Linux,仅需调整附件路径即可)

# -*- coding: utf-8 -*-
from email import encoders
import os
import traceback
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders

# 中文处理
def _format_addr(s):
 name, addr = parseaddr(s)
 return formataddr((Header(name, 'utf-8').encode(), addr))
def send_email(to_addr_in,filepath_in):
 # 邮件发送和接收人配置
 from_addr = '*******@163.com'
 smtp_server = 'smtp.163.com'
 password = '********' #这是你邮箱的第三方授权客户端密码,并非你的登录密码
 to_addr = to_addr_in
 to_addrs = to_addr.split(',')
 msg = MIMEMultipart()
 msg['From'] = _format_addr('Python爱好者 <%s>' % from_addr)  # 显示的发件人
 # msg['To'] = _format_addr('管理员 <%s>' % to_addr)    # 单个显示的收件人
 msg['To'] = ",".join(to_addrs)         # 多个显示的收件人
 msg['Subject'] = Header('来自SMTP的问候……', 'utf-8').encode()  # 显示的邮件标题
 # 需要传入的路径
 # filepath = r'D:\test'
 filepath = filepath_in
 r = os.path.exists(filepath)
 if r is False:
  msg.attach(MIMEText('no file...', 'plain', 'utf-8'))
 else:
  # 邮件正文是MIMEText:
  msg.attach(MIMEText('send with file...', 'plain', 'utf-8'))
  # 遍历指定目录,显示目录下的所有文件名
  pathDir = os.listdir(filepath)
  for allDir in pathDir:
   child = os.path.join(filepath, allDir)
   print child.decode('gbk') # .decode('gbk')是解决中文显示乱码问题
   # 添加附件就是加上一个MIMEBase,从本地读取一个文件
   with open(child, 'rb') as f:
    # 设置附件的MIME和文件名,这里是txt类型:
    mime = MIMEBase('file', 'xls', filename=allDir)
    # 加上必要的头信息:
    mime.add_header('Content-Disposition', 'attachment', filename=allDir)
    mime.add_header('Content-ID', '<0>')
    mime.add_header('X-Attachment-Id', '0')
    # 把附件的内容读进来:
    mime.set_payload(f.read())
    # 用Base64编码:
    encoders.encode_base64(mime)
    # 添加到MIMEMultipart:
    msg.attach(mime)
 try:
  server = smtplib.SMTP(smtp_server, 25)
  # server.starttls()
  server.set_debuglevel(1) # 用于显示邮件发送的执行步骤
  server.login(from_addr, password)
  # print to_addrs
  server.sendmail(from_addr, to_addrs, msg.as_string())
  server.quit()
 except Exception, e:
  print "Error: unable to send email"
  print traceback.format_exc()
if __name__ == '__main__':
 send_email('*******@qq.com,*******@163.com','D:\\test')

3、在PyCharm中执行结果如下:

日志显示邮件发送成功,请前往对应邮箱查收,确认附件文本已正常生成。

若未收到附件文本(此处截图为网易邮箱,上方截图为QQ邮箱,表明两个邮箱均已成功接收邮件):

以上即为Python实现自动发送多人、群发及多附件邮件的完整示例,希望能对读者有所帮助,欢迎支持。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表