Форум русскоязычного сообщества Ubuntu


Получить помощь и пообщаться с другими пользователями Ubuntu можно
на irc канале #ubuntu-ru в сети Freenode
и в Jabber конференции ubuntu@conference.jabber.ru

Автор Тема: разбор письма в Python  (Прочитано 2478 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн azathoth

  • Автор темы
  • Новичок
  • *
  • Сообщений: 4
    • Просмотр профиля
разбор письма в Python
« : 14 Января 2014, 12:43:50 »
Добрый день,

Возникла проблема в разборе письма, а точнее при переводе текста из Quoted-Printable в UTF-8, я разобрался как декодировать что-то из заголовка письма:
>>> import email
>>> input = open('2.msg','r')
>>> msg = email.message_from_file(input)
>>> email.Header.decode_header(msg['Subject'])

но при попытке декодировать тело письма, интерпретатор выдает ошибку:

>>> email.utils.decode_rfc2231(msg.get_payload(0))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/email/utils.py", line 236, in decode_rfc2231
    parts = s.split(TICK, 2)
AttributeError: Message instance has no attribute 'split'

Помогите, пожалуйста, разобраться в чем моя ошибка.

PS:
Я бы хотел добавить, что сейчас реализовал желаемое вот таким скриптом:
#!/usr/bin/python
# -*- coding: utf-8 -*-

import quopri

text=''

with open('2.msg','r') as input_file:
    for line in input_file.readlines():
        a = line.rstrip('=\n\r')
        text += a

with open('2.msg.decode','w') as output_file:
    output_file.write(quopri.decodestring(text))

Но мне бы очень хотелось понять мою ошибку при использовании модуля email
« Последнее редактирование: 14 Января 2014, 14:17:03 от azathoth »

Оффлайн Grigory Smirnov

  • Старожил
  • *
  • Сообщений: 1339
  • Дайте мне исходники, и я переверну Землю.
    • Просмотр профиля
    • Дафтер
Re: разбор письма в Python
« Ответ #1 : 14 Января 2014, 19:02:58 »
Цитировать
AttributeError: Message instance has no attribute 'split'
Нет такого атрибута.

Оффлайн RingOV

  • Активист
  • *
  • Сообщений: 764
    • Просмотр профиля
Re: разбор письма в Python
« Ответ #2 : 15 Января 2014, 12:46:22 »
azathoth,
Посмотреть бы вывод msg.get_payload(0), после загрузки в переменную msg

Пользователь решил продолжить мысль 15 Января 2014, 12:51:33:
Возможно в этом проблема
get_payload([i[, decode]])
...
If the payload is a string (i.e. is_multipart() is False) and i is given, a TypeError is raised
« Последнее редактирование: 15 Января 2014, 12:53:16 от RingOV »

Оффлайн Jack Sparrow

  • Активист
  • *
  • Сообщений: 630
    • Просмотр профиля
Re: разбор письма в Python
« Ответ #3 : 15 Января 2014, 22:53:44 »
Модуль специфичный, не все им пользуются. Но тут уже указали, что ошибка с атрибутом:
Код: (Python) [Выделить]
parts = s.split(TICK, 2)
AttributeError: Message instance has no attribute 'split'

"Message instance" означает, что объект s является экземпляром класса Message. А у этого класса нет такого метода или, по-питоновски, атрибута, как split. Он есть у класса String. Убедитесь, что ваш s это действительно класс String, а не Message. Попробуйте где-нибудь до этого проблемного когда вывести что-то типа:
Код: (Python) [Выделить]
type(s)
Linux is only free if your time has no value (c) Jamie Zawinski

Оффлайн RingOV

  • Активист
  • *
  • Сообщений: 764
    • Просмотр профиля
Re: разбор письма в Python
« Ответ #4 : 16 Января 2014, 18:38:38 »
Убедитесь, что ваш s это действительно класс String, а не Message. Попробуйте где-нибудь до этого проблемного когда вывести что-то типа:
Код: (Python) [Выделить]
type(s)
Ну и как вы себе это представляете? Если s - это временная переменная доступная внутри модуля /usr/lib/python2.7/email/utils.py
(Нажмите, чтобы показать/скрыть)
Как я понял из документации: если сообщение не multipart, то аргумент при получении тела не нужен.
Т.е.
Код: (Python) [Выделить]
# Заменить
#email.utils.decode_rfc2231(msg.get_payload(0))
# на
email.utils.decode_rfc2231(msg.get_payload())

Оффлайн Jack Sparrow

  • Активист
  • *
  • Сообщений: 630
    • Просмотр профиля
Re: разбор письма в Python
« Ответ #5 : 17 Января 2014, 22:48:51 »
Функции decode_rfc2231 требуется строка в качестве аргумента, а ваше msg.get_payload() возвращает тип Message (что-то вроде списка). Отсюда и ошибка.
Попробуйте так (я взял произвольное письмо, и у меня получилось):
 
Код: (Python) [Выделить]
msg.get_payload()[0].get_payload()Два раза нужно потому, что если попробовать
Код: (Python) [Выделить]
msg.is_multipart()
True
т.е. здесь msg это список объектов типа Message. Поэтому первый get_payload извлекает первый элемент (в моем случае это был объект Message с текстом письма), а второй get_payload извлекает из этого объекта уже сам текст письма. Кстати, если вместо 0 поставить 1, то из письма извлечется не текст, а вложение (по крайней мере, в моем письме было так). Как-то так.
Linux is only free if your time has no value (c) Jamie Zawinski

Оффлайн RingOV

  • Активист
  • *
  • Сообщений: 764
    • Просмотр профиля
Re: разбор письма в Python
« Ответ #6 : 17 Января 2014, 23:25:26 »
Jack Sparrow,
Да, судя по всему у ТС msg.is_multipart(). Я словил такую же ошибку.
В этом случае действительно работает вариант
Код: (Python) [Выделить]
msg.get_payload()[0].get_payload()Или можно так
Код: (Python) [Выделить]
msg.get_payload(0).get_payload()Подтверждаю, что следующие элементы списка это вложения

А вот чтобы is_multipart false такого письма не нашел. Хотелось проверить вернет ли get_payload() сразу строку.

Оффлайн Jack Sparrow

  • Активист
  • *
  • Сообщений: 630
    • Просмотр профиля
Re: разбор письма в Python
« Ответ #7 : 18 Января 2014, 00:20:26 »
Чтобы is_multipart возвращал False нужно, чтобы письмо было составлено в виде простого текста (не HTML).
Linux is only free if your time has no value (c) Jamie Zawinski

 

Страница сгенерирована за 0.066 секунд. Запросов: 25.