Dieser Code funktioniert und sendet mir eine E-Mail:
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()
Wenn ich jedoch versuche, es in eine Funktion wie diese zu verpacken:
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()
und nenne es ich bekomme folgende Fehler:
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
Kann mir jemand helfen zu verstehen warum?
Antworten:
Ich empfehle, dass Sie die Standardpakete verwenden
email
undsmtplib
zusammen E-Mails senden. Bitte schauen Sie sich das folgende Beispiel an (reproduziert aus der Python-Dokumentation ). Beachten Sie, dass bei diesem Ansatz die "einfache" Aufgabe in der Tat einfach ist und die komplexeren Aufgaben (wie das Anhängen von Binärobjekten oder das Senden von mehrteiligen einfachen / HTML-Nachrichten) sehr schnell erledigt werden.Um E-Mails an mehrere Ziele zu senden, können Sie auch dem Beispiel in der Python-Dokumentation folgen :
Wie Sie sehen können, muss der Header
To
imMIMEText
Objekt eine Zeichenfolge sein, die aus durch Kommas getrennten E-Mail-Adressen besteht. Andererseits muss das zweite Argument für diesendmail
Funktion eine Liste von Zeichenfolgen sein (jede Zeichenfolge ist eine E-Mail-Adresse).Also, wenn Sie drei E - Mail - Adressen haben:
[email protected]
,[email protected]
, und[email protected]
können Sie tun , folgt als (offensichtliche Abschnitte weggelassen):Der
",".join(to)
Teil macht eine einzelne Zeichenfolge aus der Liste, die durch Kommas getrennt ist.Aus Ihren Fragen geht hervor, dass Sie das Python-Tutorial noch nicht durchlaufen haben - es ist ein MUSS, wenn Sie irgendwo in Python hinkommen möchten -, dass die Dokumentation für die Standardbibliothek größtenteils hervorragend ist.
quelle
", ".join(["[email protected]", "[email protected]"])
with
:with open(textfile, 'rb') as fp:
. Das explizite Schließen kann gelöscht werden, da derwith
Block die Datei schließt, selbst wenn ein Fehler darin auftritt.Nun, Sie möchten eine Antwort haben, die aktuell und modern ist.
Hier ist meine Antwort:
Wenn ich in Python mailen muss , verwende ich die Mailgun- API, die viele Probleme beim Aussenden von Mails verursacht. Sie haben eine wunderbare App / API, mit der Sie 10.000 E-Mails pro Monat kostenlos senden können.
Das Senden einer E-Mail würde folgendermaßen aussehen:
Sie können auch Ereignisse und vieles mehr verfolgen, siehe die Kurzanleitung .
Ich hoffe, Sie finden das nützlich!
quelle
Ich möchte Ihnen beim Versenden von E-Mails helfen, indem ich das yagmail-Paket berate (ich bin der Betreuer, entschuldige die Werbung, aber ich denke, es kann wirklich helfen!).
Der gesamte Code für Sie wäre:
Beachten Sie, dass ich für alle Argumente Standardeinstellungen
TO
gebe. Wenn Sie beispielsweise an sich selbst senden möchten, können Sie diese weglassen . Wenn Sie keinen Betreff möchten, können Sie ihn auch weglassen.Darüber hinaus ist es das Ziel, das Anhängen von HTML-Code oder Bildern (und anderen Dateien) zu vereinfachen.
Wo Sie Inhalte ablegen, können Sie Folgendes tun:
Wow, wie einfach ist es, Anhänge zu versenden! Dies würde wie 20 Zeilen ohne yagmail dauern;)
Wenn Sie es einmal einrichten, müssen Sie das Kennwort nie wieder eingeben (und sicher aufbewahren). In Ihrem Fall können Sie Folgendes tun:
das ist viel prägnanter!
Ich möchte Sie einladen, sich den Github anzusehen oder ihn direkt mit zu installieren
pip install yagmail
.quelle
yagmail
andere als Google Mail verwenden? Ich versuche, für meinen eigenen SMTP-Server zu verwenden.Attachment
Klasse haben. es ist immer noch dasselbe. Wenn sie Ihren Code ändern können, können sie trotzdem alles tun, was sie wollen (mit / ohne root, das ist das gleiche per E-Mail). Dies scheint mir das typische "es ist bequem / magisch, also muss es weniger sicher sein". Ich bin gespannt, welche echte Bedrohung Sie sehen.Es liegt ein Einrückungsproblem vor. Der folgende Code funktioniert:
quelle
SERVER
Variable, die an die Funktion übergeben wird, sind die Benutzeranmeldeinformationen.email
Bibliothek macht dies ziemlich gut (insbesondere seit 3.6), obwohl es immer noch ein gewisses Verständnis dafür erfordert, was Sie tun.Hier ist ein Beispiel für Python
3.x
, viel einfacher als2.x
:Rufen Sie diese Funktion auf:
unten darf nur für chinesische Benutzer:
Wenn Sie 126/163, 网易 邮箱 verwenden, müssen Sie "客户 端 授权 密码" wie folgt einstellen:
Ref: https://stackoverflow.com/a/41470149/2803344 https://docs.python.org/3/library/email.examples.html#email-examples
quelle
Während Sie Ihren Code in die Funktion einrücken (was in Ordnung ist), haben Sie auch die Zeilen der rohen Nachrichtenzeichenfolge eingerückt. Führender Leerraum impliziert jedoch das Falten (Verketten) der Kopfzeilen, wie in den Abschnitten 2.2.3 und 3.2.3 von RFC 2822 - Internet Message Format beschrieben :
In der Funktionsform Ihres
sendmail
Anrufs beginnen alle Leitungen mit Leerzeichen und werden daher "entfaltet" (verkettet), und Sie versuchen zu sendenAnders als unser Verstand vermuten lässt,
smtplib
werden dieTo:
undSubject:
Überschriften nicht mehr verstanden, da diese Namen nur am Anfang einer Zeile erkannt werden. Stattdessensmtplib
wird eine sehr lange Absender-E-Mail-Adresse angenommen:Dies wird nicht funktionieren und so kommt Ihre Ausnahme.
Die Lösung ist einfach: Bewahren Sie den
message
String einfach so auf, wie er vorher war. Dies kann durch eine Funktion (wie von Zeeshan vorgeschlagen) oder sofort im Quellcode erfolgen:Jetzt findet die Entfaltung nicht mehr statt und Sie senden
Welches ist, was funktioniert und was von Ihrem alten Code getan wurde.
Beachten Sie, dass ich auch die leere Zeile zwischen Headern und Body beibehalten habe, um Abschnitt 3.5 des RFC aufzunehmen (der erforderlich ist), und das Include außerhalb der Funktion gemäß dem Python -Styleguide PEP-0008 (optional) platziert habe.
quelle
Wahrscheinlich werden Tabs in Ihre Nachricht eingefügt. Drucken Sie die Nachricht aus, bevor Sie sie an sendMail übergeben.
quelle
Stellen Sie sicher, dass Sie sowohl dem Absender als auch dem Empfänger die Berechtigung erteilt haben, E-Mails von unbekannten Quellen (externen Quellen) im E-Mail-Konto zu senden und zu empfangen.
quelle
msg
ist keine gültige SMTP-Nachricht und scheint einfach im Äther zu verschwinden, wenn Ihr Mailserver dies akzeptiert.Ich dachte, ich würde meine zwei Teile hier einfügen, da ich gerade herausgefunden habe, wie das funktioniert.
Es scheint, dass Sie den in Ihren SERVER-Verbindungseinstellungen angegebenen Port nicht haben. Dies hat mich ein wenig beeinträchtigt, als ich versuchte, eine Verbindung zu meinem SMTP-Server herzustellen, der nicht den Standardport verwendet: 25.
Gemäß den smtplib.SMTP-Dokumenten sollte Ihre Ehlo- oder Helo-Anfrage / Antwort automatisch bearbeitet werden, sodass Sie sich darüber keine Sorgen machen müssen (dies kann jedoch eine Bestätigung sein, wenn alles andere fehlschlägt).
Eine andere Frage ist, ob Sie SMTP-Verbindungen auf Ihrem SMTP-Server selbst zugelassen haben. Bei einigen Websites wie GMAIL und ZOHO müssen Sie die IMAP-Verbindungen innerhalb des E-Mail-Kontos aktivieren. Ihr Mailserver lässt möglicherweise keine SMTP-Verbindungen zu, die möglicherweise nicht von 'localhost' stammen. Etwas zu untersuchen.
Als letztes möchten Sie möglicherweise versuchen, die Verbindung über TLS herzustellen. Die meisten Server erfordern jetzt diese Art der Authentifizierung.
Sie werden sehen, dass ich zwei TO-Felder in meine E-Mail gestaut habe. Mit den msg-Wörterbuchelementen msg ['TO'] und msg ['FROM'] werden die richtigen Informationen in den Kopfzeilen der E-Mail selbst angezeigt, die am empfangenden Ende der E-Mail in den Feldern An / Von (Sie) angezeigt werden Möglicherweise können Sie hier sogar ein Antwortfeld hinzufügen. Die Felder TO und FROM selbst sind die Anforderungen des Servers. Ich weiß, dass einige E-Mail-Server E-Mails ablehnen, wenn sie nicht über die richtigen E-Mail-Header verfügen.
Dies ist der Code, den ich in einer Funktion verwendet habe, mit der ich den Inhalt einer * .txt-Datei mithilfe meines lokalen Computers und eines Remote-SMTP-Servers (ZOHO wie gezeigt) per E-Mail versenden kann:
quelle
Es ist erwähnenswert, dass das SMTP-Modul den Kontextmanager unterstützt, sodass das manuelle Aufrufen von quit () nicht erforderlich ist. Dies garantiert, dass es immer aufgerufen wird, auch wenn es eine Ausnahme gibt.
quelle
Was Ihren Code betrifft, scheint nichts grundlegend Falsches daran zu sein, außer dass es unklar ist, wie Sie diese Funktion tatsächlich aufrufen. Ich kann mir nur vorstellen, dass Sie diesen SMTPServerDisconnected-Fehler erhalten, wenn Ihr Server nicht antwortet. Wenn Sie die Funktion getreply () in smtplib nachschlagen (Auszug unten), erhalten Sie eine Idee.
Überprüfen Sie ein Beispiel unter https://github.com/rreddy80/sendEmails/blob/master/sendEmailAttachments.py , das auch einen Funktionsaufruf zum Senden einer E-Mail verwendet, wenn Sie dies versuchen (DRY-Ansatz).
quelle