使用python电子邮件发送带有非ascii文件名的附件 [英] Email an attachment with non-ascii filename with python email

查看:459
本文介绍了使用python电子邮件发送带有非ascii文件名的附件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何发送附有文件的电子邮件,其中文件名包含unicode字符?



到目前为止,文件将以文件名noname 到达。



这是对ASCII文件名非常有效的部分:

  import smtplib 
from email.mime.text import MIMEText
from email.MIMEBase imppart.add_header('Content-Disposition','attachment',filename =('utf-8','fr' os.path.basename(f).encode('utf-8')))ort MIMEBase
从email.MIMEMultipart导入MIMEMultipart
从email.mime.application导入MIMEApplication
从电子邮件。 Utils import formatdate
from email import Encoders
from email.Utils import encode_rfc2231

msg = MIMEMultipart()
msg ['Subject'] =新杂志送货! 。
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' attach',filename =('utf-8','fr',os.path.basename(f).encode('utf-8')))

第二次尝试



全局设置字符集,如下所示:

 从电子邮件导入Charset 
Charset.add_charset('utf-8',Charset.QP,Charset.QP,'utf-8 ')

第三次尝试



使用来自email.Utils的 utils.encode_rfc2231

  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))

strong>第四次尝试



使用 urllib.quote()这与文件名具有与第三种方法相同的效果。

  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。

解决方案

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

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

...当我只是发送UTF-8时没有这样告诉:

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

文件名将正确显示。



这似乎与文档,其中声明:


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


这不起作用,但 python 3文档添加了:。


如果未传递三元组,并且值包含非ASCII
字符,则会自动使用RFC 2231格式使用
CHARSET的utf-8和一个LANGUAGE无。


只有这样工作,即使对于python 2.7,虽然它没有在文档中提到。


How can I send an email with a file attached where the file name contains unicode characters?

Up to now, the file will arrive but with the filename "noname".

This is the part that works perfectly well for ASCII filenames:

import smtplib
from email.mime.text import MIMEText
from email.MIMEBase imppart.add_header('Content-Disposition', 'attachment', filename=('utf-8', 'fr', os.path.basename(f).encode('utf-8')))ort 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)

First try

Adding a tuple of encoding, language and encoded string and not only the filename.

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

Second try:

Setting the charset globally like this:

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

Third try

Using 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))

Fourth try

Using urllib.quote() to urlencode the filename. This has the same effect on the filename as the third method.

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

Any ideas?

Am I missing something essential about RFC2231 filename character encoding?

I use Gmail's SMTP server and python 2.7.

解决方案

Instead of telling the server that it's UTF-8 like this:

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

...it works when I just send UTF-8 without telling so:

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

The file name will be properly displayed.

This seems to contradict the documentation which states:

If the value contains non-ASCII characters, it must be specified as a three tuple in the format (CHARSET, LANGUAGE, VALUE), where CHARSET is a string naming the charset to be used to encode the value, LANGUAGE can usually be set to None or the empty string (see RFC 2231 for other possibilities), and VALUE is the string value containing non-ASCII code points.

This doesn't work, however the python 3 documentation adds: .

If a three tuple is not passed and the value contains non-ASCII characters, it is automatically encoded in RFC 2231 format using a CHARSET of utf-8 and a LANGUAGE of None.

Only this works, even for python 2.7, though it's not mentioned in the docs.

这篇关于使用python电子邮件发送带有非ascii文件名的附件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆