属性错误:"str"对象在解析多部分电子邮件时没有属性"副本"



Python 3.6 电子邮件模块崩溃并显示此错误:

Traceback (most recent call last):
File "empty-eml.py", line 9, in <module>
for part in msg.iter_attachments():
File "/usr/lib/python3.6/email/message.py", line 1055, in iter_attachments
parts = self.get_payload().copy()
AttributeError: 'str' object has no attribute 'copy'

崩溃可以用这个EML文件重现,

From: "xxx@xxx.xx" <xxx@xxx.xx>
To: <xx@xxx.xx>
Subject: COURRIER EMIS PAR PACIFICA 
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="----=_Part_3181_1274694650.1556805728023"
Date: Thu, 2 May 2019 16:02:08 +0200

还有这段最小的代码:

from email import policy
from email.parser import Parser
from sys import argv

with open(argv[1]) as eml_file:
msg = Parser(policy=policy.default).parse(eml_file)
for part in msg.iter_attachments():
pass

我相信它必须与内容类型multipart/mixed以及电子邮件内容为空有关,这会导致get_payload返回str。但是,我不确定,如果标准禁止这样的 EML(但我有很多这样的样本),这是电子邮件模块中的错误,或者我使用的代码错误。

如果将策略更改为strict

Parser(policy=policy.strict).parse(eml_file)

解析器引发email.errors.StartBoundaryNotFoundDefect,在文档中描述为:

StartBoundaryNotFoundDefect– 从未找到内容类型标头中声明的起始边界。

如果使用policy.default解析消息并在事后检查其defects,则它包含两个缺陷:

[StartBoundaryNotFoundDefect(), MultipartInvariantViolationDefect()]

MultipartInvariantViolationDefect– 一条消息声称是多部分,但未找到子部分。请注意,当邮件具有此缺陷时,即使其内容类型声称是多部分,其 is_multipart() 方法也可能返回 false。

StartBoundaryNotFoundDefect的结果是,分析器终止分析并将消息有效负载设置为到目前为止捕获的正文 - 在本例中为无内容,因此有效负载为空字符串,从而导致运行代码时看到的异常。

可以说,Python 在调用 payload 之前不会检查有效负载是否是listcopy()这一事实是一个错误。

实际上,您必须通过将附件的迭代包装在try/except中,对msg.defects的内容进行迭代,或者使用policy.strict解析并丢弃所有报告缺陷的消息来处理这些消息。

相关内容

  • 没有找到相关文章

最新更新