L'invio di messaggi di posta elettronica html più parti che contengono immagini incorporate
-
06-09-2019 - |
Domanda
Ho giocato in giro con il modulo di e-mail in Python, ma voglio essere in grado di sapere come incorporare le immagini che sono incluse nel codice HTML.
Così, per esempio, se il corpo è qualcosa di simile
<img src="../path/image.png"></img>
Vorrei incorporare immagine.png nel email, e l'attributo src
dovrebbe essere sostituito con content-id
. Qualcuno sa come fare questo?
Soluzione
Ecco un esempio che ho trovato.
Ricetta 473.810: Invia una e-mail HTML con immagini embedded e pianura si alternano testo :
HTML è il metodo di scelta per coloro che desiderano inviare e-mail con il testo ricco, il layout e la grafica. Spesso si tratta di desiderabile per incorporare la grafica all'interno il messaggio in modo destinatari possono visualizzare il messaggio direttamente, senza ulteriori download.
Alcuni agenti di posta non supportano HTML o i loro utenti preferiscono ricevere pianura messaggi di testo. Mittenti di HTML messaggi dovrebbero includere un testo in chiaro messaggio come un supplente per questi utenti.
Questa ricetta invia un breve messaggio HTML con una sola immagine incorporato e un si alternano messaggio di testo normale.
# 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 = 'from@example.com'
strTo = 'to@example.com'
# 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's 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()
Altri suggerimenti
Per le versioni di Python 3.4 e superiori.
La risposta accettata è eccellente, ma adatto solo per le vecchie versioni di Python (2.xe 3.3). Penso che ha bisogno di un aggiornamento.
Ecco come si può fare nelle versioni più recenti di Python (3.4 e superiori):
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 <abcd@xyz.com>'
msg['To'] = 'PQRS <pqrs@xyz.com>'
# 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's 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 <long.random.number@xyz.com>
# 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