获取邮件附件到python文件对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4067937/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting mail attachment to python file object
提问by Joshua Partogi
I have got an email multipart message object, and I want to convert the attachment in that email message into python file object. Is this possible? If it is possible, what method or class in Python I should look into to do such task?
我有一个电子邮件多部分消息对象,我想将该电子邮件消息中的附件转换为 python 文件对象。这可能吗?如果可能的话,我应该研究 Python 中的什么方法或类来完成这样的任务?
采纳答案by Gareth Rees
I don't really understand what you mean by "email multipart message object". Do you mean an object belonging to the email.message.Messageclass?
我不太明白您所说的“电子邮件多部分消息对象”是什么意思。你的意思是一个属于这个email.message.Message类的对象吗?
If that is what you mean, it's straightforward. On a multipart message, the get_payloadmethod returns a list of message parts (each of which is itself a Messageobject). You can iterate over these parts and examine their properties: for example, the get_content_typemethod returns the part's MIME type, and the get_filenamemethod returns the part's filename (if any is specified in the message). Then when you've found the correct message part, you can call get_payload(decode=True)to get the decoded contents.
如果这就是你的意思,那就很简单了。在多部分消息上,该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))
If you're programmatically extracting attachments from email messages you have received, you might want to take precautions against viruses and trojans. In particular, you probably ought only to extract attachments whose MIME types you know are safe, and you probably want to pick your own filename, or at least sanitize the output of get_filename.
如果您正在以编程方式从收到的电子邮件中提取附件,您可能需要采取预防措施来抵御病毒和特洛伊木马。特别是,您可能应该只提取您知道其 MIME 类型是安全的附件,并且您可能想要选择自己的文件名,或者至少清理get_filename.
回答by pma_
Here is working solution, messages are form IMAP server
这是有效的解决方案,消息来自 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))
回答by Jakub Pastuszuk
Actually using now-suggested email.EmailMessage API(don't confuse with old email.Message API) it is fairly easy to:
实际上使用现在建议的email.EmailMessage API(不要与旧的email.Message API混淆)很容易:
Iterate over all message elements and select only attachments
Iterate over just attachments
遍历所有消息元素并仅选择附件
只迭代附件
Let's assume that you have your message stored as byte content in envelope variable
假设您将消息作为字节内容存储在信封变量中
Solution no.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
Solution no.2:(preferable since you don't have to walk through other parts of your message object)
解决方案 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
Couple things to note:
需要注意的几点:
- We explicitly tell to use new
EmailMessageclass in our byte read method through_class=EmailMessageparameter - You can read your email message (aka envelope) from sources such as bytes-like object, binary file object or stringthanks to built-in methods in message.Parser API
- 我们
EmailMessage通过_class=EmailMessage参数明确告诉在我们的字节读取方法中使用新类 - 借助 message.Parser API 中的内置方法,您可以从类似字节的对象、二进制文件对象或字符串等来源读取您的电子邮件消息(又名信封)

