Почему часть тела электронной почты не найдена Python imap?

avatar
whatgenius
8 августа 2021 в 19:13
43
1
0

Нашел статью о чтении электронной почты с помощью Python. Отправитель письма и тема найдены, но есть проблемы с телом письма - не найдено. Может быть, есть какие-то другие способы чтения тела?

import imaplib
import email
from email.header import decode_header
import webbrowser
import os

# account credentials
username = "username@mail.ru"
password = "password"


def clean(text):
    return "".join(c if c.isalnum() else "_" for c in text)


imap = imaplib.IMAP4_SSL("imap.mail.ru")
imap.login(username, password)
# it is spam folder id
status, messages = imap.select("&BCEEPwQwBDw-")
messages = int(messages[0])

for i in range(messages, 0, -1):
    res, msg = imap.fetch(str(i), "(RFC822)")
    for response in msg:
        if isinstance(response, tuple):
            msg = email.message_from_bytes(response[1])
            subject, encoding = decode_header(msg["Subject"])[0]
            if isinstance(subject, bytes):
                subject = subject.decode(encoding)
            From, encoding = decode_header(msg.get("From"))[0]
            if isinstance(From, bytes):
                From = From.decode(encoding)
            print("Subject:", subject)
            print("From:", From)
            if msg.is_multipart():
                for part in msg.walk():
                    # extract content type of email
                    content_type = part.get_content_type()
                    content_disposition = str(part.get("Content-Disposition"))
                    try:
                        body = part.get_payload(decode=True).decode()
                    except:
                        pass
                    if content_type == "text/plain" and "attachment" not in content_disposition:
                        print(body)
                    elif "attachment" in content_disposition:
                        filename = part.get_filename()
                        if filename:
                            folder_name = clean(subject)
                            if not os.path.isdir(folder_name):
                                os.mkdir(folder_name)
                            filepath = os.path.join(folder_name, filename)
                            open(filepath, "wb").write(part.get_payload(decode=True))
            else:
                content_type = msg.get_content_type()
                body = msg.get_payload(decode=True).decode()
                if content_type == "text/plain":
                    print(body)
            if content_type == "text/html":
                folder_name = clean(subject)
                if not os.path.isdir(folder_name):
                    os.mkdir(folder_name)
                filename = "index.html"
                filepath = os.path.join(folder_name, filename)
                open(filepath, "w").write(body)
                webbrowser.open(filepath)
imap.close()
imap.logout()

По какой-то причине тело не находится и из-за этого появляется ошибка.

NameError: name 'body' is not defined
Источник

Ответы (1)

avatar
MattDMo
8 августа 2021 в 19:23
0

body не определен из-за этого:

try:
    body = part.get_payload(decode=True).decode()
except:
    pass

Вы пытались определить тело, но потерпели неудачу из-за какой-то ошибки, которую вы разрешили пропустить молча (подсказка: не делайте этого!). Затем следующие блоки кода предполагали, что body уже было присвоено, когда это не было.

Решение: определить body outside раздела try/except:

body = None
try:
    body = part.get_payload(decode=True).decode()
except:
    # pass
    import traceback
    traceback.print_exception()
    # this way you'll at least know what the error was
whatgenius
8 августа 2021 в 19:52
0

О, действительно, я забыл об этом, спасибо. Но это не меняет вопроса. Каким-то образом тело None и исключение говорит: AttributeError: 'NoneType' object has no attribute 'decode'

MattDMo
8 августа 2021 в 19:54
0

@kfcgenius, не могли бы вы отредактировать свой вопрос и опубликовать полный текст ошибки и трассировки?