通过SMTP发送邮件时策略属性错误



我想发送一封邮件,邮件正文中有图片。

我可以发送没有图像或图像作为附件的电子邮件,但我无法发送电子邮件中显示的图像。

到目前为止我所做的是:

from email.encoders import encode_base64
from email.mime.base import MIMEBase
from PIL import Image
from io import BytesIO
from smtplib import SMTPException
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from smtplib import SMTP
import smtplib

msg = MIMEMultipart("related")
msg['Subject'] = subject #time
msg['From'] = from_addr
msg['To'] = to_addr
html_output = "your html here"
msg.attach(MIMEText(html_output, "html"))
#plots is a dictionary of images
for image_name, image_location in plots.items():
img = Image.open(BytesIO(image_location))
msg.attach(img)


smtplib.SMTP(host).sendmail(from_addr, to_addr, msg.as_string())

在Databricks

中出现以下错误
/usr/lib/python3.8/email/generator.py in _handle_multipart(self, msg)
274             s = self._new_buffer()
275             g = self.clone(s)
--> 276             g.flatten(part, unixfrom=False, linesep=self._NL)
277             msgtexts.append(s.getvalue())
278         # BAW: What about boundaries that are wrapped in double-quotes?
/usr/lib/python3.8/email/generator.py in flatten(self, msg, unixfrom, linesep)
105         # they are processed by this code.
106         old_gen_policy = self.policy
--> 107         old_msg_policy = msg.policy
108         try:
109             self.policy = policy
/databricks/python/lib/python3.8/site-packages/PIL/Image.py in __getattr__(self, name)
539             )
540             return self._category
--> 541         raise AttributeError(name)
542 
543     @property
AttributeError: policy

我做错了什么?

我不能告诉您PIL调用有什么问题,但是无论如何您在这里都不应该需要PIL。只需直接附加图像二进制文件。

顺便说一下,看起来你的email代码是为旧版本的Python编写的。标准库中的email模块在Python 3.6中进行了彻底修改,使其更具逻辑性、通用性和简洁性;新的代码应该针对(不再是非常)新的EmailMessageAPI。可能会丢掉这些代码,并从Pythonemail示例文档中的现代代码重新开始。"asparagus"示例演示了如何从HTML链接到图像,以及"家庭团聚";示例显示了如何附加一系列图像。这是一个综合两者的尝试。

from email.message import EmailMessage
from email.utils import make_msgid
import smtplib

imgs = []
for image_name, image_location in plots.items():
with open(image_location, "rb") as img:
image_data = img.read()
imgs.append({
"name": image_name,
"data": image_data,
"cid": make_msgid().strip("<>")
})
html = """
<html><head><title>Plots</title></head>
<body>
<h1>Your Plots</h1>
<p>Dear Victim,</p>
<p>Here are today's plots.
<ul>
"""
for img in imgs:
html += f'    <li><img src="cid:{img["cid"]}" alt="{img["name"]}" /></li>n'
html += """
</ul>
</p>
<p>Plot to take over the world!</p>
</body>
</html>
"""
msg = EmailMessage()
msg['Subject'] = subject #time
msg['From'] = from_addr
msg['To'] = to_addr
msg.set_content(html, subtype="html")
for img in imgs:
msg.add_related(
img["data"], "image", "png",
cid=f'<{img["cid"]}>')
with smtplib.SMTP(host) as s:
s.send_message(msg)

您显然需要调整HTML以适应您的需要,并检查代码中的一些其他假设(您的示例中有几个未初始化的变量,我只是复制了它们,并且我硬编码了我的猜测,您的图像将全部是PNG)。

将数据从plots复制到imgs稍微不吸引人;也许您可以简单地将CID添加到plots结构中。我不想破坏它,以防你有其他代码需要它以特定的方式。

您可以在html正文中自定义您的电子邮件,已经在<img src="image.jpg">中导入了您的图像

最新更新