email.parser
:解析電子郵件訊息¶
原始碼: Lib/email/parser.py
訊息物件結構可以透過兩種方式建立:可以透過建立一個 EmailMessage
物件,使用字典介面新增標頭,並使用 set_content()
及相關方法新增有效載荷來從頭建立;也可以透過解析電子郵件訊息的序列化表示來建立。
email
包提供了一個標準解析器,可以理解大多數電子郵件文件結構,包括 MIME 文件。你可以向解析器傳遞一個位元組串、字串或檔案物件,解析器將返回物件結構的根 EmailMessage
例項。對於簡單的非 MIME 訊息,此根物件的有效載荷可能是一個包含訊息文字的字串。對於 MIME 訊息,根物件的 is_multipart()
方法將返回 True
,並且可以透過有效載荷操作方法(如 get_body()
、iter_parts()
和 walk()
)訪問其子部分。
實際上有兩種解析器介面可供使用:Parser
API 和增量式的 FeedParser
API。Parser
API 在你已將訊息的全部文字載入到記憶體中,或者整個訊息存在於檔案系統上的檔案中時最為有用。FeedParser
更適用於從可能因等待更多輸入而阻塞的流中讀取訊息(例如從套接字讀取電子郵件訊息)。FeedParser
可以增量地消費和解析訊息,並且只有在關閉解析器時才返回根物件。
請注意,解析器可以在有限的範圍內進行擴充套件,當然你也可以完全從頭開始實現自己的解析器。所有連線 email
包的內建解析器和 EmailMessage
類的邏輯都體現在 Policy
類中,因此自定義解析器可以透過實現相應 Policy
方法的自定義版本,以其認為必要的任何方式建立訊息物件樹。
FeedParser API¶
從 email.feedparser
模組匯入的 BytesFeedParser
提供了一個有助於增量解析電子郵件訊息的 API,例如在從可能阻塞的源(如套接字)讀取電子郵件訊息文字時所必需的。當然,BytesFeedParser
也可以用於解析完全包含在類位元組物件、字串或檔案中的電子郵件訊息,但對於此類用例,BytesParser
API 可能更方便。這兩種解析器 API 的語義和結果是相同的。
BytesFeedParser
的 API 很簡單;你建立一個例項,向其輸入位元組資料直到沒有更多資料可輸入,然後關閉解析器以檢索根訊息物件。在解析符合標準的訊息時,BytesFeedParser
非常準確,並且在解析不符合標準的訊息方面也做得很好,會提供有關訊息如何被判定為損壞的資訊。它會將訊息中發現的任何問題列表填充到訊息物件的 defects
屬性中。請參閱 email.errors
模組以獲取它能發現的缺陷列表。
以下是 BytesFeedParser
的 API:
- class email.parser.BytesFeedParser(_factory=None, *, policy=policy.compat32)¶
建立一個
BytesFeedParser
例項。可選的 _factory 是一個無引數的可呼叫物件;如果未指定,則使用 policy 的message_factory
。每當需要新的訊息物件時,就會呼叫 _factory。如果指定了 policy,則使用它指定的規則來更新訊息的表示。如果未設定 policy,則使用
compat32
策略,該策略保持與 Python 3.2 版本的 email 包的向後相容性,並提供Message
作為預設工廠。所有其他策略都提供EmailMessage
作為預設的 _factory。有關 policy 控制的其他內容的更多資訊,請參閱policy
文件。注意:應始終指定 policy 關鍵字;在 Python 的未來版本中,預設值將更改為
email.policy.default
。在 3.2 版本加入。
在 3.3 版本發生變更: 添加了 policy 關鍵字。
在 3.6 版本發生變更: _factory 預設為策略的
message_factory
。
- class email.parser.FeedParser(_factory=None, *, policy=policy.compat32)¶
工作方式與
BytesFeedParser
類似,但feed()
方法的輸入必須是字串。這個類的用途有限,因為要使這樣的訊息有效,它要麼只能包含 ASCII 文字,要麼在utf8
為True
的情況下,不包含二進位制附件。在 3.3 版本發生變更: 添加了 policy 關鍵字。
Parser API¶
從 email.parser
模組匯入的 BytesParser
類提供了一個 API,當訊息的全部內容都可在一個類位元組物件或檔案中獲取時,可以用它來解析訊息。email.parser
模組還提供了用於解析字串的 Parser
,以及只解析標頭的解析器 BytesHeaderParser
和 HeaderParser
,如果你只對訊息的標頭感興趣,可以使用它們。在這些情況下,BytesHeaderParser
和 HeaderParser
可以快得多,因為它們不嘗試解析訊息正文,而是將有效載荷設定為原始正文。
- class email.parser.BytesParser(_class=None, *, policy=policy.compat32)¶
建立一個
BytesParser
例項。_class 和 policy 引數的含義和語義與BytesFeedParser
的 _factory 和 policy 引數相同。注意:應始終指定 policy 關鍵字;在 Python 的未來版本中,預設值將更改為
email.policy.default
。在 3.3 版本發生變更: 移除了在 2.4 版本中已棄用的 strict 引數。添加了 policy 關鍵字。
在 3.6 版本發生變更: _class 預設為策略的
message_factory
。- parse(fp, headersonly=False)¶
從二進位制類檔案物件 fp 中讀取所有資料,解析得到的位元組串,並返回訊息物件。fp 必須同時支援
readline()
和read()
方法。fp 中包含的位元組必須格式化為一個 RFC 5322(或者,如果
utf8
為True
,則為 RFC 6532)風格的標頭和標頭續行塊,前面可以選擇性地帶有一個信封標頭。標頭塊以資料末尾或一個空行結束。標頭塊之後是訊息的正文(可能包含 MIME 編碼的子部分,包括 Content-Transfer-Encoding 為8bit
的子部分)。可選的 headersonly 是一個標誌,指定是否在讀取標頭後停止解析。預設為
False
,表示解析檔案的全部內容。
- parsebytes(bytes, headersonly=False)¶
與
parse()
方法類似,但它接受一個類位元組物件而不是一個類檔案物件。對一個類位元組物件呼叫此方法,等同於先將 bytes 包裝在BytesIO
例項中,然後呼叫parse()
。可選的 headersonly 與
parse()
方法中的一樣。
在 3.2 版本加入。
- class email.parser.BytesHeaderParser(_class=None, *, policy=policy.compat32)¶
與
BytesParser
完全相同,只是 headersonly 預設為True
。在 3.3 版本加入。
- class email.parser.Parser(_class=None, *, policy=policy.compat32)¶
這個類與
BytesParser
並行,但處理字串輸入。在 3.3 版本發生變更: 移除了 strict 引數。添加了 policy 關鍵字。
在 3.6 版本發生變更: _class 預設為策略的
message_factory
。- parse(fp, headersonly=False)¶
從文字模式的類檔案物件 fp 中讀取所有資料,解析得到的文字,並返回根訊息物件。fp 必須同時支援類檔案物件的
readline()
和read()
方法。除了文字模式的要求外,此方法的操作方式與
BytesParser.parse()
類似。
- class email.parser.HeaderParser(_class=None, *, policy=policy.compat32)¶
與
Parser
完全相同,只是 headersonly 預設為True
。
由於從字串或檔案物件建立訊息物件結構是一項非常常見的任務,因此提供了四個函式以方便使用。它們在頂級的 email
包名稱空間中可用。
- email.message_from_bytes(s, _class=None, *, policy=policy.compat32)¶
從類位元組物件返回一個訊息物件結構。這等同於
BytesParser().parsebytes(s)
。可選的 _class 和 policy 的解釋與BytesParser
類的建構函式一樣。在 3.2 版本加入。
在 3.3 版本發生變更: 移除了 strict 引數。添加了 policy 關鍵字。
- email.message_from_binary_file(fp, _class=None, *, policy=policy.compat32)¶
從一個開啟的二進位制檔案物件返回一個訊息物件結構樹。這等同於
BytesParser().parse(fp)
。_class 和 policy 的解釋與BytesParser
類的建構函式一樣。在 3.2 版本加入。
在 3.3 版本發生變更: 移除了 strict 引數。添加了 policy 關鍵字。
- email.message_from_string(s, _class=None, *, policy=policy.compat32)¶
從字串返回一個訊息物件結構。這等同於
Parser().parsestr(s)
。_class 和 policy 的解釋與Parser
類的建構函式一樣。在 3.3 版本發生變更: 移除了 strict 引數。添加了 policy 關鍵字。
- email.message_from_file(fp, _class=None, *, policy=policy.compat32)¶
從一個開啟的檔案物件返回一個訊息物件結構樹。這等同於
Parser().parse(fp)
。_class 和 policy 的解釋與Parser
類的建構函式一樣。在 3.3 版本發生變更: 移除了 strict 引數。添加了 policy 關鍵字。
在 3.6 版本發生變更: _class 預設為策略的
message_factory
。
以下是在 Python 互動式提示符下如何使用 message_from_bytes()
的示例:
>>> import email
>>> msg = email.message_from_bytes(myBytes)
附加說明¶
以下是關於解析語義的一些說明:
大多數非 multipart 型別的訊息被解析為帶有一個字串有效載荷的單個訊息物件。這些物件的
is_multipart()
會返回False
,而iter_parts()
將產生一個空列表。所有 multipart 型別的訊息將被解析為一個容器訊息物件,其有效載荷為子訊息物件的列表。外部容器訊息的
is_multipart()
將返回True
,而iter_parts()
將產生一個子部分列表。大多數內容型別為 message/* 的訊息(例如 message/delivery-status 和 message/rfc822)也將被解析為包含一個長度為 1 的列表有效載荷的容器物件。它們的
is_multipart()
方法將返回True
。iter_parts()
產生的單個元素將是一個子訊息物件。一些不符合標準的訊息可能在其 multipart-edness(多部分性)上內部不一致。此類訊息可能有一個型別為 multipart 的 Content-Type 標頭,但其
is_multipart()
方法可能返回False
。如果此類訊息是使用FeedParser
解析的,它們的 defects 屬性列表中將包含一個MultipartInvariantViolationDefect
類的例項。有關詳細資訊,請參閱email.errors
。