Je voulais extraire un e-mail avec une étiquette spécifique de Gmail, j'ai donc créé un mémo en Python.
La connexion et l'étiquetage sont simples.
import imaplib, re, email, six, dateutil.parser
email_default_encoding = 'iso-2022-jp'
def main():
gmail = imaplib.IMAP4_SSL("imap.gmail.com")
gmail.login("user","password")
gmail.select('INBOX') #Spécifiez votre boîte de réception
gmail.select('register') #Spécifiez l'étiquette
Récupérez le courrier avec .search ()
.
Si vous spécifiez ALL, vous pouvez obtenir tous les éléments non lus dans UNSEEN.
Pour les autres paramètres, assurez-vous de consulter le manuel IMAP4. Bien que ce soit en anglais.
INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1
typ, [data] = gmail.search(None, "(UNSEEN)")
#typ, [data] = gmail.search(None, "(ALL)")
#Vérification
if typ == "OK":
if data != '':
print("New Mail")
else:
print("Non")
#Traitement de la liste de diffusion acquise
for num in data.split():
###Traitement à chaque mail###
#Nettoyer
gmail.close()
gmail.logout()
La partie centrale vérifie simplement si elle a été reçue. Après cela, écrivez le traitement pour chaque courrier, et c'est le flux final. À partir du suivant, nous obtiendrons l'expéditeur, le titre et le texte dans la partie traitement du courrier.
Puisque seul l'identifiant du mail cible peut être obtenu par .search ()
, tout le mail avec l'identifiant spécifié par .fetch ()
est accessible.
Vous devez d'abord obtenir le code de caractère de l'e-mail.
Après avoir analysé le courrier en utilisant ʻemail.message_from_string, la partie titre est accédée, et si le code de caractère est spécifié, il est défini, sinon la valeur par défaut ʻiso2022-jp
est définie.
Après cela, je décode à nouveau avec ce code de caractère, mais je pense qu'il semble y avoir une meilleure façon de l'écrire ici ...
for num in data.split():
###Traitement à chaque mail###
result, d = gmail.fetch(num, "(RFC822)")
raw_email = d[0][1]
#Pour l'acquisition de code de caractère
msg = email.message_from_string(raw_email.decode('utf-8'))
msg_encoding = email.header.decode_header(msg.get('Subject'))[0][1] or 'iso-2022-jp'
#Analyser et préparer l'analyse
msg = email.message_from_string(raw_email.decode(msg_encoding))
print(msg.keys())
Vous pouvez vérifier les éléments qui peuvent être obtenus ici avec msg.keys ()
.
['Delivered-To', 'Received', 'X-Received', 'Return-Path', 'Received', 'Received-SPF', 'Authentication-Results', 'DKIM-Signature', 'Subject', 'From', 'To', 'Errors-To', 'MIME-Version', 'Date', 'X-Mailer', 'X-Priority', 'Content-Type', 'Message-ID', 'X-Antivirus', 'X-Antivirus-Status']
Obtenez l'expéditeur, mais ayez du mal ici.
fromObj = email.header.decode_header(msg.get('From'))
addr = ""
for f in fromObj:
if isinstance(f[0],bytes):
addr += f[0].decode(msg_encoding)
else:
addr += f[0]
print(addr)
Si vous analysez quelque chose comme "Expéditeur <[email protected]>
"
fromObj [0] [0]: b'xxxxxxxxx '・ ・ ・ Encodé "De" fromObj [0] [1]: 'iso-2022-jp' ・ ・ ・ Code de caractère fromObj [1] [0]: b '[email protected]' ・ ・ ・ Partie adresse fromObj [1] [1]: Aucun ・ ・ ・ Aucun code de caractère car seuls les caractères alphanumériques
Il semble que vous puissiez l'obtenir au format.
De plus, s'il n'y a pas de notation japonaise, elle ne sera pas décomposée si c'est comme "Sashidashi <[email protected]>
"
fromObj[0][0] : 'Sashidashi<[email protected]>'
fromObj[0][1] : None
Il devient de type str sous la forme de. Donc, j'obtiens le tout par jugement de type boucle +.
J'ai fait la même chose pour le titre et ça a marché.
subject = email.header.decode_header(msg.get('Subject'))
title = ""
for sub in subject:
if isinstance(sub[0],bytes):
title += sub[0].decode(msg_encoding)
else:
title += sub[0]
print(title)
De plus, la partie expéditeur peut ne pas pouvoir être décodée correctement si le japonais est inclus dans certains e-mails. Je vais le résumer dans un autre article.
Obtenez la date et changez le format.
Si vous voulez le format aaaaMMjj, il est facile d'utiliser dateutil
.
date = dateutil.parser.parse(msg.get('Date')).strftime("%Y/%m/%d %H:%M:%S")
print(date)
L'acquisition du texte a également une branche.
Vous pouvez l'obtenir avec .get_payload ()
, mais dans le cas du courrier envoyé au format html, le texte et le html sont également obtenus, donc le texte / plain est retiré.
body = ""
if msg.is_multipart():
for payload in msg.get_payload():
if payload.get_content_type() == "text/plain":
body = payload.get_payload()
else:
if msg.get_content_type() == "text/plain":
body = msg.get_payload()
J'ai eu du mal à ne pas savoir comment définir et supprimer des étiquettes.
#Non lu
gmail.store(num, '-FLAGS','\\SEEN')
#Ajouter une étiquette
gmail.store(num, '+X-GM-LABELS','added')
#Supprimer l'étiquette
gmail.store(num, '-X-GM-LABELS','added')
Il semble que cela puisse être fait en spécifiant "X-GM-LABELS". "+" Pour ajouter, "-" pour supprimer. Source: Extensions IMAP Gmail
Y compris ceux mentionnés ci-dessus INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1 Gmail IMAP Extensions IMAP4 (Internet Mail Access Protocol version 4) - Partie 1 IMAP4 (Internet Mail Access Protocol version 4) -Partie 2 email - Package pour le traitement des e-mails et MIME
Non, c'est difficile si vous ne comprenez pas correctement imap4.
Recommended Posts