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
相关产品推荐
相关产品推荐

