2009-09-22 117 views
28

在Python 2.6中給出了一個RFC822消息,我如何才能獲得正確的文本/純文本內容部分?基本上,該算法我想是這樣的:如何使用python獲取電子郵件的文本內容?

message = email.message_from_string(raw_message) 
if has_mime_part(message, "text/plain"): 
    mime_part = get_mime_part(message, "text/plain") 
    text_content = decode_mime_part(mime_part) 
elif has_mime_part(message, "text/html"): 
    mime_part = get_mime_part(message, "text/html") 
    html = decode_mime_part(mime_part) 
    text_content = render_html_to_plaintext(html) 
else: 
    # fallback 
    text_content = str(message) 
return text_content 

這些東西,我有get_mime_parthas_mime_part拍下來,但我不太清楚如何從MIME部分解碼的文本。我可以使用get_payload()編碼文本,但如果我嘗試使用get_payload()方法的decode參數(見the doc)我得到一個錯誤,當我把它的純文本/部分:

File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/email/message.py", line 189, in get_payload 
    raise TypeError('Expected list, got %s' % type(self._payload)) 
TypeError: Expected list, got <type 'str'> 

另外,我不知道如何將HTML呈現得儘可能接近文本。

+1

我發現類似的東西有用的解決方案http://ginstrom.com/scribbles/2007/11/19/parsing-multilingual-email-with- python/ – beldaz 2013-07-11 03:21:43

回答

69

在多部分電子郵件中,email.message.Message.get_payload()會爲每個零件返回一個包含一個項目的列表。最簡單的方法是走的消息,並得到各部分有效載荷:

import email 
msg = email.message_from_string(raw_message) 
for part in msg.walk(): 
    # each part is a either non-multipart, or another multipart message 
    # that contains further parts... Message is organized like a tree 
    if part.get_content_type() == 'text/plain': 
     print part.get_payload() # prints the raw text 

對於非多的消息,沒有必要做所有的步行。無論content_type如何,您都可以直接轉到get_payload()。

msg = email.message_from_string(raw_message) 
msg.get_payload() 

如果該內容被編碼,則需要通過None作爲第一個參數,以get_payload(),隨後真(解碼標記是第二個參數)。例如,假設我的電子郵件中包含的MS Word文檔附件:

msg = email.message_from_string(raw_message) 
for part in msg.walk(): 
    if part.get_content_type() == 'application/msword': 
     name = part.get_param('name') or 'MyDoc.doc' 
     f = open(name, 'wb') 
     f.write(part.get_payload(None, True)) # You need None as the first param 
               # because part.is_multipart() 
               # is False 
     f.close() 

至於得到一個HTML部分的合理純文本逼近,我發現html2text作品相當不錯的好。

+1

+1,非常明確有用的解釋。 – 2009-09-23 03:11:09

+0

這是一個很好的解釋......它涵蓋了我已經得到的東西;如上所述,我可以找到並提取零件的裸露有效載荷。但是,如果解碼了部分,我就不能解碼該部分,如果沒有文本/純色部分可用,我也不能將文本/ html部分渲染爲文本。 – 2009-09-23 13:45:36

+0

(關於重讀 - 對不起,咖啡是缺乏!)好吧,好吧,所以你已經解決了我的HTML到文本問題:) – 2009-09-23 13:46:16

-1

扁平比嵌套好;)

from email.mime.multipart import MIMEMultipart 
assert isinstance(msg, MIMEMultipart) 

for _ in [k.get_payload() for k in msg.walk() if k.get_content_type() == 'text/plain']: 
    print _ 
+0

這個盲目地提取所有的「文本/平原」部分,不關注哪一個是「正確的」。 – tripleee 2015-12-02 10:11:15

+0

@tripleee通常我們使用一個普通,一個html部分和幾個圖像部分。即使不是普通的部分,你怎麼知道哪一個是正確的? – guneysus 2015-12-02 22:28:55

+1

在典型的情況下,使用頂級'multipart/alternative',其中只有一個部分是'text/plain',就是那個。在更一般的情況下,我不認爲有一個正確的答案,因爲它取決於您的應用程序的目的和收件人的偏好。 – tripleee 2015-12-03 05:24:58

相關問題