2015-12-31 2 views
2

Обзор: При получении электронной почты с помощью imap с помощью imaplib в Python возвращенная полезная нагрузка представляет собой список кортежей электронной почты ... с одним байтом b')' между каждым кортежем.Почему imaplib возвращает одиночную скобку после каждого письма?

Я использую стандартную imaplib fetch вызов дается разделенных запятыми байт строка UIDs:

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, но от того, что я понимаю этой спецификации (что не очень, если честно) скобка не допускается, чтобы прийти до конца полезной нагрузки, которая, на мой взгляд, была бы после того, как все сообщения будут прочитаны.

Edit: Кстати, эта скобка показывает вверх или нет, вы выборки нескольких сообщений ... даже если вы будете следовать imaplib's own example, вы получите обратно данные похожий [(headers, payload), b')']

ответ

2

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

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

То есть, ответ на выборку является списком пара элементов данных. Скобки указывают синтаксическому анализатору, что это (возможно) список переменных длины элементов данных. В частности, когда вы запрашиваете тело, это выглядит так, концептуально:

* 27 FETCH (RFC822 BODYDATA)\r\n 

Когда сервер IMAP желает послать сгусток данных, которые могут содержать символы перевода строки или другие странные символы, он использует ускользающей механизм, что стандарт относится к литературе. Он предоставляет количество байтов в фигурных скобках, новую пару линий, а затем необработанную дамп из этого количества байтов. Затем сервер возвращается к тому, что посылала команда. Это выглядит следующим образом:

* 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 был скорее парсером, но на самом деле это всего лишь механизм доступа на низком уровне. Для более сложной работы над ним должен быть создан парсер.

+0

Спасибо за четкое объяснение. Я согласен - кажется, что просто разобрать каждый отдельный компонент сообщения в один объект ... полями будут UID, команда, RFC#, размер байта, литерал str и список close 'b ')'' ... возможно для него есть превосходная библиотека python, но я не знаю об этом. – tyleha

+0

Разборки на удивление сложны, особенно для команд расширения. Вы можете легко выполнить простой анализ, но для предоставления объектов высокого уровня требуется знание любых расширений, которые могут нуждаться в поддержке. Некоторые библиотеки с представлениями высокого уровня (например, php) не могут поддерживать ничего, что не было в нем. – Max