MIMEImage不在电子邮件正文中显示/试图将图像嵌入电子邮件中

问题描述 投票:2回答:2

我正在尝试将图像嵌入电子邮件中。我遵循了示例hereherehere以及其他示例,但是我无法显示图像。

    import smtplib
    import os

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

    logo = 'mylogo.png'
    msg = MIMEMultipart('alternative')
    msg['Subject'] = "Link"
    msg['From'] = '[email protected]'
    msg['To'] = '[email protected]'

    html = """\
    <html>
      <head></head>
    <body>
      <p>GREETING<br><br>
       SOME TEXT<br>
       MORE TEXT<br><br>
       FAREWELL <br><br>
       DISCLAIMER
    </p>
    <img src="cid:image1" alt="Logo" \>
    </body>
    </html> """

    part1 = MIMEText(text, 'plain')
    part2 = MIMEText(html, 'html', 'utf-8')

    msg.attach(part1)
    msg.attach(part2)

    fp = open(logo, 'rb')
    msgImage = MIMEImage(fp.read())
    fp.close()

    msgImage.add_header('Content-ID', '<image1>')
    msgImage.add_header('Content-Disposition', 'inline', filename=os.path.basename(logo))
    msgImage.add_header("Content-Transfer-Encoding", "base64")
    msg.attach(msgImage)

    s = smtplib.SMTP(smtp_server,25)
    s.sendmail(sender, recipient, msg.as_string())
    s.quit()

[执行此操作时,我得到一个空的身体,上面有一个红色的十字,没有图像。如何使图像与电子邮件正文内嵌显示?

[我正在使用Outlook2016。我知道我可以在使用Outlook本身时插入图片,并且我收到'普通'电子邮件,其他人在文本中插入了图像,因此,这肯定意味着我必须能够查看从python脚本生成的图像?

编辑:我已经看过给定的here解决方案,建议作为可能的重复方案,但这也没有解决我的问题。

我也尝试过将相同的电子邮件发送到Gmail和Hotmail帐户,并且仍然出现相同的问题,因此该问题显然与代码有关。

python-3.x image email html-email mime
2个回答
1
投票

我在Outlook 2013中找到了解决方案:

Outlook似乎在查找跨度标签以及一些图像信息,例如高度和宽度(目前为硬编码)和id等(请参见下文)。我将图像包装在此html文本中,然后还添加了图像作为附件使用与我的cid和id相同的编号。图像然后在Outlook中显示为嵌入式文件。

    # loop through all uploaded files and add as attachments
    for index, file in enumerate(attachment):
       with open(file, "rb") as fp:
          data = fp.read()
          fileType = os.path.splitext(file)[-1].strip(".")

          ctype, _ = mimetypes.guess_type(file)

          if embedImages and "image/" in ctype:
             image = Image.open(data)
             # Build out the html for the email
             message += '<span style = "mso-no-proof:yes"><img width = 1280 height = 1920 id = "%s" src = "cid:%s"></span>' % (index, index)
             # Define the image's ID
             msgImage = MIMEImage(data, _subtype=fileType)
             msgImage.add_header('Content-ID', '<%s>' % index)
             msg.attach(msgImage)
             att = MIMEApplication(data, _subtype=fileType)
             att.add_header("Content-Disposition", "attachment", filename="%s" % index)
             msg.attach(att)
        else:
             att = MIMEApplication(data, _subtype=fileType)
             att.add_header("Content-Disposition", "attachment", filename=fileName)
             msg.attach(att)
        fp.close()

        # Attach html text
        if message:
            if embedImages or "mimeType" in kwargs:
                msg.attach(MIMEText(message, kwargs["mimeType"], 'utf-8'))
            else:
                msg.attach(MIMEText(message, "plain", 'utf-8'))

0
投票

这里是使用MIMEMultipart('related')的另一种解决方案,因此您不必处理Outlook中的跨度。适用于任何类型的多个附件。 (除非另有说明,否则图像将被嵌入)

    # Determine attach type - defaults to attached only
    embedImages = kwargs["embedImages"] if "embedImages" in kwargs else False

    # Create the root message and fill in the from, and subject headers
    msgRoot = MIMEMultipart('related')
    msgRoot["Subject"] = subject
    msgRoot["From"] = kwargs["fromAddr"] if "fromAddr" in kwargs else noreply

    # Encapsulate the plain and HTML versions of the message body in an
    # 'alternative' part, so message agents can decide which they want to display.
    msgAlternative = MIMEMultipart('alternative')
    msgRoot.attach(msgAlternative)

    # Get Recipient Type
    recipientType = kwargs.get("recipientType")

    # Chunk Process Recipients
    batchSize = 100
    for i in range(0, len(recipientList), batchSize):
        # Handle 100 recipients at a time
        recipients = recipientList[i:i + batchSize]
        # Set the to, bcc or cc in root message
        if recipientType == "bcc":
            msgRoot["Bcc"] = ", ".join(recipients)
        elif recipientType == "cc":
            msgRoot["Cc"] = ", ".join(recipients)
        else:
            msgRoot["To"] = ", ".join(recipients)

        # Add Attachments
        if attachment and isinstance(attachment, str):
            # For backwards compatibility turn single attachment into a list
            attachment = [attachment]

        # loop through all uploaded files and add as attachments
        for index, file in enumerate(attachment):
            with open(file, "rb") as fp:
                # guess the file type from mimetypes
                ctype, _ = mimetypes.guess_type(file)
                if embedImages and "image/" in ctype:
                    # Build out the html for the email
                    message += '<p><img src="cid:%s"></p>' % index
                    msgImage = MIMEImage(fp.read())
                    # Define the image's ID in header
                    msgImage.add_header('Content-ID', '<%s>' % index)
                    # attach it to root
                    msgRoot.attach(msgImage)
                else:
                    fileName = alias if alias and len(attachment) == 1 else os.path.basename(file)
                    msgApp = MIMEApplication(fp.read())
                    # define header as attachment
                    msgApp.add_header("Content-Disposition", "attachment", filename=fileName)
                    # attach it to root
                    msgRoot.attach(msgApp)
                # close the file handle
                fp.close()

        # Attach html text
        if message:
            if embedImages or "mimeType" in kwargs:
                msgAlternative.attach(MIMEText(message, kwargs["mimeType"], 'utf-8'))
            else:
                msgAlternative.attach(MIMEText(message, "plain", 'utf-8'))
© www.soinside.com 2019 - 2024. All rights reserved.