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

使用smtplib发送邮件时Subject不显示的问题求助

邮件主题无法显示的问题排查与解决

Hey Bijan, 我仔细看了你的代码和问题描述,咱们来一步步找出邮件主题不显示的核心原因,同时优化下代码里的其他小问题。

需求说明

我的需求是读取包含收件人邮箱、抄送邮箱、邮件主题及内容的文本文件,批量发送多封邮件。

问题描述

目前邮件可正常发送,收件人、发件人信息显示正常,但邮件主题(Subject)无法显示。调试时发现msg对象的属性已正确设置,但主题并未传递至最终发送的邮件中。我已尝试调试smtplib和ssl相关文件,仍未找到问题根源,恳请各位提供帮助。

你的原始代码

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import pdb

def emailSender(emailId, password, input):
    fromaddr = emailId
    emailFile = open(input, "r") # open the generated email file with read only access
    msgTxt = ""
    server = smtplib.SMTP('outbound.___.com')
    server.starttls()
    server.login(fromaddr, password)
    for line in emailFile:
        if line.__contains__("$to$"):
            toaddr = line[4:]
        elif line.__contains__("$cc$"):
            cc = line[4:]
        elif line.__contains__("$bcc$"):
            bcc = line[5:]
        elif line.__contains__("$subj$"):
            subject = line[6:]
        elif line.__contains__("$%$"):
            msg = MIMEMultipart()
            msg['From'] = fromaddr
            msg['To'] = toaddr
            subject = subject.encode('utf-8')
            msg['Subject'] = "hello world"
            msg['Cc'] = cc
            msg.attach(MIMEText(msgTxt, 'plain'))
            text = msg.as_string()
            server.sendmail(fromaddr, toaddr, text)
            msgTxt = ""
        elif not line.__contains__("--------------------------------------------------------------------"):
            msgTxt += line
    server.quit()

if __name__ == '__main__':
    password = "****"
    emailId = "****"
    input = "input"
    emailSender(emailId, password, input)

问题根源分析

我发现了两个直接导致主题不显示的问题:

  1. 硬编码覆盖了读取的主题:你从文件里读取了subject变量,但最后赋值给msg['Subject']的是固定字符串"hello world",等于白读了主题内容!
  2. 错误的编码处理:你对subject做了encode('utf-8'),但邮件头字段需要的是字符串类型,字节对象会导致邮件头格式损坏,客户端无法解析主题。

另外还有个隐形问题:你只给server.sendmail传了toaddr,抄送和密送的邮箱不会实际收到邮件(只是邮件头显示Cc,实际没发送)。

修复后的代码

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header  # 处理非ASCII主题

def emailSender(emailId, password, input):
    fromaddr = emailId
    with open(input, "r", encoding="utf-8") as emailFile:  # 用with自动关闭文件,指定编码
        msgTxt = ""
        server = smtplib.SMTP('outbound.___.com')
        server.starttls()
        server.login(fromaddr, password)
        
        for line in emailFile:
            line_stripped = line.strip()  # 去除每行的换行和首尾空格
            if line_stripped.startswith("$to$"):
                toaddr = line_stripped[4:].strip()
            elif line_stripped.startswith("$cc$"):
                cc = line_stripped[4:].strip()
                cc_list = [addr.strip() for addr in cc.split(',')] if cc else []
            elif line_stripped.startswith("$bcc$"):
                bcc = line_stripped[5:].strip()
                bcc_list = [addr.strip() for addr in bcc.split(',')] if bcc else []
            elif line_stripped.startswith("$subj$"):
                subject = line_stripped[6:].strip()
            elif line_stripped.startswith("$%$"):
                msg = MIMEMultipart()
                msg['From'] = fromaddr
                msg['To'] = toaddr
                # 修复主题:使用读取到的内容,非ASCII主题用Header处理
                msg['Subject'] = Header(subject, 'utf-8') if subject else "无主题"
                if cc:
                    msg['Cc'] = cc
                
                msg.attach(MIMEText(msgTxt.strip(), 'plain', 'utf-8'))
                text = msg.as_string()
                
                # 修复抄送/密送:把所有收件人(to+cc+bcc)加入发送列表
                all_recipients = [toaddr] + cc_list + bcc_list
                server.sendmail(fromaddr, all_recipients, text)
                
                msgTxt = ""
            elif "--------------------------------------------------------------------" not in line:
                msgTxt += line  # 保留原始换行格式
        
        server.quit()

if __name__ == '__main__':
    password = "****"
    emailId = "****"
    input = "input"
    emailSender(emailId, password, input)

关键修改点

  • 主题修复:去掉硬编码的"hello world",直接使用读取的subject,如果有非英文主题,用Header类确保编码正确。
  • 编码规范:打开文件时指定utf-8编码,避免乱码;邮件正文也指定编码。
  • 抄送/密送功能完善:把Cc和Bcc的邮箱加入sendmail的收件人列表,确保这些邮箱能实际收到邮件。
  • 文件操作优化:用with语句自动管理文件,避免忘记关闭文件。
  • 格式处理:去除每行的多余空格和换行,避免邮箱地址或主题带无效字符。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:11:21