为什么imaplib在每封电子邮件后都会返回一个单独的括号?

时间:2015-12-31 07:20:46

标签: python imap imaplib

概述:在Python中使用带有imaplib的imap获取电子邮件时,返回的有效内容是一个电子邮件元组列表...每个元组之间都有一个字节b')'

我使用标准的imaplib fetch调用给定逗号分隔的UID字节字符串:

resp, data = mailbox.fetch(b'1,2,3'), 'RFC822')

然而,data看起来像是:

[ 
  (b'1 (BODY[HEADER.FIELDS (DATE TO CC FROM SUBJECT)] {181}',
    b'Date: Thu, 18 Jul 2013 16:08:07 -0700 From: Blah Blah\r\n\r\n'
  ),
  b')',
  (b'1 (BODY[HEADER.FIELDS (DATE TO CC FROM SUBJECT)] {181}',
    b'Date: Thu, 18 Jul 2013 16:08:07 -0700 From: Blah Blah\r\n\r\n'
  ),
  b')',
  ...
]

所以现在,当我遍历该列表时,我必须跳过所有其他元素以避免b')'。显然,这并不难......但感觉我做错了什么,或者imaplib应该更好地解析这个右括号。

为什么有那个括号,有没有办法更正确地使用IMAP来消除它?

思想:

看起来右括号是built-in part of RFC822但是根据我对该规范的理解(这不是很多,老实说),括号不应该到达有效载荷的END之前在读完所有信息之后,我会想到这一点。

编辑:顺便说一句,此括号会显示您是否正在提取多条消息...即使您按照imaplib's own example,您也会收到类似[(headers, payload), b')']的数据

1 个答案:

答案 0 :(得分:2)

简单的答案是imaplib不是解析器,而是简单的低级库。当您进行获取请求时,每条消息的响应如下所示:

* 27 FETCH (A A-DATA B B-DATA C C-DATA)\r\n

也就是说,对fetch的响应是数据项的列表。括号向解析器指示这是(可能)可变长度的数据项列表。具体来说,当你请求一个正文时,它在概念上看起来像这样:

* 27 FETCH (RFC822 BODYDATA)\r\n

当IMAP服务器希望发送可能包含换行符或其他奇怪字符的数据blob时,它使用标准称为文字的转义机制。它提供大括号中的字节数,新的行对,然后是那么多字节的原始转储。然后服务器返回到它发送的命令。这看起来像这样:

* 27 FETCH (RFC822 {457}\r\n___457 bytes of body data here___)\r\n

imaplib只知道新行和文字,但除了告诉你它是什么类型之外,它不会解析响应。它把它分成这样的碎片:

* 27 FETCH (RFC822 {457}\r\n
___457 bytes of body data here___
)\r\n

这三行是​​你看到的响应的三个部分:文字之前的东西,文字本身和文字之后的东西。在这种情况下,关闭在第一部分中打开的列表是一个单括号。如果您请求多个需要文字传输的提取片段,您会看到更多的部分。

如果imaplib更像是一个解析器,我会很高兴,但它实际上只是一个低级访问机制。对于更复杂的工作,需要在其上构建解析器。