获取Gmail附件文件名而不下载

时间:2012-12-01 20:57:36

标签: python gmail attachment imaplib

我正在尝试从Gmail帐户中获取可能包含一些大附件(大约30MB)的所有邮件。我只需要名字,而不是整个文件。我找到了一段代码来获取消息和附件的名称,但它会下载文件然后读取其名称:

import imaplib, email

#log in and select the inbox
mail = imaplib.IMAP4_SSL('imap.gmail.com')
mail.login('username', 'password')
mail.select('inbox')

#get uids of all messages
result, data = mail.uid('search', None, 'ALL') 
uids = data[0].split()

#read the lastest message
result, data = mail.uid('fetch', uids[-1], '(RFC822)')
m = email.message_from_string(data[0][1])

if m.get_content_maintype() == 'multipart': #multipart messages only
    for part in m.walk():
        #find the attachment part
        if part.get_content_maintype() == 'multipart': continue
        if part.get('Content-Disposition') is None: continue

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

我必须每分钟做一次,所以我无法下载数百MB的数据。我是网络脚本的新手,所以有人可以帮助我吗?我实际上不需要使用imaplib,任何python lib对我都没问题。

祝你好运

4 个答案:

答案 0 :(得分:9)

您可以指定RFC822,而不是抓取BODYSTRUCTURE,即完整内容。

来自imaplib的结果数据结构非常混乱,但您应该能够找到消息的每个部分的文件名,内容类型和大小,而无需下载整个内容。

答案 1 :(得分:3)

如果您对文件名有所了解,可以使用X-GM-RAW gmail extensions for imap SEARCH command。通过这些扩展,您可以使用任何gmail advanced search查询来过滤邮件。这样,您可以将下载限制为匹配的消息,或者排除一些您不想要的消息。

mail.uid('search', None, 'X-GM-RAW', 
       'has:attachment filename:pdf in:inbox -label:parsed'))

以上搜索INBOX中带有PDF附件的邮件未标记为“已解析”。

一些专业提示:

  • 标记您已解析的消息,因此您无需再次获取它们(上例中的-label:parsed过滤器)
  • 始终使用uid版本而不是标准顺序ID(您已经这样做了)
  • 遗憾的是MIME很混乱:有很多客户做了奇怪的(或者说是错误的)事情。您可以尝试仅下载并解析标题,但这是值得的吗?

[编辑]

如果在解析消息后标记消息,则可以跳过已解析的消息。这应该足够合理,以监控您的班级邮箱。

也许你生活在世界的一个角落,互联网带宽比程序员时间更贵;在这种情况下,您只能获取标题并查找“Content-disposition”==“attachment; filename = somefilename.ext”。

答案 2 :(得分:2)

RFC822消息数据项的FETCH在功能上等同于BODY[]。 IMAP4支持section 6.4.5 of RFC 3501中列出的其他邮件数据项。

尝试请求一组不同的邮件数据项,以获取所需的信息。例如,您可以尝试RFC822.HEADERBODY.PEEK[MIME]

答案 3 :(得分:0)

老问题,但只想分享我今天提出的解决方案。搜索包含附件的所有电子邮件,并输出uid,发件人,主题和格式化的附件列表。编辑相关代码以显示如何格式化BODYSTRUCTURE:

    data   = mailobj.uid('fetch', mail_uid, '(BODYSTRUCTURE)')[1]
    struct = data[0].split()        
    list   = []                     #holds list of attachment filenames

    for j, k in enumerate(struct):
        if k == '("FILENAME"':
            count = 1
            val = struct[j + count]
            while val[-3] != '"':
                count += 1
                val += " " + struct[j + count]
            list.append(val[1:-3])
        elif k == '"FILENAME"':
            count = 1
            val = struct[j + count]
            while val[-1] != '"':
                count += 1
                val += " " + struct[j + count]
            list.append(val[1:-1])

我也在GitHub发布了它。