Python-使用嵌入式图像将邮件发送到GMAIL

lol*_*olo 2 html python mail-sender

我有以下脚本可以成功发送带有附加到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)
Run Code Online (Sandbox Code Playgroud)

God*_*att 7

您需要附加它在HTML中引用它。即,附加一条带有HTML img的消息,该消息可获取已附加的图像。

我看到您进展顺利,正在使用相同的模块,并且具有正常工作的代码,因此您应该可以通过以下代码片段完成此工作:

.....
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)
Run Code Online (Sandbox Code Playgroud)