Comment puis-je obtenir le contenu d'un courriel en utilisant Python?
avec un message RFC822 en python 2.6, Comment puis-je obtenir le droit partie texte / contenu simple? Basiquement, l'algorithme que je veux est ceci:
message = email.message_from_string(raw_message)
if has_mime_part(message, "text/plain"):
mime_part = get_mime_part(message, "text/plain")
text_content = decode_mime_part(mime_part)
elif has_mime_part(message, "text/html"):
mime_part = get_mime_part(message, "text/html")
html = decode_mime_part(mime_part)
text_content = render_html_to_plaintext(html)
else:
# fallback
text_content = str(message)
return text_content
De ces choses, j'ai get_mime_part
et has_mime_part
en bref, mais je ne sais pas comment obtenir le texte décodé de la partie MIME. Je peux obtenir le codé texte à l'aide de get_payload()
, mais si j'essaie d'utiliser le decode
paramètre get_payload()
méthode (voir le doc) j'ai une erreur quand je l'appelle sur la text/plain partie:
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/ email/message.py", line 189, in get_payload raise TypeError('Expected list, got %s' % type(self._payload)) TypeError: Expected list, got <type 'str'>
en outre, Je ne sais pas comment prendre HTML et le rendre au texte aussi près que possible.
2 réponses
Dans un multipart e-mail, email.message.Message.get_payload()
renvoie une liste avec un élément pour chaque partie. La façon la plus simple est de passer le message et d'obtenir la charge utile sur chaque partie:
import email
msg = email.message_from_string(raw_message)
for part in msg.walk():
# each part is a either non-multipart, or another multipart message
# that contains further parts... Message is organized like a tree
if part.get_content_type() == 'text/plain':
print part.get_payload() # prints the raw text
pour un message non Multi-partites, pas besoin de faire toute la marche. Vous pouvez aller directement à get_payload(), indépendamment de content_type.
msg = email.message_from_string(raw_message)
msg.get_payload()
si le contenu est encodé, vous devez passer None
comme premier paramètre à get_payload()
, suivi de True (le drapeau de décodage est le second paramètre). Pour exemple, supposons que mon courriel contienne une pièce jointe MS Word:
msg = email.message_from_string(raw_message)
for part in msg.walk():
if part.get_content_type() == 'application/msword':
name = part.get_param('name') or 'MyDoc.doc'
f = open(name, 'wb')
f.write(part.get_payload(None, True)) # You need None as the first param
# because part.is_multipart()
# is False
f.close()
pour ce qui est d'obtenir une approximation raisonnable en texte clair d'une partie HTML, j'ai trouvé que html2text fonctionne sacrément bien.
appartement est mieux que imbriquées ;)
from email.mime.multipart import MIMEMultipart
assert isinstance(msg, MIMEMultipart)
for _ in [k.get_payload() for k in msg.walk() if k.get_content_type() == 'text/plain']:
print _