19.1.2. email.parser
:解析电子邮件¶
消息对象结构可以通过以下两种方式之一创建:可以通过实例化Message
对象并通过attach()
和set_payload()
调用,或者可以通过解析电子邮件消息的平面文本表示来创建。
email
包提供了一个标准解析器,可以理解大多数电子邮件文档结构,包括MIME文档。您可以向解析器传递字符串或文件对象,解析器将返回对象结构的根Message
实例。对于简单的非MIME消息,此根对象的有效内容可能是包含消息文本的字符串。对于MIME消息,根对象将从其is_multipart()
方法返回True
,并且可以通过get_payload()
访问子部分walk()
方法。
实际上有两个解析器接口可供使用,经典的Parser
API和增量FeedParser
API。如果您将消息的整个文本作为字符串存储在内存中,或者整个消息存在于文件系统上的文件中,那么经典的Parser
API很好。FeedParser
更适用于当您从可能会阻止等待更多输入的流中读取邮件时。从套接字读取电子邮件消息)。FeedParser
可以逐步使用和解析消息,并且只有在关闭解析器[1]时才返回根对象。
注意,解析器可以以有限的方式扩展,当然你可以从头开始实现自己的解析器。There is no magical connection between the email
package’s bundled parser and the Message
class, so your custom parser can create message object trees any way it finds necessary.
19.1.2.1. FeedParser API¶
从email.feedparser
模块导入的FeedParser
提供了一个有助于对电子邮件进行增量解析的API,例如在阅读电子邮件的文本时是必需的消息从可以阻止(例如插座)。FeedParser
当然可以用于解析完全包含在字符串或文件中的电子邮件,但是对于这样的用例,经典的Parser
API可能更方便。两个解析器API的语义和结果是相同的。
FeedParser
的API很简单;你创建一个实例,喂它一堆文本,直到没有更多的东西喂它,然后关闭解析器检索根消息对象。FeedParser
在解析符合标准的邮件时非常准确,并且非常适合解析不符合SSL规定的邮件,提供有关邮件被视为损坏的信息。它将填充消息对象的缺陷属性,列出在消息中找到的任何问题。有关可以找到的缺陷列表,请参阅email.errors
模块。
以下是FeedParser
的API:
- class
email.parser.
FeedParser
(_factory=email.message.Message, *, policy=policy.compat32)¶ 创建
FeedParser
实例。可选_factory是一个无参数可调用,每当需要新的消息对象时将被调用。它默认为email.message.Message
类。如果指定了policy(它必须是
policy
类的实例),请使用它指定的规则来更新消息的表示形式。如果未设置策略,请使用compat32
策略,该策略与Python 3.2版本的电子邮件包保持向后兼容。有关详细信息,请参阅policy
文档。在版本3.3中已更改:添加了政策关键字。
-
feed
(data)¶ 提供
FeedParser
一些其他数据。data应为包含一行或多行的字符串。线条可以是部分线条,FeedParser
会将这些局部线条正确地拼接在一起。字符串中的行可以有任何常见的三行结束,回车,换行或回车和换行(甚至可以混合)。
-
close
()¶ 关闭
FeedParser
完成对所有先前提供的数据的解析,并返回根消息对象。未定义如果您向关闭的FeedParser
提供更多数据会发生什么情况。
-
- class
email.parser.
BytesFeedParser
(_factory=email.message.Message)¶ 除了
feed()
方法的输入必须是字节而不是字符串,其工作原理与FeedParser
版本3.2中的新功能。
19.1.2.2. Parser class API¶
从email.parser
模块导入的Parser
类提供了一个API,可以用于在消息的完整内容在字符串中可用时解析消息,或者文件。email.parser
模块还提供称为HeaderParser
和BytesHeaderParser
的标头解析器,如果您只对消息的标题。在这些情况下,HeaderParser
和BytesHeaderParser
可以更快,因为它们不会尝试解析消息体,而是将有效负载设置为原始主体作为字符串。它们具有与Parser
和BytesParser
类相同的API。
版本3.3中的新功能: BytesHeaderParser类。
- class
email.parser.
Parser
(_class=email.message.Message, *, policy=policy.compat32)¶ Parser
类的构造函数使用可选参数_class。这必须是一个可调用的工厂(例如一个函数或一个类),并且每当需要创建子消息对象时使用它。默认为Message
(请参阅email.message
)。工厂将被调用没有参数。如果指定了policy(它必须是
policy
类的实例),请使用它指定的规则来更新消息的表示形式。如果未设置策略,请使用compat32
策略,该策略与Python 3.2版本的电子邮件包保持向后兼容。有关详细信息,请参阅policy
文档。在版本3.3中已更改:删除了在2.4中已弃用的strict参数。添加了策略关键字。
其他公共
Parser
方法是:-
parse
(fp, headersonly=False)¶ 从类似文件的对象fp读取所有数据,解析生成的文本,并返回根消息对象。fp必须同时支持类文件对象上的
readline()
和read()
方法。fp中包含的文本必须格式化为 RFC 2822样式标题和标题连续行的一个块,可选地前面加上包络头。标题块由数据的结尾或空白行终止。在标题块之后是消息的主体(其可以包含MIME编码的子部分)。
可选headersonly是一个标志,指定在读取头之后是否停止解析。默认值为
False
,意味着它将解析文件的整个内容。
-
- class
email.parser.
BytesParser
(_class=email.message.Message, *, policy=policy.compat32)¶ 这个类与
Parser
完全并行,但处理字节输入。_class和strict参数以与Parser
构造函数相同的方式解释。如果指定了policy(它必须是
policy
类的实例),请使用它指定的规则来更新消息的表示形式。如果未设置策略,请使用compat32
策略,该策略与Python 3.2版本的电子邮件包保持向后兼容。有关详细信息,请参阅policy
文档。在版本3.3中已更改:删除了严格参数。添加了策略关键字。
-
parse
(fp, headersonly=False)¶ 从二进制文件样对象fp读取所有数据,解析生成的字节,并返回消息对象。fp必须同时支持类文件对象上的
readline()
和read()
方法。fp中包含的字节必须格式化为 RFC 2822样式标题和标题连续行的块,并且可选地前面加上包络头。标题块由数据的结尾或空白行终止。Following the header block is the body of the message (which may contain MIME-encoded subparts, including subparts with a Content-Transfer-Encoding of
8bit
.可选headersonly是一个标志,指定在读取头之后是否停止解析。默认值为
False
,意味着它将解析文件的整个内容。
-
parsebytes
(bytes, headersonly=False)¶ 类似于
parse()
方法,除了它需要一个字节字符串对象而不是像文件一样的对象。在字节字符串上调用此方法完全等效于在BytesIO
实例中包装文本,然后调用parse()
。可选的headersonly与
parse()
方法一样。
版本3.2中的新功能。
-
由于从字符串或文件对象创建消息对象结构是这样的常见任务,为了方便起见,提供了四个功能。它们位于顶层的email
包命名空间中。
-
email.
message_from_string
(s, _class=email.message.Message, *, policy=policy.compat32)¶ 从字符串返回消息对象结构。这完全等效于
Parser().parsestr(s)
。_class和policy被解释为Parser
类构造函数。在版本3.3中已更改:删除了严格参数。添加了策略关键字。
-
email.
message_from_bytes
(s, _class=email.message.Message, *, policy=policy.compat32)¶ 从字节字符串返回消息对象结构。这完全等效于
BytesParser().parsebytes(s)
。可选的_class和strict解释为Parser
类构造函数。版本3.2中的新功能。
在版本3.3中已更改:删除了严格参数。添加了策略关键字。
-
email.
message_from_file
(fp, _class=email.message.Message, *, policy=policy.compat32)¶ 从打开的file object返回消息对象结构树。这完全等效于
Parser().parse(fp)
。_class和policy被解释为Parser
类构造函数。在版本3.3中已更改:删除了严格参数。添加了策略关键字。
-
email.
message_from_binary_file
(fp, _class=email.message.Message, *, policy=policy.compat32)¶ 从打开的二进制file object返回消息对象结构树。这完全等效于
BytesParser().parse(fp)
。_class和policy被解释为Parser
类构造函数。版本3.2中的新功能。
在版本3.3中已更改:删除了严格参数。添加了策略关键字。
下面是一个在交互式Python提示符下如何使用这个示例:
>>> import email
>>> msg = email.message_from_string(myString)
19.1.2.3. Additional notes¶
这里有一些关于解析语义的注释:
- 大多数非multipart类型消息将被解析为具有字符串有效内容的单个消息对象。这些对象将为
is_multipart()
返回False
。他们的get_payload()
方法将返回一个字符串对象。 - 所有multipart类型消息将被解析为容器消息对象,其有效载荷的子消息对象列表。外部容器消息将为
is_multipart()
返回True
,并且其get_payload()
方法将返回Message
- 大多数内容类型为message / *的邮件(例如message / delivery-status和message / rfc822)也将被解析为包含长度为1的列表有效内容的容器对象。他们的
is_multipart()
方法将返回True
。列表有效内容中的单个元素将是一个子消息对象。 - 一些不符合标准的消息在它们的multipart适用性方面可能内部不一致。这样的消息可以具有multipart类型的Content-Type头,但是它们的
is_multipart()
方法可以返回False
。如果此类消息通过FeedParser
解析,则它们在缺陷属性列表中将具有MultipartInvariantViolationDefect
类的实例。有关详细信息,请参阅email.errors
。
脚注
[1] | 从Python 2.4引入的电子邮件包版本3.0开始,经典的Parser 在FeedParser 方面重新实现,因此两个解析器之间的语义和结果是相同的。 |