2008-09-15 14 views
93

J'utilise la méthode suivante pour envoyer du courrier à partir de Python en utilisant SMTP. Est-ce la bonne méthode à utiliser ou y at-il des trucs qui me manquent?Envoyer du courrier à partir de Python en utilisant 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

Assurez-vous que vous obtenez la date/heure correcte. J'ai trouvé la fonction suivante assez utile, qui vous donne une valeur parfaitement formatée pour l'en-tête de date: http://docs.python.org/py3k/library/email.util.html#email.utils.formatdate – BastiBen

+0

un exemple de code qui permet de [envoyer un e-mail avec du texte Unicode dans le sujet et/ou dans le corps] (http://stackoverflow.com/a/20787826/4279) – jfs

+0

Voici un exemple de code qui montre comment [envoyer des images en ligne (plus email avec des parties html et en texte clair)] (http://stackoverflow.com/a/20485764/4279). Il montre également comment configurer les paramètres ssl sur les anciennes versions de Python. – jfs

Répondre

94

Le script que j'utilise est assez similaire; Je l'affiche ici comme un exemple de la façon d'utiliser l'email. * Modules pour générer des messages MIME; donc ce script peut être facilement modifié pour attacher des images, etc.

Je compte sur mon FAI pour ajouter l'en-tête de date-heure.

Mon FAI me demande d'utiliser une connexion smtp sécurisée pour envoyer du courrier, je compte sur le module ssmtplib (téléchargeable http://www1.cs.columbia.edu/~db2501/ssmtplib.py)

Comme dans votre script, le nom d'utilisateur et mot de passe, (donné des valeurs fictives ci-dessous), utilisé pour s'authentifier sur le serveur SMTP, sont en texte brut dans la source. C'est une faiblesse de sécurité; mais la meilleure alternative dépend de la prudence dont vous avez besoin (vouloir?) pour les protéger.

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

#! /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: mail failed; L'objet 'module' n'a pas d'attribut 'SSLFakeSocket' - en utilisant Gmail :( – RadiantHex

+0

Cela ressemble à une version ou un problème d'importation, pour aider à le dépister: Quelle version de Python utilisez-vous? - Vous devez vous connecter à votre serveur SMTP SSL (et si oui est-ce que vous importez ssmtplib, comme ci-dessus)? Pouvez-vous importer smtplib directement à partir de python interactif, si oui, y at-il une classe smtplib.SSLFakeSocket définie? Espérons que je peux aider –

+1

Utilisez smtplib.SMTP_SSL (standard dans les dernières versions de Python) pour créer la connexion à la place de ssmtplib.STMP_SSL (module tiers indiqué ci-dessus) Notez que le module standard commence par un simple 's', cela a fonctionné pour moi –

6

La principale Gotcha Je vois que vous manipulez pas d'erreurs: .login() et .sendmail() ont tous deux documenté exceptions qu'ils peuvent jeter, et il semble que .Connect() doit avoir un moyen d'indiquer qu'il était incapable de se connecter - probablement une exception lancée par le code de socket sous-jacent.

3

Vous devez vous assurer de formater la date au format correct - RFC2822.

5

Assurez-vous qu'aucun pare-feu ne bloque SMTP. La première fois que j'ai essayé d'envoyer un e-mail, il a été bloqué à la fois par le pare-feu Windows et McAfee - il a fallu une éternité pour les trouver tous les deux.

20

Aussi, si vous voulez faire une authentification SMTP avec TLS par opposition à SSL, il vous suffit de changer le port (utilisez 587) et de faire smtp.starttls(). Cela a fonctionné pour moi:

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

Merci pour ce dépliant! –

5

Et à ce sujet?

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

La méthode que je l'utilise souvent ... pas très différent, mais un peu

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() 

C'est ce

+10

IMO, c'est la meilleure réponse dans ce fil. – lpapp

+0

Si vous utilisez la validation en deux étapes, vous devez d'abord créer un mot de passe spécifique à l'application et y remplacer votre mot de passe normal. Voir [Se connecter à l'aide des mots de passe de l'application] (https://support.google.com/accounts/answer/185833?hl=fr) –

+1

@lpapp Peut-être pourriez-vous reconsidérer la meilleure réponse? – PascalVKooten

5

code suivant fonctionne bien pour moi:

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 a un cadre pour l'email: from flask.ext.mail import Mail. Je suis en train de résoudre le problème, et j'ai pensé que je reviendrais au code Python pour voir si je pouvais obtenir quelque chose pour travailler. J'ai aimé cette réponse parce que c'était des os nus. Ah oui, et ça a marché! – Aaron

+0

** Attention: ** La version précédente de la réponse comprenait la ligne: 'smtpserver.close()' Elle doit être: 'smtpserver.quit()', car 'close()' ne mettra pas fin à la connexion TLS correctement! 'close()' sera appelé pendant 'quit()'. – aronadaal

+0

Salut, j'ai du mal à exécuter les commandes ci-dessus. quand j'utilise smtpserver.starttls(), j'obtiens une erreur SMTP "SMTPServerDisconnected: Connexion inopinément fermée: [Errno 10054]" .. rapporté dans https: // stackoverflow.com/questions/46094175/starttls-donne-me-a-smtpserverdisconnect-erreur-quand-essayer-d'envoyer-emails – fazkan

2

Voir toutes ces réponses longues? S'il vous plaît permettez-moi de promouvoir moi-même en faisant tout cela en quelques lignes.

importation et Connect:

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

Ensuite, il est juste un one-liner:

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

Il sera en réalité proche quand il est hors de portée (ou peut être fermé manuellement).En outre, il vous permettra d'enregistrer votre nom d'utilisateur dans votre trousseau de clés de sorte que vous n'ayez pas à écrire votre mot de passe dans votre script (ça m'a vraiment dérangé avant d'écrire yagmail!)

Pour le package/installation, conseils et astuces s'il vous plaît regarder git ou pip, disponible pour les deux Python 2 et 3.

+0

@PascalvKoolen J'ai installé yagmail, et essayé de se connecter en donnant mon adresse e-mail et mot de passe. mais ça m'a donné une erreur d'authentification – fazkan

Questions connexes