【问题标题】:extracting email Received: headers with Python email package提取收到的电子邮件:带有 Python 电子邮件包的标头
【发布时间】:2019-02-19 10:10:06
【问题描述】:

我想从邮件中提取 Final Received: 电子邮件标题。我收到了从email.message_from_file() 返回的消息。

使用 Message.get()Message.get_item() 方法并不能保证我会得到许多 Received: 标头中的哪一个。 Message.get_all() 全部退货,但不保证订单。有没有办法保证能拿到最后一个?

【问题讨论】:

  • 为什么需要最终标题?标题的顺序肯定不重要吗?
  • @Will Received: 标头的顺序确实很重要,因为它指示消息通过处理它的各种服务器的顺序。最后一个表示消息(假定)源自的服务器。 (当然,它们可以伪造。)但是正如 hd1 在他的回复中指出的那样,它们也带有时间戳,所以我可以使用该信息。

标签: python email


【解决方案1】:

Received: 标头带有时间戳:

Received: from lb-ex1.int.icgroup.com (localhost [127.0.0.1])
by lb-ex1.localdomain (Postfix) with ESMTP id D6BDB1E26393
for <hd1@example.com>; Fri, 12 Dec 2014 12:09:24 -0500 (EST)

所以,按照你认为合适的方式执行messageInstance.get_all()sort 生成的列表,这是如何执行此操作的示例:

import email.utils
import operator
def sort_key(received_header):
    received_date = email.utils.parsedate_tz(received_header)
    return received_date

received_header_list.sort(key=sort_key)

如果它不起作用,请发表评论,我很乐意进一步研究。

【讨论】:

  • 谢谢,我真傻,忘了我可以使用时间戳。 :)
  • 但请记住,在现实世界中,并非所有服务器时钟都是准确的。我很确定标头的顺序比时间戳更可靠。
  • 另外,在现实世界中,许多服务器对Received 标头使用奇怪的格式,这些格式不能保证机器可读或有用。
【解决方案2】:

在 python 3.6.7 中,get_all() 方法上的 cmets 明确声明这些值的返回顺序与它们在消息中的顺序相同,因此 messageInstance.get_all('Received') 应该可以正常工作。

def get_all(self, name, failobj=None):
    """Return a list of all the values for the named field.

    These will be sorted in the order they appeared in the original
    message, and may contain duplicates.  Any fields deleted and
    re-inserted are always appended to the header list.

    If no such fields exist, failobj is returned (defaults to None).
    """

【讨论】:

    【解决方案3】:

    email.parserHeaderParser 实现了一个类似字典的接口,但实际上似乎以您期望的顺序返回标题。

    from email.parser import HeaderParser
    
    headers = HeaderParser().parse(open_filehandle, headersonly=True)
    for key, value in headers.items():
        if key == 'Received':
            ... do things with the value
    

    parse method 有一个姐妹parsestr method,它接受字节字符串而不是类似文件的对象。

    如果“final”是指“最新”,那将是第一个与if 匹配的,因此您可以在阅读后简单地break。如果“最终”是指其他内容,则可以在 if 中以任何您认为合适的方式实现它。

    本文改编自this answer to a related question

    【讨论】:

      猜你喜欢
      • 2020-11-23
      • 2012-01-15
      • 2021-09-15
      • 2019-02-06
      • 1970-01-01
      • 1970-01-01
      • 2019-01-09
      • 2016-12-07
      • 1970-01-01
      相关资源
      最近更新 更多