2008-09-15 31 views
93

Estoy usando el siguiente método para enviar correo desde Python usando SMTP. ¿Es el método correcto de usar o hay fallas que me faltan?Enviando correo de Python usando SMTP

from smtplib import SMTP 
import datetime 

debuglevel = 0 

smtp = SMTP() 
smtp.set_debuglevel(debuglevel) 
smtp.connect('YOUR.MAIL.SERVER', 26) 
smtp.login('[email protected]', 'PASSWORD') 

from_addr = "John Doe <[email protected]>" 
to_addr = "[email protected]" 

subj = "hello" 
date = datetime.datetime.now().strftime("%d/%m/%Y %H:%M") 

message_text = "Hello\nThis is a mail from your server\n\nBye\n" 

msg = "From: %s\nTo: %s\nSubject: %s\nDate: %s\n\n%s" 
     % (from_addr, to_addr, subj, date, message_text) 

smtp.sendmail(from_addr, to_addr, msg) 
smtp.quit() 
+2

Asegúrate de que la Fecha/Hora sea correcta. Encontré la siguiente función bastante útil, que le da un valor perfectamente formateado para el encabezado de fecha: http://docs.python.org/py3k/library/email.util.html#email.utils.formatdate – BastiBen

+0

aquí un ejemplo de código que permite [enviar un correo electrónico con texto Unicode en el asunto y/o en el cuerpo] (http://stackoverflow.com/a/20787826/4279) – jfs

+0

aquí hay un ejemplo de código que demuestra cómo [enviar imágenes en línea (más correo electrónico con partes html y texto sin formato)] (http://stackoverflow.com/a/20485764/4279). También muestra cómo configurar los parámetros ssl en versiones antiguas de Python. – jfs

Respuesta

94

El script que uso es bastante similar; Lo publico aquí como un ejemplo de cómo usar los módulos de correo electrónico. * Para generar mensajes MIME; por lo que este script se puede modificar fácilmente para adjuntar imágenes, etc.

Confío en mi ISP para agregar el encabezado de fecha y hora.

Mi ISP me obliga a utilizar una conexión segura SMTP para enviar correo, que se basan en el módulo ssmtplib (descargable en http://www1.cs.columbia.edu/~db2501/ssmtplib.py)

Al igual que en la secuencia de comandos, el nombre de usuario y contraseña, (dada valores ficticios a continuación), utilizados para autenticarse en el servidor SMTP, están en texto sin formato en la fuente. Esta es una debilidad de seguridad; pero la mejor alternativa depende del cuidado que necesita (¿quiere?) para protegerlos.

=======================================

#! /usr/local/bin/python 


SMTPserver = 'smtp.att.yahoo.com' 
sender =  '[email protected]_email_domain.net' 
destination = ['[email protected]_email_domain.com'] 

USERNAME = "USER_NAME_FOR_INTERNET_SERVICE_PROVIDER" 
PASSWORD = "PASSWORD_INTERNET_SERVICE_PROVIDER" 

# typical values for text_subtype are plain, html, xml 
text_subtype = 'plain' 


content="""\ 
Test message 
""" 

subject="Sent from Python" 

import sys 
import os 
import re 

from smtplib import SMTP_SSL as SMTP  # this invokes the secure SMTP protocol (port 465, uses SSL) 
# from smtplib import SMTP     # use this for standard SMTP protocol (port 25, no encryption) 

# old version 
# from email.MIMEText import MIMEText 
from email.mime.text import MIMEText 

try: 
    msg = MIMEText(content, text_subtype) 
    msg['Subject']=  subject 
    msg['From'] = sender # some SMTP servers will do this automatically, not all 

    conn = SMTP(SMTPserver) 
    conn.set_debuglevel(False) 
    conn.login(USERNAME, PASSWORD) 
    try: 
     conn.sendmail(sender, destination, msg.as_string()) 
    finally: 
     conn.quit() 

except Exception, exc: 
    sys.exit("mail failed; %s" % str(exc)) # give a error message 
+1

@Vincent: correo fallido; El objeto 'módulo' no tiene ningún atributo 'SSLFakeSocket' - usando Gmail :( – RadiantHex

+0

Esto suena como una versión o un problema de importación, para ayudar a rastrearlo: ¿Qué versión de Python está ejecutando? - ¿Necesita conectarse a su servidor SMTP? SSL (y si es así, ¿está importando ssmtplib, como se indicó anteriormente?) ¿Puede importar smtplib directamente desde python interactive, si es así, hay una clase smtplib.SSLFakeSocket definida? Espero que pueda ayudar –

+1

Use smtplib.SMTP_SSL (estándar en últimas versiones de Python) para crear la conexión en lugar de ssmtplib.STMP_SSL (módulo de terceros insinuado anteriormente). Fíjate que el módulo estándar comienza con una sola 's'. Eso funcionó para mí. –

6

El Gotcha principal que veo es que no se está manejando los errores: .login() y .sendmail() ambos han documentado excepciones que puede lanzar, y parece que .Connect() debe tener alguna forma de indicar que no pudo conectarse, probablemente una excepción lanzada por el código de socket subyacente.

3

Debe asegurarse de formatear la fecha en el formato correcto - RFC2822.

5

Asegúrese de que no tiene ningún firewall que bloquee SMTP. La primera vez que traté de enviar un correo electrónico, fue bloqueado tanto por Firewall de Windows como por McAfee; tardó una eternidad en encontrarlos.

20

Además, si desea hacer smtp auth con TLS en lugar de SSL, simplemente tiene que cambiar el puerto (use 587) y haga smtp.starttls(). Esto funcionó para mí:

... 
smtp.connect('YOUR.MAIL.SERVER', 587) 
smtp.ehlo() 
smtp.starttls() 
smtp.ehlo() 
smtp.login('[email protected]', 'PASSWORD') 
... 
+0

¡Gracias por este fragmento! –

5

¿Qué tal esto?

import smtplib 

SERVER = "localhost" 

FROM = "[email protected]" 
TO = ["[email protected]"] # must be a list 

SUBJECT = "Hello!" 

TEXT = "This message was sent with Python's smtplib." 

# Prepare actual message 

message = """\ 
From: %s 
To: %s 
Subject: %s 

%s 
""" % (FROM, ", ".join(TO), SUBJECT, TEXT) 

# Send the mail 

server = smtplib.SMTP(SERVER) 
server.sendmail(FROM, TO, message) 
server.quit() 
67

El método que utilice con frecuencia ... no es muy diferente, pero un poco

import smtplib 
from email.MIMEMultipart import MIMEMultipart 
from email.MIMEText import MIMEText 

msg = MIMEMultipart() 
msg['From'] = '[email protected]' 
msg['To'] = '[email protected]' 
msg['Subject'] = 'simple email in python' 
message = 'here is the email' 
msg.attach(MIMEText(message)) 

mailserver = smtplib.SMTP('smtp.gmail.com',587) 
# identify ourselves to smtp gmail client 
mailserver.ehlo() 
# secure our email with tls encryption 
mailserver.starttls() 
# re-identify ourselves as an encrypted connection 
mailserver.ehlo() 
mailserver.login('[email protected]', 'mypassword') 

mailserver.sendmail('[email protected]','[email protected]',msg.as_string()) 

mailserver.quit() 

Eso es todo

+10

IMO, esta es la mejor respuesta en este hilo. – lpapp

+0

Si usa la verificación en 2 pasos, primero debe crear una contraseña específica de la aplicación y reemplazarla con la contraseña normal. Consulte [Iniciar sesión usando contraseñas de la aplicación] (https://support.google.com/accounts/answer/185833?hl=es) –

+1

@lpapp. ¿Quizás podría reconsiderar la mejor respuesta? – PascalVKooten

5

siguiente código está trabajando bien para mí:

import smtplib 

to = '[email protected]' 
gmail_user = '[email protected]' 
gmail_pwd = 'yourpassword' 
smtpserver = smtplib.SMTP("smtp.gmail.com",587) 
smtpserver.ehlo() 
smtpserver.starttls() 
smtpserver.ehlo() # extra characters to permit edit 
smtpserver.login(gmail_user, gmail_pwd) 
header = 'To:' + to + '\n' + 'From: ' + gmail_user + '\n' + 'Subject:testing \n' 
print header 
msg = header + '\n this is test msg from mkyong.com \n\n' 
smtpserver.sendmail(gmail_user, to, msg) 
print 'done!' 
smtpserver.quit() 

Ref: http://www.mkyong.com/python/how-do-send-email-in-python-via-smtplib/

+1

Flask tiene un marco de trabajo para el correo electrónico: from flask.ext.mail import Mail. Lo estoy solucionando, y pensé que volvería al código de Python para ver si podía hacer que algo funcionara. Me gustó esta respuesta porque era escueta. Oh sí, ¡y funcionó! – Aaron

+0

** Atención: ** La versión anterior de la respuesta incluía la línea: 'smtpserver.close()' Debe ser: 'smtpserver.quit()', porque 'close()' no terminará la conexión TLS ¡correctamente! 'close()' se llamará durante 'quit()'. – aronadaal

+0

Hola, estoy teniendo problemas para ejecutar los comandos anteriores. cuando uso smtpserver.starttls(), aparece un error de SMTP "SMTPServerDisconnected: conexión cerrada inesperadamente: [Errno 10054]" .. reportada en https: // stackoverflow.com/questions/46094175/starttls-is-giving-me-a-smtpserverdisconnect-error-when-trying-to-send-emails – fazkan

2

¿Ve todas esas respuestas largas? Permítanme auto promocionar haciendo todo en un par de líneas.

Importación y conexion:

import yagmail 
yag = yagmail.SMTP('[email protected]', host = 'YOUR.MAIL.SERVER', port = 26) 

entonces es sólo una sola línea:

yag.send('[email protected]', 'hello', 'Hello\nThis is a mail from your server\n\nBye\n') 

Lo hará realidad se cierran cuando se sale del ámbito (o se puede cerrar manualmente).Además, le permitirá registrar su nombre de usuario en su llavero de modo que no tenga que escribir su contraseña en su script (realmente me molestó antes de escribir yagmail)

Para el paquete/instalación, consejos y trucos mira git o pip, disponible para Python 2 y 3.

+0

@PascalvKoolen Instalé yagmail y traté de conectar dando mi id de correo electrónico y contraseña. pero me dio un error de autenticación – fazkan

Cuestiones relacionadas