email.parser:解析电子邮件消息 — Python 文档
email.parser:解析电子邮件
源代码: :source:`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 如果您在内存中拥有消息的整个文本,或者如果整个消息存在于文件系统上的文件中,则该 API 最有用。 FeedParser 更适合当您从流中读取消息时,该流可能会阻塞等待更多输入(例如从套接字读取电子邮件)。 FeedParser可以增量消费和解析消息,并且只有在关闭解析器时才返回根对象。
请注意,解析器可以通过有限的方式进行扩展,当然您可以完全从头开始实现自己的解析器。 连接 email 包的捆绑解析器和 EmailMessage 类的所有逻辑都包含在 policy
类中,因此自定义解析器可以以任何方式创建消息对象树通过实现适当的 policy
方法的自定义版本,它认为是必要的。
FeedParser API
从 email.feedparser
模块导入的 BytesFeedParser 提供了一个有助于增量解析电子邮件消息的 API,例如在从以下来源读取电子邮件消息的文本时是必需的可以阻塞(例如套接字)。 BytesFeedParser 当然可用于解析完全包含在 bytes-like object、字符串或文件中的电子邮件,但 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 版本的向后兼容性,并提供 Message 作为默认工厂。 所有其他策略都提供 EmailMessage 作为默认 _factory。 有关 policy 控制的更多信息,请参阅 policy 文档。
注意:应该始终指定policy关键字; 在 Python 的未来版本中,默认值将更改为 email.policy.default。
3.2 版中的新功能。
3.3 版更改: 增加了 policy 关键字。
3.6 版本变更:_factory 默认为策略
message_factory
。- feed(data)
向解析器提供更多数据。 data 应该是一个 bytes-like object 包含一行或多行。 这些行可以是部分的,解析器会将这些部分行正确地拼接在一起。 这些行可以有三种常见的行结尾:回车、换行或回车和换行(它们甚至可以混合)。
- close()
完成对所有先前馈送的数据的解析并返回根消息对象。 如果在调用此方法后调用 feed() 会发生什么是不确定的。
- class email.parser.FeedParser(_factory=None, *, policy=policy.compat32)
像 BytesFeedParser 一样工作,除了 feed() 方法的输入必须是字符串。 这是有限的效用,因为这种消息有效的唯一方法是它只包含 ASCII 文本,或者,如果
utf8
是True
,则没有二进制附件。3.3 版更改: 增加了 policy 关键字。
解析器API
从 email.parser 模块导入的 BytesParser 类提供了一个 API,当消息的完整内容在 字节中可用时,该 API 可用于解析消息-like object 或文件。 email.parser 模块还提供了 Parser 用于解析字符串,以及 header-only 解析器,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 必须同时支持 [X34X]readline() 和
read()
方法。fp 中包含的字节必须格式化为 RFC 5322 的块(或者,如果
utf8
是True
, RFC 6532) 样式的标头和标头连续行,可选地以信封标头开头。 标题块以数据结尾或空行结束。 头块后面是消息的正文(可能包含 MIME 编码的子部分,包括 Content-Transfer-Encoding 为8bit
的子部分)。可选的 headersonly 是一个标志,指定是否在读取标头后停止解析。 默认值为
False
,这意味着它解析文件的全部内容。
- parsebytes(bytes, headersonly=False)
类似于 parse() 方法,除了它需要一个 bytes-like object 而不是 file-like object。 在 bytes-like object 上调用这个方法相当于首先将 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)
从 bytes-like object 返回消息对象结构。 这相当于
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。