How do I print multiple email bodies with python imap?

后端 未结 2 765
梦谈多话
梦谈多话 2021-01-25 11:43

I\'m very new at coding and this is my first real attempt to do anything like this. I want to print out multiple email bodies, that are at least two weeks old. (later on in

相关标签:
2条回答
  • 2021-01-25 12:20

    I think your problem is here:

    for i in range(latest_email_uid, latest_email_uid-5, -1):
        result, data = mail.uid('fetch', i, '(RFC822)')
    raw_email = data[0][1]
    

    After the loop, data only contains the last email you iterate over. Instead, get a list of emails:

    raw_emails = []
    for i in range(latest_email_uid, latest_email_uid-5, -1):
        result, data = mail.uid('fetch', i, '(RFC822)')
        raw_emails.append(data[0][1])
    

    You can now iterate over those:

    for raw_email in raw_emails:
        email_message = email.message_from_string(raw_email)
        ...
    

    (Note: you should follow PEP-0008 and put all import statements at the top - it makes it easier to read and understand the code, particularly as it grows.)


    Edit:

    Your revision only prints once because you print after the for loop runs, not for each iteration. Indentation is important:

    for raw_email in raw_emails:
        email_message = email.message_from_string(raw_email)
        print email_message.get_payload(decode=True) # note indentation
    
    0 讨论(0)
  • 2021-01-25 12:28

    @jonrsharpe pointed out already the indentation error in your code.

    Here's Python 3 script that you could adapt for Python 2 that prints emails from a given time period:

    #!/usr/bin/env python3
    """Print emails from a given date interval.
    
    Usage:
    
        $ %(prog)s <since_date> <before_date>
    
    since_date < before_date
    
    Date format: DD-Mon-YYYY e.g., 3-Mar-2014
    
    Based on http://pymotw.com/2/imaplib/
    """
    import email
    import sys
    from datetime import datetime
    from imaplib import IMAP4_SSL
    
    import imaplib; imaplib.Debug = True
    
    def decode_header(header_string):
        try:
            decoded_seq = email.header.decode_header(header_string)
            return str(email.header.make_header(decoded_seq))
        except Exception: # fallback: return as is
            return header_string
    
    def get_text(msg, fallback_encoding='utf-8', errors='replace'):
        """Extract plain text from email."""
        text = []
        for part in msg.walk():
            if part.get_content_type() == 'text/plain':
                p = part.get_payload(decode=True)
                if p is not None:
                    text.append(p.decode(part.get_charset() or fallback_encoding,
                                         errors))
        return "\n".join(text)
    
    
    # define since/before dates
    date_format = "%d-%b-%Y" # DD-Mon-YYYY e.g., 3-Mar-2014
    since_date = datetime.strptime(sys.argv[1], date_format)
    before_date = datetime.strptime(sys.argv[2], date_format)
    
    imap_host, imap_port = "imap.gmail.com", 993
    login, password = 'user@gmail.com', 'password'
    
    # connect to the imap server
    mail = IMAP4_SSL(imap_host, imap_port)
    mail.login(login, password)
    try:
        mail.select('INBOX', readonly=True)
    
        # get all messages since since_date and before before_date
        typ, [msg_ids] = mail.search(None,
            '(since "%s" before "%s")' % (since_date.strftime(date_format),
                                          before_date.strftime(date_format)))
    
        # get complete email messages in RFC822 format
        for num in msg_ids.split():
            typ, msg_data = mail.fetch(num, '(RFC822)')
            for response_part in msg_data:
                if isinstance(response_part, tuple):
                    msg = email.message_from_bytes(response_part[1])
                    for header in [ 'subject', 'to', 'from', 'date' ]:
                        print('%-8s: %s' % (
                            header.upper(), decode_header(msg[header])))
                    print(get_text(msg))
    finally:
        try:
            mail.close()
        finally:
            mail.logout()
    

    See imap-fetch-email-before-date.py.

    0 讨论(0)
提交回复
热议问题