【问题标题】:Correct way to handle UTF-8 for outgoing email处理外发电子邮件的 UTF-8 的正确方法
【发布时间】:2015-05-18 13:20:21
【问题描述】:

谁能解释以 UTF-8 格式发送此电子邮件的正确方法是什么?目的地作为人类不可读的代码接收。

Edit1:添加了有关显示 upload_file 变量来自何处的代码的更多详细信息。 Edit2:添加了代码的最后一部分

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
def upload(upload_file):
ftp = ftplib.FTP('ftp.domain.com')
ftp.login("user","pass")
f = open(upload_file,'rb')
ftp_server_response = ftp.storbinary('STOR %s' %upload_file, f)
ftp_server_response_msg = ftp_server_response.split("/", 5)[4]
f.close()
ftp.quit()
os.remove(upload_file)
uploaded_filename = os.path.basename(upload_file)
html = """\
<iframe src="https://example.com/embed/{file_id}/{uploaded_file}" scrolling="no" frameborder="0" width="700" height="430" allowfullscreen="true" webkitallowfullscreen="true" mozallowfullscreen="true"></iframe>
""".format(file_id=ftp_server_response_msg, uploaded_file=uploaded_filename)
From = 'email@domain.com'
Recipient  = 'email@domain.com'

# Credentials
username = 'user01@domain.com'
password = 'password'
server = smtplib.SMTP('smtp.domain.com:587')

email_msg = MIMEMultipart('alternative')
email_msg['Subject'] = os.path.basename(upload_file).rsplit(".", 1)[0]
email_msg['From'] = From
email_msg['To'] = Recipient
email_msg_part1 = MIMEText(html, 'html')
email_msg.attach(email_msg_part1)

server.ehlo()
server.starttls()
server.login(username,password)
server.sendmail(From, Recipient, email_msg.as_string())
server.quit()

if __name__ == "__main__":
pool = Pool(9)
tasks = []
for root, dirs, filenames in os.walk("/ext_hdd/download"):
    dirs[:] = [d for d in dirs if d not in exclude]
    for extension in file_extensions:
        for filename in fnmatch.filter(filenames, extension):
            match = os.path.join(root, filename)
            file_size = os.path.getsize(match)
            if file_size > 209715200:

                    tasks.append(pool.apply_async(upload, args=(match,)))
            else:
                    pass

for task in tasks:
    print task
    task.get()
pool.close()
pool.join()

【问题讨论】:

  • 一切看起来都像 ASCII 所以你应该有编码问题。可以贴一张收到的邮件的图片吗?
  • 您好,由于我是通过电子邮件发给博主的,所以我只能向您展示发送部分:pastebin.com/zu2CBzWK
  • 我怀疑您的文件名变量不是 UTF-8 编码的。 upload_file 变量在哪里创建?
  • 添加一些更详细的代码,请检查
  • upload_file source 仍未显示,您已添加 ftp 函数但未在代码中调用。

标签: python python-2.7 utf-8 html-email smtplib


【解决方案1】:

快速回答可能是因为您没有在 MIMEText 上指定编码并且主题标头未定义为 UTF-8。假设你所有的字符串都是 UTF-8 编码的,你应该使用:

email_msg_part1 = MIMEText(html, 'html', "utf-8")
email_msg['Subject'] = Header(os.path.basename(upload_file).rsplit(".", 1)[0], "utf-8")

但是,如果这不起作用,那么您应该专注于 upload_file 的来源。

我认为upload_file 来自文件列表。在 Linux 上,文件名不会像在 Windows 上那样进行中性编码,也不会在 OS X 上强制执行。这意味着您可以使用 UTF-8 编码的文件名创建文件,这对于将文件名读取为 ISO 的程序来说看起来已损坏-8859-15。

/ext_hdd/download 中的文件可能没有 UTF-8 文件名。然后,您将传递这个非 UTF-8 编码的字符串,以便在应该使用 UTF-8 编码的字符串的地方使用。

要解决这个问题,您应该尽可能使用 Unicode 字符串,并让 mime 库按照自己的意愿进行编码。要获取 Unicode 字符串,您需要对文件名等编码字符串进行解码。一种简单的方法是将 Unicode 字符串作为目录名称传递给 os.walk()

os.walk(u"/ext_hdd/download")

这将尽可能使用 Python 的语言环境来解码文件名。在哪里无法解码,它将返回编码的文件名。然后,您将需要对字符串强制编码。假设编码实际上是 Windows-1252。将此添加给您os.walk() 代码:

if isinstance(filname, str):
    filename = filename.decode("windows-1252")

然后,当您调用时,将消息部分设置为顶部给出的。

【讨论】:

  • 我将前两行应用于我的代码,出现错误:UnicodeEncodeError: 'ascii' codec can't encode characters in position 15-19: ordinal not in range(128);我怎么能确定正在使用什么编码类型,在你的例子中是 windows-1252 ?您还可以在 os.walk() 部分包含完整代码吗?我不确定如何正确实施。
猜你喜欢
  • 2012-01-27
  • 2012-12-26
  • 2011-08-20
  • 1970-01-01
  • 2022-01-09
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 2021-04-17
相关资源
最近更新 更多