我想解析(序列化)多部分电子邮件(或具有内嵌图像、附件等的多个电子邮件附件的任何和所有类型),使用一些额外信息设置其正文内容类型,并在发送之前重新生成电子邮件出来。如何用最简单的Python代码来实现这一点呢?使用Python 3.6版本。 现在我正在使用 email.walk() 并获取第一个可用的 text/plain、text/html 并假设它是覆盖邮件的正文,通过 walk() 进一步递归地解析邮件的不同部分...这看起来很麻烦。有什么简单的方法吗? 添加我正在尝试的代码片段: #!/usr/bin/python3 ”“” 用法: 从命令行:cat mail | python warning_mail_stdout.py
此脚本从标准输入读取邮件并在邮件正文中附加“警告” 并将附加邮件打印到标准输出 “”“
import imaplib
import email
import logging
import smtplib
import re
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
# from subprocess import Popen, PIPE
import sys
import email, os
title = ''
logger = logging.getLogger()
handler = logging.StreamHandler()
formatter = logging.Formatter(
'%(asctime)s %(name)-12s %(levelname)-8s %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.INFO)
from email.policy import default
from email import policy
from email.parser import BytesParser
from email.mime.message import MIMEMessage
parser = email.parser.Parser()
def login():
# Read message from Std Input
mail = BytesParser(policy=policy.default).parse(open('1email_sample.eml','rb'))
if mail is None:
print("No mail in stdin ...")
else:
#mail is not None:
mbody = ''
mhtml = ''
text_body = ''
mail_charset = None
html_body = ''
mail_from = email.utils.parseaddr(mail['From'])[1]
mwarn = ''
new_message = ''
attached_bool = False
mail_attached_bool = False
h=p=related_body=None
h_body=plain_body = None
new_message1 = email.message.EmailMessage()#policy=default)
warning_txt = "[Caution: This message came from an external domain.]"
new_message = email.message.EmailMessage()
# copying header values
for header_val in mail:
parser.parsestr(header_val)
new_message[header_val] = mail[header_val]
print(new_message[header_val])
mailbody = mail.get_body(preferencelist=('related', 'html', 'plain'))
new_message1.attach(mailbody)
new_message.set_type('multipart/related')
new_message.attach(new_message1)
for p in mail.iter_attachments():
if p.is_attachment():
new_message.attach(p)
recipients = [
"<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="25564d441216655c444d4a4a0b464a48" rel="noreferrer noopener nofollow">[email protected]</a>",
]
# s ---is the smtp server to send out mail
#'''
try:
print(new_message.get_content_type(), 'vvvvv sent')
s.sendmail(mail_from, recipients,bytes(new_message))
except UnicodeEncodeError:
s.sendmail(mail_from, recipients,
new_message.as_string().encode("utf-8"))
#'''
s.close()
if __name__ == "__main__":
login()
最佳答案
如果您只想更改 body 部位的某些内容,您甚至不需要 walk
方法。 get_body
可以为您完成这项工作,尽管它可能会对某些不合规的消息产生意外的结果,但它可能比您或我能想到的任何东西都要可靠得多。
所以你的程序流程应该是
- 使用
解析器
对象构建树 - 可能会检查
defects
属性以确保该消息适合您 - 在树上调用
get_body
- 对
get_body
返回的 mime 部分执行您需要的操作 - 使用
生成器
对象序列化树
我在这里添加一些示例。不幸的是,文档还很不清楚,所以也许这会有所帮助:
>>> from email.message import EmailMessage
>>> import email.policy
>>> from email import message_from_binary_file
>>> msgin = open('1email_sample.eml', 'rb')
>>> msg = message_from_binary_file(msgin, policy=email.policy.default)
>>> for part in msg.walk():
print(part.get_content_type())
multipart/related
multipart/alternative
text/plain
text/html
image/png
image/png
image/png
image/png
image/png
image/png
image/png
>>> body = msg.get_body('plain') ##get the plain text, not 'related'
>>> btext = body.get_payload()
>>> type(btext)
<class 'str'>
>>> len(btext)
6926
>>> body.set_payload('this is my message' + btext)
>>> len(body.get_payload())
6944
>>> body2=msg.get_body('html') ##same with html
>>> bhtml=body2.get_payload()
>>> type(bhtml)
<class 'str'>
关于python - 使用python 3.7,如何确保正确修改正文内容后正确重新生成已解析的电子邮件而不丢失任何内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67919536/