我有一个电子邮件多部分邮件对象,我想将该电子邮件中的附件转换为python文件对象。这可能吗?如果有可能,我应该研究Python中的哪种方法或类来完成这样的任务?
答案 0 :(得分:56)
我真的不明白你的意思是“电子邮件多部分邮件对象”。你的意思是属于email.message.Message
类的对象吗?
如果这就是你的意思,那就很简单了。在多部分消息上,get_payload
方法返回消息部分列表(每个部分本身都是Message
个对象)。您可以迭代这些部分并检查它们的属性:例如,get_content_type
方法返回部分的MIME类型,get_filename
方法返回部分的文件名(如果在消息中指定了任何文件名)。然后,当您找到正确的消息部分时,可以调用get_payload(decode=True)
来获取已解码的内容。
>>> import email
>>> msg = email.message_from_file(open('message.txt'))
>>> len(msg.get_payload())
2
>>> attachment = msg.get_payload()[1]
>>> attachment.get_content_type()
'image/png'
>>> open('attachment.png', 'wb').write(attachment.get_payload(decode=True))
如果您以编程方式从收到的电子邮件中提取附件,则可能需要采取预防措施来防范病毒和特洛伊木马。特别是,您可能只应该提取您知道的MIME类型安全的附件,并且您可能想要选择自己的文件名,或者至少清理get_filename
的输出。
答案 1 :(得分:14)
这是工作解决方案,消息是IMAP服务器的形式
self.imap.select()
typ, data = self.imap.uid('SEARCH', 'ALL')
msgs = data[0].split()
print "Found {0} msgs".format(len(msgs))
for uid in msgs:
typ, s = self.imap.uid('FETCH', uid, '(RFC822)')
mail = email.message_from_string(s[0][1])
print "From: {0}, Subject: {1}, Date: {2}\n".format(mail["From"], mail["Subject"], mail["Date"])
if mail.is_multipart():
print 'multipart'
for part in mail.walk():
ctype = part.get_content_type()
if ctype in ['image/jpeg', 'image/png']:
open(part.get_filename(), 'wb').write(part.get_payload(decode=True))
答案 2 :(得分:3)
实际上使用现在建议的this answer(不要与旧的email.EmailMessage API混淆),这很容易做到:
遍历所有邮件元素并仅选择附件
仅对附件进行迭代
假设您将邮件作为字节内容存储在信封变量
中解决方案1:
import email
from email.message import EmailMessage
email_message: EmailMessage = email.message_from_bytes(envelope, _class=EmailMessage)
for email_message_part in email_message.walk():
if email_message.is_attachment():
# Do something with your attachment
解决方案2:(由于您不必遍历消息对象的其他部分,因此比较可取)
import email
from email.message import EmailMessage
email_message: EmailMessage = email.message_from_bytes(envelope, _class=EmailMessage)
for email_message_attachment in email_message.iter_attachments():
# Do something with your attachment
加上注意事项:
EmailMessage
参数在字节读取方法中使用新的_class=EmailMessage
类