Чтение писем с imaplib-ошибка "получил больше 10000 байт"

Я пытаюсь подключиться к своей учетной записи gmail с помощью imaplib:

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 ответов


проблема с первой учетной записью электронной почты связана с количеством писем в ней?

Не напрямую, Но да, в значительной степени. Проблема заключается в том, что вы пытаетесь загрузить весь список из 9000 сообщений сразу.

отправка смехотворно длинных строк была полезной атакой DoS и, для программ, реализованных на C, а не на Python, атака переполнения буфера против многих сетевых клиентов и серверов. Это также может быть очень медленно, и задушить сеть. Но обратите внимание, что RFC последний раз обновлялся в 1999 году, и imaplib был написан в 1997 году, поэтому пределы "смешного", возможно, изменились с тех пор.

на право способ решить эту проблему, по словам RFC 2683, это не пытаться сделать это. (См. раздел 3.2.1.5.)


есть ли какая-то настройка по умолчанию, которая реализует некоторый предел размера?

да. Он не указан в документах, но поскольку RFC рекомендует ограничение в 8000 байт, и это позволяет 10000, я думаю, что это разумно.


как я могу обойти ошибку и прочитать мои письма?

опять же, что вы должны do разбивает это на меньшие чтения.

но пока gmail не имеет проблем с таким большим поиском, и вы рады потребовать компьютер и сетевое подключение немного лучше, чем в конце 90-х годов, вы, вероятно, можете получить вместо этого нужно обойти проблему.

к счастью, как и многие модули в stdlib,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

Итак, если вы хотите переопределить это, вы можете развить модуль (save imaplib.py as myimaplib.py и используйте это вместо этого), или вы можете просто monkeypatch его во время выполнения:

import imaplib
imaplib._MAXLINE = 40000

конечно, вам придется выбрать номер, который, по вашему мнению, лучше отражает край нелепости в 2014 году.