webentwicklung-frage-antwort-db.com.de

Wie kann ich alle E-Mails mit Anhängen von Google Mail herunterladen?

Wie verbinde ich mich mit Google Mail und bestimme, welche Nachrichten Anhänge haben? Ich möchte dann jeden Anhang herunterladen und für jede Nachricht, die ich verarbeite, den Betreff: und den Absender: ausdrucken.

83
anon

Schwer :-)

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! Das war was ;-) Aber versuch es gleich in Java, nur zum Spaß!

Übrigens habe ich das in einer Shell getestet, so dass einige Fehler wahrscheinlich bleiben.

Genießen

EDIT:

Da sich die Postfachnamen von Land zu Land ändern können, empfehle ich, m.list() auszuführen und ein Element vor m.select("the mailbox name") auszuwählen, um diesen Fehler zu vermeiden:

imaplib.error: Kommando SEARCH im Zustand AUTH unzulässig, nur in den Zuständen SELECTED erlaubt

152
e-satis

Ich bin kein Perl-Experte, aber ich weiß, dass GMail die Protokolle IMAP und POP33 2 unterstützt, die vollständig standardisiert sind und es Ihnen ermöglichen, genau das zu tun.

Vielleicht hilft Ihnen das beim Einstieg.

9
Jeroen Landheer
#!/usr/bin/env python
"""Save all attachments for given gmail account."""
import os, sys
from libgmail import GmailAccount

ga = GmailAccount("[email protected]", "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)

ungetestet

  1. Stellen Sie sicher, dass TOS solche Skripte zulässt, da sonst Ihr Konto gesperrt wird
  2. Möglicherweise gibt es bessere Optionen: GMail-Offlinemodus, Thunderbird + ExtractExtensions, GmailFS, Gmail Drive usw.
8
jfs

Schauen Sie sich Mail :: Webmail :: Gmail an:

ANHÄNGE ERHALTEN

Es gibt zwei Möglichkeiten, einen Anhang zu erhalten:

1 -> Durch Senden eines Verweises auf einen bestimmten Anhang, der von 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 -> Oder durch Senden der Anhangs-ID und der Nachrichten-ID

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

(Gibt einen Verweis auf einen Skalar zurück, der die Daten aus dem Anhang enthält.)

7
JDrago

In Google Mail können Sie nach "has: attachment" filtern und damit die Nachrichten identifizieren, die beim Testen angezeigt werden sollen. Beachten Sie, dass dies sowohl Nachrichten mit angehängten Dateien (Büroklammersymbol) als auch angehängte Inline-Bilder (keine Büroklammer) enthält.

Es gibt keine Google Mail-API, daher sind IMAP oder POP Ihre einzigen echten Optionen. Das JavaMail API kann ebenso hilfreich sein wie dieser sehr knappe Artikel über Herunterladen von Anhängen von IMAP mit Perl . Einige vorherige Fragen hier auf SO) können auch helfen.

Dies PHP-Beispiel kann auch helfen. Leider enthält der imap_header nach meinem Kenntnisstand keine Anhangsinformationen. Daher muss der Text heruntergeladen werden, damit das Feld X-Attachment-Id angezeigt werden kann. (Jemand beweist mir bitte das Gegenteil).

4
Kevin Haines

Wenn einer von euch auf python 3.3) aktualisiert hat, habe ich das 2.7-Skript aus HIER genommen und auf 3.3 aktualisiert. Auch behoben Einige Probleme mit der Art und Weise, wie Google Mail die Informationen zurückgibt.

# 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
Eric Thomas

Die Frage ist ziemlich alt und zu diesem Zeitpunkt war die Google Mail-API nicht verfügbar. Jetzt bietet Google jedoch eine Google Mail-API für den Zugriff auf IMAP. Siehe Google Mail-API hier . Siehe auch google-api-python-client auf pypi.

3
/*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 = "[email protected]";
        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-Abhängigkeit:

<dependency>
    <groupId>com.Sun.mail</groupId>
    <artifactId>javax.mail</artifactId>
    <version>1.5.1</version>
</dependency>
2
jechaviz

Folgendes habe ich geschrieben, um meine Kontoauszüge in Groovy (dynamische Sprache für die Java Platform)) herunterzuladen.

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
//    http://stackoverflow.com/questions/155504/download-mail-attachment-with-Java
//
//    Requires: 
//        Java mail jars in the class path (mail.jar and activation.jar)
//        openssl, with gmail certificate added to Java keystore (see agileice blog)
//        
//    further improvement: maybe findAll could be used to filter messages
//    subject could be added as another criteria
////////////////////// <CONFIGURATION> //////////////////////
// Maximm number of emails to access in case parameter range is too high
LIMIT = 10000

// gmail credentials
gmailServer = "imap.gmail.com"
gmailPort = 993

user = "[email protected]"
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
msanjay

Da Google Mail die Standardprotokolle POP und IMAP unterstützt, sollte jede Plattform, jedes Tool, jede Anwendung, jede Komponente oder API funktionieren, die die Clientseite beider Protokolle bereitstellt.

Ich empfehle eine Google-Suche nach Ihrer bevorzugten Sprache/Plattform (z. B. "Python"), "Pop", "IMAP", "Open Source", "Download" oder "Review" und was Sie haben die Wahl.

Es gibt zahlreiche kostenlose Anwendungen und Komponenten. Suchen Sie sich einige aus, die es wert sind, überprüft sie auf Bewertungen und lädt sie dann herunter und genießt sie.

1
Rob Williams

Sie sollten sich der Tatsache bewusst sein, dass Sie SSL benötigen, um sich mit GMail zu verbinden (sowohl für POP3 als auch für IMAP - dies gilt natürlich auch für deren SMTP-Server, abgesehen von Port 25, aber das ist eine andere Geschichte).

1
moster67

Für Java finden Sie G4J von Nutzen. Es handelt sich um eine Reihe von APIs für die Kommunikation mit Google Mail über Java (der Screenshot auf der Startseite ist ein Demo-E-Mail-Client, der darauf aufbaut)

0
Brian Agnew

Haben Sie sich die GMail 3rd Party Add-Ons auf Wikipedia angesehen?

Insbesondere PhpGmailDrive ist ein Open-Source-Add-On, das Sie möglicherweise unverändert verwenden oder vielleicht als Inspirationsquelle studieren können?

0
toolkit