Je voudrais récupérer le message entier du serveur IMAP4. Dans les documents Python, si ce code est trouvé, il fonctionne:
>>> t, data = M.fetch('1', '(RFC822)')
>>> body = data[0][1]
Je me demande si je peux toujours croire que data [0] [1] renvoie le corps du message. Quand j'ai lancé 'RFC822.SIZE', j'ai juste une chaîne au lieu d'un tuple.
J'ai parcouru rfc1730 mais je n'ai pas été en mesure de déterminer la structure de réponse appropriée pour le 'RFC822'. Il est également difficile de distinguer la structure du résultat d’extraction de la documentation d’imaplib.
Voici ce que je reçois en récupérant RFC822
:
('OK', [('1 (RFC822 {858569}', 'body of the message', ')')])
Mais quand je récupère RFC822.SIZE
je reçois:
('OK', ['1 (RFC822.SIZE 847403)'])
Comment dois-je gérer correctement la liste de données [0]? Puis-je croire que lorsqu'il s'agit d'une liste de n-uplets, les n-uplets ont exactement 3 parties et la deuxième partie est la charge utile?
Peut-être connaissez-vous une meilleure bibliothèque pour imap4?
Non ... imaplib
est une très bonne bibliothèque, c'est une carte tellement inintelligible.
Vous voudrez peut-être vérifier que t == 'OK'
, mais data[0][1]
fonctionne comme prévu pour autant que je l’ai utilisé.
Voici un exemple rapide que j'utilise pour extraire les certificats signés que j'ai reçus par courrier électronique, pas à l'abri des bombes, mais convient à mes besoins
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 __== '__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
Le paquet IMAPClient est un peu plus facile à utiliser. De la description:
Bibliothèque de clients IMAP facile à utiliser, Pythonic et complète .
C'était ma solution pour extraire les informations utiles. Cela a été fiable jusqu'à présent:
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
bibliothèque imap-tools pour une utilisation efficace des messages électroniques utilisant le protocole IMAP.