在Python中从电子邮件附件中获取文件名

4 投票
5 回答
11993 浏览
提问于 2025-04-16 20:01

我正在用我的账号登录到一个服务器,然后搜索一封主题特定的邮件。这封邮件有一个附件,我想知道这个附件的文件名,可能还想知道它的文件扩展名。

我是在用Python做这个操作,但每次我想要文件名的时候,它都返回NONE,实际上附件里是有文件名的。

from imaplib import *
import base64
import email
import os
import sys
import errno
import mimetypes




server = IMAP4("SERVER LOCATION");

server.login("USER", "PASS");
server.select("Inbox");

typ, data = server.search(None, '(SUBJECT "Hello World")');

for num in data[0].split():
    typ, data = server.fetch(num, '(RFC822)');
    print (data);
    msg = email.message_from_string(str(data[0][1]));

      counter = 1
for part in msg.walk():
    print (part.as_string() + "\n")
    # 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()


    print (filename);

    fn = msg.get_filename()

    print("The Filename was:", (fn));


    if not filename:
        ext = mimetypes.guess_extension(part.get_content_type())


                        if not ext:
            # Use a generic bag-of-bits extension
            ext = '.bin'
            filename = 'part-%03d%s' % (counter, ext)
    counter += 1


server.close()


server.logout();

我不知道为什么我总是得到NONE作为答案,有谁能帮帮我吗?

5 个回答

1

如果你把所有东西都放进“part”里,你真的能在那儿看到这个文件吗?

2

你需要先检查一下

for part in msg.walk():

    print (part.get_content_type())

然后在主循环中 -

for part in msg.walk():

只处理那些在邮件内容中存在但你不需要的内容类型。

你也可以直接检查所需的内容类型,然后再读取文件名。

比如 - 我遇到过同样的问题,我的内容类型有 multiparttext/htmlapplication/json

我没有检查 text/html,想要读取一个在 "application/json" 中的附件。结果我直接读取文件名,导致出现了错误 - 文件名是 None。

当我加上检查后 -

if part.get_content_maintype() == 'text/html':
    continue

if part.get('Content-Type')== 'application/json':

    filename = part.get_filename().split('.')

#do the stuff needed 

就不会再出现错误了。

希望这对你有帮助。

6

我也遇到过同样的问题,这里是我解决它的方法:

if msg.get_content_maintype() == 'multipart': #multipart messages only
    # loop on the parts of the mail
    for part in msg.walk():
        #find the attachment part - so skip all the other parts
        if part.get_content_maintype() == 'multipart': continue
        if part.get_content_maintype() == 'text': continue
        if part.get('Content-Disposition') == 'inline': continue
        if part.get('Content-Disposition') is None: continue

        #save the attachment in the program directory
        print "part:", part.as_string()
        filename = part.get_filename()
        print "filename :", filename
        filepath = DIR_SBD+filename
        fp = open(filepath, 'wb')
        fp.write(part.get_payload(decode=True))
        fp.close()
        print '%s saved!' % filepath

撰写回答