【发布时间】:2016-06-17 20:43:48
【问题描述】:
我仍然没有解决方案。
我正在编写一个邮件处理程序。我有一个很大的 INBOX 文件(由 Thunderbird 下载),里面有我的 gmail。
它在一些邮箱上运行,但不是来自 gmail 的收件箱。它持续了很长时间,但随后我收到了 UnicodeDecodeError 异常和一条消息
'ascii' codec can't decode byte 0xe2 in position 56: ordinal not in range(128).
修复解码逻辑是一种可能,但在尝试了各种解码字符串后,我要么仍然得到异常,要么错过处理大多数消息。
我接受某些消息可能无效或无法解码的可能性。跳过它们是可以的,但我不知道该怎么做,因为在运行 for 循环实现的底层代码时会发生异常,因此我无法使用 try/except 来捕获和跳过错误消息。
回溯只包含我程序中的一行,即这一行:
for message in mbox:
这似乎调用了itervalues,它调用了__getitem__,它在mailbox.py 中调用了get_message。我不知道 Python 中 for 循环的机制,但 itervalues 似乎是 for 循环遍历 mbox 中所有消息的方式,它通过调用通用 __getitem__ 来实现这一点,它调用 @987654328 @。
如果单个消息有问题,那很好,但我想跳过它并继续前进。问题是,由于我没有进行任何 API 调用,我不知道在哪里放置 try / except 处理程序。我想我可以用处理程序包装整个 for 循环,但这不允许我继续下一条记录。
我可以用几行代码重现问题:
import mailbox
mbox = mailbox.mbox('INBOX')
print(str(mbox.__len__()) + ' messages in mbox')
processed=0
for message in mbox:
processed += 1
if processed % 10000 == 0:
print('processed ', processed, ' so far')
异常发生在文件中包含近 200k 的 30k 条消息之后的某处。
有人可以建议如何捕获异常,让我跳过损坏的异常并继续吗?
更新:这是异常产生的回溯:
Traceback(最近一次调用最后一次):
File "C:\Users\Mark Colan\.p2\pool\plugins\org.python.pydev_4.5.5.201603221110\pysrc\pydevd.py", line 1529, in <module>
globals = debugger.run(setup['file'], None, None, is_module)
File "C:\Users\Mark Colan\.p2\pool\plugins\org.python.pydev_4.5.5.201603221110\pysrc\pydevd.py", line 936, in run
pydev_imports.execfile(file, globals, locals) # execute the script
File "C:\Users\Mark Colan\.p2\pool\plugins\org.python.pydev_4.5.5.201603221110\pysrc\_pydev_imps\_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "D:\Dev\Sandbox2\Sandbox2.py", line 6, in <module>
for message in mbox:
File "C:\Program Files\Python35\lib\mailbox.py", line 108, in itervalues
value = self[key]
File "C:\Program Files\Python35\lib\mailbox.py", line 72, in __getitem__
return self.get_message(key)
File "C:\Program Files\Python35\lib\mailbox.py", line 779, in get_message
msg.set_from(from_line[5:].decode('ascii'))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 56: ordinal not in range(128)
【问题讨论】:
-
请提供完整的堆栈跟踪,用文字描述它几乎没有提供它那么有用。
-
简单的建议,
try: ... except UnicodeDecodeError as e: print e; pass;-) 围绕那个循环或更紧,直到......你找到了“地方”或处理了有趣的消息。 -
@Dilettant
print e不会像原始回溯消息那样为您提供几乎一样多的信息,这样做的目的是什么? -
我添加了回溯。我不认为在 for 循环周围放置 track/except 有助于隔离问题,因为它似乎不在迭代的代码中,而是在 for 迭代处理本身中。
-
我想建议
try: ... except UnicodeDecodeError: pass,但感觉更需要调查 - 这是欧洲的一个深夜。说真的:OP 似乎更多地是在跳过业务,而不是在考古学 ;-) ...印刷品似乎是一个平衡的妥协。