2009-05-28 61 views
43

He estado jugando con el módulo de correo electrónico en python, pero quiero saber cómo incrustar imágenes que están incluidas en el html.Envío de mensajes html Multipart que contienen imágenes incrustadas

Así por ejemplo, si el cuerpo es algo así como

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

me gustaría incrustar image.png en el correo electrónico, y el atributo src debe sustituirse por content-id. ¿Alguien sabe cómo hacer esto?

Respuesta

102

Aquí hay un ejemplo que encontré.

Recipe 473810: Send an HTML email with embedded image and plain text alternate:

HTML es el método de elección para aquellos que deseen enviar correos electrónicos con texto enriquecido, diseño y los gráficos. A menudo es deseable incrustar los gráficos dentro de el mensaje para que los destinatarios puedan mostrar el mensaje directamente, sin más descargas.

Algunos agentes de correo no son compatibles con HTML o sus usuarios prefieren recibir mensajes de texto simples . Los remitentes de los mensajes HTML deben incluir un mensaje de texto sin formato como alternativa para estos usuarios de .

Esta receta envía un breve mensaje de HTML con una sola imagen incrustada y un mensaje de texto plano alternativo .

# 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'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() 
+0

Muchas gracias, he probado muchos solución, este es el que funciona perfecto! – wukong

+0

@Andrew Hare: hay dos vistas multipartes (las dos instancias de msgText). No veo el tipo de contenido especificado para cada uno. ¿Cómo sabría el sistema receptor qué procesar para el Html? –

+0

Agregué msgText.replace_header ('Content-Type', 'text/html') para la segunda instancia de msgText. –

1

Para las versiones de Python 3.4 y anteriores

La respuesta aceptada es excelente, pero viejo. Creo que necesita una actualización.

Así es como se puede hacer en las últimas versiones de Python (3.4 y anteriores):

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'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 <[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 
Cuestiones relacionadas