email.parser:解析电子邮件

源代码: Lib/email/parser.py


可以使用以下两种方法之一创建消息对象结构:可以pass创建EmailMessage对象,使用字典接口添加 Headers 以及使用set_content()和相关方法添加有效负载来从整个布料创建消息对象结构,也可以pass以下方式创建它们:解析电子邮件的序列化表示形式。

email软件包提供了一个标准解析器,该解析器可以理解大多数电子邮件文档结构,包括 MIME 文档。您可以向解析器传递字节,字符串或文件对象,解析器将返回给您对象结构的根EmailMessage实例。对于简单的非 MIME 消息,此根对象的有效负载可能是包含消息文本的字符串。对于 MIME 消息,根对象将从其is_multipart()方法返回True,并且可以pass有效负载操纵方法(例如get_body()iter_parts()walk())来访问子部分。

实际上有两个解析器接口可供使用,即Parser API 和增量FeedParser API。如果您将消息的整个文本存储在内存中,或者如果整个消息都位于文件系统上的文件中,则Parser API 最为有用。当您从流中读取消息(可能会阻止 await 更多 Importing)(例如从套接字读取电子邮件)时,FeedParser更合适。 FeedParser可以递增地使用和解析消息,并且仅在关闭解析器时返回根对象。

请注意,可以以有限的方式扩展解析器,当然,您可以完全从头开始实现自己的解析器。连接email包的 Binding 解析器和EmailMessage类的所有逻辑都包含在policy类中,因此自定义解析器可以pass实现适当的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 关键字 ;在 Future 的 Python 版本中,默认值将更改为email.policy.default

3.2 版中的新Function。

在版本 3.3 中进行了更改:添加了* policy *关键字。

在版本 3.6 中更改:* _factory *默认为策略message_factory

  • feed(* data *)

    • 向解析器提供更多数据。 * data *应该是包含一个或多个行的bytes-like object。这些行可以是部分行,并且解析器会将这些部分行正确地缝合在一起。这些行可以具有三个公共行结尾中的任何一个:回车,换行或回车和换行(甚至可以混合使用)。
  • close ( )

    • 完成所有先前 Importing 的数据的解析,并返回根消息对象。调用此方法后,如果调用feed(),将会发生什么情况尚不确定。
    • class * email.parser. FeedParser(* _factory = None **,* policy = policy.compat32 *)
    • BytesFeedParser一样工作,除了feed()方法的 Importing 必须是字符串。这是有限的 Util,因为使这种消息有效的唯一方法是仅包含 ASCII 文本,或者如果utf8True则不包含二进制附件。

在版本 3.3 中进行了更改:添加了* policy *关键字。

Parser API

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

    • class * email.parser. BytesParser(* _class = None **,* policy = policy.compat32 *)
    • 创建一个BytesParser实例。 * _class policy 参数与BytesFeedParser _factory policy *参数具有相同的含义和语义。

注意: 应该始终指定 policy 关键字 ;在 Future 的 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(或utf8True RFC 6532)样式的 Headers 和 Headers 延续行,并可选地在前加上信封 Headers。标题块以数据结尾或空行结尾。Headers 块之后是消息的正文(可能包含 MIME 编码的子部分,包括 Content-Transfer-Encoding *为8bit的子部分)。

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

可选的* headersonly *与parse()方法相同。

3.2 版中的新Function。

    • class * email.parser. BytesHeaderParser(* _class = None **,* policy = policy.compat32 *)
    • 类似于BytesParser,除了* headersonly *默认为True

版本 3.3 中的新Function。

    • class * email.parser. Parser(* _class = None **,* policy = policy.compat32 *)
    • 此类与BytesParserParallel,但处理字符串 Importing。

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

在版本 3.6 中更改:* _class *默认为策略message_factory

  • parse(* fp headersonly = False *)
    • 从类似于文本模式文件的对象* fp *中读取所有数据,解析结果文本,然后返回根消息对象。 * fp *必须同时支持类似文件的对象的readline()read()方法。

除了文本模式要求之外,此方法的运行方式类似于BytesParser.parse()

  • parsestr(* text headersonly = False *)
    • parse()方法类似,不同之处在于它采用字符串对象而不是类似文件的对象。在字符串上调用此方法等效于首先在StringIO实例中包装* text *并调用parse()

可选的* headersonly *与parse()方法相同。

    • class * email.parser. HeaderParser(* _class = None **,* policy = policy.compat32 *)
    • 类似于Parser,除了* headersonly *默认为True

由于从字符串或文件对象创建消息对象结构是一种常见的任务,因此为方便起见,提供了四个Function。它们在顶级email软件包名称空间中可用。

  • email. message_from_bytes(* s _class = None **,* policy = policy.compat32 *)
    • bytes-like object返回消息对象结构。这等效于BytesParser().parsebytes(s)。可选的* _class policy *与BytesParser类构造函数一样解释。

3.2 版中的新Function。

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

  • email. message_from_binary_file(* fp _class = None **,* policy = policy.compat32 *)
    • 从打开的二进制file object返回消息对象结构树。这等效于BytesParser().parse(fp)。 * _class policy *与BytesParser类构造函数一样解释。

3.2 版中的新Function。

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

  • email. message_from_string(* s _class = None **,* policy = policy.compat32 *)
    • 从字符串返回消息对象结构。这等效于Parser().parsestr(s)。 * _class policy *的解释与Parser class 构造函数相同。

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

  • email. message_from_file(* fp _class = None **,* policy = policy.compat32 *)
    • 从打开的file object返回消息对象结构树。这等效于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)

Additional notes

以下是有关解析语义的一些注意事项:

  • 大多数非* multipart *类型的消息都被解析为带有字符串有效负载的单个消息对象。这些对象将针对is_multipart()返回False,而iter_parts()将产生一个空列表。

  • 所有* multipart *类型的消息都将被解析为容器消息对象,并带有其有效负载的子消息对象列表。外部容器消息将为is_multipart()返回True,而iter_parts()将产生一个子 Component 列表。

  • 大多数 Content Type 为* message/*的消息(例如 message/delivery-status message/rfc822 *)也将被解析为包含长度为 1 的列表有效负载的容器对象。它们的is_multipart()方法将返回Trueiter_parts()产生的单个元素将是一个子消息对象。

  • 某些不符合标准的消息可能在内部* multipart * -edness 不一致。这样的消息可能具有* multipart 类型的 Content-Type 头,但是它们的is_multipart()方法可能返回False。如果使用FeedParser解析了此类消息,则它们的 defects *属性列表中将具有MultipartInvariantViolationDefect类的实例。有关详细信息,请参见email.errors