Mailabrufe

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
reneschmidt
User
Beiträge: 48
Registriert: Montag 4. Januar 2016, 15:14

Hallo zusammen,

ich möchte mit Python Mail aus einem Postfach abrufen und die Anhänge speichern.

Hintergrund ist, das E-Mails mit bestimmten Anhängen eingehen die automatisch abgearbeitet werden können. Andere Mails müssen händisch abgearbeitet werden. Daher liste ich mir den Posteingang und dort nur die ungelesenen Mails. Prüfen ob die Mail nur einen Anhang hat und ob dieser Anhang die entsprechende Dateiendung hat. Wenn ja verschiebe ich die Mail und verarbeite den Anhang.

Mein Problem ist jetzt, das in dem Postfach auch HTML E-Mails landen wo in der Signatur eine Bild ist welches vom Script als Anhang erkannt wird und dadurch fällt die Mail dann durchs Raster.

Gibt es eine Möglichkeit nur die eigentlichen Anhänge zu einer Mail auszugeben und die in die HTML E-Mail eingebundenen Bilder zu erkennen und auszuschlißen?

Ich verwende die Python imaplib zum abruf:

Code: Alles auswählen

#!/usr/bin/python
import email
from email.header import Header, decode_header, make_header
import os
import poplib
import time
import subprocess
import imaplib
import re
import sys

MAILSERVER = ''
BENUTZER = ''
PASSWORT = ''

POSTEINGANG = "INBOX"
VERARBEITUNGSVERZEICHNIS = POSTEINGANG + "/V E R A R B E I T E T"

#Verbindung zum Server aufbauen
imap = imaplib.IMAP4_SSL(MAILSERVER)
imap.login(BENUTZER,PASSWORT)


#Lesen der ungelesenen Mail im Posteingang
imap.select(POSTEINGANG)
#typ, data  = imap.search(None, 'UnSeen')
typ, data  = imap.search(None, 'All')

for mailid in data[0].split(' '):
        typ, maildata = imap.fetch(mailid,'(RFC822)')
        emailBody = maildata[0][1]
        mail = email.message_from_string(emailBody)

        decode = email.header.decode_header(mail['Subject'])[0]
        subject = unicode(decode[0])
        print subject

        attcnt = 0

        #Lesen der Dateianhaenge
        for part in mail.walk():
                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()
                print fileName
                #print fileName
                attcnt = attcnt + 1


        #Wenn nur ein Dateianhang vorhanden ist, wird weiter verarbeitet
        if attcnt == 1:
                #pruefen der Datei ob PDF:
                if fileName[-4:].upper() == ".PDF":
                        tmpcnt = 0
                        dateiname = ABLAGEPFAD + "/" + str(tmpcnt) + "-" + fileName
                        while os.path.exists(dateiname):
                                tmpcnt = tmpcnt + 1
                                dateiname = ABLAGEPFAD + "/" + str(tmpcnt) + "-" + fileName

                        print dateiname
                        fp = open(dateiname, 'wb')
                        fp.write(part.get_payload(decode=True))
                        fp.close()

                        #kopieren der Mail
                        imap.copy(mailid, hverzeichnis)
                        imap.store(mailid, '+FLAGS', '\\Deleted')
        else:
                imap.store(mailid, '-FLAGS', '\Seen')

imap.close()
imap.logout()
Sirius3
User
Beiträge: 18268
Registriert: Sonntag 21. Oktober 2012, 17:20

Eingebettete Bilder unterscheiden sich rein technisch nicht von anderen Anhängen. Aber Du untersuchst ja die Anhänge schon weiter, und arbeitest nur die ab, die einen PDF-Angang haben. Wo ist also Dein Problem?
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

@Sirius3 Der Code funktioniert nicht mehr wenn es mehr als einen Anhang gibt, also z.B. Bild von der Signatur + PDF.
Benutzeravatar
__blackjack__
User
Beiträge: 14036
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Das/Ein Problem ist, dass der Code gar nicht sauber ”Anhänge” erfasst. Nicht alles was nicht 'multipart' ist und einen 'Content-Disposition'-Wert hat, ist auch ein Anhang. Und man könnte da auch gleich nach dem Inhaltstyp und/oder Dateinamen filtern.

Der Name `attcnt` ist falsch, das müsste `atthoe` heissen. Oder kann man tatsächlich „attention cunt“ sagen? Ich kenne nur „attention whore“. Vielleicht sollte man aber auch einfach das Abkürzen sein lassen. :twisted:
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Sirius3
User
Beiträge: 18268
Registriert: Sonntag 21. Oktober 2012, 17:20

@reneschmidt: das Problem ist, dass Du zwei for-Schleifen vermischst, statt sie sauber zu trennen. Erster Schritt ist die richtigen Anhänge zu suchen, zweiter, sie weiter zu verarbeiten.
Nach Konvention wird immer mit 4 Leerzeichen pro Ebene eingerückt und Variablen klein_mit_unterstrich geschrieben.

Code: Alles auswählen

attachements = [part for part in mail.walk()
    if part.get_filename('').lower().endswith('.pdf')]
if attachements:
    for attachement in attachements:
        filename = os.path.basename(attachement.get_filename())
        for filecount in itertools.count():
            fullname = os.path.join(ABLAGEPFAD, '{:03d}-{}'.format(filecount, filename))
            if not os.path.exists(fullname):
                break
        with open(fullname, 'wb') as output:
            output.write(attachement.get_payload(decode=True))
    imap.copy(mailid, hverzeichnis)
    imap.store(mailid, '+FLAGS', '\\Deleted')
else:
    imap.store(mailid, '-FLAGS', '\\Seen')
Antworten