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

使用smtplib发送多附件时非Gmail邮箱接收异常问题求助

问题分析与解决方案

问题根源

你的代码在循环处理完所有附件后,额外执行了两行错误代码,导致邮件结构被破坏:

  • 循环外的part.add_header("Content-Disposition",f"attachment; filename= {attachments}",)会把整个附件列表转成字符串(比如['file1xxx.pdf', 'file2.pdf'])作为文件名,非Gmail客户端(如Outlook)解析时会误把这个字符串当成附件名,且丢失扩展名。
  • 重复执行message.attach(part)会再次添加最后一个附件,造成冗余,进一步干扰客户端的解析逻辑。

另外,用'attachments' in globals()判断附件存在完全没必要——你已经显式定义了这个变量,直接判断列表是否非空即可。

修正后的代码

import smtplib
import os
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
import ssl

sender_email = "sender@gmail.com"
receiver_email = str(names[i])
# 注意:开启双因素认证的Gmail必须用【应用专用密码】,不是登录验证码
password = input("输入应用专用密码: ")

subject = "Title"    
body = """Hi,
    
This is the body of the email
"""
 
attachments = [f'file1{str(names[i])}.pdf', 'file2.pdf']  # 用f-string简化文件名拼接

# 创建多部分邮件并设置头信息
message = MIMEMultipart()
message["From"] = sender_email
message["To"] = receiver_email
message["Subject"] = subject
# 批量发送时建议用Bcc隐藏收件人,单个发送可省略此行
message["Bcc"] = receiver_email  

# 添加邮件正文
message.attach(MIMEText(body, "plain"))

# 处理附件(直接判断列表是否非空)
if attachments:
    for filename in attachments:
        # 用with语句安全打开文件,避免资源泄漏
        with open(filename, "rb") as f:
            part = MIMEBase('application', "octet-stream")
            part.set_payload(f.read())
            encoders.encode_base64(part)    
            # 确保文件名正确解析
            part.add_header(
                'Content-Disposition',
                f'attachment; filename="{os.path.basename(filename)}"'
            )
            message.attach(part)

# 转换邮件为字符串
text = message.as_string()

# 连接服务器发送邮件
context = ssl.create_default_context()
with smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context) as server:
    server.login(sender_email, password)
    server.sendmail(sender_email, receiver_email, text)

额外注意事项

  1. Gmail双因素认证:必须使用Google账号安全设置中生成的应用专用密码,普通密码或登录验证码无法用于SMTP登录。
  2. 特殊文件名处理:如果文件名包含中文或非ASCII字符,需要用email.header.Header处理编码,确保所有客户端正常显示:
    from email.header import Header
    part.add_header(
        'Content-Disposition',
        f'attachment; filename="{Header(os.path.basename(filename), "utf-8").encode()}"'
    )
    
  3. 批量发送优化:循环发送时,建议把所有收件人放在Bcc字段中,避免泄露收件人邮箱列表。

内容的提问来源于stack exchange,提问作者and_36100

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 20:01:13