msg.is_attachment() 是否足以在 python 中获取电子邮件中的所有附件,或者我们也应该检查 msg.is_multipart() 吗?

问题描述 投票:0回答:2

我正在搜索来自特定发件人且具有特定主题的邮件。 我收到第一封电子邮件,然后想从中检索附件。

我正在使用 imaplib。

我的代码-

_, mails = imap_client.search(None, f'(FROM "{sender}")', f'(SUBJECT "{subject}")')
first_mail = mails[0].split()[0]
mail_msgs = [email.message_from_bytes(response[1]) for response in first_mail if isinstance(response, tuple)]
msg = mail_msgs[0]
attachments = [part for part in msg.walk() if msg.is_multipart() and part.get_content_disposition() == "attachment"]

我的问题是关于最后一行 - 要检索附件,我是否需要检查消息是否同时是

is_multipart()
get_content_disposition()

attachments = [part for part in msg.walk() if msg.is_multipart() and part.get_content_disposition() == "attachment"]

或者只检查

get_content_disposition()
就足够了?

attachments = [part for part in msg.walk() if part.get_content_disposition() == "attachment"]
    
python imaplib
2个回答
1
投票

可能的错误

不保证

email.message_from_bytes()
返回
email.message.EmailMessage
对象。它返回一个
email.message.Message
对象,该对象不一定具有
is_attachment()
方法。 所以你可能想将
_class=email.message.EmailMessage
传递给
email.message_from_bytes()

回答问题

Message.is_multipart()
检查消息是否是多部分消息。这并不意味着它包含附件文件。它还将匹配使用双
text/html
text/plain
正文发送的电子邮件。如果您想过滤多部分消息,这就是您所需要的。如果您想过滤 file 附件,您需要在消息
parts
上使用 part.is_attachment() 进行过滤。在后一种情况下,
is_attachment()
就足够了。


0
投票

也许这一点被忽略了,但是 EmailMessage 有一个 iter_attachments 方法:

from email import message_from_string, policy
from email.message import EmailMessage


msg = EmailMessage()
msg.set_content("Plain text")
msg.add_alternative("<b>HTML content</b>", subtype="html")
for n in range(3):
    msg.add_attachment(
        f"test {n}".encode(), maintype="text", subtype="csv", filename=f"test{n}.csv"
    )

# Send over wire
raw_email = msg.as_string()

# Use `policy.default` to get as EmailMessage object
email_msg = message_from_string(raw_email, policy=policy.default)
for attachment in email_msg.iter_attachments():
    print(
        attachment.get_filename(),
        attachment.get_content_type(),
        attachment.get_content(),
    )

输出

test0.csv text/csv test 0
test1.csv text/csv test 1
test2.csv text/csv test 2
© www.soinside.com 2019 - 2024. All rights reserved.