Тело электронной почты иногда является строкой, а иногда списком. Зачем? - PullRequest
7 голосов
/ 27 февраля 2009

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

13 голосов
/ 27 февраля 2009

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

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()

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

10 голосов
/ 23 августа 2010

Вместо того, чтобы просто искать часть, используйте 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

10 голосов
/ 27 февраля 2009

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

0 голосов
/ 27 февраля 2009
...