email.parser:解析电子邮件消息 — Python 文档

来自菜鸟教程
Python/docs/3.7/library/email.parser
跳转至:导航、​搜索

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 文本,或者,如果 utf8True,则没有二进制附件。

3.3 版更改: 增加了 policy 关键字。


解析器API

email.parser 模块导入的 BytesParser 类提供了一个 API,当消息的完整内容在 字节中可用时,该 API 可用于解析消息-like object 或文件。 email.parser 模块还提供了 Parser 用于解析字符串,以及 header-only 解析器,BytesHeaderParserHeaderParser,可以使用如果您只对邮件的标题感兴趣。 BytesHeaderParserHeaderParser 在这些情况下可以更快,因为它们不会尝试解析消息正文,而是将有效负载设置为原始正文。

class email.parser.BytesParser(_class=None, *, policy=policy.compat32)

创建一个 BytesParser 实例。 _classpolicy 参数与 BytesFeedParser_factorypolicy 参数具有相同的含义和语义。

注意:应该始终指定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 的块(或者,如果 utf8TrueRFC 6532) 样式的标头和标头连续行,可选地以信封标头开头。 标题块以数据结尾或空行结束。 头块后面是消息的正文(可能包含 MIME 编码的子部分,包括 Content-Transfer-Encoding8bit 的子部分)。

可选的 headersonly 是一个标志,指定是否在读取标头后停止解析。 默认值为 False,这意味着它解析文件的全部内容。

parsebytes(bytes, headersonly=False)

类似于 parse() 方法,除了它需要一个 bytes-like object 而不是 file-like object。 在 bytes-like object 上调用这个方法相当于首先将 bytes 包装在 BytesIO 实例中并调用 parse()

可选的 headersonlyparse() 方法一样。

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()

parsestr(text, headersonly=False)

类似于 parse() 方法,除了它采用字符串对象而不是类文件对象。 对字符串调用此方法相当于先将 text 包装在 StringIO 实例中,然后调用 parse()

可选的 headersonlyparse() 方法一样。

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)。 可选的 _classpolicy 被解释为 BytesParser 类构造函数。

3.2 版中的新功能。

3.3 版更改: 删除了 strict 参数。 添加了 policy 关键字。

email.message_from_binary_file(fp, _class=None, *, policy=policy.compat32)

从打开的二进制 文件对象 返回消息对象结构树。 这相当于 BytesParser().parse(fp)_classpolicy 被解释为 BytesParser 类构造函数。

3.2 版中的新功能。

3.3 版更改: 删除了 strict 参数。 添加了 policy 关键字。

email.message_from_string(s, _class=None, *, policy=policy.compat32)

从字符串返回消息对象结构。 这相当于 Parser().parsestr(s)_classpolicy 被解释为 Parser 类构造函数。

3.3 版更改: 删除了 strict 参数。 添加了 policy 关键字。

email.message_from_file(fp, _class=None, *, policy=policy.compat32)

从打开的 文件对象 返回消息对象结构树。 这相当于 Parser().parse(fp)_classpolicy 被解释为 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-statusmessage/rfc822)也将被解析为包含列出长度为 1 的有效载荷。 他们的 is_multipart() 方法将返回 Trueiter_parts() 产生的单个元素将是一个子消息对象。
  • 一些不符合标准的消息在它们的 multipart-edness 方面可能在内部不一致。 此类消息可能具有 multipart 类型的 Content-Type 标头,但它们的 is_multipart() 方法可能返回 False。 如果使用 FeedParser 解析此类消息,则它们的 defects 属性列表中将具有 MultipartInvariantViolationDefect 类的实例。 有关详细信息,请参阅 email.errors