2010-02-09 8 views
16

Ich möchte die gesamte Nachricht vom IMAP4-Server abrufen. In Python-Dokumentation, wenn dieses Stück Code gefunden, das funktioniert:Wie man einen E-Mail-Körper mit imaplib in Python holt?

>>> t, data = M.fetch('1', '(RFC822)') 
>>> body = data[0][1] 

Ich frage mich, wenn ich immer vertrauen können, dass die Daten [0] [1], um den Körper der Nachricht zurückgibt. Wenn ich 'RFC822.SIZE' ausgeführt habe, habe ich nur eine Zeichenfolge anstelle eines Tupels.

Ich habe durch RFC1730 überflogen, aber ich war nicht in der Lage, die richtige Antwort Struktur für die "RFC822" herauszufinden. Es ist auch schwierig, die Fetch-Ergebnisstruktur aus der imaplib-Dokumentation zu ermitteln. Hier

ist das, was ich bekomme, wenn RFC822 holen:

('OK', [('1 (RFC822 {858569}', 'body of the message', ')')]) 

Aber wenn ich RFC822.SIZE hole ich bin immer:

('OK', ['1 (RFC822.SIZE 847403)']) 

Wie sollte ich die Daten richtig verarbeiten [0] Liste ? Kann ich darauf vertrauen, dass, wenn es eine Liste von Tupeln ist, die Tupel genau 3 Teile haben und der zweite Teil die Nutzlast?

Vielleicht kennen Sie eine bessere Bibliothek für imap4?

+0

wenn u erfolgreich den Körper Mail abgerufen können Sie bitte den Code teilen? – hussain

Antwort

19

Nein ... imaplib ist eine ziemlich gute Bibliothek, es ist IMAP, die so unverständlich ist.

Vielleicht möchten Sie überprüfen, dass t == 'OK', aber data[0][1] funktioniert wie erwartet, so viel wie ich es benutzt habe.

Hier ist ein kurzes Beispiel ich signierte Zertifikate extrahieren wir per E-Mail erhalten haben, nicht bombensicher, sondern paßt meine Zwecke:

import getpass, os, imaplib, email 
from OpenSSL.crypto import load_certificate, FILETYPE_PEM 

def getMsgs(servername="myimapserverfqdn"): 
    usernm = getpass.getuser() 
    passwd = getpass.getpass() 
    subject = 'Your SSL Certificate' 
    conn = imaplib.IMAP4_SSL(servername) 
    conn.login(usernm,passwd) 
    conn.select('Inbox') 
    typ, data = conn.search(None,'(UNSEEN SUBJECT "%s")' % subject) 
    for num in data[0].split(): 
    typ, data = conn.fetch(num,'(RFC822)') 
    msg = email.message_from_string(data[0][1]) 
    typ, data = conn.store(num,'-FLAGS','\\Seen') 
    yield msg 

def getAttachment(msg,check): 
    for part in msg.walk(): 
    if part.get_content_type() == 'application/octet-stream': 
     if check(part.get_filename()): 
     return part.get_payload(decode=1) 

if __name__ == '__main__': 
    for msg in getMsgs(): 
    payload = getAttachment(msg,lambda x: x.endswith('.pem')) 
    if not payload: 
     continue 
    try: 
     cert = load_certificate(FILETYPE_PEM,payload) 
    except: 
     cert = None 
    if cert: 
     cn = cert.get_subject().commonName 
     filename = "%s.pem" % cn 
     if not os.path.exists(filename): 
     open(filename,'w').write(payload) 
     print "Writing to %s" % filename 
     else: 
     print "%s already exists" % filename 
+0

Gut zu wissen, dass dies für Sie funktioniert. Aber irgendwelche Gedanken, warum es wie beschrieben funktioniert? –

+0

Die Rückgabewerte sind die Token-Antwort des IMAP-Servers. – MattH

+0

Vermutlich müssen höhere Imap-Bibliotheken mit Schwächen zwischen verschiedenen Imap-Implementierungen umgehen oder inkompatibel sein. – MattH

7

Das IMAPClient Paket ein gutes Stück einfacher zu handhaben ist. Aus der Beschreibung:

Einfach zu bedienende, Pythonic und komplette IMAP-Client-Bibliothek .

+0

Ich unterstütze das. IMAPClient ist sehr zu verwenden und objektorientiert. Es ist viel einfacher zu benutzen als imaplib und hat keine großen Probleme. – zoobert

0

Dies war meine Lösung, um die nützlichen Informationen zu extrahieren. Es ist so weit zuverlässig gewesen:

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 
0

imap-tools Bibliothek für effektives Arbeiten mit E-Mail-Nachrichten IMAP-Protokoll.

  • transparente Arbeit mit Buchstaben Attributen (einschließlich uid)
  • Arbeit mit Buchstaben in Verzeichnissen (Kopieren, Löschen, Flagge, verschieben, zu sehen)
  • Arbeit mit Verzeichnissen (Liste, gesetzt, erhalten, erstellen, besteht , umbenennen, löschen, Status)
  • keine externen Abhängigkeiten
Verwandte Themen