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]时才返回根对象。

注意,解析器可以以有限的方式扩展,当然你可以从头开始实现自己的解析器。There is no magical connection between the email package’s bundled parser and the Message class, so your custom parser can create message object trees any way it finds necessary.

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=policy.compat32)

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

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

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

feed(data)

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

close()

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

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

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

版本3.2中的新功能。

19.1.2.2. Parser class API

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

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

class email.parser.Parser(_class=email.message.Message, *, policy=policy.compat32)

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

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

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

其他公共Parser方法是:

parse(fp, headersonly=False)

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

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

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

parsestr(text, headersonly=False)

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

可选的headersonlyparse()方法一样。

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

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

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

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

parse(fp, headersonly=False)

从二进制文件样对象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(bytes, headersonly=False)

类似于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. Additional notes

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

  • 大多数非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]从Python 2.4引入的电子邮件包版本3.0开始,经典的ParserFeedParser方面重新实现,因此两个解析器之间的语义和结果是相同的。