开发者

Parsing Message-ID header returned by imaplib

I'm fetching the messageid from emails in Gmail via IMAP.

This code:

开发者_StackOverflow社区
messageid = m.fetch(num, '(BODY[HEADER.FIELDS (MESSAGE-ID)])')
print messageid

returns this:

[('1 (BODY[HEADER.FIELDS (MESSAGE-ID)] {78}', 'Message-ID: <actualmessageid@mail.mail.gmail.com>\r\n\r\n'), ')']

How would I parse just the actual message-id out of that?


You can also achieve what you want using the email module's HeaderParser.parsestr() function (same API as Parser but doesn't worry about the email's body) and the parseaddr() function.

>>> from email.parser import HeaderParser
>>> from email.utils import parseaddr

>>> hp = HeaderParser()

>>> response = [('1 (BODY[HEADER.FIELDS (MESSAGE-ID)] {78}',
                 'Message-ID: <actualmessageid@mail.mail.gmail.com>\r\n\r\n'), ')']

>>> header_string = response[0][1]

>>> header_string
'Message-ID: <actualmessageid@mail.mail.gmail.com>\r\n\r\n'

>>> header = hp.parsestr(header_string)

>>> header
<email.message.Message instance at 0x023A6198>

>>> header['message-id']
'<actualmessageid@mail.mail.gmail.com>'

>>> msg_id = parseaddr(header['message-id'])

>>> msg_id
('', 'actualmessageid@mail.mail.gmail.com')

>>> msg_id[1]
'actualmessageid@mail.mail.gmail.com'

Thus:

from email.parser import HeaderParser
from email.utils import parseaddr

hp = HeaderParser()

def get_id(response):
    header_string = response[0][1]
    header = hp.parsestr(header_string)
    return parseaddr(header['message-id'])[1]

response = [('1 (BODY[HEADER.FIELDS (MESSAGE-ID)] {78}',
             'Message-ID: <actualmessageid@mail.mail.gmail.com>\r\n\r\n'), ')']


print(get_id(response))

returns:

actualmessageid@mail.mail.gmail.com


From RFC 1036, 822:

In order to conform to RFC-822, the Message-ID must have the format: <unique@full_domain_name>

So the actual message ID would be between < and > The domain part is part of the ID.

I'd probably strip the string, then split on the < character, verify it ends with > and then cut that off.

I can't really work out a good solution with your data (is there a typo in it at the end?), but if it looks like the following I'd parse it something like this

 # Note: my list does not end with , ")"]
 messageparts = [('1 (BODY[HEADER.FIELDS (MESSAGE-ID)] {78}', 
                  'Message-ID: <actualmessageid@mail.mail.gmail.com>\r\n\r\n')]

 for envelope, data in messageparts:
        # data: the part with Message-ID in it
        # data.strip(): Newlines removed
        # .split("<"): Break in 2 parts, left of < and right of <. Removes <
        # .rstrip(">") remove > from the end of the line until there is 
        # no > there anymore;
        # "x>>>".rstrip() -> "x"
        print "The message ID is: ", data.strip().split("<")[1].rstrip(">")

    # Short alternative version:
    messageids = [data.strip().split("<")[1].rstrip(">") \
                  for env,data in messageparts]
    print messageids

Output:

The message ID is:  actualmessageid@mail.mail.gmail.com
['actualmessageid@mail.mail.gmail.com']

I splitted some lines using '\' to make it a bit more readable here, and the code assumes the headers are all valid.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜