Python消息”对象没有属性“ get_body”

时间:2019-01-15 08:55:52

标签: python imaplib

我正在尝试搜索电子邮件正文,但遇到一些问题:

 #!/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:“消息”对象没有属性“ get_body”

3 个答案:

答案 0 :(得分:1)

如果您可以首先从文本中删除所有换行符=^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']

正向后方是一个非捕获组,因此正则表达式中唯一被捕获的组是您想要的字符串。

答案 1 :(得分:1)

您不应将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可能会折断长行,包括在您尝试提取的值中间,因此您确实想在尝试提取任何内容之前先进行解码。

答案 2 :(得分:1)

要解决此消息:

AttributeError:“消息”对象没有属性“ get_body”

在创建Message对象时,您需要指定一个策略,或者获取默认的email.policy.Compat32策略。 get_body()和其他一些方法在Python 3.2中不存在。

创建邮件对象的行应为:

mail = email.message_from_bytes(data, policy=email.policy.default)

更多信息,位于:

https://docs.python.org/3/library/email.policy.html