2011-09-06 20 views
17

Sto usando pythons imaplib per connettermi al mio account gmail. Voglio recuperare i primi 15 messaggi (da leggere o leggere, non importa) e visualizzare solo i soggetti e il nome del mittente (o indirizzo) ma non so come visualizzare il contenuto della casella di posta.python imaplib per ottenere posta in arrivo gmail titoli titoli e nome mittente

Ecco il mio codice finora (connessione riuscita)

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() 

credo che questo dovrebbe essere abbastanza semplice, mi basta che non hanno familiarità con i comandi per la libreria imaplib. Qualsiasi aiuto sarebbe apprezzato ... deve

UPDATE grazie a Julian posso scorrere ogni messaggio e recuperare l'intero contenuto con:

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() 

ma sto volendo solo il soggetto e il mittente. Esiste un comando imaplib per questi elementi o dovrò analizzare l'intero contenuto dei dati [0] [1] per il testo: Subject e Sender?

UPDATE OK, ha ottenuto la parte oggetto e il mittente di lavoro, ma l'iterazione (1, 15) è fatto per ordine decrescente a quanto pare mi mostra i messaggi meno recenti. Come posso cambiare questo? Ho provato a fare questo:

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

ma che semplicemente mi dà None per tutti i 15 iterazioni ... tutte le idee? Ho anche provato mail.sort('REVERSE DATE', 'UTF-8', 'ALL') ma pretende molto gmail supporta la funzione .Sort()

UPDATE trovato un modo per farlo:

#....^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 

questo mi dà la più recente soggetto 15 messaggio e mittente indirizzo in ordine decrescente come richiesto! Grazie a tutti coloro che hanno aiutato!

+0

L'esempio dalla documentazione Python funziona bene per me: http://docs.python.org/library/ imaplib # imap4-example – Julian

+0

Sì, hai ragione, funziona tranquillamente per recuperare il contenuto completo del messaggio di tutti i messaggi. Voglio solo il soggetto e l'indirizzo del mittente però. Posso quindi creare il ciclo for solo da 1 a 15 – sadmicrowave

+0

E un altro collegamento ai documenti Python: http://docs.python.org/library/email.html;) – Julian

risposta

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]) 

Questo dovrebbe darti un'idea su come recuperare il soggetto e da?

+2

che cos'è l'email?ti riferisci alla mia variabile 'mail'? e cosa è message_from_string() è inventato? Sto ricevendo un errore che dice 'AttributeError (" Unknown IMAP4 command: '% s' "% attr) AttributeError: Unknown IMAP4 command: 'message_from_string'' – sadmicrowave

+2

non importa, capito, non ho incluso il modulo email. grazie – sadmicrowave

+0

Aggiunto al mio problema OP, aiuto con questa parte e ti darò la vittoria! – sadmicrowave

4

Per chi cerca il modo per controllare la posta e analizzare le intestazioni, questo è quello che ho usato:

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: l'oggetto 'module' non ha attributo 'message_from_string'. Sto importando e-mail, prometto. –

+1

@ChaseRoberts è necessario utilizzare 'dall'email import email'. Presumo che tu abbia usato "import email", il che significa che stai provando ad accedere a "message_from_string' al livello sbagliato. – blockloop

+0

Bwahaha, grazie molte. –

3

Cercavo un semplice script già pronto alla lista ultima casella di posta tramite IMAP senza ordinamento attraverso tutti i messaggi . Le informazioni qui sono utili, anche se fai da te e mancano alcuni aspetti. Innanzitutto, IMAP4.select restituisce il conteggio dei messaggi. In secondo luogo, la decodifica dell'intestazione dell'oggetto non è semplice.

#! /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

Questa era la mia soluzione per ottenere i bit di informazioni utili da e-mail:

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 
Problemi correlati