Подтвердить что ты не робот

Отправка многостраничных html-сообщений, содержащих встроенные изображения

Я играл с модулем электронной почты в python, но я хочу знать, как вставлять изображения, которые включены в html.

Так, например, если тело похоже на

<img src="../path/image.png"></img>

Я хотел бы вставить image.png в электронную почту, а атрибут src должен быть заменен на content-id. Кто-нибудь знает, как это сделать?

4b9b3361

Ответ 1

Вот пример, который я нашел.

Рецепт 473810: отправьте HTML-письмо со встроенным изображением и альтернативным альтернативным текстом:

HTML - это метод выбора для тех желая отправлять электронные письма с использованием богатого текста, макет и графика. Часто это желательно встроить графику в сообщение, которое получатели могут отображать сообщение напрямую, без дальнейших загрузки.

Некоторые почтовые агенты не поддерживают HTML или их пользователи предпочитают получать простые текстовые сообщения. Отправители HTML сообщения должны включать обычный текст сообщение в качестве альтернативы для этих пользователей.

Этот рецепт отправляет короткое сообщение HTML с одним встроенным изображением и альтернативное текстовое сообщение.

# Send an HTML email with an embedded image and a plain text message for
# email clients that don't want to display the HTML.

from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEImage import MIMEImage

# Define these once; use them twice!
strFrom = '[email protected]'
strTo = '[email protected]'

# Create the root message and fill in the from, to, and subject headers
msgRoot = MIMEMultipart('related')
msgRoot['Subject'] = 'test message'
msgRoot['From'] = strFrom
msgRoot['To'] = strTo
msgRoot.preamble = 'This is a multi-part message in MIME format.'

# 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)

msgText = MIMEText('This is the alternative plain text message.')
msgAlternative.attach(msgText)

# We reference the image in the IMG SRC attribute by the ID we give it below
msgText = MIMEText('<b>Some <i>HTML</i> text</b> and an image.<br><img src="cid:image1"><br>Nifty!', 'html')
msgAlternative.attach(msgText)

# This example assumes the image is in the current directory
fp = open('test.jpg', 'rb')
msgImage = MIMEImage(fp.read())
fp.close()

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

# Send the email (this example assumes SMTP authentication is required)
import smtplib
smtp = smtplib.SMTP()
smtp.connect('smtp.example.com')
smtp.login('exampleuser', 'examplepass')
smtp.sendmail(strFrom, strTo, msgRoot.as_string())
smtp.quit()

Ответ 2

Для Python версии 3.4 и выше.

Принятый ответ превосходный, но подходит только для старых версий Python (2.x и 3.3). Я думаю, что он нуждается в обновлении.

Здесь вы можете сделать это в новых версиях Python (3.4 и выше):

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

msg = EmailMessage()

# generic email headers
msg['Subject'] = 'Hello there'
msg['From'] = 'ABCD <[email protected]>'
msg['To'] = 'PQRS <[email protected]>'

# set the plain text body
msg.set_content('This is a plain text body.')

# now create a Content-ID for the image
image_cid = make_msgid(domain='xyz.com')
# if 'domain' argument isn't provided, it will 
# use your computer name

# set an alternative html body
msg.add_alternative("""\
<html>
    <body>
        <p>This is an HTML body.<br>
           It also has an image.
        </p>
        <img src="cid:{image_cid}">
    </body>
</html>
""".format(image_cid=image_cid[1:-1]), subtype='html')
# image_cid looks like <[email protected]>
# to use it as the img src, we don't need '<' or '>'
# so we use [1:-1] to strip them off


# now open the image and attach it to the email
with open('path/to/image.jpg', 'rb') as img:

    # know the Content-Type of the image
    maintype, subtype = mimetypes.guess_type(img.name)[0].split('/')

    # attach it
    msg.get_payload()[1].add_related(img.read(), 
                                         maintype=maintype, 
                                         subtype=subtype, 
                                         cid=image_cid)


# the message is ready now
# you can write it to a file
# or send it using smtplib

Ответ 3

Этот метод для Python 3.X.X не работает правильно. Если вы отправите электронное письмо, используя описанную выше процедуру, например, для учетной записи Gmail, веб-клиент отобразит изображение как вложение, а не как встроенное изображение. Thunderbird v.69.0 показывает правильное сообщение.