在电子邮件中嵌入图片

Posted

技术标签:

【中文标题】在电子邮件中嵌入图片【英文标题】:Embed picture in email 【发布时间】:2011-12-07 00:24:23 【问题描述】:

我目前有一个程序可以从列表中随机选择引号并通过电子邮件发送给它们。我现在也在尝试在电子邮件中嵌入图像。我遇到了一个问题,我可以附加电子邮件,但我的报价不再有效。我在网上进行了研究,但解决方案对我不起作用。请注意,我使用的是 Python 3.2.2。

任何指导将不胜感激。

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage

attachment = 'bob.jpg' 

msg = MIMEMultipart()
msg["To"] = to_addr
msg["From"] = from_addr
msg["Subject"] = subject_header

#msgText = MIMEText(<b>%s</b><br><img src="cid:bob.jpg"><br>, 'html') % body

fp = open(attachment, 'rb')
img = MIMEImage(fp.read())
fp.close()

msg.attach(img)

#email_message = '%s\n%s\n%s' % (subject_header, body, img)
email_message = '%s\n%s' % (subject_header, body)

emailRezi = smtplib.SMTP(mail_server, mail_server_port)
emailRezi.set_debuglevel(1)
emailRezi.login(mail_username, mail_password)
emailRezi.sendmail(from_addr, to_addr, email_message)
#emailRezi.sendmail(from_addr, to_addr, msg.as_string())
emailRezi.quit()

从上面的代码可以看出,我尝试了不同的方法(引用 #)

【问题讨论】:

因为现在电子邮件几乎总是以 HTML 格式显示,包括图像不是问题,但最终用户是否会看到它是另一回事,因为除非另有说明,否则它们几乎总是被阻止 请发布您正在使用的代码。 Python: Sending Multipart html emails which contain embedded images 的可能重复项 【参考方案1】:

您正在费尽心思在 msg 中构造一个有效的 MIME 消息,然后放弃它并发送一个简单的字符串 email_message

您应该首先了解正确的 MIME 结构是什么样的。多部分消息本身是没有内容的,如果你想要一个文本部分,你必须添加一个文本部分。

以下是添加了缺失部分的脚本编辑。我没有尝试发送结果消息。 但是,请参阅下面的现代化版本。

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText  # Added
from email.mime.image import MIMEImage

attachment = 'bob.jpg'

msg = MIMEMultipart()
msg["To"] = to_addr
msg["From"] = from_addr
msg["Subject"] = subject

msgText = MIMEText('<b>%s</b><br/><img src="cid:%s"/><br/>' % (body, attachment), 'html')   
msg.attach(msgText)   # Added, and edited the previous line

with open(attachment, 'rb') as fp:
    img = MIMEImage(fp.read())
img.add_header('Content-ID', '<>'.format(attachment))
msg.attach(img)

print(msg.as_string()) # or go ahead and send it

(我还稍微清理了HTML。)

自 Python 3.6 以来,Python 的 email 库已升级为更加模块化、逻辑化和正交化(从技术上讲,自 3.3 以来已经真正实现了,但在 3.6 中,新版本成为首选)。新代码应该避免像上面的代码那样显式创建单独的 MIME 部分,并且可能看起来更像

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

attachment = 'bob.jpg'

msg = EmailMessage()
msg["To"] = to_addr
msg["From"] = from_addr
msg["Subject"] = subject

attachment_cid = make_msgid()

msg.set_content(
    '<b>%s</b><br/><img src="cid:%s"/><br/>' % (
        body, attachment_cid[1:-1]), 'html')

with open(attachment, 'rb') as fp:
    msg.add_related(
        fp.read(), 'image', 'jpeg', cid=attachment_cid)

# print(msg.as_string()), or go ahead and send

您会注意到这与email examples documentation in the Python standard library. 中的“芦笋”示例非常相似

【讨论】:

太棒了。感谢您为此提供帮助。电子邮件发送时带有图片作为电子邮件正文中的红色 X 框。 我应该添加我的修复方法。除了来自 Tripleee 的添加之外,我还把我的 img 放在了 imgur 上并引用了 url。 如果您真的想附加图像,正确的解决方法是将正确的文件名添加到附件的元数据中。 ***.com/questions/920910/… 有一个更完整的例子。 需要是:img.add_header('Content-ID', '&lt;&gt;'.format(attachment)) @ZackPlauché 感谢您的注意,我忘记修剪 HTML 中 cid: 链接周围的断点。现已修复。【参考方案2】:

我已编辑以将图像附加到邮件正文和 HTML 模板上。

import smtplib
from email import encoders
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage

strFrom = 'zzzzzz@gmail.com'
strTo = 'xxxxx@gmail.com'

# Create the root message 

msgRoot = MIMEMultipart('related')
msgRoot['Subject'] = 'test message'
msgRoot['From'] = strFrom
msgRoot['To'] = strTo
msgRoot['Cc'] =cc
msgRoot.preamble = 'Multi-part message in MIME format.'

msgAlternative = MIMEMultipart('alternative')
msgRoot.attach(msgAlternative)

msgText = MIMEText('Alternative plain text message.')
msgAlternative.attach(msgText)

msgText = MIMEText('<b>Some <i>HTML</i> text</b> and an image.<br><img src="cid:image1"><br>KPI-DATA!', 'html')
msgAlternative.attach(msgText)

#Attach Image 
fp = open('test.png', 'rb') #Read image 
msgImage = MIMEImage(fp.read())
fp.close()

# Define the image's ID as referenced above
msgImage.add_header('Content-ID', '<image1>')
msgRoot.attach(msgImage)

import smtplib
smtp = smtplib.SMTP()
smtp.connect('smtp.gmail.com') #SMTp Server Details
smtp.login('exampleuser', 'examplepass') #Username and Password of Account
smtp.sendmail(strFrom, strTo, msgRoot.as_string())
smtp.quit()

【讨论】:

嘿,这行得通!但是,您使用的是“compat32”API。我不知道如何使用更“现代”的 EmailMessage 界面来做同样的事情,你知道怎么做吗? 这就像一个魅力。谢谢@Sachin @musbur,到目前为止我还没有探索过。

以上是关于在电子邮件中嵌入图片的主要内容,如果未能解决你的问题,请参考以下文章

使用电子表格插入图片,如何使图片刚好填满整个单元格,而不是浮在上面

如何确保 HTML 电子邮件中嵌入的图像显示出来?

Gmail 阻止电子邮件模板中嵌入的小型嵌入式图像

在c++builder中使用indy编程,想要在邮件体内嵌入一个jpg图片,不用超链接的方法怎么实现。

在邮件正文 phpmailer 类中添加嵌入图像

如何插入嵌入的图片?