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

Python smtplib发送HTML/纯文本邮件异常:显示与编码问题

问题排查与解决方案

核心问题解析

  1. MIME多部分结构直接显示:未正确设置邮件的multipart/alternative类型,导致邮件客户端无法识别内容版本,直接输出原始MIME源码。
  2. 编码显示异常:Gr=C3=BCsse是UTF-8内容的quoted-printable编码形式,未显式指定编码或编码处理逻辑缺失,导致客户端未自动解码。
  3. 换行丢失问题:HTML内容的换行需要用<br>标签或块级元素实现,纯文本换行需保留原始格式,此前未区分处理两种内容的换行规则。

修正步骤

1. 正确构建多部分邮件

使用EmailMessage时,必须将邮件的Content-Type设置为multipart/alternative,这是告诉客户端这是同一内容的不同展示版本,优先渲染HTML。

2. 显式指定编码

为纯文本和HTML部分都指定utf-8编码,确保特殊字符(如德语变音符号)被正确处理,避免编码混乱。

3. 区分处理换行

  • 纯文本部分:保留原始字符串的换行符(\n)。
  • HTML部分:将原始文本中的换行符转换为<br>标签,或确保BBcode转换后的HTML已包含正确的换行格式。

4. 使用正确的发送方法

坚持使用send_message而非sendmail,前者会自动处理MIME结构的封装和编码,无需手动拼接邮件内容。

修正后的代码示例

import smtplib
from email.message import EmailMessage

# 自定义BBcode转HTML函数,根据实际规则调整
def bbcode_to_html(bbcode_str):
    html = bbcode_str.replace("[b]", "<strong>").replace("[/b]", "</strong>")
    html = html.replace("\n", "<br>")
    return html

def send_subscription_email(smtp_server, smtp_port, smtp_user, smtp_pass, recipients, subject, plain_text, html_content, bbcode_content):
    # 处理BBcode转HTML(优先级:BBcode > 传入的HTML)
    final_html = bbcode_to_html(bbcode_content) if bbcode_content else html_content

    msg = EmailMessage()
    msg['Subject'] = subject
    msg['From'] = smtp_user
    msg['To'] = ', '.join(recipients)

    # 添加纯文本和HTML版本,指定UTF-8编码
    msg.add_alternative(plain_text, subtype='plain', charset='utf-8')
    msg.add_alternative(final_html, subtype='html', charset='utf-8')

    # 发送邮件
    with smtplib.SMTP(smtp_server, smtp_port) as server:
        server.starttls()
        server.login(smtp_user, smtp_pass)
        server.send_message(msg)

# 调用示例
recipients = ["user1@example.com", "user2@example.com"]
subject = "订阅更新通知"
plain_text = "Hallo,\n\nGrüsse aus unserem Team!\n\nDein Abonnement wurde aktualisiert."
html_content = ""
bbcode_content = "[b]Hallo,[/b]\n\nGrüsse aus unserem Team!\n\nDein Abonnement wurde aktualisiert."

send_subscription_email(
    smtp_server="smtp.example.com",
    smtp_port=587,
    smtp_user="your_email@example.com",
    smtp_pass="your_password",
    recipients=recipients,
    subject=subject,
    plain_text=plain_text,
    html_content=html_content,
    bbcode_content=bbcode_content
)

验证要点

  • 发送前可打印msg.as_string(),检查MIME结构是否包含Content-Type: multipart/alternative; boundary=...,且各子部分有正确的Content-Type和charset=utf-8。
  • 测试不同邮件客户端,确认HTML优先显示,纯文本作为备选正常展示,特殊字符无编码异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 11:01:01