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