Path: csiph.com!fu-berlin.de!uni-berlin.de!not-for-mail From: "Martin A. Brown" Newsgroups: de.comp.lang.python Subject: Re: [Python-de] Datum aus Mails parsen Date: Tue, 22 Mar 2016 19:00:22 -0700 Lines: 156 Message-ID: References: <2799516.e1sbLbDSJX@horus> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 8BIT X-Trace: news.uni-berlin.de pxNG7ubQeaiMXOrWp/Ye5gqXUBJKjt7i+Kvh81snc+Rw== Return-Path: X-Original-To: python-de@python.org Delivered-To: python-de@mail.python.org X-X-Sender: mabrown@macron.wonderfrog.net In-Reply-To: <2799516.e1sbLbDSJX@horus> X-Content-Filtered-By: Mailman/MimeDel 2.1.21 X-BeenThere: python-de@python.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Die Deutsche Python Mailingliste List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Xref: csiph.com de.comp.lang.python:4322 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@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 ; 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 ; 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 ; Fri, 5 Feb 2016 10:09:11 +0100 (CET) >Received: by mail-lf0-f52.google.com with SMTP id 78so52976351lfy.3 > for ; 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/