【问题标题】:How to include inline images in e-mail signature when sent out with python?使用python发送时如何在电子邮件签名中包含内联图像?
【发布时间】:2023-03-18 08:51:01
【问题描述】:

如何发送带有内嵌图像的python电子邮件作为签名?目前,我使用一个链接来显示这样的图像:

<img border="0" src="https://website.com/logo.png" role="presentation" alt="logo mail icon" style="max-width: 300px; width: 300px; display: block;">

但在 Outlook 中,图像未加载,用户需要单击“显示图像”,这会破坏电子邮件,因为我将其用于商业目的(这是注册的确认链接)。有没有办法如何内联显示图像并通过电子邮件而不是链接发送它们?

到目前为止我的代码:

from email.message import EmailMessage
import smtplib, ssl
import email.utils
import html2text

with open(html_template, 'r') as f:
        html_string = f.read()

plain_text = html2text.html2text(html_string)

msg               = EmailMessage()
msg['Subject']    = subject
msg['From']       = mail_address
msg['To']         = email_receiver
msg['Date']       = email.utils.formatdate()
msg.add_header('Content-Type','text/html')
msg.add_header('Content-Disposition', 'attachment', filename=file_attachment)
msg.set_content(plain_text)
msg.add_alternative(html_string.format(name=surname), subtype='html')

files = [file_attachment]
for file in files:
    with open(file, 'rb') as f:
        file_data = f.read()
        file_name = f.name
    msg.add_attachment(file_data, maintype='application', subtype='octet-stream', filename=file_name)

with smtplib.SMTP(smtp, port) as smtp:
    smtp.ehlo()
    smtp.starttls(context=ssl.create_default_context())
    smtp.ehlo()
    smtp.login(mail_address, mail_password)

try:
    smtp.send_message(msg)
    smtp.quit()

except Exception as e:
    print('ERROR')

我找不到太多方法或解决方案。我已经阅读了有关将图像编码为 base64 的信息,但我有点困惑。

提前致谢!

【问题讨论】:

    标签: python html css email


    【解决方案1】:

    要内联显示图像,您必须在电子邮件本身中提供图像数据。您可以使用图像数据的 base64 编码字符串来实现。举个例子:

    &lt;img alt="Website" width="16" height="16" style="border:none;" src="data:image/png;filename=web.png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAABsAAAAbAFcG/0uAAABPElEQVQ4jaVT3U3DMBD+mgUSJqAbNEyQbkDYgL43Ejz7pUjkPZIHoBvUjNAJcDcoG7QTBH3mMzoikEC1dPL5/r+782wcR9jTdv09AFKD72cPYBu821rpV4C26+cAAoCF0Z91l0Z2oHnw7shHYZwjAN6PcnySLIo/S5ds5fMZQJlL0YNuOlaiONGV8sHsdv1MvC8AbhR9AHCNn8+7grD8NwCrQg17Dd7F4F1QRpZ8JbwH8ZRVtKEtfehbqNvB5EvlB+9OABKJP06aSZ+GEEZlOUnRmHctWe7HQuNEfhe/YP3zyQGG4N2SpPdGfBScpZoLYzfkMbKkdrI8ddv1eYSV+LlZLMhnPx0jMW/+M8a0ym3Xs9S8wjRigDsFS5AA7IwurXTwrs49YDksj0RsCUYeo3irIyXYF3+my74zgA9tApBUsNxB3wAAAABJRU5ErkJggg==" /&gt;

    您可以使用online converters 获取您的base64 字符串或直接在您的python 脚本中构建它:

    import base64
    encoded_string = base64.b64encode(open("image.png", "rb").read())
    

    请记住,内联图像也可能被收件人邮件客户端阻止,因此请始终提供正确的 alt 描述。

    【讨论】:

    • 非常感谢您的回复。我用几张图片尝试了你的建议进行测试,它部分有效 - 一张损坏的图片显示如下:imgur.com/a/q4Cz9JM 一张损坏的图片,但至少它是一张图片......这可能是由于缺少 add_header 还是什么造成的可能是问题吗?
    • 我刚刚意识到,问题在于 Gmail 没有解码图像而不是我的代码。这会导致另一个问题 - 如果使用 base64 编码,它在 Outlook 中看起来不错,但在 Gmail 中看起来很糟糕,反之亦然,当使用外部 src 链接时。我现在不知道该怎么办?
    • 您是否使用了正确的数据类型,例如data:image/png 用于 PNG 文件?
    • 是的 - 问题是 Gmail 不解码图像 - 我发现有几个线程在讨论这个问题。我现在将尝试使用“img src="cid:1" 嵌入它,所以让我们看看它是如何工作的......你知道如何在 python 代码中加载图像吗?谢谢!
    【解决方案2】:

    图像必须是 base64 编码,并且在将其实现到 html 标签时,需要使用 .decode() 删除 b' 前缀

    import base64
    encoded_string = base64.b64encode(open("image.png", "rb").read()).decode()
    

    HTML 代码:

    html = '''<img alt="Website" width="16" height="16" style="border:none;" src="data:image/png;filename=web.png;base64," />'''.format(logo=encoded_string)
    

    【讨论】:

      猜你喜欢
      • 2016-07-10
      • 2014-03-18
      • 2011-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-10
      • 1970-01-01
      相关资源
      最近更新 更多