Python:同时包含嵌入图片和附件的多部分HTML电子邮件被发送了。

3

我查看了很多相关的帖子,但仍然找不到解决方案。我能够发送包含嵌入图片的电子邮件,但是该电子邮件也包括这些图片作为附件,而我只需要嵌入的图片。我尝试了许多变化,包括“related”类型,“mixed”类型。还使用Python程序内部的HTML代码(而不是Jinja2模板),但我无法使其正常工作。

list_of_images = get_graphs() #list with file names

# here if I put "related" - images are sent ONLY as attachments 
mail = MIMEMultipart() 
for filename in list_of_images:
    fp = open(filename, 'rb')
    msg_img = MIMEImage(fp.read())
    fp.close()
    msg_img.add_header('Content-ID', '<{}>'.format(filename))
    msg_img.add_header('Content-Disposition', 'inline', filename=filename)
    mail.attach(msg_img)
#Jinja2 for html template
env = Environment(loader=FileSystemLoader('.'))
main = env.get_template('images.tpl')
html = main.render(pictures=list_of_images)
msgHtml = MIMEText(html, 'html')
mail.attach(msgHtml)

mail['Subject'] = "TEST"
mail['From'] = "email@addr"
mail['To'] = "email@addr"
s = smtplib.SMTP("localhost")
s.sendmail(mail['From'], "email@addr", mail.as_string())
s.quit()

Jinja模板:

<html>
<body>
{% for image in pictures %}
<img src="cid:{{image}}">
{% endfor %}
</body>
</html>
1个回答

1

首先附上HTML或在multipart/related内容类型中指定“start”参数。

引用RFC2387

如果提供了start参数,则为复合对象的内容ID。 如果不存在,则“root”是Multipart/Related实体中的第一个正文部分。 “root”是应用程序首先处理的元素。

因此,在您的示例中,您可能需要进行以下更改以标记根元素:

mail = MIMEMultipart("related", start="<HTML>", type="text/html") 
...
msgHtml.add_header('Content-ID', '<HTML>')

至少在Google邮件中,将HTML放在前面或添加“start”参数都可以使图像内联显示。
完整示例:
from jinja2 import Template
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
from glob import glob
from getpass import getpass
import smtplib

me = 'example@gmail.com'
you= 'example@gmail.com'
auth = ('example@gmail.com', getpass())
mx=  ('smtp.gmail.com', 465)

list_of_images = glob('*.jpg')

mail = MIMEMultipart("related")
#Jinja2 for html template
main = Template('''
    <html><body>
    {% for image in pictures %}<img src="cid:{{image}}">{% endfor %}
    </body></html>''')
html = main.render(pictures=list_of_images)
msgHtml = MIMEText(html, 'html')
mail.attach(msgHtml)

for filename in list_of_images:
    fp = open(filename, 'rb')
    msg_img = MIMEImage(fp.read())
    fp.close()
    msg_img.add_header('Content-ID', '<{}>'.format(filename))
    msg_img.add_header('Content-Disposition', 'inline', filename=filename)
    mail.attach(msg_img)

mail['Subject'] = "TEST"
mail['From'] = me
mail['To'] = you

s = smtplib.SMTP_SSL(*mx)
s.login(*auth)
s.sendmail(me, you, mail.as_string())
s.quit()

谢谢你的回答,Rob! - Yuliya
如果我将HTML部分放在图像部分之前,它就解决了我的问题。然而,“start”选项的情况对我没有起作用,仍然会发送嵌入式图像和附件。 - Yuliya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接