Python:发送多部分 html 电子邮件,同时包含嵌入图像和附件
Python: Multipart html email is sent both with embedded image and attachment
查了很多帖子,还是没找到解决办法。
我可以发送带有嵌入图片的电子邮件,但电子邮件还包含这些图片作为附件,我只需要嵌入图片。我尝试了很多变体,'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>
首先附加 HTML 或为 multipart/related 内容类型指定一个“开始”参数。
引用 RFC2387:
The start parameter, if given, is the content-ID of the compound
object's "root". If not present the "root" is the first body part in
the Multipart/Related entity. The "root" is the element the
applications processes first.
因此,在您的示例中,您可以进行这些更改以标记根元素:
mail = MIMEMultipart("related", start="<HTML>", type="text/html")
...
msgHtml.add_header('Content-ID', '<HTML>')
至少在 Google 邮件中,首先放置 HTML 或添加“开始”参数可以让图像内联显示。
完整示例:
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()
查了很多帖子,还是没找到解决办法。 我可以发送带有嵌入图片的电子邮件,但电子邮件还包含这些图片作为附件,我只需要嵌入图片。我尝试了很多变体,'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>
首先附加 HTML 或为 multipart/related 内容类型指定一个“开始”参数。
引用 RFC2387:
The start parameter, if given, is the content-ID of the compound object's "root". If not present the "root" is the first body part in the Multipart/Related entity. The "root" is the element the applications processes first.
因此,在您的示例中,您可以进行这些更改以标记根元素:
mail = MIMEMultipart("related", start="<HTML>", type="text/html")
...
msgHtml.add_header('Content-ID', '<HTML>')
至少在 Google 邮件中,首先放置 HTML 或添加“开始”参数可以让图像内联显示。
完整示例:
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()