Python和imaplib:在不下载完整电子邮件的情况下获取附件名称或正文

Python和imaplib:在不下载完整电子邮件的情况下获取附件名称或正文,python,imaplib,Python,Imaplib,我在Django有一个电子邮件客户端。目前支持使用imaplib的GMail帐户 我的问题是:我想获得附件的名称,而不必下载完整的电子邮件。目前,为了获取附件名称或电子邮件正文,我需要使用带有参数(RFC822)的fetch函数下载整个电子邮件 我知道我只能使用HEADER.fields获取特定字段,对于主题,例如,从cc。但是,有没有一种方法可以在不下载整个电子邮件的情况下获取附件名称或电子邮件正文 我的具体意思是:假设我有一封30Mb的电子邮件,正文中有一行文字和两个15Mb的附件。我想在不

我在Django有一个电子邮件客户端。目前支持使用imaplib的GMail帐户

我的问题是:我想获得附件的名称,而不必下载完整的电子邮件。目前,为了获取附件名称或电子邮件正文,我需要使用带有参数(RFC822)的fetch函数下载整个电子邮件

我知道我只能使用HEADER.fields获取特定字段,对于主题,例如,从cc。但是,有没有一种方法可以在不下载整个电子邮件的情况下获取附件名称或电子邮件正文

我的具体意思是:假设我有一封30Mb的电子邮件,正文中有一行文字和两个15Mb的附件。我想在不下载完整的30Mb正文的情况下获得附件名称和该行文本


谢谢你

假设你问的是我认为你在问的问题,下面是该做的:

首先,获取
BODYSTRUCTURE
。假设gmail的IMAP服务器支持此功能,您将得到如下结果:

(("TEXT" "PLAIN" ("CHARSET" "UTF-8") NIL NIL "QUOTED-PRINTABLE" 56 1 NIL NIL NIL NIL)
 ("TEXT" "HTML" ("CHARSET" "UTF-8") (NAME "") NIL NIL "BASE64" 12345 NIL 
  ("attachment" ("FILENAME" "")) NIL NIL) 
 ("IMG" "JPEG" (NAME "funny picture") NIL NIL "BASE64" 56789 NIL
  ("attachment" ("FILENAME" "image.jpg")) NIL NIL))
 "MIXED" ("BOUNDARY" "----_=_NextPart_001_1234ABCD.56789EF0") NIL NIL NIL)
然后取
(BODY信封)
就是结构有一个

如果你看,它解释了如何处理这些问题

一旦确定
(BODY[1])
(BODY[2])
是主要内容的纯文本和HTML版本,并且
(BODY[3])
是第一个真正的附件,您就可以通过获取
(BODY[1])
下载纯文本正文,并从结构中获得附件的名称

对不起,这里没有代码。我不认为
imaplib
或任何与stdlib MIME和mail相关的模块都能为您完成困难的部分(解释结构),但我实际上还没有检查,所以我会先查看那里,如果没有,请转到PyPI查看是否有其他人已经编写了代码

嗯,实际上,首先,我只需要获取
BODYSTRUCTURE
(bodyenvelope)
(BODY[3])
来获取一条特定的消息,以确保gmail在编写一大堆代码之前得到了完全的支持

另外,如果最坏的情况是最坏的,如果您的用例像您描述的那样简单和严格,您可以总是获取
BODYSTRUCTURE
(BODY[1])
,如果失败,则返回到
RFC822
,并通过在结构上运行hacky regexp而不是真正的解析来获取附件名称。我写这篇文章不是为了一个简单的脚本或一个快速而肮脏的原型来了解gmail,但对于那些情况,我可能会这样做。

[Edit]

好了,我们开始吧=)

此邮件的附件名为“attiny40.pdf”,您可以在正文结构中清楚地看到该名称。剩下的就是解析BODYSTRUCTURE

代码基本上直接取自下面的最后一个链接

[/编辑]

您需要将fetch的参数从RFC822更改为BODYSTRUCTURE

然后,如所述,例如

例如,由文本和文本组成的两部分消息 BASE64编码文本附件的主体结构可以是: ((“文本”“普通”(“字符集”“US-ASCII”)NIL NIL“7BIT”1152 23)(“文本”“普通”(“字符集”“US-ASCII”“名称”“cc.diff”) “”“编译器差异” “BASE64”455473“混合”)


另见和。最后一个链接看起来和你想做的差不多。

“…不下载整个电子邮件就可以获得[]电子邮件正文的方法”->没有你所指的附件?你知道
正文结构
(正文信封)
?@JonClements:不,IMAP服务器可以为你解析正文并返回你想要的部分。你必须能够解析
主体结构
,才能知道要问什么,但你可以做到。@abarnert是的,我发布了,然后意识到可以做些什么,大约在你发布的同时-所以我想我应该删除它:)编辑了问题以更好地详细说明问题。将调查车身结构和(车身外壳)。谢谢,这似乎正是我想要的。将在接下来的5分钟内进行测试,如果有效,则标记为正确答案。已接受。谢谢你的努力非常好和完整的答案,但是我必须接受另一张海报的答案,因为它大约提前了10分钟,并且同样完整。但是谢谢你的努力。这也是我想要的。
>>> import imaplib, email
>>> mail = imaplib.IMAP4_SSL('imap.gmail.com')
>>> mail.login('emailaddr@gmail.com', 'password')
('OK', ['emailaddr@gmail.com Inget Namn authenticated (Success)'])
>>> mail.select('inbox')
('OK', ['14'])
>>> result, data = mail.uid('search', None, 'ALL')
>>> uids=data[0].split()
>>> result, data = mail.uid('fetch', uids[-1], 'BODYSTRUCTURE')
>>> print data
['14 (UID 340 BODYSTRUCTURE ((("TEXT" "PLAIN" ("CHARSET" "ISO-8859-1") NIL NIL "7BIT" 17 1 NIL NIL NIL)("TEXT" "HTML" ("CHARSET" "ISO-8859-1") NIL NIL "7BIT" 17 1 NIL NIL NIL) "ALTERNATIVE" ("BOUNDARY" "20cf3071d16a5a877b04d0adcc43") NIL NIL)("APPLICATION" "PDF" ("NAME" "attiny40.pdf") NIL NIL "BASE64" 8429956 NIL ("ATTACHMENT" ("FILENAME" "attiny40.pdf")) NIL) "MIXED" ("BOUNDARY" "20cf3071d16a5a878104d0adcc45") NIL NIL))']
>>>