2008-09-15 4 views
93

Ich verwende die folgende Methode, um E-Mails von Python mit SMTP zu senden. Ist es die richtige Methode zu verwenden oder gibt es Gotchas, die ich vermisse?Senden von E-Mail aus Python mit 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

Stellen Sie sicher, dass Sie das Datum/Uhrzeit korrekt erhalten. Ich fand die folgende Funktion sehr nützlich, die Ihnen einen perfekt formatierten Wert für den Date-Header gibt: http://docs.python.org/py3k/library/email.util.html#email.utils.formatdate – BastiBen

+0

hier ist ein Codebeispiel, das [E-Mail senden mit Unicode-Text im Betreff und/oder im Text] ermöglicht (http://stackoverflow.com/a/20787826/4279) – jfs

+0

Hier ist ein Codebeispiel, das zeigt, wie [Inline-Bilder senden (plus E-Mail mit HTML- und Nur-Text-Teilen)] (http://stackoverflow.com/a/20485764/4279). Es zeigt auch, wie SSL-Parameter in alten Python-Versionen konfiguriert werden. – jfs

Antwort

94

Das Skript, das ich verwende, ist ziemlich ähnlich; Ich poste es hier als ein Beispiel dafür, wie man die email. * Module benutzt, um MIME-Nachrichten zu erzeugen; so kann dieses Skript leicht geändert werden, um Bilder usw. anzufügen.

Ich verlasse mich auf meinen ISP, um den Datumzeitheader hinzuzufügen.

ISP verlangt von mir eine sicheren SMTP-Verbindung zu verwenden, um Mail zu senden, ich auf dem ssmtplib Modul verlassen (zum Herunterladen auf http://www1.cs.columbia.edu/~db2501/ssmtplib.py)

Wie in Ihrem Skript, der Benutzername und das Passwort, (Dummy-Wert weiter unten), verwendet, um auf dem SMTP-Server zu authentifizieren, sind in Klartext in der Quelle. Dies ist eine Sicherheitsschwäche; aber die beste Alternative hängt davon ab, wie vorsichtig Sie (wollen?) sein müssen, um diese zu schützen.

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

#! /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 fehlgeschlagen; 'Modul' Objekt hat kein Attribut 'SSLFakeSocket' - mit Gmail :( – RadiantHex

+0

Das klingt wie eine Version oder ein Import-Problem, um zu verfolgen, welche Version Python Sie ausführen? - Müssen Sie eine Verbindung zu Ihrem SMTP-Server über SSL (und wenn ja, importieren Sie ssmtplib, wie oben)? Kannst du smtplib direkt von Python interaktiv importieren, wenn ja, gibt es eine Klasse smtplib.SSLFakeSocket? Ich kann helfen –

+1

Verwenden Sie smtplib.SMTP_SSL (Standard in (die neuesten Versionen von Python), um die Verbindung anstelle von ssmtplib.STMP_SSL (Drittanbieter-Modul oben) zu erstellen. Beachten Sie, dass das Standardmodul mit einem einzelnen 's' beginnt. Das hat für mich funktioniert. –

6

Der Haupt Gotcha ich sehe, ist, dass Sie keine Fehler Handhabung: .login() und .sendmail() haben beide Ausnahmen dokumentiert, dass sie werfen können, und es scheint, wie .Connect() müssen ein Weg, um anzuzeigen, dass es keine Verbindung herstellen konnte - wahrscheinlich eine Ausnahme, die vom zugrunde liegenden Socket-Code ausgelöst wurde.

3

Sie sollten sicherstellen, dass Sie das Datum im richtigen Format formatieren - RFC2822.

5

Stellen Sie sicher, dass keine Firewalls SMTP blockieren. Als ich das erste Mal versuchte, eine E-Mail zu senden, wurde sie sowohl von der Windows-Firewall als auch von McAfee blockiert - es dauerte ewig, bis sie beide gefunden hatten.

20

Auch wenn Sie smtp auth mit TLS im Gegensatz zu SSL tun wollen, dann müssen Sie nur den Port ändern (verwenden Sie 587) und tun Sie smtp.starttls(). Dies funktionierte für mich:

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

Danke für diesen Ausschnitt! –

5

Was ist damit?

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

Die Methode, die ich häufig verwenden ... nicht viel anders, aber ein wenig

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

Das ist es

+10

IMO, das ist die beste Antwort in diesem Thread. – lpapp

+0

Wenn Sie die Bestätigung in zwei Schritten verwenden, müssen Sie zuerst ein anwendungsspezifisches Passwort erstellen und Ihr normales Passwort damit ersetzen. Siehe [Mit App-Passwörtern anmelden] (https://support.google.com/accounts/answer/185833?hl=de) –

+1

@lpapp Vielleicht könnten Sie die beste Antwort noch einmal überdenken? – PascalVKooten

5

folgenden Code funktioniert gut für mich:

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 hat ein Framework für E-Mail: aus flask.ext.mail importieren Mail. Ich bin mit der Fehlersuche beschäftigt und dachte, ich würde zurück zum Python-Code gehen, um zu sehen, ob ich etwas zum Arbeiten bekommen könnte. Ich mochte diese Antwort, weil es nackte Knochen war. Oh ja, und es hat funktioniert! – Aaron

+0

** Achtung: ** Die vorherige Version der Antwort enthielt die Zeile: 'smtpserver.close()' Es muss sein: 'smtpserver.quit()', weil 'close()' die TLS-Verbindung nicht beendet richtig! 'close()' wird während 'quit()' aufgerufen. – aronadaal

+0

Hallo, ich habe Probleme, die obigen Befehle auszuführen. Wenn ich smtpserver.starttls() verwende, erhalte ich einen SMTP-Fehler "SMTPServerDisconnected: Verbindung unerwartet geschlossen: [Errno 10054]" .. berichtet in https: // stackoverflow.com/questions/46094175/starttls-is-giving-me-a-smtpserverdisconnect-Fehler-wenn-versuchen-zu-senden-E-Mails – fazkan

2

Sehen Sie alle diese langen Antworten? Bitte erlauben Sie mir selbst zu fördern, indem Sie alles in ein paar Zeilen tun.

Import und Connect:

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

Dann ist es nur ein Einzeiler:

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

es tatsächlich zu schließen, wenn es den Bereich verlässt (oder kann manuell geschlossen werden).Darüber hinaus können Sie Ihren Benutzernamen in Ihrem Schlüsselbund registrieren, so dass Sie nicht Ihr Passwort in Ihrem Skript schreiben müssen (es hat mich wirklich gestört yagmail!)

Für das Paket/Installation, Tipps und Tricks bitte schauen Sie auf git oder pip, verfügbar für Python 2 und 3.

+0

@PascalvKoolen Ich habe Yagmail installiert, und versuchte Verbindung durch Angabe meiner E-Mail-ID und Passwort. aber es gab mir einen Authentifizierungsfehler – fazkan

Verwandte Themen