19.1.2. email.parser:解析电子邮件

源代码: Lib / email / parser.py

消息对象结构可以通过以下两种方式之一创建:可以通过实例化Message对象并通过attach()set_payload()调用,或者可以通过解析电子邮件消息的平面文本表示来创建。

email包提供了一个标准解析器,可以理解大多数电子邮件文档结构,包括MIME文档。您可以向解析器传递字符串或文件对象,解析器将返回对象结构的根Message实例。对于简单的非MIME消息,此根对象的有效内容可能是包含消息文本的字符串。对于MIME消息,根对象将从其is_multipart()方法返回True,并且可以通过get_payload()访问子部分walk()方法。

实际上有两个解析器接口可供使用,经典的Parser API和增量FeedParser API。如果您将消息的整个文本作为字符串存储在内存中,或者整个消息存在于文件系统上的文件中,那么经典的Parser API很好。FeedParser更适用于当您从可能会阻止等待更多输入的流中读取邮件时。从套接字读取电子邮件消息)。FeedParser可以逐步使用和解析消息,并且只有在关闭解析器[1]时才返回根对象。

注意,解析器可以以有限的方式扩展,当然你可以从头开始实现自己的解析器。email包的捆绑解析器和Message类之间没有神奇的联系,所以您的定制解析器可以以任何需要的方式创建消息对象树。

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.compat32

创建FeedParser实例。可选_factory是一个无参数可调用,每当需要新的消息对象时将被调用。它默认为email.message.Message类。

如果指定了policy(它必须是policy类的实例),请使用它指定的规则来更新消息的表示形式。如果未设置策略,请使用compat32策略,该策略与Python 3.2版本的电子邮件包保持向后兼容。有关详细信息,请参阅policy文档。

在版本3.3中已更改:添加了政策关键字。

进料 T0> ( T1> 数据 T2> ) T3> ¶ T4>

提供FeedParser一些其他数据。data应为包含一行或多行的字符串。线条可以是部分线条,FeedParser会将这些局部线条正确地拼接在一起。字符串中的行可以有任何常见的三行结束,回车,换行或回车和换行(甚至可以混合)。

靠近 T0> ( T1> ) T2> ¶ T3>

关闭FeedParser完成对所有先前提供的数据的解析,并返回根消息对象。未定义如果您向关闭的FeedParser提供更多数据会发生什么情况。

class email.parser.BytesFeedParser(_factory=email.message.Message)

除了feed()方法的输入必须是字节而不是字符串,其工作原理与FeedParser

版本3.2中的新功能。

19.1.2.2. 解析器类API

email.parser模块导入的Parser类提供了一个API,可以用于在消息的完整内容在字符串中可用时解析消息,或者文件。email.parser模块还提供称为HeaderParserBytesHeaderParser的标头解析器,如果您只对消息的标题。在这些情况下,HeaderParserBytesHeaderParser可以更快,因为它们不会尝试解析消息体,而是将有效负载设置为原始主体作为字符串。它们具有与ParserBytesParser类相同的API。

版本3.3中的新功能: BytesHeaderParser类。

class email.parser。 解析器 _class = email.message.Message*策略= policy.compat32

Parser类的构造函数使用可选参数_class这必须是一个可调用的工厂(例如一个函数或一个类),并且每当需要创建子消息对象时使用它。默认为Message(请参阅email.message)。工厂将被调用没有参数。

如果指定了policy(它必须是policy类的实例),请使用它指定的规则来更新消息的表示形式。如果未设置策略,请使用compat32策略,该策略与Python 3.2版本的电子邮件包保持向后兼容。有关详细信息,请参阅policy文档。

在版本3.3中已更改:删除了在2.4中已弃用的strict参数。添加了策略关键字。

其他公共Parser方法是:

解析 fpheadersonly = False t5 >

从类似文件的对象fp读取所有数据,解析生成的文本,并返回根消息对象。fp必须同时支持类文件对象上的readline()read()方法。

fp中包含的文本必须格式化为 RFC 2822样式标题和标题连续行的一个块,可选地前面加上包络头。标题块由数据的结尾或空白行终止。在标题块之后是消息的主体(其可以包含MIME编码的子部分)。

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

parsestr textheadersonly = False t5 >

类似于parse()方法,除了它需要一个字符串对象而不是像文件一样的对象。在字符串上调用此方法完全等效于在StringIO实例中包装文本,然后调用parse()

可选的headersonlyparse()方法一样。

class email.parser。 BytesParser _class = email.message.Message*策略= policy.compat32

这个类与Parser完全并行,但处理字节输入。_classstrict参数以与Parser构造函数相同的方式解释。

如果指定了policy(它必须是policy类的实例),请使用它指定的规则来更新消息的表示形式。如果未设置策略,请使用compat32策略,该策略与Python 3.2版本的电子邮件包保持向后兼容。有关详细信息,请参阅policy文档。

在版本3.3中已更改:删除了严格参数。添加了策略关键字。

解析 fpheadersonly = False t5 >

从二进制文件样对象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 bytesheadersonly = False t5 >

类似于parse()方法,除了它需要一个字节字符串对象而不是像文件一样的对象。在字节字符串上调用此方法完全等效于在BytesIO实例中包装文本,然后调用parse()

可选的headersonlyparse()方法一样。

版本3.2中的新功能。

由于从字符串或文件对象创建消息对象结构是这样的常见任务,为了方便起见,提供了四个功能。它们位于顶层的email包命名空间中。

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

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

在版本3.3中已更改:删除了严格参数。添加了策略关键字。

email.message_from_bytes(s, _class=email.message.Message, *, policy=policy.compat32)

从字节字符串返回消息对象结构。这完全等效于BytesParser().parsebytes(s)可选的_classstrict解释为Parser类构造函数。

版本3.2中的新功能。

在版本3.3中已更改:删除了严格参数。添加了策略关键字。

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

从打开的file object返回消息对象结构树。这完全等效于Parser().parse(fp)_classpolicy被解释为Parser类构造函数。

在版本3.3中已更改:删除了严格参数。添加了策略关键字。

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

从打开的二进制file object返回消息对象结构树。这完全等效于BytesParser().parse(fp)_classpolicy被解释为Parser类构造函数。

版本3.2中的新功能。

在版本3.3中已更改:删除了严格参数。添加了策略关键字。

下面是一个在交互式Python提示符下如何使用这个示例:

>>> import email
>>> msg = email.message_from_string(myString)  

19.1.2.3. 其他注意事项

这里有一些关于解析语义的注释:

  • 大多数非multipart类型消息将被解析为具有字符串有效内容的单个消息对象。这些对象将为is_multipart()返回False他们的get_payload()方法将返回一个字符串对象。
  • 所有multipart类型消息将被解析为容器消息对象,其有效载荷的子消息对象列表。外部容器消息将为is_multipart()返回True,并且其get_payload()方法将返回Message
  • 大多数内容类型为message / *的邮件(例如message / delivery-statusmessage / rfc822)也将被解析为包含长度为1的列表有效内容的容器对象。他们的is_multipart()方法将返回True列表有效内容中的单个元素将是一个子消息对象。
  • 一些不符合标准的消息在它们的multipart适用性方面可能内部不一致。这样的消息可以具有multipart类型的Content-Type头,但是它们的is_multipart()方法可以返回False如果此类消息通过FeedParser解析,则它们在缺陷属性列表中将具有MultipartInvariantViolationDefect类的实例。有关详细信息,请参阅email.errors

脚注

[1] T0>从Python 2.4引入的电子邮件包版本3.0开始,经典的ParserFeedParser方面重新实现,因此两个解析器之间的语义和结果是相同的。