Сообщение Python 'у объекта нет атрибута' get_body - PullRequest
0 голосов
/ 15 января 2019

Я пытаюсь найти тело письма, но сталкиваюсь с некоторыми проблемами:

 #!/usr/local/bin/python3
from email.message import EmailMessage
import email
import imaplib
import re
import sys
import logging
import base64
import os
logging.basicConfig(stream=sys.stdout, level=logging.INFO)

###########log in to mailbox########################
user = 'email@company.com'
pwd = 'pwd'

conn = imaplib.IMAP4_SSL("outlook.office365.com")
conn.login(user,pwd)
conn.select("test")
count = conn.select("test")

resp, items = conn.uid("search" ,None, '(OR (FROM "some@email) (FROM "some@email"))')

items = items[0].split()
for emailid in items:
    resp, data = conn.uid("fetch",emailid, "(RFC822)")
    if resp == 'OK':
        email_body = data[0][1]#.decode('utf-8')
        mail = email.message_from_bytes(email_body)

        #get all emails with words "PA1" or "PA2" in subject
        if mail["Subject"].find("PA1") > 0 or mail["Subject"].find("PA2") > 0:
           print (mail)

У меня есть проблемы в следующей строке:

body = mail.get_body(preferencelist=('plain', 'html'))

Получение:

AttributeError: у объекта 'Message' нет атрибута 'get_body'

Ответы [ 2 ]

0 голосов
/ 15 января 2019

Не следует преобразовывать структуру MIME в строку, а затем передавать ее в message_from_string. Вместо этого сохраните его как bytes объект.

...
items = items[0].split()
for emailid in items:
    resp, data = conn.uid("fetch",emailid, "(RFC822)")
    if resp == 'OK':
        email_blob = data[0][1]
        mail = email.message_from_bytes(email_blob)
        if not any(x in mail['subject'] for x in ('PA1', 'PA2')):
            continue

Вы не показываете, как вы проходите через структуру MIME, поэтому я полагаю, что вы в настоящее время вообще этого не делаете. Возможно, вы хотите что-то вроде

        # continuation for the above code
        body = mail.get_body(preferencelist=('plain', 'html'))
        for lines in body.split('\n'):
            if line.startswith('MACHINE:'):
                result = line[8:].strip()
                break

Похоже, у вас есть часть тела письма, закодированная с использованием Content-Transfer-Encoding: quoted-printable. Вышеприведенный код устойчив к различным кодировкам, потому что библиотека email прозрачно декодирует инкапсуляцию для вас, что избавляет от любых разрывов строк, экранированных QP, как в вашем вопросе. Для справки, quoted-printable может разбить длинную строку в любом месте, в том числе в середине значения, которое вы пытаетесь извлечь, так что вы действительно хотите расшифровать перед попыткой извлечь что-либо.

0 голосов
/ 15 января 2019

Если для вас приемлемо сначала удалить все разрывы строк =^M\n из текста, тогда это довольно просто:

import re

email_body = open("1.txt").read().replace("=^M\n", "")

matches = re.findall(r"(?<=MACHINE:)\s*(\w+)", email_body)

print(matches)
print(list(set(matches)))

Выход:

['p1prog07', 'p2prog06', 'p2prog06', 'p1prog07', 'ldnv260']
['p2prog06', 'ldnv260', 'p1prog07']

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

...