Python IMAP TypeError: объект «не тип» не может быть подписан - PullRequest
1 голос
/ 22 марта 2019

Я использую imap для проверки непрочитанных писем, которые соответствуют определенной теме. Когда я получаю электронное письмо от моего тестового электронного письма, оно работает нормально, но когда оно приходит от автоматической системы, от которой мне требуется проверить электронную почту, я получаю сообщение об ошибке, указывающее, что 'Nonetype' object is not subscriptable. Ниже приведен мой код:

import imaplib, time, email, mailbox, datetime
server = "imap.gmail.com"
port = 993
user = "Redacted"
password = "Redacted"

def main():
    while True:            
        conn = imaplib.IMAP4_SSL(server, port)
        conn.login(user, password)
        conn.list()
        conn.select('inbox', readonly=True)
        result, data = conn.search(None, '(UNSEEN SUBJECT "Alert: Storage Almost At Max Capacity")')
        i = len(data[0].split())

        for x in range (i):
            latest_email_uid = data[0].split()[x]
            result, email_data = conn.uid('fetch', latest_email_uid, '(RFC822)')
            raw_email = email_data[0][1] #This is where it throws the error
            raw_email_string = raw_email.decode('utf-8')
            email_message = email.message_from_string(raw_email_string)
            date_tuple = email.utils.parsedate_tz(email_message['Date'])
            local_date = datetime.datetime.fromtimestamp(email.utils.mktime_tz(date_tuple))
            local_message_date = "%s" %(str(local_date.strftime("%a, %d %b %Y %H:%M:%S")))
            for part in email_message.walk():
                if part.get_content_type() == "text/plain":
                    body = part.get_payload(decode=True)
                    body = body.decode('utf-8')
                    body = body.split()
                    #Do some stuff
        conn.close()

if __name__ == "__main__":
    main()

А вот обратная трассировка:

Traceback (most recent call last):
    File "TestEmail.py", line 200, in <module>
        main()
    File "TestEmail.py", line 168, in main
        raw_email = email_data[0][1]
TypeError: 'NoneType' object is not subscriptable.

Я не понимаю, почему это будет работать в электронном письме, отправленном с электронной почты человека, но не будет работать, когда моя система отправит мне уведомление по электронной почте. Есть ли какое-нибудь очевидное решение этого вопроса?

РЕДАКТИРОВАТЬ: я попытался напечатать переменные result и email. Следующим был их вывод:

Result: OK
Email: [None]

Принимая во внимание, что если я проверяю сценарий на электронное письмо с тем же предметом, но отправленное с моего тестового электронного письма, result все еще в порядке, но электронное письмо содержится.

РЕДАКТИРОВАТЬ # 2: Я заметил, что формат электронных писем немного отличается. Тот, кто получает штраф, - это и text/plain, и text/html, тогда как тот, который не принимается, - text/plain с Content-Transfer-Encoding: 7-bit. Как я могу исправить это? Если я пересылаю письмо через фильтр и проверяю почту, полученную от фильтра, мой код работает нормально. Однако я бы не хотел использовать для этого несколько писем.

1 Ответ

1 голос
/ 23 марта 2019

Вы ищете порядковые номера сообщений и извлекаете их с помощью uid.Если вы собираетесь использовать conn.uid('fetch'), вы также должны использовать conn.uid('search'), в противном случае вы ищете яблоки и собираете апельсины.

Таким образом, поскольку не все MSN являются UID, вы иногда получаете несуществующиесообщения, которые не являются ошибкой, но ничего не возвращают.

...