Enviar correo electrónico vía SMTP

Versión: 2.x, 3.x

(Hay una versión más completa y actualizada de este mismo artículo para Python 3.6 o superior: Enviar correo electrónico en HTML y con adjuntos vía SMTP).

De forma estándar Python permite enviar correos electrónicos fácilmente haciendo uso de los módulos email y smtplib. El primero es empleado para construir el mensaje, mientras que el segundo para conectar con el servidor y enviarlo.

Existen otras soluciones, tal vez algo más simples pero no se incluyen en la librería estándar, como pyzmail, aunque no están cubiertas en este artículo.

Para comenzar, importemos las clases necesarias:

from email.mime.text import MIMEText

Los mensajes utilizan el estándar MIME, por lo tanto, empleamos la clase MIMEText para construir un correo de texto plano.

from smtplib import SMTP

La clase SMTP representa una conexión a un servidor SMTP.

A continuación especificamos nuestra dirección de correo electrónico, el destino y el mismo mensaje.

from_address = "contacto@recursospython.com"  # Dirección personal
to_address = "articulos@recursospython.com"  # Destino
message = "Hello, world!"  # Mensaje

Implementamos una instancia de la clase MIMEText para construir el mensaje.

mime_message = MIMEText(message, "plain")
mime_message["From"] = from_address
mime_message["To"] = to_address
mime_message["Subject"] = "Correo de prueba"  # Asunto

En caso que message contenga carácteres unicode, considera especificar la codificación:

mime_message = MIMEText(message, "plain", _charset="utf-8")

La información del remitente y el destinatario, en este caso, puede también ser un nombre o cualquier otra cadena.

mime_message["From"] = "Contacto - Recursos Python"
mime_message["To"] = "Articulos - Recursos Python"

Puedes modificar el aspecto visual del mensaje utilizando HTML:

message = "<em>Hello</em>, <strong>world</strong>!"
# ...
mime_message = MIMEText(message, "html", _charset="utf-8")

También puedes enviar aplicaciones, imágenes y audios, utilizando las clases MIMEApplication, MIMEImage, y MIMEAudio, respectivamente. Por ejemplo:

f = open("image.jpg", "rb")
image = f.read()
f.close()

mime_message = MIMEImage(image)

Una vez elaborado el mensaje, debemos realizar la conexión al servidor SMTP.

smtp = SMTP("mail.recursospython.com")

En mi caso utilizo la dirección del servidor que me brinda mi proveedor de hosting. En el caso de los servicios más importantes, las direcciones son: smtp.live.com (Outlook / Hotmail), smtp.mail.yahoo.com (Yahoo!) y smtp.gmail.com (Gmail).

Ingresamos los datos para la autenticación, nombre de usuario (generalmente la dirección de correo electrónico) y contraseña.

smtp.login(from_address, "clave")

Por último, enviamos el correo:

smtp.sendmail(from_address, to_address, mime_message.as_string())

Y cerramos la conexión:

smtp.quit()

Código completo:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from email.mime.text import MIMEText
from smtplib import SMTP


def main():
    from_address = "remitente@ejemplo.com"
    to_address = "destino@ejemplo.com"
    message = "Hello, world!"
    
    mime_message = MIMEText(message, "plain")
    mime_message["From"] = from_address
    mime_message["To"] = to_address
    mime_message["Subject"] = "Correo de prueba"
    
    smtp = SMTP("smtp.ejemplo.com")
    smtp.login(from_address, "clave")
    
    smtp.sendmail(from_address, to_address, mime_message.as_string())
    smtp.quit()


if __name__ == "__main__":
    main()

Curso online 👨‍💻

¡Ya lanzamos el curso oficial de Recursos Python en Udemy! Un curso moderno para aprender Python desde cero con programación orientada a objetos, SQL y tkinter en 2024.

Consultoría 💡

Ofrecemos servicios profesionales de desarrollo y capacitación en Python a personas y empresas. Consultanos por tu proyecto.

11 comentarios.

  1. Muy buen aporte, sin embargo a mi me arroja un error:

    socket.gaierror: [Errno -5] No address associated with hostname

    Será porque utilizo un servidor proxy?

    Gracias

      • Muchas gracias, este es mi código y estoy utilizando la versión 2.7

        # envia_correo.py
        # ———————————————————

        from email.mime.text import MIMEText
        from smtplib import SMTP

        def manda_correo(nombre, direccion):

        from_address = «brunoruizv@gmail.com»
        to_address = direccion
        message = «Hola » + nombre +», \n\n» + \
        «Este correo es solo para saludarte.» + \
        «\n\nAtentamente,» + \
        «\n\nTu funcion que manda correos desde Python.»

        mime_message = MIMEText(message, «plain»)
        mime_message[«From»] = from_address
        mime_message[«To»] = to_address
        mime_message[«Subject»] = «Saludos » + nombre

        smtp = SMTP(«smtp.gmail.com», 587)
        smtp.login(from_address, «texicano04»)
        smtp.sendmail(from_address, to_address, mime_message.as_string())
        smtp.quit()

        manda_correo(«Bruno»,»brunoruizv@gmail.com»)

        Y marca lo siguiente :

        Traceback (most recent call last):
        File «correo_3.py», line 27, in
        manda_correo(«Bruno»,»arturo.ruiz02@cfe.gob.mx»)
        File «correo_3.py», line 22, in manda_correo
        smtp = SMTP(«smtp.cfe.gob.mx», 587)
        File «/usr/local/lib/python2.7/smtplib.py», line 256, in __init__
        (code, msg) = self.connect(host, port)
        File «/usr/local/lib/python2.7/smtplib.py», line 316, in connect
        self.sock = self._get_socket(host, port, self.timeout)
        File «/usr/local/lib/python2.7/smtplib.py», line 291, in _get_socket
        return socket.create_connection((host, port), timeout)
        File «/usr/local/lib/python2.7/socket.py», line 557, in create_connection
        for res in getaddrinfo(host, port, 0, SOCK_STREAM):
        socket.gaierror: [Errno -5] No address associated with hostname

        Gracias de nuevo.

  2. Hola, he logrado enviar un correo con exito, incluso estoy implementando un ejemplo que envié un correo dependiendo de la temperatura de un sensor por ejemplo así:

    if temperatura > 70:

    Estoy recibiendo los datos de una base de datos que recibe los valores de un sensor de temperatura y esta se actualiza cada 15 seg y me gráfica los datos. Me envía un correo si el valor de la temperatura pasa los 25°C. Mi pregunta es si hay alguna manera de limitar el envió del correo ya que si el valor se mantiene arriba de los 25°C me estará enviando un correo cada 15 seg ya que ese es el tiempo en el que se reciben valores para después graficarlos. Por ejemplo limitar el envió cada 20 minutos si es que la temperatura se mantiene arriba de los 25°C por 2 horas por ejemplo.

    Muchas gracias.

    • Recursos Python says:

      Hola Saul. Cuando la temperatura es mayor a 25ºC deberías chequear el valor de la última temperatura recibida. Si este último es mayor a 25 quiere decir que el email ya fue enviado y no deberías proceder.

      Saludos

    • Recursos Python says:

      Hola, deberías cambiar la línea 15 por mime_message["To"] = ", ".join(lista_de_contactos) y la 21 por smtp.sendmail(from_address, lista_de_contactos, mime_message.as_string()).

      Saludos

  3. Hola estaba probando un código, pero no enviaba el asunto así que agregue parte de tu código para armar el mensaje y funciono. Muchas gracias fue de gran ayuda.

  4. Hola, excelente su sitio sobre python, muy práctico y bien explicado de manera sencilla. He estado unos meses traveseando con python y buscaba esto de poder enviar e-mails lo he hecho con el ejemplo que han puesto. Mi pregunta ahora es: ¿hay alguna forma de automatizar el envío de un correo electrónico? No he encontrado nada al respecto y me serviría mucho para poder enviar varios informes de texto a fin de mes todos los meses de forma automática a una hora específica. Espero puedas ayudarme con eso. Saludos y sigue publicando estas excelentes ayudas.

    • Recursos Python says:

      Hola Samuel, gracias por el comentario y me alegro que te haya sido de utilidad el artículo. Con respecto a tu problema, el mismo excede los límites de Python. Generalmente para este tipo de procedimientos se utilizan tareas programadas o crontab en Unix. La idea es programar la ejecución periódica de tu script Python que envía los correos. En caso que tengas un panel de control como CPanel, podrás programar tus tareas desde allí fácilmente. Si utilizas Windows, tendrás también un bonito asistente para hacerlo.

      Un saludo.

Deja una respuesta