Ce code fonctionne et m'envoie un e-mail très bien:
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('myserver')
server.sendmail(FROM, TO, message)
server.quit()
Cependant, si j'essaie de l'envelopper dans une fonction comme celle-ci:
def sendMail(FROM,TO,SUBJECT,TEXT,SERVER):
import smtplib
"""this is some test documentation in the function"""
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()
et appelez-le, je reçois les erreurs suivantes:
Traceback (most recent call last):
File "C:/Python31/mailtest1.py", line 8, in <module>
sendmail.sendMail(sender,recipients,subject,body,server)
File "C:/Python31\sendmail.py", line 13, in sendMail
server.sendmail(FROM, TO, message)
File "C:\Python31\lib\smtplib.py", line 720, in sendmail
self.rset()
File "C:\Python31\lib\smtplib.py", line 444, in rset
return self.docmd("rset")
File "C:\Python31\lib\smtplib.py", line 368, in docmd
return self.getreply()
File "C:\Python31\lib\smtplib.py", line 345, in getreply
raise SMTPServerDisconnected("Connection unexpectedly closed")
smtplib.SMTPServerDisconnected: Connection unexpectedly closed
Quelqu'un peut-il m'aider à comprendre pourquoi?
Réponses:
Je vous recommande d'utiliser les packages standard
email
etsmtplib
d'envoyer des e-mails ensemble. Veuillez regarder l'exemple suivant (reproduit à partir de la documentation Python ). Notez que si vous suivez cette approche, la tâche "simple" est en effet simple, et les tâches les plus complexes (comme attacher des objets binaires ou envoyer des messages simples / HTML en plusieurs parties) sont accomplies très rapidement.Pour envoyer un e-mail à plusieurs destinations, vous pouvez également suivre l'exemple de la documentation Python :
Comme vous pouvez le voir, l'en-tête
To
de l'MIMEText
objet doit être une chaîne composée d'adresses e-mail séparées par des virgules. D'autre part, le deuxième argument de lasendmail
fonction doit être une liste de chaînes (chaque chaîne est une adresse e-mail).Donc, si vous avez trois adresses e - mail:
[email protected]
,[email protected]
et[email protected]
, vous pouvez le faire comme suit (sections évidentes omis):la
",".join(to)
partie fait une seule chaîne de la liste, séparée par des virgules.D'après vos questions, je suppose que vous n'avez pas parcouru le didacticiel Python - c'est un MUST si vous voulez aller n'importe où en Python - la documentation est principalement excellente pour la bibliothèque standard.
la source
", ".join(["[email protected]", "[email protected]"])
with
:with open(textfile, 'rb') as fp:
. La fermeture explicite peut être supprimée, car lewith
bloc fermera le fichier même si une erreur se produit à l'intérieur.Eh bien, vous voulez avoir une réponse à jour et moderne.
Voici ma réponse:
Quand j'ai besoin d'envoyer un mail en python, j'utilise l' API mailgun qui me donne beaucoup de mal à envoyer des mails triés. Ils ont une application / api merveilleuse qui vous permet d'envoyer gratuitement 10000 e-mails par mois.
L'envoi d'un e-mail serait comme ceci:
Vous pouvez également suivre les événements et bien plus encore, consultez le guide de démarrage rapide .
J'espère que vous trouvez ça utile!
la source
Je voudrais vous aider à envoyer des courriels en conseillant le paquet yagmail (je suis le mainteneur, désolé pour la publicité, mais je pense que cela peut vraiment aider!).
Le code entier pour vous serait:
Notez que je fournis des valeurs par défaut pour tous les arguments, par exemple si vous voulez vous envoyer vous-même, vous pouvez omettre
TO
, si vous ne voulez pas de sujet, vous pouvez également l'omettre.De plus, le but est également de rendre très facile l'attachement de code html ou d'images (et d'autres fichiers).
Là où vous mettez du contenu, vous pouvez faire quelque chose comme:
Wow, comme il est facile d'envoyer des pièces jointes! Cela prendrait environ 20 lignes sans yagmail;)
De plus, si vous le configurez une fois, vous n'aurez plus jamais à saisir le mot de passe (et à le conserver en toute sécurité). Dans votre cas, vous pouvez faire quelque chose comme:
ce qui est beaucoup plus concis!
Je vous invite à jeter un œil au github ou à l'installer directement avec
pip install yagmail
.la source
yagmail
autre chose que Gmail? J'essaye d'utiliser pour mon propre serveur SMTP.Attachment
classe; c'est toujours la même chose. S'ils peuvent changer votre code, alors ils peuvent faire tout ce qu'ils veulent de toute façon (avec / sans root, c'est la même chose pour l'envoi d'e-mails). Cela me semble être le typique "c'est pratique / magique donc ça doit être moins sûr". Je suis curieux de savoir quelle menace réelle voyez-vous?Il y a un problème d'indentation. Le code ci-dessous fonctionnera:
la source
SERVER
variable transmise à la fonction est les informations d'identification de l'utilisateur.email
bibliothèque Python le fait raisonnablement bien (en particulier depuis la version 3.6) bien qu'elle nécessite toujours une certaine compréhension de ce que vous faites.Voici un exemple sur Python
3.x
, bien plus simple que2.x
:appelez cette fonction:
ci-dessous ne peut que pour les utilisateurs chinois:
Si vous utilisez 126/163, 网易 邮箱, vous devez définir "客户 端 授权 密码", comme ci-dessous:
réf: https://stackoverflow.com/a/41470149/2803344 https://docs.python.org/3/library/email.examples.html#email-examples
la source
Lors de l'indentation de votre code dans la fonction (ce qui est correct), vous avez également indenté les lignes de la chaîne de message brute. Mais le premier espace blanc implique le pliage (concaténation) des lignes d'en-tête, comme décrit dans les sections 2.2.3 et 3.2.3 de la RFC 2822 - Format de message Internet :
Dans la forme de fonction de votre
sendmail
appel, toutes les lignes commencent par un espace blanc et sont donc "dépliées" (concaténées) et vous essayez d'envoyerAutre que notre esprit ne le suggère,
smtplib
ne comprendra plus les enTo:
-Subject:
têtes et , car ces noms ne sont reconnus qu'au début d'une ligne. Au lieu de cela,smtplib
il supposera une adresse e-mail d'expéditeur très longue:Cela ne fonctionnera pas et vient donc votre exception.
La solution est simple: il suffit de conserver la
message
chaîne telle qu'elle était avant. Cela peut être fait par une fonction (comme Zeeshan l'a suggéré) ou tout de suite dans le code source:Maintenant, le déploiement ne se produit pas et vous envoyez
qui est ce qui fonctionne et ce qui a été fait par votre ancien code.
Notez que je préservais également la ligne vide entre les en-têtes et le corps pour accueillir la section 3.5 de la RFC (qui est obligatoire) et mettre l'inclusion en dehors de la fonction selon le guide de style Python PEP-0008 (qui est facultatif).
la source
Cela met probablement des onglets dans votre message. Imprimez le message avant de le transmettre à sendMail.
la source
Assurez-vous d'avoir autorisé l'expéditeur et le destinataire à envoyer des e-mails et à recevoir des e-mails de sources inconnues (sources externes) dans le compte de messagerie.
la source
msg
n'est pas un message SMTP valide et semblera simplement disparaître dans l'éther si votre serveur de messagerie l'accepte.Je pensais que j'avais mis mes deux morceaux ici puisque je viens de comprendre comment cela fonctionne.
Il semble que vous n'ayez pas le port spécifié dans vos paramètres de connexion SERVER, cela m'a un peu affecté lorsque j'essayais de me connecter à mon serveur SMTP qui n'utilise pas le port par défaut: 25.
Selon la documentation smtplib.SMTP, votre demande / réponse ehlo ou helo devrait être automatiquement prise en charge, vous ne devriez donc pas avoir à vous en soucier (mais cela pourrait être quelque chose à confirmer si tout le reste échoue).
Une autre chose à vous demander est avez-vous autorisé les connexions SMTP sur votre serveur SMTP lui-même? Pour certains sites comme GMAIL et ZOHO, vous devez réellement entrer et activer les connexions IMAP dans le compte de messagerie. Votre serveur de messagerie peut ne pas autoriser les connexions SMTP qui ne proviennent pas de 'localhost' peut-être? Quelque chose à examiner.
La dernière chose est que vous voudrez peut-être essayer d'initier la connexion sur TLS. La plupart des serveurs nécessitent désormais ce type d'authentification.
Vous verrez que j'ai bloqué deux champs TO dans mon courrier électronique. Les éléments de dictionnaire msg ['TO'] et msg ['FROM'] msg permettent aux informations correctes de s'afficher dans les en-têtes de l'e-mail lui-même, que l'on voit à la réception de l'e-mail dans les champs À / De (vous peut même être en mesure d'ajouter un champ Répondre à ici. Les champs TO et FROM eux-mêmes sont ce dont le serveur a besoin. Je sais que j'ai entendu parler de certains serveurs de messagerie rejetant des e-mails s'ils ne disposent pas des en-têtes d'e-mail appropriés.
C'est le code que j'ai utilisé, dans une fonction, qui fonctionne pour moi pour envoyer par courrier électronique le contenu d'un fichier * .txt en utilisant mon ordinateur local et un serveur SMTP distant (ZOHO comme indiqué):
la source
Il est à noter que le module SMTP prend en charge le gestionnaire de contexte, il n'est donc pas nécessaire d'appeler manuellement quit (), cela garantira qu'il est toujours appelé même s'il y a une exception.
la source
En ce qui concerne votre code, il ne semble pas y avoir quoi que ce soit de fondamentalement incorrect, sauf que, on ne sait pas comment vous appelez réellement cette fonction. Tout ce que je peux penser, c'est que lorsque votre serveur ne répond pas, vous obtiendrez cette erreur SMTPServerDisconnected. Si vous recherchez la fonction getreply () dans smtplib (extrait ci-dessous), vous aurez une idée.
consultez un exemple sur https://github.com/rreddy80/sendEmails/blob/master/sendEmailAttachments.py qui utilise également un appel de fonction pour envoyer un e-mail, si c'est ce que vous essayez de faire (approche DRY).
la source