在Python 3.x中解码邮件主题雷鸟

问题描述 投票:1回答:1

抱歉,我实在太笨了,无法独自解决。我正在尝试从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内容的重点,不是吗?

感谢您的帮助!

python python-3.x email unicode thunderbird
1个回答
0
投票

在现实世界中,将会有不符合标准的消息。如果不想拒绝不良消息,可以尝试使代码更具容忍性。使用“ 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))
© www.soinside.com 2019 - 2024. All rights reserved.