在Python3.x中解码邮件主题Thunderbird
有关解决方法,请参见下文 /原始问题: 对不起,我实在太笨了,无法独自解决这个问题。我正试图从雷鸟的.mbox文件夹中读取几封电子邮件中的“主题”。现在,我正在尝试使用在Python3.x中解码邮件主题Thunderbird,python,python-3.x,email,unicode,thunderbird,Python,Python 3.x,Email,Unicode,Thunderbird,有关解决方法,请参见下文 /原始问题: 对不起,我实在太笨了,无法独自解决这个问题。我正试图从雷鸟的.mbox文件夹中读取几封电子邮件中的“主题”。现在,我正在尝试使用decode\u header()对头进行解码,但仍然会出现错误 我正在使用以下功能(我相信有一种更聪明的方法可以做到这一点,但这不是本文的重点) 前100个左右的输出完全正常,但随后出现以下错误消息: ----------------------------------------------------------------
decode\u header()
对头进行解码,但仍然会出现错误
我正在使用以下功能(我相信有一种更聪明的方法可以做到这一点,但这不是本文的重点)
前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)
。。。只需使用:
for x in range(len(mflder)):
try:
message = mflder[x]
print(header_to_string(message["subject"]))
except:
print("Failed loading message!")
这将跳过.mbox文件夹中的断开邮件。然而,在处理.mbox文件夹主题时,我偶然发现了几个其他问题。例如,在使用decode\u header()
函数时,有时会将头拆分为几个元组。因此,为了接收完整的主题,还需要向header\u to\u string()
函数添加更多内容。但这与这个问题无关了。我是一个noob和一个爱好编程的人,但我记得我使用outlookapi和Python,这更容易…解决方案
您可能损坏了“mailfolder”mbox文件,或者Python的邮箱
模块中存在由文件中的某些内容触发的错误。如果没有mbox输入文件或复制问题的最小示例输入文件,我就无法判断发生了什么
你可以自己调试一下。文件中的每条消息都以“发件人”行开头,该行应如下所示:
From-Mon-Mar 30 18:18:04 2020
从您发布的堆栈跟踪来看,其中一条消息中该行的格式似乎不正确。就我个人而言,我会使用IDE调试器(PyCharm)来跟踪格式错误的行是什么,但这可以通过Python内置的pdb
来完成。像这样包装您的循环:
导入pdb
尝试:
对于mFolder中的消息:
打印(标题到字符串(消息[“主题”]))
除:
pdb.验尸报告()
当您现在运行代码时,当异常发生时,它将进入调试器。在该提示下,您可以输入l
,列出调试器停止的代码;这应该与最初发布的堆栈跟踪中打印的最后一帧匹配。到达后,有两个命令将告诉您发生了什么:
p from_line
将显示格式错误的“发件人”行
将显示邮箱
代码认为邮件应该在文件中的偏移量
以前的答案没有解决原来的问题,但仍然适用
在现实世界中,会有不符合标准的消息。如果您不想拒绝错误消息,可以尝试使代码更宽容。使用“latin-1”解码是处理这些带有ASCII以外字节的报头的一种方法。这不能失败,因为所有可能的字节值都映射到有效的Unicode字符(Unicode与ISO/IEC 8859-1的前256个代码的一对一映射,也称为“拉丁-1”)。这可能会也可能不会给您发送人想要的文本
导入邮箱
从email.header导入解码\u头
mflder=mailbox.mbox(“邮件文件夹”)
def get_主题(消息):
标题=消息[“主题”]
如果不是标题:
返回“”
头,编码=解码头(头)[0]
如果编码不是无:
尝试:
头=头。解码(编码)
除:
header=header.decode('latin-1')
回流集管
对于mFolder中的消息:
打印(获取主题(消息))
谢谢你的想法!但这并不能解决问题。从错误消息中可以看出,问题发生在迭代mailboxfolder时。这似乎是get_message()
方法的一个问题,该方法尝试将某些内容解码为“ascii”,而显然不是“ascii”。我不知道如何解决这个问题。。。有没有一种方法可以组合一个try。。除了
循环的块之外?多亏了corona,我现在无法测试它,因为我的孩子们快把我逼疯了。^^我更新了我的答案,以表明您的问题与mbox文件中格式错误的“发件人”行有关。如果您可以更新您的问题,使其包含重现问题的示例mbox文件,或者在错误发生时至少包含调试信息,如from\u line
的值,我们可能能够找到根本原因。好的,非常感谢您的帮助!我将对此进行测试,否则只需尝试找出导致这些问题的邮件,将其删除,然后重试。好的,我更新了我的初始帖子,因为我找到了解决方法。问题是直接迭代.mbox文件夹,这会导致邮件中断问题。
for x in range(len(mflder)):
try:
message = mflder[x]
print(header_to_string(message["subject"]))
except:
print("Failed loading message!")
p from_line
p start