Python解析郵件
郵件的解析是個大課題,遠超一般人的預期。它遠比傳送郵件和接收郵件要複雜的多的多。
傳送郵件好說,接收和下載郵件也好說。關鍵是下載下來的郵件是一種比HTML還複雜的巢狀結構
MIME郵件協議
先不論Python,也不談什麼郵件發展歷史,只論現在:
現在我們要達到通過程式設計來解析郵件,就絕對避不開這個問題:
MIME郵件結構
.
MIME是一整套的協議,就像HTTP協議、TCP協議之類的一樣,都是解析郵件的一套規則。
所以我們想要解析一封郵件(把它拆成人能讀懂的標題、收發件人、內容、附件等),就必須得理解這套協議。
就算有現成的Python處理庫也一樣要懂了以後才能開始操作。
瞭解MIME協議,其實主要就是了解郵件的巢狀結構
。這個懂了就全懂了。
要知道,我們收到的一封郵件可能是以下這幾種不同的結構型別:
-
簡單的幾句話,全是文字。
(text/plain)
-
非常漂亮的網頁一樣的頁面。
(text/html)
-
包括回覆另一封郵件的層層巢狀的內容。
(multipart/mixed)
-
帶附件的內容,比如一張圖片。
(multipart/mixed)
+(image/jpeg)
當然,這不是全部,只是有代表性的幾種文件型別。最重要的是知道:
所有超出簡單文字或網頁HTML之外的,全都是multiparts
。
最難理解的也是這個multiparts。
下面是最複雜的Multiparts郵件,包括了所有能包括的結構。其中每個方塊
都有自己的Content Type
和Body
。
簡單點的結構圖:
[站外圖片上傳中...(image-8219fc-1548158814349)]
文字型結構圖:
multipart/mixed | +-- multipart/related || |+-- multipart/alternative ||| ||+-- text/plain ||+-- text/html || |+-- image/gif | +-- application/msword
詳細一點的結構圖:
[站外圖片上傳中...(image-36fdd8-1548158814349)]
這裡是所有郵件能支援的Content Type
文件型別:
text/plain text/html image/jpeg image/gif audio/x-wave audio/mpeg video/mpeg application/zip
程式設計上需要明確的是:要讀取巢狀結構,必須用遞迴的方法。
Content-Disposition 附件的存在方式
對於附件,有兩種存在方式:
inline attachment
一般我們只需要處理attachment格式的附件,而inline的東西就讓它儲存在inline裡吧。
郵件裡面要獲取這個部分的格式,需要找到這個引數:Content-Disposition
。其它並拍的引數還要Content-Type
和Content-ID
等。
Content-Transfer-Encoding 文字傳輸的編碼方式
這個只針對text/plain & text/html
型別的文字有用。
這個是每封郵件的必須資料,它必須要指出每段文字的傳輸編碼方式
,有的可以壓縮傳輸(base64),有的可以原文傳輸(8bit或7bit),有的可以內建base64圖片可直接列印(quoted-printable)。
正因為每封郵件都可能採用不同的傳輸編碼策略,所以我們解析內容之前必須要判斷是哪種方式才能正確解碼為原文的內容。
目前常見的傳輸編碼方式有:
-
8bit
或7bit
:這個最簡單,直接是原文,不需要轉碼。 -
base64
:內容全文 用base64壓縮,所以需要用base64.b64decode()
庫函式來解碼。 -
quoted-printable
:另一種壓縮方式,需要用quopri.decodestring()
庫函式來解碼。
獲取當前內容的傳輸編碼方式的程式碼如下:
encoding = part.get('Content-Transfer-Encoding')
其中part
可以是庫email.message.Message
的例項或者其中multipart多部分中的sub-part,都可以。