Senden einer E-Mail aus einem Python3 Skript

In diesem Beitrag möchte ich dir ausführlich zeigen, wie du eine E-Mail aus einem Python3 Skript senden kannst. Des Weiteren zeige ich dir auch wie du eine E-Mail inkl. Dateianhänge absenden kannst.

Python3 - E-Mail senden
Python3 – E-Mail senden

E-Mail-Adresse zum Testen

Für diesen Beitrag verwende ich eine kostenfreie E-Mail von web.de. Du kannst natürlich auch jeden anderen E-Mail Dienst nutzen.

Bei der Verwendung von Gmail.com musst du jedoch noch eine zusätzliche App einrichten, was den Aufwand etwas erhöht.

Die Daten des SMTP Ausgangsservers von web.de sind:

Serversmtp.web.de
Port587
VerschlüsselungSTARTTLS, TLS oder Verschlüsselung
Daten des SMTP Ausgangsservers von web.de

aktivieren von Pop3/IMAP in web.de

Damit jedoch das Absenden einer E-Mail von einem externen Programm mit einem web.de Account möglich ist, muss die Einstellung „POP3 und IMAP erlauben“ gesetzt (Haken ist gesetzt) werden.

Einstellung für die Aktivierung von Pop3 / IMAP in web.de
Einstellung für die Aktivierung von Pop3 / IMAP in web.de

Senden einer E-Mail mit Text

Zunächst möchte ich dir zeigen wie du einen einfachen Text per E-Mail senden kannst.

Dabei müssen Zeilenumbrüche in dem Text per „\n“ ersetzt oder gesetzt werden!

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

# Serverdaten
smtpServer = "smtp.web.de"
smtpPort = 587

# Zugangsdaten
username = "abc@web.de"
password = "xyz#567"

# Sender & Empfänger
sender = "mytestmail0815@web.de"
reciever = "info@draeger-it.blog"

# Betreff & Inhalt
subject = "Hallo Welt!"
body = "Hier steht ein Text. \n Mit einem Zeilenumbruch."

# Message Objekt für die E-Mail
# später kann an dieses Objekt eine
# oder mehrere Dateien angehängt
# werden.
msg = MIMEMultipart()
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = reciever

part = MIMEText(body, 'plain')
msg.attach(part)

# Erzeugen einer Mail Session
smtpObj = smtplib.SMTP(smtpServer, smtpPort)
# Debuginformationen auf der Konsole ausgeben
smtpObj.set_debuglevel(1)
# Wenn der Server eine Authentifizierung benötigt dann...
smtpObj.starttls()
smtpObj.login(username, password)

# absenden der E-Mail
smtpObj.sendmail(sender, reciever, msg.as_string())

Wenn das Skript nun ausgeführt wird, dann erscheint beim Empfänger nachfolgende E-Mail.

Ansicht der E-Mail im Client

Absenden von HTML Mails

Im ersten Beispiel habe ich gezeigt wie du eine einfache Mail mit einem „Plaintext“ senden kannst. Diese Form des Textes ist recht sicher da so ziemlich jeder Mail Client diesen Text anzeigen lassen kann.

Wenn es etwas schöner sein soll, dann greift man auf HTML Text zurück. Hier hat man deutlich mehr Möglichkeiten seine E-Mail zu gestalten.

body_html = "<html><body>"\
    "<h1>Eine Überschrift</h1>"\
    "<p style='color:red'>Ein Text in der Schriftfarbe rot</p>"\
    "<div style='background-color:green'>Hier ist ein Text mit einer Hintergrundfarbe.</div>"\
    "</body></html>"

html_part = MIMEText(body_html, 'html')
msg.attach(html_part)
E-Mail mit HTML Content
E-Mail mit HTML Content

Absenden einer E-Mail mit Dateianhängen

Möchte man nun eine Datei per E-Mail versenden, so muss diese als weiteren „part“ angehängt werden.

Jedoch muss diese Datei zuvor in BASE64 Codiert werden.

from email.mime.base import MIMEBase
from email import encoders
...
filename = "test.txt"

file_part = MIMEBase('application', "octet-stream")
file_part.set_payload(open(filename, "rb").read())
encoders.encode_base64(part)

file_part.add_header('Content-Disposition', 'attachment; filename="'+filename+'"')
msg.attach(file_part)
...
E-Mail mit Dateinanhang und HTML Content
E-Mail mit Dateinanhang und HTML Content

fertiges Python3 Skript zum senden von E-Mails mit Dateianhänge

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders

# Serverdaten
smtpServer = "smtp.web.de"
smtpPort = 587

# Zugangsdaten
username = "abc@web.de"
password = "xyz#123"

# Sender & Empfänger
sender = "mytestmail0815@web.de"
reciever = "info@draeger-it.blog"

# Betreff
subject = "Hallo Welt!"

# Inhalt der Mail
body = "Hier steht ein Text. \n Mit einem Zeilenumbruch."
body_html = "<html><body>"\
    "<h1>Eine Überschrift</h1>"\
    "<p style='color:red'>Ein Text in der Schriftfarbe rot</p>"\
    "<div style='background-color:green'>Hier ist ein Text mit einer Hintergrundfarbe.</div>"\
    "</body></html>"

# Message Objekt für die E-Mail
# später kann an dieses Objekt eine
# oder mehrere Dateien angehängt
# werden.
msg = MIMEMultipart()
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = reciever

# Plain Text
part = MIMEText(body, 'plain')
msg.attach(part)

# HTML Text
html_part = MIMEText(body_html, 'html')
msg.attach(html_part)

# Dateianhang
filename = "test.txt"
file_part = MIMEBase('application', "octet-stream")
file_part.set_payload(open(filename, "rb").read())
encoders.encode_base64(file_part)
file_part.add_header('Content-Disposition', 'attachment; filename="'+filename+'"')
msg.attach(file_part)

# Erzeugen einer Mail Session
smtpObj = smtplib.SMTP(smtpServer, smtpPort)
# Debuginformationen auf der Konsole ausgeben
smtpObj.set_debuglevel(1)
# Wenn der Server eine Authentifizierung benötigt dann...
smtpObj.starttls()
smtpObj.login(username, password)

# absenden der E-Mail
smtpObj.sendmail(sender, reciever, msg.as_string())

15 Kommentare

  1. Herzlichen Dank für diese gute Schritt-für-Schritt-Anleitung! So kann auch ein Programmier-Anfänger wie ich das Thema gut verstehen 😀 Vielen Dank für den Beitrag und weiter so!
    Liebe Grüße
    Julius

  2. Zu allererst vielen Dank für die super Anleitung 🙂

    Leider bekomme ich stets diese Fehlermeldung: UnicodeEncodeError: ‚ascii‘ codec can’t encode characters in position 671-673: ordinal not in range(128)

    mit einer 4 zeiligen csv datei klappt es manchmal. Mit einer txt Datei leider überhaupt nicht. Bitte um Hilfe !!

    1. Hi,

      das klingt nach Zeichen welche nicht decodiert werden können.

      Hast einmal ein Beispiel welches du mir per Email senden kannst?

      Gruß

      Stefan Draeger

  3. Moin, danke für das Beispiel. Ich glaube da hat sich ein kleiner Fehlerteufel eingeschlichen.
    In Zeile 51 encoders.encode_base64(part) müsste
    es wohl encoders.encode_base64(file_part) heißen. Dadurch wird der Body Text verändert.
    Noch eine Frage, gibt es eine einfache Möglichkeit zu erkennen, ob das Versenden der Mail funktioniert hat.
    MfG Dieter Jürggensen

  4. Hallo zusammen,

    ich bekomme hierbei ein Fehlercode der vermutlich mit der host und port Adresse zusammenhängt.
    Bei mir wäre das soweit ich verstanden habe bei Gmail: smtp.gmail.com und 465

    Fehlercode:

    SMTPServerDisconnected Traceback (most recent call last)
    in
    25 msg.attach(part)
    26 # Erzeugen einer Mail Session
    —> 27 smtpObj = smtplib.SMTP(smtpServer, smtpPort)
    28 # Debuginformationen auf der Konsole ausgeben
    29 smtpObj.set_debuglevel(1)

    ~\anaconda3\lib\smtplib.py in __init__(self, host, port, local_hostname, timeout, source_address)
    251
    252 if host:
    –> 253 (code, msg) = self.connect(host, port)
    254 if code != 220:
    255 self.close()

    ~\anaconda3\lib\smtplib.py in connect(self, host, port, source_address)
    337 self.sock = self._get_socket(host, port, self.timeout)
    338 self.file = None
    –> 339 (code, msg) = self.getreply()
    340 if self.debuglevel > 0:
    341 self._print_debug(‚connect:‘, repr(msg))

    ~\anaconda3\lib\smtplib.py in getreply(self)
    394 if not line:
    395 self.close()
    –> 396 raise SMTPServerDisconnected(„Connection unexpectedly closed“)
    397 if self.debuglevel > 0:
    398 self._print_debug(‚reply:‘, repr(line))

    SMTPServerDisconnected: Connection unexpectedly closed

    Für Hilfe wäre ich dankbar 🙂
    Gruß Robin

  5. Hallo zusammen,
    ich erhalte leider Fehlermeldungen für den Login.
    Verwendet habe ich eine Gmail Adresse mit dem Server: smtp.googlemail.com und dem Port 587. Meine Fehlermeldung sieht wie folgt aus: —————————————————————————
    SMTPAuthenticationError Traceback (most recent call last)
    in
    35 # Wenn der Server eine Authentifizierung benötigt dann…
    36 smtpObj.starttls()
    —> 37 smtpObj.login(username, password)
    38 # absenden der E-Mail
    39 smtpObj.sendmail(sender, reciever, msg.as_string())

    ~\anaconda3\lib\smtplib.py in login(self, user, password, initial_response_ok)
    730
    731 # We could not login successfully. Return result of last attempt.
    –> 732 raise last_exception
    733
    734 def starttls(self, keyfile=None, certfile=None, context=None):

    ~\anaconda3\lib\smtplib.py in login(self, user, password, initial_response_ok)
    719 method_name = ‚auth_‘ + authmethod.lower().replace(‚-‚, ‚_‘)
    720 try:
    –> 721 (code, resp) = self.auth(
    722 authmethod, getattr(self, method_name),
    723 initial_response_ok=initial_response_ok)

    ~\anaconda3\lib\smtplib.py in auth(self, mechanism, authobject, initial_response_ok)
    642 if code in (235, 503):
    643 return (code, resp)
    –> 644 raise SMTPAuthenticationError(code, resp)
    645
    646 def auth_cram_md5(self, challenge=None):

    SMTPAuthenticationError: (535, b’5.7.8 Username and Password not accepted. Learn more at\n5.7.8

    Über Hilfe wäre ich sehr dankbar,
    Gruß Robin

    1. Hi,

      das Problem bei GMail besteht darin das man ein gesondertes Passwort über die GMail Seite für externe Dienste erstellen muss, damit kann man sich dann erfolgreich anmelden.

      Daher verwende ich in meinen Beiträgen immer eine Web.de Adresse hier ist es nur ein einfacher Haken welcher gesetzt werden muss.

      Gruß,

      Stefan

  6. Hallo Stefan,
    als Erstes: Super Anleitung (auch für Python Dummies) und auch für Deine schnellen Reaktionen.
    Ich hab eine kleine Routine erstellt, die im Falle eines „Alarms“ eine Sub-Routine aufruft, die eine Mail versendet. Jetzt ist es so, dass hie und da mal der Server nicht erreichbar ist, etc.
    Ich habe mir gedacht, dass man in der Mailroutine im Falle des Falles einen Fehler ausgibt, der von der Hauptroutine ausgewertet wird und dann z.B. versucht über eine andere Mailadresse eine Mail versendet.
    Beispiel: Primär wird über WEB.DE und im Fehlerfall über GMAIL.COM versendet.

    Gruß
    Wolfgang

      1. Hi,
        ich bezeichne mich ja als Dummy oder wenigstens Newbee.
        In diesem Sinne hatte ich gehofft einen Tipp zu bekommen, wie man aus „set_debuglevel(1)“ eine Variable raus kriegt, die weiter verarbeitet werden kann. So im Sinne:
        If Error = true:
        send_Backupmail (x,y,z);
        #Else:
        do nothing;
        Danke
        Wolfgang

Kommentar hinterlassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert