抱歉,我实在太笨了,无法独自解决。我正在尝试从Thunderbird的.mbox文件夹中存储的几封电子邮件中读取“主题”。现在,我正在尝试使用decode_header()
解码标头,但仍收到UnicodeErrors。
我正在使用以下功能(我敢肯定有一种更聪明的方法可以做到这一点,但这不是本文的重点)
import mailbox
from email.header import decode_header
mflder = mailbox.mbox("mailfolder")
for message in mflder:
print(header_to_string(message["subject"]))
def header_to_string(header):
try:
header, encoding = decode_header(header)[0]
except:
return "something went wrong {}".format(header)
if encoding == None:
return header
else:
return header.decode(encoding)
大约前100个输出都很好,但是随后出现此错误消息:
---------------------------------------------------------------------------
---------------------------------------------------------------------------
UnicodeDecodeError Traceback (most recent call last)
<ipython-input-97-e252df04c215> in <module>
----> 1 for message in mflder:
2 try:
3 print(header_to_string(message["subject"]))
4 except:
5 print("0")
~\anaconda3\lib\mailbox.py in itervalues(self)
107 for key in self.iterkeys():
108 try:
--> 109 value = self[key]
110 except KeyError:
111 continue
~\anaconda3\lib\mailbox.py in __getitem__(self, key)
71 """Return the keyed message; raise KeyError if it doesn't exist."""
72 if not self._factory:
---> 73 return self.get_message(key)
74 else:
75 with contextlib.closing(self.get_file(key)) as file:
~\anaconda3\lib\mailbox.py in get_message(self, key)
779 string = self._file.read(stop - self._file.tell())
780 msg = self._message_factory(string.replace(linesep, b'\n'))
--> 781 msg.set_from(from_line[5:].decode('ascii'))
782 return msg
783
UnicodeDecodeError: 'ascii' codec can't decode byte 0x93 in position 4: ordinal not in range(128)
我如何强制mailbox.py解码不同的编码?还是标题只是坏了?如果我理解正确,标题应该是“ ASCII”,对吗?我的意思是,这就是整个MIME内容的重点,不是吗?
感谢您的帮助!
在现实世界中,将会有不符合标准的消息。如果不想拒绝不良消息,可以尝试使代码更具容忍性。使用“ latin-1”进行解码是一种处理这些标头的方法,这些标头使用ASCII以外的字节。这不会失败,因为所有可能的字节值都映射到有效的Unicode字符(Unicode与ISO / IEC 8859-1的前256个代码(也称为“ latin-1”)的一对一映射)。这可能会也可能不会给您发件人想要的文字。
import mailbox
from email.header import decode_header
mflder = mailbox.mbox("mailfolder")
def get_subject(message):
header = message["subject"]
if not header:
return ''
header, encoding = decode_header(header)[0]
if encoding is not None:
try:
header = header.decode(encoding)
except:
header = header.decode('latin-1')
return header
for message in mflder:
print(get_subject(message))