如何跳过处理作为其他邮件附件的邮件附件
使用jython
我遇到了一种情况,邮件里有不同的附件。有些文件类型我会处理,有些我会忽略,不会写入文件。现在我遇到一个麻烦的情况,因为有时候人们会把一封邮件作为附件发送,而这个附带的邮件里又有法律相关的附件。
我想做的是跳过那个附带的邮件和它所有的附件。
我想用python/jython的标准邮件库来实现这个功能,应该怎么做呢?
为了更清楚一些
我需要解析一封邮件(称为根邮件),我想用jython从这封邮件中获取附件。接下来,有些附件是支持的,比如.pdf、.doc等。恰好的是,客户发送了一封邮件(根邮件),里面有另一封邮件(子邮件)作为附件,而在子邮件里又有.pdf等附件。
我需要的是:去掉任何附在根邮件上的子邮件和子邮件的附件。现在的问题是,我遍历整个邮件时,它会把每个附件都解析出来,包括根邮件的附件和子邮件的附件,就好像它们都是根邮件的附件一样。
我不能这样。我只对根邮件的合法附件感兴趣,比如.pdf、.doc、.xls、.rtf、.tif、.tiff。
就这些了,我得赶去赶公交车!谢谢!
4 个回答
我理解你的问题是“我需要检查一封邮件的所有附件,但如果某个附件也是一封邮件,我想忽略它。”无论如何,这个答案应该能帮你找到正确的方向。
我认为你想要的是 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消息解压到一个文件夹里的例子”呢?看起来跟你想要的很接近。
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())
...
现有建议的问题在于“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应该返回一个顶层消息的列表,而不是递归地查找。