[Python-de] Datum aus Mails parsen
Martin A. Brown
martin at linux-ip.net
Di Mär 22 22:00:22 EDT 2016
Grüße Florian,
>ich will das Datum einer Mail rausfinden, ob es das Sende- oder
>Empfangsdatum ist, oder eins der Stationen in der Mitte ist egal.
Aber es kommt darauf an ....
Ich meine, wie Christopher Arndt schon beantwortet hat--Du mußt
wissen was für Deine Zwecke dient. Ich würde auch noch etwas
hinzufügen: Man sollte diese Daten nicht schlichtweg trauen, denn
jeder Rechner kann von NTP [0] Synchronismus abweichen.
>Nun habe ich mir mal eine beliebige Mail rausgegriffen:
>
>From someone at gmail.com Fri Feb 05 09:09:11 2016
Vorige Zeile wurde von dem MDA [1] geschreiben. Diese Zeitstempel
gehört nicht zu dem Netzwerk, sondern (ich vermute) den Rechner
'hermes.informatik.uni-stattgart.de' und wurde von dem Dovecot MDA
hinzugefügt.
>Received: from ipvsmail.informatik.uni-stuttgart.de
> by hermes.informatik.uni-stuttgart.de (Dovecot) with LMTP id 842rLx9mtFbVeAAAqVsIVA
> for <user at ipvs.uni-stuttgart.de>; Fri, 05 Feb 2016 10:09:12 +0100
>Received: from mx3.informatik.uni-stuttgart.de (mailgw.informatik.uni-stuttgart.de [129.69.211.42])
> by ipvsmail.informatik.uni-stuttgart.de (Postfix) with ESMTP id D3111EA3
> for <somereceiver at ipvsmail.informatik.uni-stuttgart.de>; Fri, 5 Feb 2016 10:09:12 +0100 (CET)
>Received: by mx3.informatik.uni-stuttgart.de (Postfix, from userid 65534)
> id BD6DB6251; Fri, 5 Feb 2016 10:09:12 +0100 (CET)
>Received: from mail-lf0-f52.google.com (mail-lf0-f52.google.com [209.85.215.52])
> (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits))
> (No client certificate requested)
> by mx3.informatik.uni-stuttgart.de (Postfix) with ESMTPS id E6D546249
> for <somereceiver at ipvs.uni-stuttgart.de>; Fri, 5 Feb 2016 10:09:11 +0100 (CET)
>Received: by mail-lf0-f52.google.com with SMTP id 78so52976351lfy.3
> for <somereceiver at ipvs.uni-stuttgart.de>; Fri, 05 Feb 2016 01:09:11 -0800 (PST)
>X-Received: by 10.25.42.18 with SMTP id q18mr5524069lfq.151.1454663351309;
> Fri, 05 Feb 2016 01:09:11 -0800 (PST)
>Received: by 10.25.145.21 with HTTP; Fri, 5 Feb 2016 01:09:11 -0800 (PST)
>Received: by 10.25.145.21 with HTTP; Fri, 5 Feb 2016 01:09:11 -0800 (PST)
Die oben kopierten Headers sind alle von Rechnern durch die diese
Email geflossen hat. Jeder Rechner stellt sein eigenes 'Received'
Header ganz oben voran. D.h. die Ursprüngliche Nachricht trug nur
dieses Datum:
>Date: Fri, 5 Feb 2016 10:09:11 +0100
Normaleweise, traut man die Zeitstempel (gewissermaßen). In diesem
Beispiel, brauchte es nur eine Sekunde um vom Rechner des Absenders
zum Dovecot LMTP MDA auf hermes.informatik.uni-stuttgart.de. Ich
vermute deshalb daß es höchstwahrscheinlich 10:09:11 CET war am
Rechner der Sender.
Die anderen Received headers berichten den Weg (stufenweise).
Wenn Du weiter über Email und das Datumformat wissen wolltest,
kannst Du das alles in den RFCs lesen und lernen:
* RFC 5322 [2] (aktuell)
* RFC 2822 [3] (ein Zwischenstop)
* RFC 822 [4] (die Quelle)
>Ein wenig habe ich schon irrelevante Infos rausgenommen.
>
>Probleme die ich sehe ist a) die Zuverlässigkeit des Datums und b)
>die Standardisierung des Formates.
Standardisierung: In Received Headers, ist das herkömmliche
Datumformat RFC822 genannt. Zum Beispiel auf ein Linux system:
$ date --rfc-822
Tue, 22 Mar 2016 18:00:52 -0700
Zuverlässigkeit: Ein unlösliches Problem, denn E-Mail ist ein
dezentrales System und jeder Rechner eine falsche Zeitstempel
hinzufügen kann. Auch wenn es nicht absichtlich ist.
>Der Date Header springt natürlich sofort ins Auge, aber ich denke
>nicht, dass der sonderlich zuverlässig ist.
>Regelmäßig bekomme ich Spam mit unbekannten Datum oder Datum in der
>Zukunft. Außerdem habe ich bei ersten Testläufen auch verschiedene
>Formate gesehen (z.B. die Zeit ohne Sekunden)
Ein E-Mail Programm (MUA [5]) kann irgendeine Datumformat benutzen.
(Die meisten Programmen benutzen ein vernünftiges Format.) Es soll
nicht so sein, aber das wichtigste ist daß, dieses Datum für die
Lieferung nicht geeignet ist. Dieses Datum ist nur für den
endgültige Leser vorgelegt.
Du kannst Dich entscheiden daß dieses Datum Deine Zwecke dient.
Ich würde lieber ein Server Zeitstempel trauen/glauben.
(Noch etwas: Die übliche Zeile 'From' 'To', 'Cc', 'Subject', 'Date'
sind bei manchen MTAs [6] nicht gelesen, nur die Absender- u.
Empfängeradresse vom SMTP Protokoll.)
>Nun frage ich mich, was da am zuverlässigsten ist?
Als Empfänger, kannst Du nie wirklich wissen. Es ist möglich daß
alle Rechner gelogen haben. Ein Rechner konnte alle vorige Received
Header geändert haben. Es ist auch möglich daß keiner gelogen hat.
Wenn alle Daten in Einklang sind, dann denke ich nur daß alles gut
läuft.
>Die erste Zeile From gibt es offensichtlich auch nicht bei allen
>Mails.
Ein bißchen merkwürdig(, aber fast alles ist so in diesem veralteten
System!) Die Verantwortung für dieses 'From' Zeile (N.B. keinen
Doppelpunkt, ':') gehört dem MDA [1] (Dovecot in Deinem Beispiel).
Vielleicht sind einige Emails auf anderer Weise in diesem
Datenverzeichnis geschrieben worden? (D.h. nicht von dem MDA
geschrieben worden, sondern von einem anderen Programm...)
>Sollte man einfach den ersten Received Header nehmen, am ";"
>trennen und dann datetime.strptime mit einen entsprechenden Format
>String drauf los lassen?
>
>Was denkt Ihr, ist das Beste?
Wenn ich wissen wollte wann ein Email geschickt wurde, würde ich
genau das tun. Man weiß daß ein Rechner vielleicht von NTP
(korrekte Zeit) abgeweicht ist. Aber was tut man, wenn man schon
ein Datei mit diesem Datum hat? Wenn es nicht um legales oder
gefährliches geht, dann greife ich zum ersten Received Header.
Man kann auch die Received Headers programmatisch lesen um
herauszufinden wo eine Email sich verspätet hat.
Und Christopher Arndt hat recht mit seinem dateutil Vorschlag:
>>> parser = dateutil.parser.parse
>>> parser('Fri, 5 Feb 2016 10:09:12 +0100 (CET)')
datetime.datetime(2016, 2, 5, 10, 9, 12, tzinfo=tzoffset(u'CET', 3600))
-Martin
[0] https://de.wikipedia.org/wiki/Network_Time_Protocol
[1] https://de.wikipedia.org/wiki/Mail_Delivery_Agent
[2] https://tools.ietf.org/html/rfc5322#section-3.3
[3] https://tools.ietf.org/html/rfc2822
[4] https://tools.ietf.org/html/rfc822
[5] https://de.wikipedia.org/wiki/E-Mail-Programm
[6] https://de.wikipedia.org/wiki/Mail_Transfer_Agent
[7] https://de.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol#Protokoll
(Meiner Meinung nach ist es auch ein Irrweg in der Perfektion von
dem eigenen Rechner zu glauben.)
--
Martin A. Brown
http://linux-ip.net/
Mehr Informationen über die Mailingliste python-de