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,该 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
policy,它保持与电子邮件包的 Python 3.2 版本的向后兼容性,并提供Message
作为默认工厂。所有其他 policy 都提供EmailMessage
作为默认的 _factory。有关 policy 还控制什么内容的更多信息,请参见policy
文档。注意:应始终指定 policy 关键字;默认值将在未来的 Python 版本中更改为
email.policy.default
。3.2 版本中新增。
在 3.3 版本中更改:添加了 policy 关键字。
在 3.6 版本中更改:_factory 默认为 policy
message_factory
。
- class email.parser.FeedParser(_factory=None, *, policy=policy.compat32)¶
其工作方式类似于
BytesFeedParser
,区别在于feed()
方法的输入必须是字符串。它的用途有限,因为只有当消息仅包含 ASCII 文本,或者当utf8
为True
时,不包含二进制附件,这样的消息才是有效的。在 3.3 版本中更改:添加了 policy 关键字。
解析器 API¶
从 email.parser
模块导入的 BytesParser
类提供了一个 API,当消息的完整内容在 bytes-like 对象或文件中可用时,可以使用它来解析消息。 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-like 对象而不是类文件对象。在 bytes-like 对象上调用此方法等效于首先将 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 属性上内部不一致。此类消息可能具有类型为 multipart 的 Content-Type 标头,但它们的
is_multipart()
方法可能返回False
。如果使用FeedParser
解析此类消息,则它们的 defects 属性列表中将包含MultipartInvariantViolationDefect
类的实例。有关详细信息,请参阅email.errors
。