首先,您可能希望使用 stdlib 的email
包来解析消息。
我不确定您是如何获取消息的——stdlibimaplib
或 gmail API 之类的东西为您提供了一种将标头与正文分开获取的方法,但其他方法可能会为您提供整个消息。无论哪种方式,您都可以将整个内容传递email.parser.HeaderParser
给解析标题并忽略其他任何内容:
>>> from email.parser import HeaderParser
>>> msg = HeaderParser().parsestr(header) # or parsestr(msg) if you have the whole msg
>>> return_path = msg.get('Return-Path')
现在,return_path
是字符串"<bob@example2.com>"
,您可以将其解析为电子邮件地址(或者None
,如果没有)。
>>> from email.utils import parseaddr
>>> realname, emailaddr = parseaddr(return_path)
现在,realname
是""
,emailaddr
是'bob@example2.com'
。
之所以有两部分,是因为这也是完全有效的:
Return-Path: "Bob Example" <bob@example.com>
现在,这可能不太正确。你可以有两个Return-Path
标题吗?或者Return-Path
标题可以包含多个地址吗?我不记得了。我可以在相关的 RFC 中查找它,但随后我还必须进行一些搜索,以确定是否有任何受欢迎的客户端违反了这些特定规则。我不记得这一切了。所以,为了方便起见,我通常假设任何东西都可以是多头和多值,并以这种方式做事:
>>> return_paths = msg.get_all('Return-Path')
这将返回list
["<bob@example2.com>"]
. (如果没有Return-Path
标题,你会得到一个空list
的,而不是None
,这样。)你可以一次解析所有的,得到一个list
名称,地址对而不是一个:
>>> from email.utils import getaddresses
>>> for realname, emailaddr in getaddresses(returnpaths):
... print(realname, emailaddr)
如果事实证明 Return-Path 只允许单个值,则相同的代码将按原样工作。