使用python电子邮件

时间:2016-01-08 01:49:17

标签: python email unicode character-encoding rfc2231

如何在文件名包含unicode字符的情况下发送附有文件的电子邮件?

到目前为止,文件将到达,但文件名为“noname”

这是适用于ASCII文件名的部分:

import smtplib
from email.mime.text import MIMEText
from email.MIMEBase import MIMEBase
from email.MIMEMultipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.Utils import formatdate
from email import Encoders
from email.Utils import encode_rfc2231

msg = MIMEMultipart()
msg['Subject'] = "New magazine delivery!"
msg['From'] = sender_email
msg['To'] = ', '.join(kindle_emails)
msg['Date'] = formatdate(localtime=True)
message = "see attachment"
msg.attach(MIMEText(message))
part = MIMEApplication(open(f, 'rb').read(), _subtype='application/x-mobipocket-ebook')

part.add_header('Content-Disposition', 'attachment', filename=os.path.basename(filename)
msg.attach(part)

首先尝试

添加编码,语言和编码字符串的元组,而不仅仅是文件名。

part.add_header('Content-Disposition', 'attachment', filename=('utf-8', 'fr', os.path.basename(f).encode('utf-8')))

第二次尝试:

像这样全局设置charset:

from email import Charset
Charset.add_charset('utf-8', Charset.QP, Charset.QP, 'utf-8')

第三次尝试

使用utils.encode_rfc2231

from email.Utils import encode_rfc2231
utf8filename = encode_rfc2231(os.path.basename(f).encode('utf-8'), charset='utf-8')
part.add_header('Content-Disposition', 'attachment', filename=('utf-8', 'fr', utf8filename))

第四次尝试

使用urllib.quote()对文件名进行urlencode。这对文件名的影响与第三种方法相同。

utf8filename = urllib.quote(os.path.basename(f).encode('utf-8'))
part.add_header('Content-Disposition', 'attachment', filename=('utf-8', 'fr', utf8filename))

有什么想法吗?

我是否遗漏了有关RFC2231文件名字符编码的重要信息?

我使用Gmail的SMTP服务器和python 2.7。

1 个答案:

答案 0 :(得分:3)

而不是像这样告诉服务器它是UTF-8:

filename=('utf-8', 'fr', os.path.basename(f).encode('utf-8')))

...当我发送UTF-8时没有这么说就可以了:

filename=os.path.basename(f).encode('utf-8'))

将正确显示文件名。

这似乎与documentation相矛盾:

  

如果值包含非ASCII字符,则必须将其指定为a   格式为三个元组(CHARSET,LANGUAGE,VALUE),其中CHARSET为   命名charset的字符串,用于对值LANGUAGE进行编码   通常可以设置为None或空字符串(有关其他信息,请参阅RFC 2231)   可能性),VALUE是包含非ASCII的字符串值   代码点。

这不起作用,但是python 3 documentation添加:。

  

如果未传递三元组且值包含非ASCII   字符,它使用一个自动编码为RFC 2231格式   CHARSET的utf-8和语言无。

只有这样才有效,即使对于python 2.7,尽管文档中没有提到它。