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
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?
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
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
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.
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
Merci beaucoup c'est bien à cause de ça, énorme prise de tête vu que mon mémoire est à rendre dans 5 jours
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
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.
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_parserMais 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