【问题标题】:How can I attach image files and same image embedded to html email body in a mail?如何在邮件中附加图像文件和嵌入到 html 电子邮件正文的相同图像?
【发布时间】:2019-08-29 03:23:44
【问题描述】:

我只能附加图像文件,但嵌入的图像文件不会出现在邮件中。它说链接图像无法显示文件可能被删除、删除或重命名。验证链接点到正确的图像文件和位置,并且附加的文件大小相同。下面是我使用的代码

from requests_toolbelt import MultipartEncoder
import requests
import smtplib
import base64
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.mime.image import MIMEImage
from os.path import basename
from jinja2 import Template

def send_mail(send_from: str, subject: str, text: str,send_to: list, files= None):

    send_to= default_address if not send_to else send_to
    main = Template('''
    <html><body>
    {% for image in pictures %}<img src="cid:{{image}}">{% endfor %}
    </body></html>''')  
    msg = MIMEMultipart()
    html = main.render(pictures=files)
    part2 = MIMEText(html, 'html')
    msg.attach(part2)
    msg['From'] = send_from
    msg['To'] = ', '.join(send_to)
    msg['Subject'] = subject
    for f in files or []:
        with open(f, "rb") as fil:
            msgImage = MIMEImage(fil.read())
            ext = f.split('.')[-1:]
            attachedfile = MIMEApplication(fil.read(), _subtype = ext)
            fil.close()
            msgImage.add_header('Content-ID', '<{}>'.format(f))
            msgImage.add_header('content-Disposition','inline',filename=f)
            msg.attach(msgImage)
            attachedfile.add_header(
                'content-disposition', 'attachment', filename=basename(f) )
        msg.attach(msgImage)
        msg.attach(attachedfile)
    smtp = smtplib.SMTP(host="smtp-mail.outlook.com", port= 25)
    smtp.starttls()
    smtp.login(usr,pwd)
    smtp.sendmail(send_from, send_to, msg.as_string())
    smtp.close()
send_mail(send_from= frommail,
subject="Daily backup Testing",
text='files added: ',
send_to= tomail,
files= files_list)

我收到的邮件是。图像路径文件正确。当我打印时,我得到了这个files ['check123\\Screenshot (161).png', 'check123\\Screenshot (163).png', 'check123\\Screenshot (164).png'] 我该如何解决这个问题?

【问题讨论】:

    标签: python python-3.x email jinja2


    【解决方案1】:

    文件名不是特别适合作为cid: 标识符。特别是,反斜杠和括号在 cid: 标识符中无效。另见What are the valid characters for a Mime Multipart message ContentId "CID:"?

    也许只是从一组受限制的字符中生成唯一的随机标识符,然后将它们映射到您的文件名。

    在我的脑海中(未经测试),

    import random # in addition to the other imports you have
    import string
    
    # cribbed from https://stackoverflow.com/a/2030081/874188
    def random_cid ():
        letters = string.ascii_lowercase
        return ''.join(random.choice(letters) for i in range(10))
    
    def send_mail(send_from: str, subject: str, text: str,send_to: list, files= None):
    
        send_to= default_address if not send_to else send_to
    
        cid_map = { x: random_cid() for x in files }
        main = Template('''
        <html><body>
        {% for image in pictures %}<img src="cid:{{cid_map[image]}}">{% endfor %}
        </body></html>''')
        msg = MIMEMultipart()
        html = main.render(pictures=files, cid_map=cid_map)
        part2 = MIMEText(html, 'html')  
        # ...
        for f in files:
            with open(f, "rb") as fil:
                msgImage = MIMEImage(fil.read())
                ext = f.split('.')[-1:]
                attachedfile = MIMEApplication(fil.read(), _subtype = ext)
                fil.close()
                msgImage.add_header('Content-ID', '<{}>'.format(cid_map[f]))
                msgImage.add_header('content-Disposition','inline',filename=f)
                msg.attach(msgImage)
                attachedfile.add_header(
                    'content-disposition', 'attachment', filename=basename(f) )
    

    【讨论】:

    • 嘿,谢谢你的回答,我根据你的回答试过了,我得到了 UndefinedError: 'cid_map' is undefined, 我已经包含了有问题的更改代码,请看一下
    • @canIfixit 感谢您的反馈!我也需要将cid_map 传递给main.render(...) - 现在查看更新的答案。
    • 解决了我的图像嵌入问题,谢谢,但附件仍然是与图片问题相同大小的损坏文件。我没有看到任何解决此问题的方法。可能你应该知道问题的原因
    • 两次read() 文件的尝试肯定被破坏了,但我真的看不出你在这里要做什么......如果意图是修复图像的类型,不应该你要更新实际的MIMEImage 的类型?您认为您可以共享生成的 MIME 消息的 Pastebin 或类似内容吗?
    • 我正在尝试将图像文件附加并嵌入到邮件中。 MIMEImage 用于读取图像文件以嵌入图像,MIMEApplication 用于读取图像以附加图像文件。我不知道 pastebin 或任何其他共享方式
    猜你喜欢
    • 2010-10-29
    • 2011-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-16
    • 2012-05-10
    相关资源
    最近更新 更多