【问题标题】:Python parse a raw email and get the text content of the bodyPython解析原始电子邮件并获取正文的文本内容
【发布时间】:2017-09-21 04:58:17
【问题描述】:

如何获取不带 html 标记的电子邮件正文。

我尝试了下面的代码来解析邮件,但我得到了整个部分 '--------=_Part_2' 部分作为正文。

我的代码

import email
message = email.message_from_string(text)
print_payload(message)

def print_payload(message):
    print('******')
    if message.is_multipart():
        for payload in message.get_payload():
            print_payload(payload)
    else:
        print message.get_payload()
        for part in message.walk():
            if part.get_content_type():
                body = str(part.get_payload())
                print(body)
    print('******')

实际电子邮件正文:

另一封测试邮件。
谢谢,
穆内什

原始电子邮件:

Return-Path: abc@mydomain.com Date: Mon, 18 Sep 2017 23:07:16 +0000 From: abc@mydomain.com To: xyz@mydomain.com Cc: abc@mydomain.com Message-ID: <1233.5.68566565@host.corp.mydomain.com> Subject: My email subject MIME-Version: 1.0 Content-Type: application/ms-tnef Content-Transfer-Encoding: binary X-MS-Exchange-Organization-SCL: -1 X-MS-Exchange-Organization-MessageDirectionality: Originating Thread-Topic: My email subject X-Forefront-Antispam-Report: SFV:SKI;SCL:-1; X-MS-PublicTrafficType: Email X-MS-Exchange-Organization-Antispam-Report: SFV:SKI;SCL:-1; Accept-Language: en-US Content-Language: en-US

------=_Part_2_123.456 Content-Type: text/html; charset=us-ascii Content-Transfer-Encoding: 7bit

<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="Generator" content="Microsoft Word 14 (filtered medium)"><style><!-- /* Font Definitions */ @font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri","sans-serif";} a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;} a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;} span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri","sans-serif";
        color:windowtext;} .MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri","sans-serif";} @page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;} div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml><o:shapedefaults v:ext="edit" spidmax="1026" /></xml><![endif]--><!--[if gte mso 9]><xml><o:shapelayout v:ext="edit"><o:idmap v:ext="edit" data="1" /></o:shapelayout></xml><![endif]--></head><body lang="EN-US" link="blue" vlink="purple"><div class="WordSection1"><p class="MsoNormal">Another test mail.<o:p></o:p></p><p class="MsoNormal"><o:p>&nbsp;</o:p></p><p class="MsoNormal">Thanks,<o:p></o:p></p><p class="MsoNormal">Munesh<o:p></o:p></p><p class="MsoNormal"><o:p>&nbsp;</o:p></p></div></body></html>

------=_Part_2_123.456--

提前致谢。

【问题讨论】:

    标签: python email parsing


    【解决方案1】:

    使用 BeautifulSoup 库,解析文本其实并不难。如果您没有图书馆,请确保您首先pip install bs4。之后,应该不会太难:

    from bs4 import BeautifulSoup
    def print_payload(message):
        print('******')
        if message.is_multipart():
            for payload in message.get_payload():
                print_payload(payload)
        else:
             print message.get_payload()
             for part in message.walk():
                 if part.get_content_type():
                     body = str(part.get_payload())
                     soup = BeautifulSoup(body)
                     paragraphs = soup.find_all('p')
                     for paragraph in paragraphs:
                         print(paragraph.text)
        print('******')
    

    BeautifulSoup 雄辩地做的是创建一个解析树,从中可以选择 html 元素。因此,如果您的电子邮件中包含其他 html 元素,您可能还必须搜索它们以获取所有数据。但是对于这封简单的电子邮件,找到所有带有标签 'p' 的 html 元素就足够了。

    【讨论】:

    • 感谢您的解决方案。但它正在部分工作。当我搜索标签“p”时,html 之外的初始文本(如 Part_2 和 Content-Type)也会被打印出来。你能指导我如何获取邮件正文
    • 嗯,我不确定为什么会这样。如果你跳过第一段怎么办?即:for paragraph in paragraphs[1:]
    • paragraphs[1:] 有效。但这看起来更像是一个黑客而不是一个适当的修复。不管怎么说,还是要谢谢你。如果您找到更好的方法,请告诉我。
    • 我承认是这样,但 HTML 是出了名的难以解析。您可能还可以使用正则表达式来检查 xml 代码并排除任何看起来像 xml 的内容,但这看起来也有点乱。
    • 我使用 text=True 来过滤不需要的数据,使用 paragraphs_all = soup.find_all('p',text=False), paragraphs_extra = soup.find_all('p',text=True ),paragraphs=set(paragraphs_all)-set(paragraphs_extra)
    猜你喜欢
    • 2017-10-08
    • 2012-01-09
    • 2013-07-26
    • 1970-01-01
    • 2013-08-18
    • 2023-04-06
    • 2018-12-01
    • 2020-07-20
    • 2016-06-22
    相关资源
    最近更新 更多