83 votes

Comment puis-je télécharger tous les e-mails avec pièces jointes de Gmail ?

Comment puis-je me connecter à Gmail et déterminer quels messages comportent des pièces jointes ? Je veux ensuite télécharger chaque pièce jointe, en imprimant le sujet et l'origine de chaque message au fur et à mesure que je le traite.

154voto

e-satis Points 146299

C'est difficile :-)

import email, getpass, imaplib, os

detach_dir = '.' # directory where to save attachments (default: current)
user = raw_input("Enter your GMail username:")
pwd = getpass.getpass("Enter your password: ")

# connecting to the gmail imap server
m = imaplib.IMAP4_SSL("imap.gmail.com")
m.login(user,pwd)
m.select("[Gmail]/All Mail") # here you a can choose a mail box like INBOX instead
# use m.list() to get all the mailboxes

resp, items = m.search(None, "ALL") # you could filter using the IMAP rules here (check http://www.example-code.com/csharp/imap-search-critera.asp)
items = items[0].split() # getting the mails id

for emailid in items:
    resp, data = m.fetch(emailid, "(RFC822)") # fetching the mail, "`(RFC822)`" means "get the whole stuff", but you can ask for headers only, etc
    email_body = data[0][1] # getting the mail content
    mail = email.message_from_string(email_body) # parsing the mail content to get a mail object

    #Check if any attachments at all
    if mail.get_content_maintype() != 'multipart':
        continue

    print "["+mail["From"]+"] :" + mail["Subject"]

    # we use walk to create a generator so we can iterate on the parts and forget about the recursive headach
    for part in mail.walk():
        # multipart are just containers, so we skip them
        if part.get_content_maintype() == 'multipart':
            continue

        # is this part an attachment ?
        if part.get('Content-Disposition') is None:
            continue

        filename = part.get_filename()
        counter = 1

        # if there is no filename, we create one with a counter to avoid duplicates
        if not filename:
            filename = 'part-%03d%s' % (counter, 'bin')
            counter += 1

        att_path = os.path.join(detach_dir, filename)

        #Check if its already there
        if not os.path.isfile(att_path) :
            # finally write the stuff
            fp = open(att_path, 'wb')
            fp.write(part.get_payload(decode=True))
            fp.close()

Wowww ! C'était quelque chose ;-) Mais essayez la même chose en Java, juste pour le plaisir !

Au fait, j'ai testé cela dans un shell, il est donc probable que certaines erreurs subsistent.

Profitez de

EDITAR:

Comme les noms de boîtes aux lettres peuvent changer d'un pays à l'autre, je recommande de faire m.list() et de choisir un élément dans la liste avant m.select("the mailbox name") pour éviter cette erreur :

imaplib.error : la commande SEARCH est illégale dans l'état AUTH, elle est uniquement autorisée dans l'état SELECTED. états SELECTED

9voto

Jeroen Landheer Points 3346

Je ne suis pas un expert de Perl, mais ce que je sais, c'est que GMail prend en charge IMAP et POP3, deux protocoles tout à fait standard qui vous permettent de faire exactement cela.

Peut-être que cela vous aidera à démarrer.

8voto

J.F. Sebastian Points 102961
#!/usr/bin/env python
"""Save all attachments for given gmail account."""
import os, sys
from libgmail import GmailAccount

ga = GmailAccount("your.account@gmail.com", "pA$$w0Rd_")
ga.login()

# folders: inbox, starred, all, drafts, sent, spam
for thread in ga.getMessagesByFolder('all', allPages=True):
    for msg in thread:
        sys.stdout.write('.')
        if msg.attachments:
           print "\n", msg.id, msg.number, msg.subject, msg.sender
           for att in msg.attachments:
               if att.filename and att.content:
                  attdir = os.path.join(thread.id, msg.id)
                  if not os.path.isdir(attdir):
                     os.makedirs(attdir)                
                  with open(os.path.join(attdir, att.filename), 'wb') as f:
                       f.write(att.content)

non testé

  1. Assurez-vous que les TOS autorisent de tels scripts, sinon votre compte sera suspendu.
  2. Il y a peut-être de meilleures options : Mode hors ligne de GMail, Thunderbird + ExtractExtensions, GmailFS, Gmail Drive, etc.

7voto

JDrago Points 1479

Jetez un coup d'œil à Mail::Webmail::Gmail :

OBTENIR DES PIÈCES JOINTES

Il y a deux façons d'obtenir une pièce jointe :

1 -> En envoyant une référence à une pièce jointe spécifique retournée par get_indv_email

# Creates an array of references to every attachment in your account
my $messages = $gmail->get_messages();
my @attachments;

foreach ( @{ $messages } ) {
    my $email = $gmail->get_indv_email( msg => $_ );
    if ( defined( $email->{ $_->{ 'id' } }->{ 'attachments' } ) ) {
        foreach ( @{ $email->{ $_->{ 'id' } }->{ 'attachments' } } ) {
            push( @attachments, $gmail->get_attachment( attachment => $_ ) );
            if ( $gmail->error() ) {
                print $gmail->error_msg();
            }
        }
    }
}

2 -> Ou en envoyant l'ID de la pièce jointe et l'ID du message

#retrieve specific attachment
my $msgid = 'F000000000';
my $attachid = '0.1';
my $attach_ref = $gmail->get_attachment( attid => $attachid, msgid => $msgid );

( Retourne une référence à un scalaire qui contient les données de la pièce jointe. )

4voto

Kevin Haines Points 867

Dans gmail, vous pouvez filtrer sur "has:attachment", utilisez-le pour identifier les messages que vous devriez recevoir lors du test. Notez que cela semble donner à la fois des messages avec des fichiers joints (icône en forme de trombone affichée) et des images jointes en ligne (pas de trombone affiché).

Il n'y a pas d'API Gmail, donc IMAP ou POP sont vos seules véritables options. Le site API JavaMail peut être d'une certaine utilité ainsi que cet article très laconique sur les téléchargement de pièces jointes à partir d'IMAP à l'aide de Perl . Quelques questions précédentes ici sur SO peut aussi aider.

Ce site Exemple de PHP peut aussi aider. Malheureusement, d'après ce que je vois, l'en-tête imap_header ne contient pas d'informations sur les pièces jointes. Il faut donc télécharger le corps du message pour pouvoir voir le champ X-Attachment-Id. (quelqu'un peut me prouver que j'ai tort).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X