这个问题实际上是这个答案的延续 https://stackoverflow.com/a/49098251/19308674。我正在尝试将多个嵌入图像(不仅仅是一个)添加到电子邮件内容中。
我想以循环遍历图像列表的方式来做到这一点,此外,每个图像旁边都会有不同的文本。 例如,您可以在“未来 10 天的天气”中看到类似的内容我想循环浏览文件夹中的图像,每个图像旁边都会有一些不同的文本,如示例中所示。
from email.message import EmailMessage
from email.utils import make_msgid
import mimetypes
msg = EmailMessage()
# generic email headers
msg['Subject'] = 'Hello there'
msg['From'] = 'ABCD <[email protected]>'
msg['To'] = 'PQRS <[email protected]>'
# set the plain text body
msg.set_content('This is a plain text body.')
# now create a Content-ID for the image
image_cid = make_msgid(domain='example.com')
# if `domain` argument isn't provided, it will
# use your computer's name
# set an alternative html body
msg.add_alternative("""\
<html>
<body>
<p>This is an HTML body.<br>
It also has an image.
</p>
<img src="cid:{image_cid}">
</body>
</html>
""".format(image_cid=image_cid[1:-1]), subtype='html')
# image_cid looks like <[email protected]>
# to use it as the img src, we don't need `<` or `>`
# so we use [1:-1] to strip them off
# now open the image and attach it to the email
with open('path/to/image.jpg', 'rb') as img:
# know the Content-Type of the image
maintype, subtype = mimetypes.guess_type(img.name)[0].split('/')
# attach it
msg.get_payload()[1].add_related(img.read(),
maintype=maintype,
subtype=subtype,
cid=image_cid)
# the message is ready now
# you can write it to a file
# or send it using smtplib
如果我能够猜到你想问什么,解决方案就是为每个图像生成一个唯一的
cid
。
from email.message import EmailMessage
from email.utils import make_msgid
# import mimetypes
msg = EmailMessage()
msg["Subject"] = "Hello there"
msg["From"] = "ABCD <[email protected]>"
msg["To"] = "PQRS <[email protected]>"
# create a Content-ID for each image
image_cid = [make_msgid(domain="example.com")[1:-1],
make_msgid(domain="example.com")[1:-1],
make_msgid(domain="example.com")[1:-1]]
msg.set_content("""\
<html>
<body>
<p>This is an HTML body.<br>
It also has three images.
</p>
<img src="cid:{image_cid[0]}"><br/>
<img src="cid:{image_cid[1]}"><br/>
<img src="cid:{image_cid[2]}">
</body>
</html>
""".format(image_cid=image_cid), subtype='html')
for idx, imgtup in enumerate([
("path/to/first.jpg", "jpeg"),
("file/name/of/second.png", "png"),
("path/to/third.gif", "gif")]):
imgfile, imgtype = imgtup
with open(imgfile, "rb") as img:
msg.add_related(
img.read(),
maintype="image",
subtype=imgtype,
cid=f"<{image_cid[idx]}>")
# The message is ready now.
# You can write it to a file
# or send it using smtplib
感谢使用现代
EmailMessage
API;我们仍然看到太多问题,盲目地从 Python 复制/粘贴旧 API <= 3.5 with MIMEMultipart
等等。
我拿出了
mimetypes
图像格式查询逻辑,有利于在代码中拼写出每个图像的类型。如果你需要Python来猜测,你知道如何做到这一点,但对于一个小的静态图像列表,似乎更有意义的是只指定每个图像,并避免开销以及不太可能但仍然不是不可能的问题启发式猜测错误。
我猜你的图像都将使用相同的格式,所以你实际上可以简单地硬编码
subtype="png"
或其他。
如何将更多的每图像信息添加到图像元组的循环中应该是显而易见的,但如果您的需求超出了微不足道的范围,您可能希望将图像及其各种属性封装到一个简单的类中。
对于无法访问 HTML 部分的收件人来说,您的消息显然毫无意义,因此我取出了您的虚假
text/plain
部分。您实际上是在向偏好查看纯文本而不是 HTML 的收件人发送了完全不同的消息;如果这确实是你的意图,请停止。如果您无法在纯文本版本中提供与 HTML 版本相同的信息,至少不要让这些收件人觉得您一开始就没有什么重要的事情要说。
顺便说一句,请不要伪造不属于您的域名的电子邮件地址。您最终会向垃圾邮件发送者通风报信,并让他们试图向无辜的第三方发送未经请求的消息。始终使用 IANA 保留域,如 example.com
、
example.org
等,这些域保证在现实中永远不存在。我编辑了你的问题来解决这个问题。仅作为嵌入与Python3.6中的EmailMessage()
。就我而言,图像已正确嵌入,但也显示为同一电子邮件中的附件,这非常烦人。
MIMEMultipart('related')
,因为
EmailMessage()
不行。下面是在 HTML 中发送嵌入图像的完整示例,图像也不会显示为附件。import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
from email.mime.text import MIMEText
# Must be set to 'related'
msg = MIMEMultipart('related')
msg['Subject'] = 'Email with Embedded Image'
msg['From'] = '[email protected]'
msg['To'] = '[email protected]'
# Your HTML - include image cid.
html_content = """
<html>
<body>
<p>Body with my embedded image.</p>
<img src="cid:foo">
</body>
</html>
"""
# Add HTML content to message
html_part = MIMEText(html_content, 'html')
msg.attach(html_part)
# Open the image in binary format, then attach to the message (it will be embedded)
with open('/path/to/img/foo.gif', 'rb') as img_file:
img = MIMEImage(img_file.read())
img.add_header('Content-ID', '<foo>')
img.add_header('Content-Disposition', 'inline; filename="/path/to/img/foo.gif"')
msg.attach(img)
# Send email
with smtplib.SMTP('internalsmtp.example.com', 587) as server:
server.send_message(msg)