Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 用字节解码电子邮件文本。解码(编码)_Python_Email_Encoding_Character Encoding - Fatal编程技术网

Python 用字节解码电子邮件文本。解码(编码)

Python 用字节解码电子邮件文本。解码(编码),python,email,encoding,character-encoding,Python,Email,Encoding,Character Encoding,我正在尝试用Python 3的字节解码一些电子邮件文本。解码(编码),其中编码来自电子邮件标题的字符集字段 问题:一些电子邮件将“cp-850”列为其字符集,而decode()接受“cp850” 如果我简单地去掉连字符,那么像iso-8859-6这样的另一个代码集就变成了iso88596,这是一种无法识别的编码 如何在不创建更多未知编码的情况下清理arg编码 [编辑]后续问题:如何从email.message.message对象中获取字符集,其格式(别名)为bytes.decode() [编辑]

我正在尝试用Python 3的
字节解码一些电子邮件文本。解码(编码)
,其中
编码
来自电子邮件标题的
字符集
字段

问题:一些电子邮件将“cp-850”列为其字符集,而
decode()
接受“cp850”

如果我简单地去掉连字符,那么像iso-8859-6这样的另一个代码集就变成了iso88596,这是一种无法识别的编码

如何在不创建更多未知编码的情况下清理arg
编码

[编辑]后续问题:如何从
email.message.message
对象中获取字符集,其格式(别名)为
bytes.decode()


[编辑]澄清了这个问题。以前在我指字符集时使用了一个不正确的术语“内容编码”。

您可以删除连字符,并检查是否有支持结果编码的编解码器:

import codecs

def sanitize_encoding(enc):
    try:
        codecs.lookup(enc)
        return enc
    except LookupError:
        try:
            enc = enc.replace('-','')
            codecs.lookup(enc)
            return enc
        except LookupError:
            # Not a thing, either way
            return None

sanitize_encoding('cp-850')
#'cp850'
sanitize_encoding('iso-8859-6')
#'iso-8859-6'
包含从IANA字符集标签到Python内部使用的别名的映射;但很可能你根本不需要自己做这件事

下面是对

这将获得零件字符集的IANA字符集标签;但是(默认情况下,
email.policy
)文本负载将被解码为Unicode,因此您根本不需要自己进行转换

电子邮件
库在Python3.5中进行了正式的大修(大修在Python3.3中已经非正式地引入),使用基于策略的系统,如果确实需要,允许您接管消息解析的某些部分;但是,对于格式良好的符合标准的消息(以及在野外看到的一些常见变化),您可以坐下来让Python标准库为您完成工作

然而,正如您所注意到的,代码实际上无法与
cp-850
身体部位一起工作,这正是您所陈述的原因。您可能希望这会起作用,但它不会:

# FIXME: broken code, doesn't help
import email.charset as email_charset
email_charset.add_alias('cp-850', 'cp850')
相反,您必须:


还请注意,令人困惑的是,别名有一个下划线,然后在一些内部黑色巫毒魔法中映射到一个破折号。

有一种方法可以为编码添加别名,但是
email
模块应该已经知道如何将IANA编码名称映射到Python的内部标签。除非你知道
电子邮件
库不能做你想做的事情,否则你真的不应该自己解析电子邮件。@tripleee嗨,你的意思是
电子邮件
模块在解析后会自动计算出每封邮件的编码内容吗?与中一样,在使用(例如)
email.message\u from\u binary\u file()
解析电子邮件后,返回的
message
对象将自动计算出电子邮件的内容编码?是,它可以解析电子邮件,并向您呈现MIME部分的合理统一结构,如果它是文本部分,您可以从中提取已解码的文本。(“内容编码”在此上下文中是另一回事。您正在查看内容类型的
charset=
值。)啊,是的,我很抱歉。我指的是字符集:我想得到消息中任何文本(普通或html)的正确字符集。希望采用
bytes.decode()
接受的格式(或别名)。您好,谢谢您的代码片段!我测试了它,发现当我尝试执行
part.get_content()
时,它仍然被cp-850中编码的子消息绊倒:(回溯表明
contentmanager
找不到编码cp-850。get_text\u content return content.decode中第67行的“`` File”/usr/lib/python3.6/email/contentmanager.py”(charset,errors=errors)LookupError:unknown encoding:cp-850``它使用
get\u-payload(decode=True)
而不是
get\u-content()
。我也更新了答案来显示这一点。可能
get\u-content()
中有一个bug?结果是
get\u-text\u-content()
调用
get\u-payload(decode=True)
然后尝试
。解码结果…我不确定此代码是否正确;负载应该已经被解码…等等,这也不正确;它解码为一个字节字符串。所以代码毕竟是正确的,cp-850编解码器有点问题,就像你说的。是的,因为
。decode()
应使用“cp850”(无连字符)而不是“cp-850”。
# FIXME: broken code, doesn't help
import email.charset as email_charset
email_charset.add_alias('cp-850', 'cp850')
import encodings
encodings.aliases.aliases['cp_850'] = 'cp850'