作为一些电子邮件批处理的一部分,我们需要解码和“清理”消息。该过程的一个关键部分是将邮件正文与邮件附件分开。最棘手的部分是确定何时将“Content-Disposition: inline”部分视为消息正文替代或文件。
到目前为止,这段代码似乎处理了大多数情况:
请注意,该代码依赖于内联部分在头部中指定文件名的情况,Outlook似乎对其所有的“multipart/related”消息都这样做。 “Content-ID”也可以用作提示,但根据RFC 2387,它不是这样的指示器。
因此,如果嵌入式图像被编码为具有“Content-Disposition:inline”的消息部分,并定义了“Content-ID”,并且没有文件名,则上述代码可能会错误地将其分类为消息正文替代品。
从我从RFC中读到的内容来看,在找到简单检查方面并没有太大希望(特别是由于按照RFC进行编码在现实世界几乎没有用处,因为没有人这样做);但我想知道误分类的可能性有多大。
到目前为止,这段代码似乎处理了大多数情况:
from email import message_from_string
def split_parts(raw):
msg = message_from_string(raw)
bodies = []
files = []
for sub in msg.walk():
if sub.is_multipart():
continue
cd = sub.get("Content-Disposition", "")
if cd.startswith("attachment") or (cd.startswith("inline") and
sub.get_filename()):
files.append(sub)
else:
bodies.append(sub)
return bodies, files
请注意,该代码依赖于内联部分在头部中指定文件名的情况,Outlook似乎对其所有的“multipart/related”消息都这样做。 “Content-ID”也可以用作提示,但根据RFC 2387,它不是这样的指示器。
因此,如果嵌入式图像被编码为具有“Content-Disposition:inline”的消息部分,并定义了“Content-ID”,并且没有文件名,则上述代码可能会错误地将其分类为消息正文替代品。
从我从RFC中读到的内容来看,在找到简单检查方面并没有太大希望(特别是由于按照RFC进行编码在现实世界几乎没有用处,因为没有人这样做);但我想知道误分类的可能性有多大。
原理
我可以有一组函数来处理每个multipart/*
情况,并让它们间接递归。然而,我们并不太关心忠实的显示;事实上,我们会通过tidy过滤所有HTML消息。相反,我们更感兴趣的是选择一个消息正文的备选项并尽可能保存尽可能多的附件,即使它们被用于嵌入。
此外,某些用户代理在组合带有嵌入式附件(如PDF文件)的multipart/alternative
消息时会出现非常奇怪的问题,这是由于用户将任意文件拖放到组合窗口中而导致的结果。