Тело сообщения электронной почты иногда представляет собой строку, а иногда - список. Почему?

Мое приложение написано на питоне. Что я делаю, так это запускаю скрипт для каждого письма, полученного postfix, и что-то делаю с его содержанием. Procmail отвечает за запуск сценария, принимая электронную почту в качестве входных данных. Проблема началась, когда я преобразовывал входное сообщение (может быть текст) в объект email_message (потому что последний пригодится). Я использую email.message_from_string (где электронная почта является модулем электронной почты по умолчанию, поставляется с python).

import email message = email.message_from_string(original_mail_content) message_body = message.get_payload()

Это message_body иногда возвращает список [экземпляр email.message.Message, экземпляр email.message.Message] и иногда возвращает строку (фактическое содержимое тела входящего письма). Почему это. И даже нашел еще одно наблюдение. Когда я просматривал строку документации email.message.Message.get_payload (), я обнаружил это ...
"" "Полезная нагрузка будет либо объектом списка, либо строкой. Если вы измените объект списка, вы измените полезную нагрузку сообщения в место....."""

Итак, как мне получить общий метод для получения тела письма через Python? Пожалуйста, помогите мне.

Ответов (4)

Решение

Что ж, ответы правильные, вам следует прочитать документацию, но для примера общего способа:

def get_first_text_part(msg):
    maintype = msg.get_content_maintype()
    if maintype == 'multipart':
        for part in msg.get_payload():
            if part.get_content_maintype() == 'text':
                return part.get_payload()
    elif maintype == 'text':
        return msg.get_payload()

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

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

Это может быть MIME multipart

См. http://docs.python.org/library/email.parser.html#additional-notes

Вместо того, чтобы просто искать часть, используйте walk () для перебора содержимого сообщения.

def walkMsg(msg):
  for part in msg.walk():
    if part.get_content_type() == "multipart/alternative":
      continue
    yield part.get_payload(decode=1)

Метод walk () возвращает итератор, который можно использовать в цикле (т.е. генератор). Если сообщение не является контейнером частей (т.е. не имеет вложений или альтернатив), тогда метод walk () вернет итератор с единственным элементом - самим сообщением.

Вы хотите пропустить любые "составные" части, так как они просто приклеиваются.

Вышеупомянутый метод возвращает все читаемые части. Вы можете расширить это, чтобы просто вернуть текстовые части, если они содержат информацию, которую вы ищете.

Обратите внимание, что начиная с Python 2.5 методы get_type (), get_main_type () и get_subtype () были удалены -> http://docs.python.org/library/email.message.html#email.message.Message.walk