Уведомления

Группа в Telegram: @pythonsu

#1 Июнь 12, 2014 12:36:35

Snuff4uk
Зарегистрирован: 2014-06-12
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с кодировками poplib

Добрый день. Пытаюсь считать почту с pop.mail.ru через poplib:

 
# -*- coding: utf-8 -*-
import email, poplib
import quopri

server = "pop.mail.ru"
port = "995"
user = "user"
pasw= "pass"

mServer = poplib.POP3_SSL(server,port)
mServer.user(user)
mServer.pass_(pasw)

#Get the number of mail messages
numMessages = len(mServer.list()[1])

print ("You have %d messages." % (numMessages))
print ("Message List:")

#List the subject line of each message

messages = []
for mList in range(numMessages) :
for msg in mServer.retr(mList+1)[1]:
if msg.startswith(b'Subject'):
# msg=str(msg)
msg=email.message_from_bytes(msg)
# msg=quopri.decodestring(msg.encode('utf-8')).decode('utf-8')
messages.append(msg)
break

mServer.quit()

for i in messages:
print (i)
Как правильно декодировать результат? Данная тема уже была, но её решения не работают для питона 3.4.
И, если можно, скажите, как считать только непрочитанные сообщения и их авторов?
Спасибо.

Офлайн

#2 Июнь 12, 2014 22:30:05

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10022
Репутация: +  857  -
Профиль   Отправить e-mail  

Проблема с кодировками poplib

Заголовки раскодируются через email.header.decode_header().
Кодировка берётся из сообщения через msg.get_charsets().

Там много нюансов, они бывают повреждены и так далее, поэтому нужно сделать умный обработчик (и расширяемый), который всё это учитывает.

Это из своей программы. Чисто обработчик заголовков.

class HeadersHandler:
    def __init__(self, headers, select):
        #дано    : заголовки и список заголовков для выбора
        #получить: заголовки и список заголовков для выбора
        #          сохранёны;
        #          создано сообщение из заголовков, получена
        #          кодировка сообщения, и сохранены
        self._headers = headers
        self._select = select
        self._msg = email.message_from_bytes(
            b'\n'.join(self._headers)
        )
        self._charset = self._msg.get_charsets()[0]
 
    def start(self):
        #дано    :
        #получить:
        pass
 
    def filter(self):
        #дано    : сообщение и список заголовков для выбора
        #получить: ответ = список выбранных раскодированных
        #          заголовков
        return tuple(self._decode_header(self._msg.get(header))
                     for header in self._select)
 
    def _decode_header(self, header):
        #дано    : заголовок и кодировка сообщения
        #получить: ответ = раскодированный заголовок
        #          (если раскодирование невозможно,
        #          ответ = первоначальный заголовок)
        res = ''
        for i in email.header.decode_header(header):
            if i[1]:
                if i[1] != 'unknown-8bit':
                    s = i[0].decode(i[1])
                else:
                    s = i[0].decode(self._charset)
            else:
                try:
                    s = i[0].decode('latin1')
                except AttributeError:
                    s = i[0]
            res += s
        return res
 
    def end(self):
        #дано    :
        #получить:
        pass



Отредактировано py.user.next (Июнь 12, 2014 22:33:08)

Офлайн

#3 Июнь 14, 2014 22:30:05

Snuff4uk
Зарегистрирован: 2014-06-12
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с кодировками poplib

py.user.next
Заголовки раскодируются через email.header.decode_header().Кодировка берётся из сообщения через msg.get_charsets()
А как быть, если я буду считывать через pop3.top() а не через retr. Питон говорит что это уже не заголовки.

Офлайн

#4 Июнь 14, 2014 23:28:36

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10022
Репутация: +  857  -
Профиль   Отправить e-mail  

Проблема с кодировками poplib

Snuff4uk
А как быть, если я буду считывать через pop3.top() а не через retr.
Точно так же.

Snuff4uk
Питон говорит что это уже не заголовки.
Значит, что-то не то делаешь.

Проверил с
conn.top(n, 0)
получаются те же заголовки из которых всё достаётся.



Офлайн

#5 Июнь 15, 2014 19:45:41

Snuff4uk
Зарегистрирован: 2014-06-12
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с кодировками poplib

py.user.next
Точно так же.
Пробую
For i in range(numMessages):
for msg in mServer.top(i+1,0)[1]:
enc=msg.get_charsets()
Пишет ‘bytes’ object has no attribute ‘get_charsets’

Отредактировано Snuff4uk (Июнь 15, 2014 19:46:09)

Офлайн

#6 Июнь 15, 2014 21:31:30

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10022
Репутация: +  857  -
Профиль   Отправить e-mail  

Проблема с кодировками poplib

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



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version