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

comment me connecter à Gmail et déterminer quels messages ont des pièces jointes? Je veux ensuite télécharger chaque pièce jointe, en imprimant le sujet: et de: pour chaque message que je traite.

82
demandé sur Honest Abe 2008-12-08 06:57:49

13 réponses

Dure": -)

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 essayer la même chose en Java, juste pour le fun!

soit dit en passant, j'ai testé ça dans un shell, donc il reste probablement des erreurs.

Profiter

EDIT:

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

imaplib.erreur: recherche de commande illégale dans L'état AUTH, seulement autorisé dans états SÉLECTIONNÉS

148
répondu e-satis 2013-03-08 05:12:49

Je ne suis pas un expert en Perl, mais ce que je sais, C'est que GMail prend en charge les protocoles IMAP et POP3, 2 qui sont complètement standard et vous permettent de le faire.

peut-être que ça vous aide à commencer.

9
répondu Jeroen Landheer 2008-12-08 04:17:37
#!/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 TOS autorise de tels scripts sinon votre compte sera suspendu
  2. il pourrait y avoir de meilleures options: GMail mode offline, Thunderbird + ExtractExtensions, GmailFS, Gmail Drive, etc.
8
répondu jfs 2009-03-13 08:40:25

regardez Courrier::le Webmail::Gmail :

OBTENTION DE 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 la pièce jointe ID et le message ID

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

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

7
répondu JDrago 2009-03-13 15:52:00

dans gmail, vous pouvez filtrer sur "has:attachment", utilisez-le pour identifier les messages que vous devriez recevoir lors des tests. Notez que ceci semble donner à la fois des messages avec des fichiers attachés (icône de trombone montrée), aussi bien que des images attachées inline (pas de trombone montrée).

il n'y a pas D'API Gmail, donc IMAP ou POP sont vos seules options réelles. Le JavaMail API peut être d'une certaine aide ainsi que cet article très succinct sur téléchargement pièces jointes de L'IMAP utilisant Perl . Certains questions précédentes ici, donc peut également aider.

Ce en PHP, par exemple peut aider trop. Malheureusement, d'après ce que je vois, il n'y a pas d'information sur les pièces jointes dans l'imap_header, de sorte que le téléchargement du corps est nécessaire pour pouvoir voir le champ X-Attachment-Id. (que quelqu'un me prouve que j'ai tort).

4
répondu Kevin Haines 2017-05-23 12:32:29

si l'un de vous a mis à jour vers python 3.3, j'ai pris le script 2.7 de ici et l'ai mis à jour vers 3.3. A également corrigé certains problèmes avec la façon dont gmail retournait l'information.

# Something in lines of http://stackoverflow.com/questions/348630/how-can-i-download-all-emails-with-attachments-from-gmail
# Make sure you have IMAP enabled in your gmail settings.
# Right now it won't download same file name twice even if their contents are different.
# Gmail as of now returns in bytes but just in case they go back to string this line is left here.

import email
import getpass, imaplib
import os
import sys
import time

detach_dir = '.'
if 'attachments' not in os.listdir(detach_dir):
    os.mkdir('attachments')

userName = input('Enter your GMail username:\n')
passwd = getpass.getpass('Enter your password:\n')


try:
    imapSession = imaplib.IMAP4_SSL('imap.gmail.com',993)
    typ, accountDetails = imapSession.login(userName, passwd)
    if typ != 'OK':
        print ('Not able to sign in!')
        raise

    imapSession.select('Inbox')
    typ, data = imapSession.search(None, 'ALL')
    if typ != 'OK':
        print ('Error searching Inbox.')
        raise

    # Iterating over all emails
    for msgId in data[0].split():
        typ, messageParts = imapSession.fetch(msgId, '(RFC822)')

        if typ != 'OK':
            print ('Error fetching mail.')
            raise 

        #print(type(emailBody))
        emailBody = messageParts[0][1]
        #mail = email.message_from_string(emailBody)
        mail = email.message_from_bytes(emailBody)

        for part in mail.walk():
            #print (part)
            if part.get_content_maintype() == 'multipart':
                # print part.as_string()
                continue
            if part.get('Content-Disposition') is None:
                # print part.as_string()
                continue

            fileName = part.get_filename()

            if bool(fileName):
                filePath = os.path.join(detach_dir, 'attachments', fileName)
                if not os.path.isfile(filePath) :
                    print (fileName)
                    fp = open(filePath, 'wb')
                    fp.write(part.get_payload(decode=True))
                    fp.close()

    imapSession.close()
    imapSession.logout()

except :
    print ('Not able to download all attachments.')
    time.sleep(3)
3
répondu Eric Thomas 2013-08-15 19:02:05

la question est assez ancienne et à l'époque L'API Gmail n'était pas disponible. Mais maintenant, Google fournit L'API Gmail pour accéder à IMAP. Voir L'API Gmail de Google ici . Voir aussi Google-api-python-client sur pypi.

3
répondu Mitesh Budhabhatti 2016-11-06 07:29:10
/*based on http://www.codejava.net/java-ee/javamail/using-javamail-for-searching-e-mail-messages*/
package getMailsWithAtt;

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;

import javax.mail.Address;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.NoSuchProviderException;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.MimeBodyPart;
import javax.mail.search.AndTerm;
import javax.mail.search.SearchTerm;
import javax.mail.search.ReceivedDateTerm;
import javax.mail.search.ComparisonTerm;

public class EmailReader {
    private String saveDirectory;

    /**
     * Sets the directory where attached files will be stored.
     * 
     * @param dir
     *            absolute path of the directory
     */
    public void setSaveDirectory(String dir) {
        this.saveDirectory = dir;
    }

    /**
     * Downloads new messages and saves attachments to disk if any.
     * 
     * @param host
     * @param port
     * @param userName
     * @param password
     * @throws IOException
     */
    public void downloadEmailAttachments(String host, String port,
            String userName, String password, Date startDate, Date endDate) {
        Properties props = System.getProperties();
        props.setProperty("mail.store.protocol", "imaps");
        try {
            Session session = Session.getDefaultInstance(props, null);
            Store store = session.getStore("imaps");
            store.connect("imap.gmail.com", userName, password);
            // ...
            Folder inbox = store.getFolder("INBOX");
            inbox.open(Folder.READ_ONLY);
            SearchTerm olderThan = new ReceivedDateTerm (ComparisonTerm.LT, startDate);
            SearchTerm newerThan = new ReceivedDateTerm (ComparisonTerm.GT, endDate);
            SearchTerm andTerm = new AndTerm(olderThan, newerThan);
            //Message[] arrayMessages = inbox.getMessages(); <--get all messages
            Message[] arrayMessages = inbox.search(andTerm);
            for (int i = arrayMessages.length; i > 0; i--) { //from newer to older
                Message msg = arrayMessages[i-1];
                Address[] fromAddress = msg.getFrom();
                String from = fromAddress[0].toString();
                String subject = msg.getSubject();
                String sentDate = msg.getSentDate().toString();
                String receivedDate = msg.getReceivedDate().toString();

                String contentType = msg.getContentType();
                String messageContent = "";

                // store attachment file name, separated by comma
                String attachFiles = "";

                if (contentType.contains("multipart")) {
                    // content may contain attachments
                    Multipart multiPart = (Multipart) msg.getContent();
                    int numberOfParts = multiPart.getCount();
                    for (int partCount = 0; partCount < numberOfParts; partCount++) {
                        MimeBodyPart part = (MimeBodyPart) multiPart
                                .getBodyPart(partCount);
                        if (Part.ATTACHMENT.equalsIgnoreCase(part
                                .getDisposition())) {
                            // this part is attachment
                            String fileName = part.getFileName();
                            attachFiles += fileName + ", ";
                            part.saveFile(saveDirectory + File.separator + fileName);
                        } else {
                            // this part may be the message content
                            messageContent = part.getContent().toString();
                        }
                    }
                    if (attachFiles.length() > 1) {
                        attachFiles = attachFiles.substring(0,
                                attachFiles.length() - 2);
                    }
                } else if (contentType.contains("text/plain")
                        || contentType.contains("text/html")) {
                    Object content = msg.getContent();
                    if (content != null) {
                        messageContent = content.toString();
                    }
                }

                // print out details of each message
                System.out.println("Message #" + (i + 1) + ":");
                System.out.println("\t From: " + from);
                System.out.println("\t Subject: " + subject);
                System.out.println("\t Received: " + sentDate);
                System.out.println("\t Message: " + messageContent);
                System.out.println("\t Attachments: " + attachFiles);
            }

            // disconnect
            inbox.close(false);
            store.close();

        } catch (NoSuchProviderException e) {
            e.printStackTrace();
            System.exit(1);
        } catch (MessagingException e) {
            e.printStackTrace();
            System.exit(2);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Runs this program with Gmail POP3 server
     * @throws ParseException 
     */
    public static void main(String[] args) throws ParseException {
        String host = "pop.gmail.com";
        String port = "995";
        String userName = "user@gmail.com";
        String password = "pass";
        Date startDate = new SimpleDateFormat("yyyy-MM-dd").parse("2014-06-30");
        Date endDate = new SimpleDateFormat("yyyy-MM-dd").parse("2014-06-01");
        String saveDirectory = "C:\Temp";

        EmailReader receiver = new EmailReader();
        receiver.setSaveDirectory(saveDirectory);
        receiver.downloadEmailAttachments(host, port, userName, password,startDate,endDate);

    }
}

Maven Dependency:

<dependency>
    <groupId>com.sun.mail</groupId>
    <artifactId>javax.mail</artifactId>
    <version>1.5.1</version>
</dependency>
2
répondu jechaviz 2014-09-24 07:29:37

étant donné que Gmail supporte les protocoles STANDARD POP et IMAP, toute plate-forme, Outil, application, composant ou API qui fournit le côté client de l'un ou l'autre protocole devrait fonctionner.

je suggère de faire une recherche Google pour votre langue/plate-forme préférée (par exemple," python"), plus" pop", plus" imap", plus peut-être" open source", plus peut-être" download "ou" review", et voir ce que vous obtenez pour les options.

Il ya de nombreuses applications gratuites et composants, choisir quelques-uns qui semblent dignes, vérifier les commentaires, puis télécharger et profiter.

1
répondu Rob Williams 2008-12-08 05:23:54

vous devez être conscient du fait que vous avez besoin de SSL pour vous connecter à GMail (à la fois pour POP3 et IMAP - cela est bien sûr vrai aussi pour leurs serveurs SMTP à l'exception du port 25 mais c'est une autre histoire).

1
répondu moster67 2009-01-05 13:07:02

voici quelque chose que j'ai écrit pour télécharger mes relevés bancaires dans Groovy (langage dynamique pour la plate-forme Java).

import javax.mail.*
import java.util.Properties

String  gmailServer
int gmailPort
def user, password, LIMIT
def inboxFolder, root, StartDate, EndDate


//    Downloads all attachments from a gmail mail box as per some criteria
//    to a specific folder
//    Based on code from
//    http://agileice.blogspot.com/2008/10/using-groovy-to-connect-to-gmail.html
//    /q/download-mail-attachment-with-java-18828/"imap.gmail.com"
gmailPort = 993

user = "gmailuser@gmail.com"
password = "gmailpassword"

// gmail label, or "INBOX" for inbox
inboxFolder = "finance"

// local file system where the attachment files need to be stored
root = "D:\AttachmentStore" 

// date range dd-mm-yyyy
StartDate= "31-12-2009"
EndDate = "1-6-2010" 
////////////////////// </CONFIGURATION> //////////////////////

StartDate = Date.parse("dd-MM-yyyy", StartDate)
EndDate = Date.parse("dd-MM-yyyy", EndDate)

Properties props = new Properties();
props.setProperty("mail.store.protocol", "imaps");
props.setProperty("mail.imaps.host", gmailServer);
props.setProperty("mail.imaps.port", gmailPort.toString());
props.setProperty("mail.imaps.partialfetch", "false");

def session = javax.mail.Session.getDefaultInstance(props,null)
def store = session.getStore("imaps")

store.connect(gmailServer, user, password)

int i = 0;
def folder = store.getFolder(inboxFolder)

folder.open(Folder.READ_ONLY)

for(def msg : folder.messages) {

     //if (msg.subject?.contains("bank Statement"))
     println "[$i] From: ${msg.from} Subject: ${msg.subject} -- Received: ${msg.receivedDate}"

     if (msg.receivedDate <  StartDate || msg.receivedDate > EndDate) {
         println "Ignoring due to date range"
         continue
     }


     if (msg.content instanceof Multipart) {
         Multipart mp = (Multipart)msg.content;

         for (int j=0; j < mp.count; j++) {

             Part part = mp.getBodyPart(j);

             println " ---- ${part.fileName} ---- ${part.disposition}"

             if (part.disposition?.equalsIgnoreCase(Part.ATTACHMENT)) {

                 if (part.content) {

                     def name = msg.receivedDate.format("yyyy_MM_dd") + " " + part.fileName
                     println "Saving file to $name"

                     def f = new File(root, name)

                     //f << part.content
                     try {
                         if (!f.exists())
                             f << part.content
                     }
                     catch (Exception e) {
                         println "*** Error *** $e" 
                     }
                 }
                 else {
                    println "NO Content Found!!"
                 }
             }
         }
     }

     if (i++ > LIMIT)
         break;

}
1
répondu msanjay 2010-11-13 10:32:33

avez-vous regardé les GMail add-ons sur wikipedia?

En particulier, PhpGmailDrive est un add-on que vous pourrez utiliser tel quel, ou peut-être d'étude pour l'inspiration?

0
répondu toolkit 2009-03-13 03:52:27

pour Java, vous trouverez G4J d'utilisation. C'est un ensemble D'API pour communiquer avec Google Mail via Java (la capture d'écran sur la page d'accueil est un client email de démonstration construit autour de cela)

0
répondu Brian Agnew 2009-03-13 11:56:17