Aus Mail den Text auslesen

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Hallo Leute,
Ich habe ein Programm, mit dem rufe ich die erste Mail auf dem Server ab, und lese von ihr aus, von wem sie stammt, den Betreff und den Text.
So schaut meine Funktion aus:

Code: Alles auswählen

def getMail():
    try:
        M = poplib.POP3('mailserver')
        M.user("user")
        M.pass_("password")
        
        for s in M.retr(1)[1]:
            if (s.startswith("From: ")):
                sender = s[6:]
            if (s.startswith("Subject: ")):
                subject = s[9:]
        M.dele(1)
        M.quit()
        return ("das sollte der text stehen", sender, subject)
    except:
        return 0
Aber ich hab keine blassen Schimmer, wie ich den Nachrichten Text kriege.
So schaut das ganze aus, was einem retr liefert:

Code: Alles auswählen

('+OK 1485 octets', ['Return-path: <armin.ronacher@active-4.com>', 'Delivery-date: Mon, 22 Nov 2004 17:49:12 +0100', 'Received: by server001.webpack.hosteurope.de running Exim 4.34 using esmtp', '\tfrom delta.mc1.hosteurope.de ([80.237.128.251])', '\tid 1CWHNH-0003y6-Mf; Mon, 22 Nov 2004 17:49:12 +0100', 'Received: by delta.mc1.hosteurope.de running Exim 4.34 using esmtp', '\tfrom server001.webpack.hosteurope.de ([80.237.130.9])', '\tid 1CWHNH-0000ww-0e', '\tfor activetravel@active-4.com; Mon, 22 Nov 2004 17:49:11 +0100', 'Received: by server001.webpack.hosteurope.de running Exim 4.34 using asmtp', '\tfrom l0191p30.dipool.highway.telekom.at ([62.46.87.222] helo=[192.168.6.15])', '\tid 1CWHNG-0003y0-Rg; Mon, 22 Nov 2004 17:49:11 +0100', 'Message-ID: <41A21868.8060806@active-4.com>', 'Date: Mon, 22 Nov 2004 17:48:40 +0100', 'From: Armin Ronacher <armin.ronacher@active-4.com>', 'User-Agent: Mozilla Thunderbird 0.9 (Windows/20041103)', 'X-Accept-Language: de-DE, de, en-us, en', 'MIME-Version: 1.0', 'To: Active-4 Mail Server <activetravel@active-4.com>', 'Subject: asldfhasdlgjhasdgljsh', 'Content-Type: text/plain; charset=ISO-8859-1; format=flowed', 'Content-Transfer-Encoding: 7bit', 'X-HE-Spam-Level: /', 'X-HE-Spam-Score: 0.0', 'X-HE-Spam-Report: Content analysis details:   (0.0 points)', '\tpts rule name              description', '\t---- ---------------------- --------------------------------------------------', 'Envelope-to: activetravel@active-4.com', '', 'dghasljghaslghsag', 'as', 'gas', 'dg', 'asg', 'asgshglkjashglsajg', 'asg', 'sagkjashgljashgljasdhglasdg', ''], 1485)
Kann mir da jemand helfen?
TUFKAB – the user formerly known as blackbird
fs111
User
Beiträge: 170
Registriert: Samstag 15. November 2003, 11:42
Kontaktdaten:

Benutz das email-Modul, das bietet fertige Funktionen für sowas.

fs111
Pydoc-Integration in vim - Feedback willkommen: http://www.vim.org/scripts/script.php?script_id=910
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Ich find die Funktion nicht. Kannst du mir einen Tipp geben?
TUFKAB – the user formerly known as blackbird
fs111
User
Beiträge: 170
Registriert: Samstag 15. November 2003, 11:42
Kontaktdaten:

Code: Alles auswählen


import email

msg = email.message_from_string("Hier will die ganze Mail hin")
print msg.get_payload()
Das sollte ungefähr so funktionieren, wenn es eine Mulitpart-Mail ist, musst Du die einzelnen parts einzeln behandeln.


fs111
Pydoc-Integration in vim - Feedback willkommen: http://www.vim.org/scripts/script.php?script_id=910
denis_std
User
Beiträge: 6
Registriert: Sonntag 3. Dezember 2006, 16:21

Habe mir eben auch schnell ein kleines Programm geschrieben, dass mir die Mails abholt. (mein erstes kleines Python Programm :D)

Code: Alles auswählen

import poplib

def popMailer():
# Eingabe des Hosts, der Userdaten, des Passworts

    hostname = raw_input('Geben Sie bitte den Host ein: ')
    named = raw_input('Geben Sie bitte den Usernamen ein: ')
    passwort = raw_input('Geben Sie bitte das Passwort ein: ')
    secure = raw_input('Wollen Sie eine sichere Verbindung verwenden? (1 ja/ 0 nein): ')

    #Setzen des Ports auf 110 (unsicher) bzw. 995 (SSL)

    if secure == 1:
	  portname = 995
    else:
	  portname = 110

    #Verbindungsaufbau
    mailer = poplib.POP3(hostname,portname)
    mailer.set_debuglevel(0)

    mailer.user(named)
    mailer.pass_(passwort)

    #Ausgabe
    # print mailer.getwelcome() #Gibt die Willkommens Nachricht des Mailservers aus
    status = mailer.stat()
    print 'Die Messagegroesse betraegt: %s' % status[1]
    print 'Sie haben %s Nachrichten in ihrem Mailkonto' % status[0]
    liste = mailer.retr(1)
    print liste[1]

popMailer()
Nun verstehe ich absolut nicht, wie ich den Text rausbekomme. Absender etc finde ich ja, aber den Text hmm. Habe mir auch das email Modul angesehen, kann aber im Moment noch nicht so viel damit anfangen. Kann mir da jemand ein Stichwort geben? Ich stehe noch ein bischen auf dem Schlauch. (2 Tage Python halt :D)

Danke schonmal!

Gruß

EDIT:

Hab es inzwischen gefunden. Scite hat die Ausgabe abgeschnitten :(

EDIT:

So ganz habe ich es wohl doch nicht verstanden:

So weit bin ich im Moment:

Code: Alles auswählen

import poplib

def popMailer():
# Eingabe des Hosts, der Userdaten, des Passworts

    hostname = raw_input('Geben Sie bitte den Host ein: ')
    named = raw_input('Geben Sie bitte den Usernamen ein: ')
    passwort = raw_input('Geben Sie bitte das Passwort ein: ')
    secure = raw_input('Wollen Sie eine sichere Verbindung verwenden? (1 ja/ 0 nein): ')

    #Setzen des Ports auf 110 (unsicher) bzw. 995 (SSL)

    if secure == 1:
	portname = 995
    else:
	portname = 110

    #Verbindungsaufbau
    mailer = poplib.POP3(hostname,portname)
    mailer.set_debuglevel(0)

    mailer.user(named)
    mailer.pass_(passwort)

    #Ausgabe
    # print mailer.getwelcome() #Gibt die Willkommens Nachricht des Mailservers aus
    status = mailer.stat()
    print 'Die Messagegroesse betraegt: %s' % status[1]
    print 'Sie haben %s Nachrichten in ihrem Mailkonto' % status[0]
    anzahl = int(status[0])

    #Schleife, die mir alle Mails abholt
    liste = []
    for i in range(0,anzahl):
	  liste.append(mailer.retr(i+1))
	  print 'Nachricht %d'%(i+1)
	  print liste
	  print 'Absender: %s'%liste[i][1][6]
	  print 'Empfaenger: %s'%liste[i][1][7]
	  print 'Betreff: %s'%liste[i][1][8].replace('Subject:','')
	  print 'Text: %s'%liste[i][1][-3]
    else:
	  print 'Alle Mails ausgelesen!'
	
popMailer()
Nu habe ich den Text immer an anderer Stelle in der Liste bzw. aufgeteilt. Vielleicht kann mir das jemand in einfachen Worten beschreiben, bzw mir die Seite im email Modul geben wo ich das ganze finde. So ganz blicke ich noch nicht durch.

Vielen Dank schonmal.

Gruß Denis
denis_std
User
Beiträge: 6
Registriert: Sonntag 3. Dezember 2006, 16:21

fs111 hat geschrieben:

Code: Alles auswählen


import email

msg = email.message_from_string("Hier will die ganze Mail hin")
print msg.get_payload()
Das sollte ungefähr so funktionieren, wenn es eine Mulitpart-Mail ist, musst Du die einzelnen parts einzeln behandeln.


fs111
Hab nun das ganze mit dem oben beschriebenen vorgehen mal versucht und es geht auch einwandfrei bei Text Mails. Sobald es HTML Mails sind, die aus mehreren Parts bestehen funktioniert es natürlich nicht und ich bekomme nur sowas heraus wie:

Code: Alles auswählen

[<email.message.Message instance at 0x00DD2148>, <email.message.Message instance at 0x00DD2170>]
Kann mir vielleicht jemand einen Tip geben (bitte nicht die ganze Lösung, ich möchte es selber herausfinden :D) wie ich die einzeln behandeln könnte.
Hier mal mein aktueller Stand:

http://phpfi.com/181916

Hab nun auch mal mit walk() herumgespielt, aber finde auch keinen Weg wie ich die einzelnen Parts öffne. Irgendwie blicke ich in der Doku des email Moduls noch nicht wirklich durch :D

http://phpfi.com/181918 (naja auch nicht das was ich will , aber es funktioniert)

Vielen Dank schonmal!

Gruß Denis
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Sie mal einer an. Da wurde ein Thread aus meine Python Anfangszeit ausgegraben. Ich hab zwar jetzt die Lösung nicht im Kopf, aber wenn du den Quellcode der ganzen Mail laden kannst hilft dir das email Package.

Code: Alles auswählen

>>> import email
>>> msg = email.message_from_string("""From: foo.bar@example.com
... To: bar.foo@example.com
... Subject: BLbu blub blub
... Content-Type: text/plain; encoding=utf-8
... 
... Hello World!""")
>>> msg.get_payload()
'Hello World!'
[('From', 'foo.bar@example.com'), ('To', 'bar.foo@example.com'), ('Subject', 'BLbu blub blub'), ('Content-Type', 'text/plain; encoding=utf-8')]
TUFKAB – the user formerly known as blackbird
denis_std
User
Beiträge: 6
Registriert: Sonntag 3. Dezember 2006, 16:21

Das Problem ist. Ich bekomme mit

msg.get_payload() eine Mail, die rein aus Text besteht locker ausgelesen. Und die Funktion gibt mir auch den Text zurück. Wenn ich aber eine HTML Mail habe, dann stückeln die Mailprogramme ja die Mail in verschiedene Parts und da seh ich keine Möglichkeit die auszulesen. (also nur den reinen Text) Ich komm einfach nicht dahinter wie man das macht.
snoopy
User
Beiträge: 2
Registriert: Montag 8. Januar 2007, 17:50
Wohnort: Alzey-Land

Hi,
ja ein eMail besteht meistens aus mehrere Teile. Es kann, aber muss nicht, sowohl ein text/plain Teil besitzen, als auch ein text/html Teil, und vieles mehr. Ich kann nur beraten, ein MIME-Mail auseinander zu nehmen und die verschiedene Details irgendwo auszugeben (Console, Datei, GUI-Widget). So sieht man was dahinter steckt.

Nehmen wir an, Sie haben ein "message" vom POP3-Server gelesen. Wandeln dies in einem String-Objekt und dann in ein eMail Objekt (Modules email muss dazu importiert werden).

Code: Alles auswählen

        messageStr = string.join(message, "\n")
        emailMessage = email.message_from_string( messageStr )
Jetzt können wir diese eMail auseinander nehemen:

Code: Alles auswählen

      i=1
      for part in emailMessage.walk():
            
            msgText = self.language.getElement('Part') + " %s\n" % i
            print msgText
            
            typeStr = part.get_content_type()
            
            paramList = part.get_params()
            if paramList != None:
                for param in paramList:
                    print param[0], param[1]
                    
                if param[0] == 'name':
                    print "Anhang:", param[1] 
                    
            if typeStr.find("text/plain") >= 0:
                # Accept only the FIRST text/plain as a possible message
                textPart = part.get_payload(decode=True)
                print textPart
            
            if foundHtml == False and typeStr.find("text/html") >= 0:
                # Accept only the FIRST text/html as a possible message
                htmlPart = part.get_payload(decode=True)
                print htmlPart
             
            i += 1
Edit (Leonidas): Code in Python-Tags gesetzt.
Antworten