【问题标题】:Email body is a string sometimes and a list sometimes. Why?电子邮件正文有时是一个字符串,有时是一个列表。为什么?
【发布时间】:2010-10-10 07:43:07
【问题描述】:

我的应用程序是用 python 编写的。我正在做的是我在 postfix 收到的每封电子邮件上运行一个脚本,并对电子邮件内容做一些事情。 Procmail 负责运行以电子邮件为输入的脚本。当我将输入消息(可能是文本)转换为 email_message 对象(因为后者派上用场)时,问题就开始了。我正在使用 email.message_from_string (其中 email 是默认的电子邮件模块,带有 python)。

import email message = email.message_from_string(original_mail_content) message_body = message.get_payload()

这个 message_body 有时会返回一个列表[email.message.Message instance,email.message.Message instance],有时会返回一个字符串(传入电子邮件的实际正文内容)。为什么。甚至我还发现了另一个观察结果。当我浏览 email.message.Message.get_payload() 文档字符串时,我发现了这个..
""" 有效负载将是一个列表对象或一个字符串。如果你改变 列表对象,您就地修改消息的有效负载....."""

那么我如何使用通用方法通过 python 获取电子邮件正文?请帮帮我。

【问题讨论】:

    标签: python email message payload


    【解决方案1】:

    嗯,答案是正确的,您应该阅读文档,但是对于通用方式的示例:

    def get_first_text_part(msg):
        maintype = msg.get_content_maintype()
        if maintype == 'multipart':
            for part in msg.get_payload():
                if part.get_content_maintype() == 'text':
                    return part.get_payload()
        elif maintype == 'text':
            return msg.get_payload()
    

    这很容易造成一些灾难,因为可以想象这些部分本身可能有多个部分,并且它实际上只返回第一个文本部分,所以这也可能是错误的,但你可以玩它。

    【讨论】:

    • 在我谈到的消息列表中,我尝试在每个对象上运行 get_payload()。两者都返回相同的东西。一种对象是另一种对象的克隆,所以如果我在一个部分上调用 get_payload 就可以了???
    • 取决于您收到的内容。例如,您可能通常会获得同一事物的 text/html 和 text/plain 版本。您可以修改函数以查找和喜欢文本/纯内容类型而不是其他文本/类型。
    • 还要注意消息没有“正确”的结构。不同的邮件客户端会有不同的结构,以及设置不同的标题。
    • 忽略某些消息是 HTML 的事实 - 您需要一个 HTML 反解析器才能使用 所有 可能的文本子类型。
    【解决方案2】:

    虽然看起来很疯狂,但有时字符串有时是列表语义的原因是given in the documentation。基本上,多部分消息作为列表返回。

    【讨论】:

      【解决方案3】:

      不是简单地寻找一个子部分,而是使用 walk() 来遍历消息内容

      def walkMsg(msg):
        for part in msg.walk():
          if part.get_content_type() == "multipart/alternative":
            continue
          yield part.get_payload(decode=1)
      

      walk() 方法返回一个可以循环使用的迭代器(即它是一个生成器)。如果消息不是部分容器(即没有附件或替代项),则 walk() 方法将返回一个带有单个元素的迭代器 - 消息本身。

      您想跳过任何“多部分”部分,因为它们只是胶水。

      上述方法返回所有可读部分。如果文本部分包含您正在寻找的信息,您可能希望将其扩展为仅返回文本部分。

      请注意,从 Python 2.5 开始,方法 get_type()、get_main_type() 和 get_subtype() 已被删除 -> http://docs.python.org/library/email.message.html#email.message.Message.walk

      【讨论】:

      • 这是一个比 OP 接受的答案更好的答案,恕我直言。
      • 我认为if语句中的单个'='应该是'=='
      【解决方案4】:
      猜你喜欢
      • 2018-03-23
      • 2012-01-23
      • 1970-01-01
      • 2022-11-15
      • 2018-03-04
      • 1970-01-01
      • 2017-04-05
      • 1970-01-01
      • 2012-04-01
      相关资源
      最近更新 更多