email.parser
: 解析電子郵件信息?
源代碼: Lib/email/parser.py
使用以下兩種方法的其中一種以創(chuàng )建消息對象結構:直接創(chuàng )建一個(gè) EmailMessage
對象,使用字典接口添加消息頭,并且使用 set_content()
和其他相關(guān)方法添加消息負載;或者通過(guò)解析一個(gè)電子郵件消息的序列化表達來(lái)創(chuàng )建消息對象結構。
email
包提供了一個(gè)可以理解包含 MIME 文檔在內的絕大多數電子郵件文檔結構的標準語(yǔ)法分析程序。 你可以傳遞給語(yǔ)法分析程序一個(gè)字節串、字符串或者文件對象,語(yǔ)法分析程序會(huì )返回給你對應于該對象結構的根 EmailMessage
實(shí)例。 對于簡(jiǎn)單的、非 MIME 的消息,這個(gè)根對象的負載很可能就是一個(gè)包含了該消息文字內容的字符串。 對于 MIME 消息,調用根對象的 is_multipart()
方法會(huì )返回 True
,其子項可以通過(guò)負載操縱方法來(lái)進(jìn)行訪(fǎng)問(wèn),例如 get_body()
、iter_parts()
還有 walk()
。
事實(shí)上你可以使用的語(yǔ)法分析程序接口有兩種: Parser
API 和增量式的 FeedParser
API。當你的全部消息內容都在內存當中,或者整個(gè)消息都保存在文件系統內的一個(gè)文件當中的時(shí)候,Parser
API非常有用。當你從可能會(huì )為了等待更多輸入而阻塞的數據流當中讀取消息(比如從套接字當中讀取電子郵件消息)的時(shí)候,FeedParser
會(huì )更合適。FeedParser
會(huì )增量讀取并解析消息,并且只有在你關(guān)閉語(yǔ)法分析程序的時(shí)候才會(huì )返回根對象。
請注意,語(yǔ)法分析程序可以進(jìn)行有限的拓展,你當然也可以完全從零開(kāi)始實(shí)現你自己的語(yǔ)法分析程序。將 email
包中內置的語(yǔ)法分析程序和 EmailMessage
類(lèi)連接起來(lái)的所有邏輯代碼都包含在 policy
類(lèi)當中,所以如有必要,自定義的語(yǔ)法分析程序可以通過(guò)實(shí)現自定義的對應 policy
方法來(lái)創(chuàng )建對應的消息對象樹(shù)。
FeedParser API?
從 email.feedparser
模塊導入的 BytesFeedParser
類(lèi)提供了一個(gè)適合于增量解析電子郵件消息的API,比如說(shuō)在從一個(gè)可能會(huì )阻塞(例如套接字)的源當中讀取消息文字的場(chǎng)合中它就會(huì )變得很有用。當然, BytesFeedParser
也可以用來(lái)解析一個(gè)已經(jīng)完整包含在一個(gè) bytes-like object 、字符串或文件內的電子郵件消息,但是在這些場(chǎng)合下使用 BytesParser
API可能會(huì )更加方便。這兩個(gè)語(yǔ)法分析程序API的語(yǔ)義和最終結果是一致的。
BytesFeedParser
的API十分簡(jiǎn)潔易懂:你創(chuàng )建一個(gè)語(yǔ)法分析程序的實(shí)例,向它不斷輸入大量的字節直到盡頭,然后關(guān)閉這個(gè)語(yǔ)法分析程序就可以拿到根消息對象了。 在處理符合標準的消息的時(shí)候 BytesFeedParser
非常準確;在處理不符合標準的消息的時(shí)候它做的也不差,但這視消息損壞的程度而定。它會(huì )向消息對象的 defects
屬性中寫(xiě)入它從消息中找到的問(wèn)題列表。關(guān)于它能找到的所有問(wèn)題類(lèi)型的列表,詳見(jiàn) email.errors
模塊。
這里是 BytesFeedParser
的 API:
- class email.parser.BytesFeedParser(_factory=None, *, policy=policy.compat32)?
創(chuàng )建一個(gè)
BytesFeedParser
實(shí)例??蛇x的 _factory 參數是一個(gè)不帶參數的可調用對象;如果沒(méi)有被指定,就會(huì )使用 policy 參數的message_factory
屬性。 每當需要一個(gè)新的消息對象的時(shí)候,_factory 都會(huì )被調用。如果指定了 policy 參數,它就會(huì )使用這個(gè)參數所指定的規則來(lái)更新消息的表達方式。 如果沒(méi)有設定 policy 參數,它就會(huì )使用
compat32
策略。 這個(gè)策略維持了對 Python 3.2 版本的 email 包的后向兼容性,并且使用Message
作為默認的工廠(chǎng)。 其他策略使用EmailMessage
作為默認的 _factory。 關(guān)于 policy 還會(huì )控制什么,參見(jiàn)policy
的文檔。注: 一定要指定policy關(guān)鍵字。 在未來(lái)版本的 Python 當中,它的默認值會(huì )變成
email.policy.default
。3.2 新版功能.
在 3.3 版更改: 添加了 policy 關(guān)鍵字。
在 3.6 版更改: _factory 默認為策略
message_factory
。- feed(data)?
向語(yǔ)法分析程序輸入更多數據。data 應當是一個(gè)包含一行或多行內容的 bytes-like object。 行內容可以是不完整的,語(yǔ)法分析程序會(huì )妥善的將這些不完整的行縫合在一起。每一行可以使用以下三種常見(jiàn)的終止符號的其中一種:回車(chē)符、換行符或回車(chē)符加換行符(三者甚至可以混合使用)。
- class email.parser.FeedParser(_factory=None, *, policy=policy.compat32)?
行為跟
BytesFeedParser
類(lèi)一致,只不過(guò)向feed()
方法輸入的內容必須是字符串。它的實(shí)用性有限,因為這種消息只有在其只含有ASCII文字,或者utf8
被設置為True
且沒(méi)有二進(jìn)制格式的附件的時(shí)候,才會(huì )有效。在 3.3 版更改: 添加了 policy 關(guān)鍵字。
Parser API?
BytesParser
類(lèi)從 email.parser
模塊導入,當消息的完整內容包含在一個(gè) bytes-like object 或文件中時(shí)它提供了可用于解析消息的 API。 email.parser
模塊還提供了 Parser
用來(lái)解析字符串,以及只用來(lái)解析消息頭的 BytesHeaderParser
和 HeaderParser
,如果你只對消息頭感興趣就可以使用后兩者。 在這種場(chǎng)合下 BytesHeaderParser
和 HeaderParser
速度非???,因為它們并不會(huì )嘗試解析消息體,而是將載荷設為原始數據。
- class email.parser.BytesParser(_class=None, *, policy=policy.compat32)?
創(chuàng )建一個(gè)
BytesParser
實(shí)例。 _class 和 policy 參數在含義和語(yǔ)義上與BytesFeedParser
的 _factory 和 policy 參數一致。注: 一定要指定policy關(guān)鍵字。 在未來(lái)版本的 Python 當中,它的默認值會(huì )變成
email.policy.default
。在 3.3 版更改: 移除了在2.4版本中被棄用的 strict 參數。新增了 policy 關(guān)鍵字。
在 3.6 版更改: _class 默認為策略
message_factory
。- parse(fp, headersonly=False)?
從二進(jìn)制的類(lèi)文件對象 fp 中讀取全部數據、解析其字節內容、并返回消息對象。 fp 必須同時(shí)支持
readline()
方法和read()
方法。fp 內包含的字節內容必須是一塊遵循 RFC 5322 (如果
utf8
為True
,則為 RFC 6532 )格式風(fēng)格的消息頭和消息頭延續行,并可能緊跟一個(gè)信封頭。 頭塊要么以數據結束,要么以一個(gè)空行為終止。 跟著(zhù)頭塊的是消息體(消息體內可能包含 MIME 編碼的子部分,這也包括 Content-Transfer-Encoding 字段為8bit
的子部分)。可選的 headersonly 指示了是否應當在讀取完消息頭后就終止。默認值為
False
,意味著(zhù)它會(huì )解析整個(gè)文件的全部?jì)热荨?/p>
- parsebytes(bytes, headersonly=False)?
與
parse()
方法類(lèi)似,只不過(guò)它要求輸入為一個(gè) bytes-like object 而不是類(lèi)文件對象。于一個(gè) bytes-like object 調用此方法相當于先將這些字節包裝于一個(gè)BytesIO
實(shí)例中,然后調用parse()
方法。可選的 headersonly 與
parse()
方法中的 headersonly 是一致的。
3.2 新版功能.
- class email.parser.BytesHeaderParser(_class=None, *, policy=policy.compat32)?
除了 headersonly 默認為
True
,其他與BytesParser
類(lèi)完全一樣。3.3 新版功能.
- class email.parser.Parser(_class=None, *, policy=policy.compat32)?
這個(gè)類(lèi)與
BytesParser
一樣,但是處理字符串輸入。在 3.3 版更改: 移除了 strict 參數。添加了 policy 關(guān)鍵字。
在 3.6 版更改: _class 默認為策略
message_factory
。- parse(fp, headersonly=False)?
從文本模式的文件類(lèi)對象 fp 讀取所有數據,解析所讀取的文本,并返回根消息對象。 fp 必須同時(shí)支持文件類(lèi)對象上的
readline()
和read()
方法。除了文字模式的要求外,這個(gè)方法跟
BytesParser.parse()
的運行方式一致。
- class email.parser.HeaderParser(_class=None, *, policy=policy.compat32)?
除了 headersonly 默認為
True
,其他與Parser
類(lèi)完全一樣。
考慮到從一個(gè)字符串或一個(gè)文件對象中創(chuàng )建一個(gè)消息對象是非常常見(jiàn)的任務(wù),我們提供了四個(gè)方便的函數。它們于頂層 email
包命名空間內可用。
- email.message_from_bytes(s, _class=None, *, policy=policy.compat32)?
從一個(gè) bytes-like object 中返回消息對象。 這與
BytesParser().parsebytes(s)
等價(jià)。 可選的 _class 和 policy 參數與BytesParser
類(lèi)的構造函數的參數含義一致。3.2 新版功能.
在 3.3 版更改: 移除了 strict 參數。添加了 policy 關(guān)鍵字。
- email.message_from_binary_file(fp, _class=None, *, policy=policy.compat32)?
從打開(kāi)的二進(jìn)制 file object 中返回消息對象。 這與
BytesParser().parse(fp)
等價(jià)。 _class 和 policy 參數與BytesParser
類(lèi)的構造函數的參數含義一致。3.2 新版功能.
在 3.3 版更改: 移除了 strict 參數。添加了 policy 關(guān)鍵字。
- email.message_from_string(s, _class=None, *, policy=policy.compat32)?
從一個(gè)字符串中返回消息對象。 這與
Parser().parsestr(s)
等價(jià)。 _class 和 policy 參數與Parser
類(lèi)的構造函數的參數含義一致。在 3.3 版更改: 移除了 strict 參數。添加了 policy 關(guān)鍵字。
- email.message_from_file(fp, _class=None, *, policy=policy.compat32)?
從一個(gè)打開(kāi)的 file object 中返回消息對象。 這與
Parser().parse(fp)
等價(jià)。 _class 和 policy 參數與Parser
類(lèi)的構造函數的參數含義一致。在 3.3 版更改: 移除了 strict 參數。添加了 policy 關(guān)鍵字。
在 3.6 版更改: _class 默認為策略
message_factory
。
這里是一個(gè)展示了你如何在Python交互式命令行中使用 message_from_bytes()
的例子:
>>> import email
>>> msg = email.message_from_bytes(myBytes)
附加說(shuō)明?
在解析語(yǔ)義的時(shí)候請注意:
大多數非 multipart 類(lèi)型的消息都會(huì )被解析為一個(gè)帶有字符串負載的消息對象。這些對象在調用
is_multipart()
的時(shí)候會(huì )返回False
,調用iter_parts()
的時(shí)候會(huì )產(chǎn)生一個(gè)空列表。所有 multipart 類(lèi)型的消息都會(huì )被解析成一個(gè)容器消息對象。該對象的負載是一個(gè)子消息對象列表。外層的容器消息在調用
is_multipart()
的時(shí)候會(huì )返回True
,在調用iter_parts()
的時(shí)候會(huì )產(chǎn)生一個(gè)子部分列表。大多數內容類(lèi)型為 message/* (例如 message/delivery-status 和 message/rfc822 )的消息也會(huì )被解析為一個(gè)負載是長(cháng)度為1的列表的容器對象。在它們身上調用
is_multipart()
方法會(huì )返回True
,調用iter_parts()
所產(chǎn)生的單個(gè)元素會(huì )是一個(gè)子消息對象。一些不遵循標準的消息在其內部關(guān)于它是否為 multipart 類(lèi)型前后不一。這些消息可能在消息頭的 Content-Type 字段中寫(xiě)明為 multipart ,但它們的
is_multipart()
方法的返回值可能是False
。如果這種消息被FeedParser
類(lèi)解析,它們的 defects 屬性列表當中會(huì )有一個(gè)MultipartInvariantViolationDefect
類(lèi)的實(shí)例。關(guān)于更多信息,詳見(jiàn)email.errors
。