Разбирайте многоэлементную электронную почту с помощью частей с помощью Python
Я использую эту функцию для анализа электронной почты. Я могу разобрать «простые» многостраничные электронные письма, но при этом возникает ошибка (UnboundLocalError: локальная переменная «html», на которую ссылаются до назначения), когда электронное письмо определяет несколько границ (подчастей). Я хотел бы, чтобы сценарий разделял текст и части html и возвращал только часть html (если только нет html-части, верните текст).
def get_text(msg): text = "" if msg.is_multipart(): for part in msg.get_payload(): if part.get_content_charset() is None: charset = chardet.detect(str(part))['encoding'] else: charset = part.get_content_charset() if part.get_content_type() == 'text/plain': text = unicode(part.get_payload(decode=True),str(charset),"ignore").encode('utf8','replace') if part.get_content_type() == 'text/html': html = unicode(part.get_payload(decode=True),str(charset),"ignore").encode('utf8','replace') if html is None: return text.strip() else: return html.strip() else: text = unicode(msg.get_payload(decode=True),msg.get_content_charset(),'ignore').encode('utf8','replace') return text.strip()
- читатель арифметических выражений в python
- Запрос на возврат объектов с локальным областью в python
- Как извлечь подпись из ссылки на функцию в Python?
- Для чего используется функция id ()?
- Python – переопределить статический метод
Как и комментарий, вы всегда проверяете html, но только объявляете его в одном из конкретных случаев. То что сообщение говорит вам, вы ссылаетесь html перед назначать его. В python неверно проверять, является ли что-то None, если оно не было назначено никому. Например, откройте интерактивную подсказку python:
>>> if y is None: ... print 'none' ... Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'y' is not defined
Как вы можете видеть, вы не можете просто проверить, нет ли какой-либо переменной. Вернемся к вашему конкретному делу.
Сначала вам нужно установить html в None, а затем вы будете проверять, не осталось ли еще. т.е. отредактируйте свой код следующим образом:
def get_text(msg): text = "" if msg.is_multipart(): html = None for part in msg.get_payload(): if part.get_content_charset() is None: charset = chardet.detect(str(part))['encoding'] else: charset = part.get_content_charset() if part.get_content_type() == 'text/plain': text = unicode(part.get_payload(decode=True),str(charset),"ignore").encode('utf8','replace') if part.get_content_type() == 'text/html': html = unicode(part.get_payload(decode=True),str(charset),"ignore").encode('utf8','replace') if html is None: return text.strip() else: return html.strip() else: text = unicode(msg.get_payload(decode=True),msg.get_content_charset(),'ignore').encode('utf8','replace') return text.strip()
Это объясняет немного больше: http://code.activestate.com/recipes/59892-testing-if-a-variable-is-defined/
Вот тот же код с полезным предложением OlliM. Без этого изменения вы не сможете правильно разобрать контейнеры «multipart / alternative» в электронных письмах.
import chardet def get_text(msg): """ Parses email message text, given message object This doesn't support infinite recursive parts, but mail is usually not so naughty. """ text = "" if msg.is_multipart(): html = None for part in msg.get_payload(): if part.get_content_charset() is None: charset = chardet.detect(str(part))['encoding'] else: charset = part.get_content_charset() if part.get_content_type() == 'text/plain': text = unicode(part.get_payload(decode=True),str(charset),"ignore").encode('utf8','replace') if part.get_content_type() == 'text/html': html = unicode(part.get_payload(decode=True),str(charset),"ignore").encode('utf8','replace') if part.get_content_type() == 'multipart/alternative': for subpart in part.get_payload(): if subpart.get_content_charset() is None: charset = chardet.detect(str(subpart))['encoding'] else: charset = subpart.get_content_charset() if subpart.get_content_type() == 'text/plain': text = unicode(subpart.get_payload(decode=True),str(charset),"ignore").encode('utf8','replace') if subpart.get_content_type() == 'text/html': html = unicode(subpart.get_payload(decode=True),str(charset),"ignore").encode('utf8','replace') if html is None: return text.strip() else: return html.strip() else: text = unicode(msg.get_payload(decode=True),msg.get_content_charset(),'ignore').encode('utf8','replace') return text.strip()
Написание более элегантной структуры, которая не повторяет никакого кода, остается как упражнение для читателя.
Кроме того, ознакомьтесь с этой полезной схемой структуры контейнера .
- Питонический способ проверки выражения 0 в if?
- Развертывающая инфраструктура URL-адреса Django перестает работать
- Как установить точность без округления?
- передача логического состояния в качестве параметра
- Python Facebook SDK: объект 'module' не имеет атрибута 'GraphAPI'
- Нужна помощь для настройки Apache Server для запуска CGI-скрипта, написанного на Python
- Как подсчитать несколько уникальных вхождений уникальных вхождений в список Python?
- Новый объект в повторном StructuredProperty, хранящийся как _BaseValue
- Пара дополнительных аргументов
- Файл чтения Python, распознающий символ точки
- Почтовые строки в файле со списком и итерацией