Se connecter

Informatique

Programmation

Sujet : Impossible de parser certains mails
1
Exacompta
Niveau 10
05 mai 2021 à 23:44:30

Salut, pour un projet de mémoire je dois parser de nombreux mails et récupérer leur contenu pour certains ca fonctionne, et d'autres ca ne fonctionne pas.
Je cherche un moyen fiable en python ou en bash de récupérer le body du mail ainsi que ses pièces jointes (ou au moins le text/plain).

J'ai essayé avec un script de la doc officiel de python mais pour certains fichiers ca me les renvoie en entier au lieu de chaque parties. Le script en question : https://pastebin.com/mXRFhP57
le mail en question qui bloque : https://wikileaks.org/macron-emails//get/30435

Merci d'avance, ca fait des jours que je suis en galère car je dois rester absolument en python ou utilitaires linux

godrik
Niveau 22
06 mai 2021 à 00:32:29

mmm, le message a l'air bien former. Tu veux dire que walk ne renvoie qu'une seule partie et que cette partie est le message en entier, header inclu?

Exacompta
Niveau 10
06 mai 2021 à 01:11:42

Le 06 mai 2021 à 00:32:29 :
mmm, le message a l'air bien former. Tu veux dire que walk ne renvoie qu'une seule partie et que cette partie est le message en entier, header inclu?

Exact ! Le script me renvoie littéralement tout le mail et ce pour beaucoup de cas, et je ne trouve rien de spécial sur le net concernant cette erreur à croire que je suis le seul :hap:
Ca me fait devenir fou car j'ai 67k mails à parser et je ne sais pas quoi changer, car à lire tous les posts, le script fonctionne très bien

godrik
Niveau 22
06 mai 2021 à 03:51:32

OK.

Quand tu charges un email, tu recois un objet de type EmailMessage : https://docs.python.org/3/library/email.message.html
Il y a un champ de l'objet appelle "defects" qui te permet de savoir si le parsing c'est bien passe. Quand je regarde le contenu de defects su ton email j'obtiens: [MissingHeaderBodySeparatorDefect()]
La documentation de ce champ est dans: https://docs.python.org/3/library/email.errors.html#module-email.errors
Et cette erreur est documente par: "MissingHeaderBodySeparatorDefect - A line was found while parsing headers that had no leading white space but contained no ‘:’. Parsing continues assuming that the line represents the first line of the body."

Quand je regarde le contenu du fichier, je ne vois pas d'espace en debut de ligne. Mais par contre, j'ai remarque le fichier est ouvert avec un format binaire, et que le fichier est encode au format dos.
Ca veut dire que le fichier ne separe pas les lignes par un \n mais par \r\n
Je pense que c'est ca le probleme. Quand je converti le fichier de \r\n a \n, avec dos2unix, et que je reparse le fichier avec le module email: ca marche.

En esperant que ca t'aide.

Azerban
Niveau 15
06 mai 2021 à 13:02:04

Effectivement, c'est bien lié au format DOS et les retours à la ligne qui sèment la zizanie. J'ajoute que l'encodage utf-8 semble également poser des problèmes et qu'il vaut mieux encoder le tout en ASCII pour le parsing (ce que semble faire dos2unix).

En python si tu ne veux pas utiliser l'utilitaire tu peux faire comme ça.

# parsing_eml_files.py

import os.path
from email import policy
from email.parser import BytesParser

EMAIL_FILE = "./00035646.eml"

def dos2unix(filepath):
    """Convert DOS file to Unix file (remove CRLF line terminators)"""
    with open(filepath, mode="r") as file:
        path, extension = os.path.splitext(filepath)
        content = file.read().replace('\r\n', '\n')
        new_file = f"{path}_unix{extension}"
        with open(new_file, mode="w", encoding="ASCII", errors="ignore") as write_file:
            write_file.write(content)
    return new_file


if __name__ == "__main__":

    with open(dos2unix(EMAIL_FILE), "rb") as fp:
        msg = BytesParser(policy=policy.default).parse(fp)

    print("To:", msg["to"])
    print("From:", msg["from"])
    print("Subject:", msg["subject"])

Tu auras un fichier qui se terminera par _unix.eml (libre à toi de le supprimer ensuite ou pas). Le mieux est peut être de convertir chaque mail au format Unix avant le parsing.

Le script retourne:

To: mjs <mjs-86@googlegroups.com>
From: romain sling <romain.sling@gmail.com>
Subject: Re: tract formule H
Exacompta
Niveau 10
06 mai 2021 à 14:25:09

Merci beaucoup c'est bien à cause de ça, énorme prise de tête vu que mon mémoire est à rendre dans 5 jours :hap:
Merci encore, je pensais pas que ca serait un problème car j'avais essayé de changer la "policy" en ne mettant rien pour que les \r\n soient pris en compte mais apparemment ca ne fonctionnait pas comme ça :hap:

Azerban
Niveau 15
06 mai 2021 à 14:44:22

Après il y a des libs Python pour parser des fichiers eml : https://github.com/GOVCERT-LU/eml_parser

Mais je ne sais pas si c'est autorisé dans le cadre de ton mémoire.

Exacompta
Niveau 10
06 mai 2021 à 18:17:47

Le 06 mai 2021 à 14:44:22 :
Après il y a des libs Python pour parser des fichiers eml : https://github.com/GOVCERT-LU/eml_parser

Mais je ne sais pas si c'est autorisé dans le cadre de ton mémoire.

Ouai je connais mais je trouve ça un peu inutile d'utiliser d'autres libs sachant qu'il y en a déjà une intégrée dans python qui fait le taff.
D'ailleurs j'avais essayé avec des libs externes mais ca ne fonctionnait toujours pas

1
Sujet : Impossible de parser certains mails
   Retour haut de page
Consulter la version web de cette page