如何跳过处理作为其他邮件附件的邮件附件

3 投票
4 回答
1235 浏览
提问于 2025-04-11 19:03

使用jython

我遇到了一种情况,邮件里有不同的附件。有些文件类型我会处理,有些我会忽略,不会写入文件。现在我遇到一个麻烦的情况,因为有时候人们会把一封邮件作为附件发送,而这个附带的邮件里又有法律相关的附件。

我想做的是跳过那个附带的邮件和它所有的附件。

我想用python/jython的标准邮件库来实现这个功能,应该怎么做呢?


为了更清楚一些

我需要解析一封邮件(称为根邮件),我想用jython从这封邮件中获取附件。接下来,有些附件是支持的,比如.pdf、.doc等。恰好的是,客户发送了一封邮件(根邮件),里面有另一封邮件(子邮件)作为附件,而在子邮件里又有.pdf等附件。

我需要的是:去掉任何附在根邮件上的子邮件和子邮件的附件。现在的问题是,我遍历整个邮件时,它会把每个附件都解析出来,包括根邮件的附件和子邮件的附件,就好像它们都是根邮件的附件一样。

我不能这样。我只对根邮件的合法附件感兴趣,比如.pdf、.doc、.xls、.rtf、.tif、.tiff。

就这些了,我得赶去赶公交车!谢谢!

4 个回答

0

我理解你的问题是“我需要检查一封邮件的所有附件,但如果某个附件也是一封邮件,我想忽略它。”无论如何,这个答案应该能帮你找到正确的方向。

我认为你想要的是 mimetypes.guess_type()。使用这个方法比单纯检查文件扩展名的列表要好得多。

def check(self, msg):
    import mimetypes

    for part in msg.walk():
        if part.get_filename() is not None:
            filenames = [n for n in part.getaltnames() if n]
            for filename in filenames:
                type, enc = mimetypes.guess_type(filename)
                if type.startswith('message'):
                    print "This is an email and I want to ignore it."
                else:
                    print "I want to keep looking at this file."

请注意,如果这仍然会查看附加的邮件,可以把它改成这样:

def check(self, msg):
    import mimetypes

    for part in msg.walk():
        filename = part.get_filename()
        if filename is not None:
            type, enc = mimetypes.guess_type(filename)
            if type.startswith('message'):
                print "This is an email and I want to ignore it."
            else:
                part_filenames = [n for n in part.getaltnames() if n]
                for part_filename in part_filenames:
                    print "I want to keep looking at this file."

MIME类型文档

0

那关于这个例子“这是一个如何将像上面那样的MIME消息解压到一个文件夹里的例子”呢?看起来跟你想要的很接近。

import email
...
msg = email.message_from_file(fp)
...
for part in msg.walk():
    # multipart/* are just containers
    if part.get_content_maintype() == 'multipart':
        continue
    # Applications should really sanitize the given filename so that an
    # email message can't be used to overwrite important files
    filename = part.get_filename()
    if not filename:
        ext = mimetypes.guess_extension(part.get_content_type())
    ...
2

现有建议的问题在于“walk”这个方法。它是通过递归的方式,深度优先地遍历整个树,包括所有的子节点。

你可以看看“walk”方法的源代码,然后调整它,让它跳过递归的部分。简单看一下代码,似乎可以这样做:

if msg.is_multipart():
    for part in msg.get_payload():
          """ Process message, but do not recurse """
          filename = part.get_filename()

根据pydocs的说明,get_payload应该返回一个顶层消息的列表,而不是递归地查找。

撰写回答