Python - 使用嵌入图像向 GMAIL 发送邮件
Posted
技术标签:
【中文标题】Python - 使用嵌入图像向 GMAIL 发送邮件【英文标题】:Python - send mail to GMAIL with embedded images 【发布时间】:2019-12-12 10:31:55 【问题描述】:我有以下脚本可以成功发送带有附加到 hotmail 的图像的邮件。 问题是,如果我向 GMAIL 发送相同的邮件,图像会附加在邮件中,而不是嵌入在 html 中。 为什么会这样?如何解决? 例如,HTML 中的图像以下列方式显示:
这是当前代码
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import base64
import email
import smtplib
import os
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
from email.header import Header
import codecs
from bs4 import BeautifulSoup
import mimetypes
import requests
import time
SMTP_SERVER = "xxx"
SMTP_PORT = 587
SMTP_USERNAME = "xxx"
SMTP_PASSWORD = "xxx"
SMTP_USE_TLS = False
FROM_EMAIL = "xxx@xxx.com"
lista_mails = ['my_mail@hotmail.com']
lista_apodos =['user']
subject='Test Mail'
def get_image(img_src):
if img_src.startswith('http://') or img_src.startswith('https://'):
try:
resp = requests.get(img_src)
except:
print("Failed to retrieve ".format(img_src))
print(resp.text)
return None
return MIMEImage(resp.content)
elif os.path.exists(img_src):
fh = open(img_src, 'rb')
image = MIMEImage(fh.read(),'jpeg')
image.add_header('Content-Disposition', 'attachment', filename=os.path.basename(img_src))
fh.close()
return image
return None
def envio_mail(who,nickname,subject):
html = codecs.open("index.html", 'r', 'utf-8').read()
msgRoot = MIMEMultipart('related')
msgRoot['From'] = FROM_EMAIL
msgRoot['Subject'] = subject
msgRoot['To'] = nickname + " <" + who + ">"
soup = BeautifulSoup(html,'lxml')
cid = 0
images = []
for img_element in soup.findAll('img', None):
img_src = img_element.get('src')
image = get_image(img_src)
if image is not None:
image.add_header('Content-ID', str(cid))
images.append(image)
img_element['src'] = "cid:" + str(cid)
cid += 1
for element in soup.findAll(attrs="background" : True):
img_src = element.get('background')
image = get_image(img_src)
if image is not None:
image.add_header('Content-ID', str(cid))
images.append(image)
element['background'] = "cid:" + str(cid)
cid += 1
html = str(soup)
msgAlternative = MIMEMultipart('alternative')
msgAlternative.attach(MIMEText(html, "html"))
msgRoot.attach(msgAlternative)
for image in images:
msgRoot.attach(image)
s = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
s.ehlo()
if SMTP_USE_TLS:
s.starttls() #Puts connection to SMTP server in TLS mode
s.ehlo()
s.login(SMTP_USERNAME, SMTP_PASSWORD)
s.sendmail(msgRoot['From'], who, msgRoot.as_string())
s.quit()
envio_mail(lista_mails[0],lista_apodos[0],subject)
【问题讨论】:
Send e-mail to Gmail with inline image using Python的可能重复 什么是 index.html ? 它是包含图像的 HTML: 我认为此链接可能对您有所帮助。 ***.com/questions/920910/… 【参考方案1】:您需要附加它并在 HTML 中引用它。 IE。附加一条带有 HTML img 的消息,该消息来源于您所附加的图像。
我看到你正在进行中,使用相同的模块并有一个工作代码,所以你应该能够使用下面的这个 sn-p 代码完成它:
.....
import os
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
.....
# Get the files/images you want to add.
img_dir = "/images"
images = [os.path.join(img_dir, i) for i in os.listdir(img_dir)]
# Added a enumerate loop around the whole procedure.
# Reference to cid:image_id_"j", which you will attach to the email later.
for j, val in enumerate(images):
msgText = MIMEText('<br> <img src="cid:image_id_"> </br>'.format(j), 'html')
msgAlternative.attach(msgText)
with open(''.format(val), "rb") as attachment:
msgImage = MIMEImage(attachment.read())
# Define the image's ID with counter as you will reference it.
msgImage.add_header('Content-ID', '<image_id_>'.format(j))
msgRoot.attach(msgImage)
【讨论】:
如何嵌入大约 10 张图片?我为每张图片重复“打开”? 好的,有多个图片/附件:我认为这样的东西应该适合你。只需循环/枚举附件过程 n 次并在“image_id”中添加一个计数器【参考方案2】:对我有用的代码如下,因为“msgAlternative.attach(msgText)”被其他图像覆盖,只有最后一个图像被发现嵌入:
for val in file_list:
img = dict(title = val, path = val, cid = str(uuid.uuid4()))
image.append(img)
msg_html += u'<h3>title</h3><div dir="ltr">''<img src="cid:cid" ><br></div>'.format(alt=cgi.escape(img['title'], quote=True), **img)
msg_html = MIMEText(msg_html, 'html', 'utf-8')
msgAlternative.attach(msg_html)
for j, val in enumerate(file_list):
with open(''.format(val), "rb") as attachment:
msgImage = MIMEImage(attachment.read())
# Define the image's ID with counter as you will reference it.
msgImage.add_header('Content-ID', '<>'.format(image[j]['cid']))
msgRoot.attach(msgImage)
【讨论】:
以上是关于Python - 使用嵌入图像向 GMAIL 发送邮件的主要内容,如果未能解决你的问题,请参考以下文章