2011-09-06 25 views
17

Używam pythons imaplib do łączenia się z moim kontem Gmail. Chcę pobrać 15 najlepszych wiadomości (nieprzeczytanych lub przeczytanych, nie ma to znaczenia) i wyświetlić tylko tematy i nazwę nadawcy (lub adres), ale nie wiem, jak wyświetlić zawartość skrzynki odbiorczej.python imaplib, aby uzyskać skrzynki pocztowe w Gmailu, tytuły i nazwę nadawcy

Oto mój kod tak daleko (udane połączenie)

import imaplib 

mail = imaplib.IMAP4_SSL('imap.gmail.com') 
mail.login('[email protected]', 'somecrazypassword') 
mail.list() 
mail.select('inbox') 

#need to add some stuff in here 

mail.logout() 

Wierzę, że to powinno być na tyle proste, że jestem na tyle zaznajomiony z poleceniami dla biblioteki imaplib. Każda pomoc będzie mile widziane ...

musi

UPDATE dzięki Julian mogę iterację każdej wiadomości i pobrać całą zawartość z:

typ, data = mail.search(None, 'ALL') 
for num in data[0].split(): 
    typ, data = mail.fetch(num, '(RFC822)') 
    print 'Message %s\n%s\n' % (num, data[0][1]) 
mail.close() 

ale ja chce tylko przedmiot i nadawca. Czy istnieje polecenie imaplib dla tych elementów lub czy będę musiał przeanalizować całą zawartość danych [0] [1] dla tekstu: Temat i Nadawca?

UPDATE OK, dostał przedmiot i nadawcy część działa, ale iteracji (1, 15) jest wykonana na zlecenie malejąco najwyraźniej pokazuje mi najpierw najstarsze wiadomości. Jak mogę to zmienić? Próbowałem w ten sposób:

for i in range(len(data[0])-15, len(data[0])): 
    print data 

ale to właśnie daje mi None dla wszystkich 15 powtórzeń ... jakieś pomysły? Próbowałem zostały również mail.sort('REVERSE DATE', 'UTF-8', 'ALL') ale robi Gmail obsługuje funkcji .sort()

UPDATE wymyśliliśmy sposób, aby to zrobić:

#....^other code is the same as above except need to import email module 
mail.select('inbox') 
typ, data = mail.search(None, 'ALL') 
ids = data[0] 
id_list = ids.split() 
#get the most recent email id 
latest_email_id = int(id_list[-1]) 

#iterate through 15 messages in decending order starting with latest_email_id 
#the '-1' dictates reverse looping order 
for i in range(latest_email_id, latest_email_id-15, -1): 
    typ, data = mail.fetch(i, '(RFC822)') 

    for response_part in data: 
     if isinstance(response_part, tuple): 
      msg = email.message_from_string(response_part[1]) 
      varSubject = msg['subject'] 
      varFrom = msg['from'] 

    #remove the brackets around the sender email address 
    varFrom = varFrom.replace('<', '') 
    varFrom = varFrom.replace('>', '') 

    #add ellipsis (...) if subject length is greater than 35 characters 
    if len(varSubject) > 35: 
     varSubject = varSubject[0:32] + '...' 

    print '[' + varFrom.split()[-1] + '] ' + varSubject 

to daje mi ostatnią wiadomość 15 temat i nadawcę adres w porządku malejącym zgodnie z żądaniem! Dziękuję wszystkim, którzy pomogli!

+0

Przykład z docs Python działa dobrze dla mnie: http://docs.python.org/library/ imaplib # imap4-example – Julian

+0

Tak, masz rację, to działa bardzo dobrze, aby pobrać pełną treść wiadomości ze wszystkich wiadomości. Chcę tylko temat i adres nadawcy. Mogę wtedy utworzyć pętlę for od 1 do 15 – sadmicrowave

+0

I jeszcze jeden link do dokumentacji w Pythonie: http://docs.python.org/library/email.html;) – Julian

Odpowiedz

12
c.select('INBOX', readonly=True) 

    for i in range(1, 30): 
     typ, msg_data = c.fetch(str(i), '(RFC822)') 
     for response_part in msg_data: 
      if isinstance(response_part, tuple): 
       msg = email.message_from_string(response_part[1]) 
       for header in [ 'subject', 'to', 'from' ]: 
        print '%-8s: %s' % (header.upper(), msg[header]) 

To powinno dać ci pojęcie, jak odzyskać temat i od?

+2

co to jest e-mail?Czy odnosisz się do mojej zmiennej "mail"? a czym jest komunikat message_from_string()? Otrzymuję komunikat o błędzie z informacją "AttributeError" ("Nieznane polecenie IMAP4:"% s ""% attr) AttributeError: Nieznane polecenie IMAP4: "message_from_string'' – sadmicrowave

+2

nevermind, wymyśliłem to, nie uwzględniłem modułu e-mail. dzięki – sadmicrowave

+0

Dodano do mojego problemu OP, pomoc w tej części, a dam ci wygrać! – sadmicrowave

4

Dla tych, którzy szukają sposobu, by sprawdzić pocztę i analizowania nagłówków, to co kiedyś:

def parse_header(str_after, checkli_name, mailbox) : 
    #typ, data = m.search(None,'SENTON', str_after) 
    print mailbox 
    m.SELECT(mailbox) 
    date = (datetime.date.today() - datetime.timedelta(1)).strftime("%d-%b-%Y") 
    #date = (datetime.date.today().strftime("%d-%b-%Y")) 
    #date = "23-Jul-2012" 

    print date 
    result, data = m.uid('search', None, '(SENTON %s)' % date) 
    print data 

    doneli = [] 
    for latest_email_uid in data[0].split(): 
     print latest_email_uid 
     result, data = m.uid('fetch', latest_email_uid, '(RFC822)') 
     raw_email = data[0][1] 

     import email 
     email_message = email.message_from_string(raw_email) 
     print email_message['To'] 
     print email_message['Subject'] 
     print email.utils.parseaddr(email_message['From']) 
     print email_message.items() # print all headers 
+0

AttributeError: 'module' object nie ma atrybutu 'message_from_string'. Importuję e-maile, obiecuję. –

+1

@ChaseRoberts musisz użyć 'from email email email import '. Zakładam, że użyłeś 'import email ', co oznacza, że ​​próbujesz uzyskać dostęp do' message_from_string' na niewłaściwym poziomie. – blockloop

+0

Bwahaha, dziękuję bardzo. –

3

ja szukałem gotowego prostego skryptu do listy ostatnią skrzynkę odbiorczą poprzez IMAP bez sortowania przez wszystkich wiadomości . Informacje tutaj są użyteczne, choć majsterkowicz i brakuje niektórych aspektów. Po pierwsze, IMAP4.select zwraca liczbę wiadomości. Po drugie, dekodowanie nagłówka tematu nie jest proste.

#! /usr/bin/env python 
# -*- coding: utf-8 -*- 


import imaplib 
import email 
from email.header import decode_header 
import HTMLParser 


# to unescape xml entities 
_parser = HTMLParser.HTMLParser() 

def decodeHeader(value): 
    if value.startswith('"=?'): 
    value = value.replace('"', '') 

    value, encoding = decode_header(value)[0] 
    if encoding: 
    value = value.decode(encoding) 

    return _parser.unescape(value) 

def listLastInbox(top = 4): 
    mailbox = imaplib.IMAP4_SSL('imap.gmail.com') 
    mailbox.login('[email protected]', 'somecrazypassword') 

    selected = mailbox.select('INBOX') 
    assert selected[0] == 'OK' 
    messageCount = int(selected[1][0]) 

    for i in range(messageCount, messageCount - top, -1): 
    reponse = mailbox.fetch(str(i), '(RFC822)')[1] 
    for part in reponse: 
     if isinstance(part, tuple): 
     message = email.message_from_string(part[1]) 
     yield {h: decodeHeader(message[h]) for h in ('subject', 'from', 'date')} 

    mailbox.logout() 


if __name__ == '__main__': 
    for message in listLastInbox(): 
    print '-' * 40 
    for h, v in message.items(): 
     print u'{0:8s}: {1}'.format(h.upper(), v) 
2

To było moje rozwiązanie, aby uzyskać drobne informacje z e-maili:

import datetime 
import email 
import imaplib 
import mailbox 


EMAIL_ACCOUNT = "[email protected]" 
PASSWORD = "your password" 

mail = imaplib.IMAP4_SSL('imap.gmail.com') 
mail.login(EMAIL_ACCOUNT, PASSWORD) 
mail.list() 
mail.select('inbox') 
result, data = mail.uid('search', None, "UNSEEN") # (ALL/UNSEEN) 
i = len(data[0].split()) 

for x in range(i): 
    latest_email_uid = data[0].split()[x] 
    result, email_data = mail.uid('fetch', latest_email_uid, '(RFC822)') 
    # result, email_data = conn.store(num,'-FLAGS','\\Seen') 
    # this might work to set flag to seen, if it doesn't already 
    raw_email = email_data[0][1] 
    raw_email_string = raw_email.decode('utf-8') 
    email_message = email.message_from_string(raw_email_string) 

    # Header Details 
    date_tuple = email.utils.parsedate_tz(email_message['Date']) 
    if date_tuple: 
     local_date = datetime.datetime.fromtimestamp(email.utils.mktime_tz(date_tuple)) 
     local_message_date = "%s" %(str(local_date.strftime("%a, %d %b %Y %H:%M:%S"))) 
    email_from = str(email.header.make_header(email.header.decode_header(email_message['From']))) 
    email_to = str(email.header.make_header(email.header.decode_header(email_message['To']))) 
    subject = str(email.header.make_header(email.header.decode_header(email_message['Subject']))) 

    # Body details 
    for part in email_message.walk(): 
     if part.get_content_type() == "text/plain": 
      body = part.get_payload(decode=True) 
      file_name = "email_" + str(x) + ".txt" 
      output_file = open(file_name, 'w') 
      output_file.write("From: %s\nTo: %s\nDate: %s\nSubject: %s\n\nBody: \n\n%s" %(email_from, email_to,local_message_date, subject, body.decode('utf-8'))) 
      output_file.close() 
     else: 
      continue