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

smtplib使用.join拼接多收件人时仅首个地址收信问题咨询

问题根因

只有第一个收件人能收到邮件的核心原因是sendmail方法参数传错,另外代码里还有两处冗余和小bug:

  • smtplib的sendmail()方法第二个参数(实际投递收件人列表)要求传入可迭代的地址列表/元组对象,你现在传的是用, .join()拼接出来的单个字符串,SMTP服务器解析这个参数时只会识别第一个有效邮箱地址,剩余地址会被直接忽略,自然无法收信。

    注意:给message['To']赋值的逗号拼接字符串只是邮件头里展示给收件人看的内容,和SMTP协议层面的实际投递列表是两个独立逻辑,不能混为一谈。

  • 代码冗余创建了两次SMTP连接:先建了587端口的STARTTLS连接做了登录,后面发信时又重新建了465端口的SSL连接,前面的连接完全没被使用,属于无效代码。
  • 附件的Content-Disposition头末尾少了闭合双引号,部分邮件客户端会无法正常识别附件。
修复后代码

直接替换原有代码即可正常给所有收件人发信:

MY_ADDRESS = "*****@gmail.com"         # 替换为你的发件人邮箱
MY_PASSWORD = "*****"                  # 替换为你的邮箱授权码/密码
RECIPIENT_ADDRESS = ['*****@gmail.com', '*****@gmail.com']  # 替换为收件人列表

HOST_ADDRESS = 'smtp.gmail.com'
HOST_PORT = 465  # SSL连接直接用465端口即可,不需要额外走587的STARTTLS逻辑


import smtplib
from email.utils import formataddr
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.mime.text import MIMEText

# 建立服务连接,用with语句自动处理连接关闭
with smtplib.SMTP_SSL(host=HOST_ADDRESS, port=HOST_PORT) as smtp_obj:
    smtp_obj.login(MY_ADDRESS, MY_PASSWORD)

    # 创建邮件对象
    message = MIMEMultipart()

    # 配置邮件头
    message['From'] = formataddr(('Management', MY_ADDRESS))
    message['To'] = ", ".join(RECIPIENT_ADDRESS)  # 这里的拼接仅用于邮件头展示
    message['Subject'] = "Test Bill - July"

    # 构造邮件正文
    textPart = MIMEText("Hello John & Johnny,\n\nAttached below is your rent bill for the month of July 2022. To receive your rent bill with a physical copy please email back requesting for us to do so. Otherwise, you will receive your rent bill through email. If you pay online and have scheduled a payment then just double check that the amount paid covers the amount due in the bill you receive.\n\nBest,\ Management", 'plain')

    # 构造附件
    filename = "Test Bill - John.pdf"
    filePart = MIMEApplication(open(filename,"rb").read(),Name=filename)
    filePart["Content-Disposition"] = f'attachment; filename="{filename}"'  # 补全闭合引号

    # 组装邮件内容
    message.attach(textPart)
    message.attach(filePart)

    # 发信:第二个参数直接传原始收件人列表,不要传拼接后的字符串
    smtp_obj.sendmail(message['From'], RECIPIENT_ADDRESS, message.as_string())
关键修改点说明
  • 删掉了原来无用的587端口冗余连接,统一用上下文管理器处理465端口的SSL连接,不需要手动调用quit()关闭连接
  • sendmail的第二个参数直接传入原始的RECIPIENT_ADDRESS列表,保证SMTP服务能识别所有待投递收件人
  • 补全了附件头的闭合引号,避免部分客户端无法识别附件
  • 发件人地址直接复用预定义的MY_ADDRESS变量,减少重复硬编码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 07:09:24