![](/img/trans.png)
[英]Thunderbird (python, Mac):Fill out email, subject, body, attach file
[英]Decoding Mail Subject Thunderbird in Python 3.x
有關解決方法,請參見下文
/原問題:
對不起,我太笨了,無法自己解決這個問題。 我正在嘗試從 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 事情的重點,不是嗎?
謝謝你的幫助!
/解決方法
我通過避免直接迭代 .mbox 郵件文件夾表示找到了一種解決方法。 而不是使用...
for message in mflder:
# do something
...只需使用:
for x in range(len(mflder)):
try:
message = mflder[x]
print(header_to_string(message["subject"]))
except:
print("Failed loading message!")
這將跳過 .mbox 文件夾中損壞的消息。 然而,我在處理 .mbox 文件夾主題時偶然發現了其他幾個問題。 例如,在使用decode_header()
函數時,標題有時會被分成幾個元組。 因此,為了接收完整的主題,還需要向header_to_string()
函數添加更多內容。 但這不再與這個問題有關。 我是一個菜鳥和業余程序員,但我記得使用 Outlook API 和 Python,這要容易得多......
看起來您的“mailfolder”mbox 文件已損壞,或者文件中的某些內容觸發了 Python mailbox
模塊中的錯誤。 如果沒有 mbox 輸入文件或重現問題的最小示例輸入文件,我無法判斷發生了什么。
你可以自己做一些調試。 文件中的每條消息都以“發件人”行開頭,如下所示:
From - Mon Mar 30 18:18:04 2020
從您發布的堆棧跟蹤來看,該行在其中一條消息中的格式似乎不正確。 就個人而言,我會使用 IDE 調試器 (PyCharm) 來追蹤格式錯誤的行是什么,但可以使用 Python 的內置pdb
來完成。 像這樣包裹你的循環:
import pdb
try:
for message in mflder:
print(header_to_string(message["subject"]))
except:
pdb.post_mortem()
當你現在運行代碼時,它會在異常發生時進入調試器。 在那個提示下,你可以輸入l
來列出調試器停止的代碼; 這應該與您最初發布的堆棧跟蹤中打印的最后一幀相匹配。 一旦你在那里,有兩個命令會告訴你發生了什么:
p from_line
將向您顯示格式錯誤的“From”行。
p start
將顯示mailbox
代碼認為郵件應該在文件中的偏移量。
在現實世界中,會有不符合標准的消息。 如果你不想拒絕壞消息,你可以嘗試讓代碼更寬容。 使用“latin-1”解碼是處理這些帶有 ASCII 以外字節的標頭的一種方法。 這不會失敗,因為所有可能的字節值都映射到有效的 Unicode 字符(Unicode 的前 256 個代碼與 ISO/IEC 8859-1,又名“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))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.