使用imaplib读取邮件 - “超过10000字节”错误

15 投票
1 回答
6247 浏览
提问于 2025-04-18 18:15

我正在尝试用 imaplib 连接我的 Gmail 账户:

import imaplib
mail = imaplib.IMAP4_SSH('imap.gmail.com')
mail.login('myemail@gmail.com', 'mypassword')
mail.select("inbox")
# returns ('OK', [b'12009'])

这一切看起来都很顺利,但是:

mail.search(None, "ALL")
# returns error: command: SEARCH => got more than 10000 bytes
mail.logout()
# returns ('NO',
# ["<class 'imaplib.IMAP4.error'>: command: LOGOUT => got more than 10000 bytes"])

我想访问的这个账户收件箱里大约有 9000 封邮件。我用另一个账户试过,那个账户只有不到 1000 封邮件,代码运行得很好。

第一个邮箱账户的问题是不是和里面邮件的数量有关?有没有什么默认设置限制了邮件的数量?

我该如何解决这个错误,顺利读取我的邮件呢?

1 个回答

33

第一个邮箱的问题和里面邮件的数量有关吗?

不是直接相关,但差不多。问题在于你试图一次性下载9000封邮件的整个列表。

发送超长的行一直是个有效的拒绝服务攻击(DoS),而且对于用C语言而不是Python编写的程序来说,这也是一种针对许多网络客户端和服务器的缓冲区溢出攻击。这种做法可能会非常慢,还会堵塞网络。不过要注意,相关的标准文档最后更新是在1999年,而imaplib是1997年写的,所以“荒谬”的界限可能早就变了。

根据RFC 2683,解决这个问题的正确方法是不要这样做。(特别是看一下第3.2.1.5节。)


有没有什么默认设置来限制大小?

有的。虽然文档里没有列出,但因为RFC建议限制在8000字节,而它允许10000字节,我想这也算合理。


我该怎么绕过这个错误,读取我的邮件?

再次强调,你应该把这个分成小块来读取。

不过,只要Gmail对这么大的搜索没有问题,而且你愿意使用比90年代末标准稍好一点的电脑和网络连接,你可能可以通过其他方式解决这个问题。

幸运的是,像标准库中的许多模块一样,imaplib不仅仅是为了被用作模块而写的,它也可以作为有用的示例代码。你总能通过查看文档,发现它在最上面就链接到了源代码

所以,如果你看看,你会发现,在顶部不远的地方:

# reading arbitrary length lines. RFC 3501 and 2060 (IMAP 4rev1)
# don't specify a line length. RFC 2683 however suggests limiting client
# command lines to 1000 octets and server command lines to 8000 octets.
# We have selected 10000 for some extra margin and since that is supposedly
# also what UW and Panda IMAP does.
_MAXLINE = 10000

因此,如果你想覆盖这个限制,你可以分叉这个模块(把imaplib.py保存为myimaplib.py并使用它),或者你也可以在运行时直接修改它:

import imaplib
imaplib._MAXLINE = 40000

当然,你得选择一个你认为在2014年更能反映“荒谬”边界的数字。

撰写回答