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

Python发送邮件时JSON附件西里尔字母编码异常修复求助

问题描述

我有一个包含西里尔字母的JSON文件,内容如下:

{
  "Полотенцесушитель EF 600L (белый)": {
    "sku": "Полотенцесушитель EF 600L (белый)",
    "price": "2 690 грн",
    "link": "https://example.org/some_link_bla_bla"
  }
}

我使用以下Python代码将该文件作为附件发送邮件:

def send_email(subject: str, json_file_path):
    """Send email."""
    m = MIMEMultipart()
    m.add_header("from", sender)
    m.add_header("to", receiver)
    m.add_header("subject", subject)

    if json_file_path:
        with open(json_file_path, 'r', encoding='utf-8') as file:
            attachment = MIMEApplication(file.read(), _subtype="json")
            attachment.add_header('Content-Disposition', 'attachment', filename='file.json')
            m.attach(attachment)

    context = ssl.create_default_context()
    try:
        with smtplib.SMTP_SSL(
            smtp_server, smtp_port, context=context, timeout=20
        ) as server:
            server.login(smtp_username, smtp_password)
            server.sendmail(sender, receiver, m.as_string())
        ic("Email sent")
    except Exception as e:
        logging.error(e)
        ic(e)

邮件发送成功,但附件中的西里尔字母全部变为Unicode转义序列,示例如下:

{
  "\u041f\u043e\u043b\u043e\u0442\u0435\u043d\u0446\u0435\u0441\u0443\u0448\u0438\u0442\u0435\u043b\u044c EF 600L (\u0431\u0435\u043b\u044b\u0439)": {
    "sku": "\u041f\u043e\u043b\u043e\u0442\u0435\u043d\u0446\u0435\u0441\u0443\u0448\u0438\u0442\u0435\u043b\u044c EF 600L (\u0431\u0435\u043b\u044b\u0439)",
    "price": "2 690 \u0433\u0440\u043d",
    "link": "https://example.org/some_link_bla_bla"
  }
}

如何修复该编码异常问题?

解决方案

问题根源是MIMEApplication处理文本内容时,默认会将非ASCII字符转义为Unicode序列。以下两种方法可解决该问题:

方法一:二进制模式读取文件并显式设置编码

直接以二进制模式读取文件,保留原始UTF-8编码,同时给附件显式指定字符集:

if json_file_path:
    with open(json_file_path, 'rb') as file:  # 二进制模式读取,避免字符串转义
        attachment = MIMEApplication(file.read(), _subtype="json")
        attachment.add_header('Content-Disposition', 'attachment', filename='file.json')
        attachment.set_charset('utf-8')  # 强制指定UTF-8编码
        m.attach(attachment)

方法二:使用MIMEText处理文本附件

对于JSON这类纯文本附件,使用MIMEText更合适,可直接指定编码类型:

if json_file_path:
    with open(json_file_path, 'r', encoding='utf-8') as file:
        # 直接指定文本类型、子类型和编码
        attachment = MIMEText(file.read(), 'json', 'utf-8')
        attachment.add_header('Content-Disposition', 'attachment', filename='file.json')
        m.attach(attachment)

注意事项

  • 两种方法都能确保西里尔字母以原始UTF-8编码传输,收件方打开附件时可正常显示字符。
  • 推荐使用第二种方法,MIMEText专门针对文本类附件设计,编码逻辑更清晰直接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 09:05:44