2009-05-19 22 views
189

¿Cómo puedo enviar el contenido HTML en un correo electrónico usando Python? Puedo enviar un texto simple.Enviando correo electrónico HTML usando Python

+1

Si desea enviar un HTML con Unicode ver aquí: http://stackoverflow.com/questions/36397827/send-html-mail-with-unicode – guettli

+0

Sólo una advertencia grande y gordo . Si está enviando un correo electrónico que no sea [ASCII] (http://en.wikipedia.org/wiki/ASCII) usando Python <3.0, considere usar el correo electrónico en [Django] (http://en.wikipedia.org/wiki)./Django_% 28web_framework% 29). Envuelve [UTF-8] (http://en.wikipedia.org/wiki/UTF-8) cadenas correctamente, y también es mucho más simple de usar. Usted ha sido advertido :-) –

Respuesta

296

De Python v2.7.14 documentation - 18.1.11. email: Examples:

Here’s an example of how to create an HTML message with an alternative plain text version:

#! /usr/bin/python 

import smtplib 

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

# me == my email address 
# you == recipient's email address 
me = "[email protected]" 
you = "[email protected]" 

# Create message container - the correct MIME type is multipart/alternative. 
msg = MIMEMultipart('alternative') 
msg['Subject'] = "Link" 
msg['From'] = me 
msg['To'] = you 

# Create the body of the message (a plain-text and an HTML version). 
text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttp://www.python.org" 
html = """\ 
<html> 
    <head></head> 
    <body> 
    <p>Hi!<br> 
     How are you?<br> 
     Here is the <a href="http://www.python.org">link</a> you wanted. 
    </p> 
    </body> 
</html> 
""" 

# Record the MIME types of both parts - text/plain and text/html. 
part1 = MIMEText(text, 'plain') 
part2 = MIMEText(html, 'html') 

# Attach parts into message container. 
# According to RFC 2046, the last part of a multipart message, in this case 
# the HTML message, is best and preferred. 
msg.attach(part1) 
msg.attach(part2) 

# Send the message via local SMTP server. 
s = smtplib.SMTP('localhost') 
# sendmail function takes 3 arguments: sender's address, recipient's address 
# and message to send - here it is sent as one string. 
s.sendmail(me, you, msg.as_string()) 
s.quit() 
+0

¿Es posible adjuntar una tercera y una cuarta parte, las cuales son adjuntos (una ASCII, una binaria)? ¿Cómo podría uno hacer eso? Gracias. –

+0

Hola, noté que al final 'abandonas' el objeto 's'. ¿Qué pasa si quiero enviar múltiples mensajes? ¿Debo dejar de fumar cada vez que envío el mensaje o enviarlos todos (en un bucle for) y luego salir de una vez por todas? – xpanta

+0

Asegúrate de adjuntar html al final, ya que la parte preferida (que muestra) será la última que se adjunte. '# De acuerdo con RFC 2046, la última parte de un mensaje multiparte, en este caso # el mensaje HTML, es el mejor y preferido. 'Me gustaría leer esto hace 2 horas – dwkd

9

Aquí es código de ejemplo. Esto se inspira de código que se encuentra en el sitio Python Cookbook (no puede encontrar el enlace exacto)

def createhtmlmail (html, text, subject, fromEmail): 
    """Create a mime-message that will render HTML in popular 
    MUAs, text in better ones""" 
    import MimeWriter 
    import mimetools 
    import cStringIO 

    out = cStringIO.StringIO() # output buffer for our message 
    htmlin = cStringIO.StringIO(html) 
    txtin = cStringIO.StringIO(text) 

    writer = MimeWriter.MimeWriter(out) 
    # 
    # set up some basic headers... we put subject here 
    # because smtplib.sendmail expects it to be in the 
    # message body 
    # 
    writer.addheader("From", fromEmail) 
    writer.addheader("Subject", subject) 
    writer.addheader("MIME-Version", "1.0") 
    # 
    # start the multipart section of the message 
    # multipart/alternative seems to work better 
    # on some MUAs than multipart/mixed 
    # 
    writer.startmultipartbody("alternative") 
    writer.flushheaders() 
    # 
    # the plain text section 
    # 
    subpart = writer.nextpart() 
    subpart.addheader("Content-Transfer-Encoding", "quoted-printable") 
    pout = subpart.startbody("text/plain", [("charset", 'us-ascii')]) 
    mimetools.encode(txtin, pout, 'quoted-printable') 
    txtin.close() 
    # 
    # start the html subpart of the message 
    # 
    subpart = writer.nextpart() 
    subpart.addheader("Content-Transfer-Encoding", "quoted-printable") 
    # 
    # returns us a file-ish object we can write to 
    # 
    pout = subpart.startbody("text/html", [("charset", 'us-ascii')]) 
    mimetools.encode(htmlin, pout, 'quoted-printable') 
    htmlin.close() 
    # 
    # Now that we're done, close our writer and 
    # return the message body 
    # 
    writer.lastpart() 
    msg = out.getvalue() 
    out.close() 
    print msg 
    return msg 

if __name__=="__main__": 
    import smtplib 
    html = 'html version' 
    text = 'TEST VERSION' 
    subject = "BACKUP REPORT" 
    message = createhtmlmail(html, text, subject, 'From Host <[email protected]>') 
    server = smtplib.SMTP("smtp_server_address","smtp_port") 
    server.login('username', 'password') 
    server.sendmail('[email protected]', '[email protected]', message) 
    server.quit() 
+0

FYI; esto vino de http://code.activestate.com/recipes/67083-send-html-mail-from-python/history/1/ –

50

puede intentar utilizar mi módulo mailer.

from mailer import Mailer 
from mailer import Message 

message = Message(From="[email protected]", 
        To="[email protected]") 
message.Subject = "An HTML Email" 
message.Html = """<p>Hi!<br> 
    How are you?<br> 
    Here is the <a href="http://www.python.org">link</a> you wanted.</p>""" 

sender = Mailer('smtp.example.com') 
sender.send(message) 
+0

Wow, eso es mucho más simple que smtplib. Supongo que la ventaja de smtplib es que se envía con la mayoría de las distribuciones de Python. ¡Creo que debes presionar para que Mailer se envíe en Debian! –

+0

El módulo de correo es excelente, pero afirma que funciona con Gmail, pero no lo hace y no hay documentos. – MFB

+1

@MFB - ¿Has probado el repositorio Bitbucket? https://bitbucket.org/ginstrom/mailer/ –

32

Aquí es una aplicación Gmail de la respuesta aceptada:

import smtplib 

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

# me == my email address 
# you == recipient's email address 
me = "[email protected]" 
you = "[email protected]" 

# Create message container - the correct MIME type is multipart/alternative. 
msg = MIMEMultipart('alternative') 
msg['Subject'] = "Link" 
msg['From'] = me 
msg['To'] = you 

# Create the body of the message (a plain-text and an HTML version). 
text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttp://www.python.org" 
html = """\ 
<html> 
    <head></head> 
    <body> 
    <p>Hi!<br> 
     How are you?<br> 
     Here is the <a href="http://www.python.org">link</a> you wanted. 
    </p> 
    </body> 
</html> 
""" 

# Record the MIME types of both parts - text/plain and text/html. 
part1 = MIMEText(text, 'plain') 
part2 = MIMEText(html, 'html') 

# Attach parts into message container. 
# According to RFC 2046, the last part of a multipart message, in this case 
# the HTML message, is best and preferred. 
msg.attach(part1) 
msg.attach(part2) 
# Send the message via local SMTP server. 
mail = smtplib.SMTP('smtp.gmail.com', 587) 

mail.ehlo() 

mail.starttls() 

mail.login('userName', 'password') 
mail.sendmail(me, you, msg.as_string()) 
mail.quit() 
+1

Excelente código, funciona para mí, si activo [baja seguridad en google] (https://www.google.com/settings/security/lesssecureapps) – Tovask

+11

Utilizo una contraseña [contraseña específica de la aplicación] de google (https: //support.google.com/accounts/answer/185833) con Python smtplib, hizo el truco sin tener que pasar por baja seguridad. – yoyo

27

Aquí es una forma sencilla de enviar un correo electrónico HTML, simplemente especificando la cabecera Content-Type como 'text/html':

import email.message 
import smtplib 

msg = email.message.Message() 
msg['Subject'] = 'foo' 
msg['From'] = '[email protected]' 
msg['To'] = '[email protected]' 
msg.add_header('Content-Type','text/html') 
msg.set_payload('Body of <b>message</b>') 

s = smtplib.SMTP(mailmerge_conf.smtp_server) 
s.starttls() 
s.login(email_login, 
     email_passwd) 
s.sendmail(msg['From'], [msg['To']], msg.as_string()) 
+2

Esta es una respuesta simple y agradable, útil para scripts rápidos y sucios, gracias. Por cierto, uno puede referirse a la respuesta aceptada para un ejemplo simple 'smtplib.SMTP()', que no usa tls. Usé esto para un script interno en el trabajo donde usamos ssmtp y un mailhub local. Además, este ejemplo falta 's.quit()'. no se define –

+0

"mailmerge_conf.smtp_server" ... al menos es lo que dice Python 3.6 ... – ZEE

+0

i ha obtenido un error cuando se utiliza la lista en base recepients AttributeError: 'lista' objeto no tiene atributo 'lstrip' alguna solución? – navotera

2

En realidad, yagmail tuvo un enfoque un poco diferente.

por defecto enviar HTML, con respaldo automático para lectores de correo electrónico incapaces. Ya no es el siglo XVII.

Por supuesto, también se puede modificar, pero aquí va:

import yagmail 
yag = yagmail.SMTP("[email protected]", "mypassword") 

html_msg = """<p>Hi!<br> 
       How are you?<br> 
       Here is the <a href="http://www.python.org">link</a> you wanted.</p>""" 

yag.send("[email protected]", "the subject", html_msg) 

Para obtener instrucciones de instalación y muchas características más, echar un vistazo a la github.

0

aquí está mi respuesta para AWS utilizando boto3

subject = "Hello" 
    html = "<b>Hello Consumer</b>" 

    client = boto3.client('ses', region_name='us-east-1', aws_access_key_id="your_key", 
         aws_secret_access_key="your_secret") 

client.send_email(
    Source='ACME <[email protected]>', 
    Destination={'ToAddresses': [email]}, 
    Message={ 
     'Subject': {'Data': subject}, 
     'Body': { 
      'Html': {'Data': html} 
     } 
    } 
1

Aquí hay un ejemplo de trabajo para enviar mensajes de correo electrónico de texto y HTML sin formato a partir Python usando smtplib junto con la CC y BCC opciones.

https://varunver.wordpress.com/2017/01/26/python-smtplib-send-plaintext-and-html-emails/

#!/usr/bin/env python 
import smtplib 
from email.mime.multipart import MIMEMultipart 
from email.mime.text import MIMEText 

def send_mail(params, type_): 
     email_subject = params['email_subject'] 
     email_from = "[email protected]" 
     email_to = params['email_to'] 
     email_cc = params.get('email_cc') 
     email_bcc = params.get('email_bcc') 
     email_body = params['email_body'] 

     msg = MIMEMultipart('alternative') 
     msg['To'] = email_to 
     msg['CC'] = email_cc 
     msg['Subject'] = email_subject 
     mt_html = MIMEText(email_body, type_) 
     msg.attach(mt_html) 

     server = smtplib.SMTP('YOUR_MAIL_SERVER.DOMAIN.COM') 
     server.set_debuglevel(1) 
     toaddrs = [email_to] + [email_cc] + [email_bcc] 
     server.sendmail(email_from, toaddrs, msg.as_string()) 
     server.quit() 

# Calling the mailer functions 
params = { 
    'email_to': '[email protected]', 
    'email_cc': '[email protected]', 
    'email_bcc': '[email protected]', 
    'email_subject': 'Test message from python library', 
    'email_body': '<h1>Hello World</h1>' 
} 
for t in ['plain', 'html']: 
    send_mail(params, t) 
+0

Piensa que esta respuesta cubre todo. Gran enlace – stingMantis

Cuestiones relacionadas