Skip to content

Technik Blog

Programmieren | Arduino | ESP32 | MicroPython | Python | Raspberry Pi | Raspberry Pi Pico

Menu
  • Smarthome
  • Arduino
  • ESP32 & Co.
  • Raspberry Pi & Pico
  • Solo Mining
  • Über mich
  • Deutsch
  • English
Menu

Senden einer E-Mail aus einem Python3 Skript

Posted on 7. Juli 20213. Mai 2023 by Stefan Draeger

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
  • aktivieren von Pop3/IMAP in web.de
  • Senden einer E-Mail mit Text
    • Absenden von HTML Mails
  • Absenden einer E-Mail mit Dateianhängen
  • fertiges Python3 Skript zum senden von E-Mails mit Dateianhänge

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())
Python3 Skript zum senden von E-Mails mit DateianhängeHerunterladen

16 thoughts on “Senden einer E-Mail aus einem Python3 Skript”

  1. Julius sagt:
    28. Juli 2021 um 10:43 Uhr

    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

    Antworten
  2. Philipp Vogt sagt:
    11. Februar 2022 um 19:53 Uhr

    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 !!

    Antworten
    1. Stefan Draeger sagt:
      12. Februar 2022 um 19:33 Uhr

      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

      Antworten
  3. Klaus S. sagt:
    26. April 2022 um 08:11 Uhr

    Recht herzlichen Dank.
    Gut aufbereitet und auch für mich verständlich. 🙂

    Gruß, Klaus S.

    Antworten
  4. Dieter Jürgensen sagt:
    8. August 2022 um 16:37 Uhr

    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

    Antworten
    1. Stefan Draeger sagt:
      20. August 2022 um 18:24 Uhr

      Hi Dieter,

      vielen Dank für den Hinweis.
      Ich habe das soeben geändert.

      Gruß,

      Stefan

      Antworten
  5. Robin Klotz sagt:
    7. November 2022 um 22:39 Uhr

    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

    Antworten
  6. Robin sagt:
    7. November 2022 um 22:52 Uhr

    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

    Antworten
    1. Stefan Draeger sagt:
      8. November 2022 um 07:26 Uhr

      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

      Antworten
      1. Robin sagt:
        8. November 2022 um 09:13 Uhr

        Hallo Stefan,
        danke für die verdammt schnelle Antwort!
        Gruß Robin

        Antworten
        1. Stefan Draeger sagt:
          8. November 2022 um 20:15 Uhr

          Hi Robin,

          ich habe dir soeben den Beitrag https://draeger-it.blog/gmail-account-app-passwort-erstellen/ erstellt in welchem ich erläutere wie du ein App-Passwort
          erstellst und eine einfache E-Mail aus Python3 absendest.

          Gruß

          Stefan Draeger

          Antworten
  7. Wolfgang S sagt:
    19. Dezember 2022 um 22:30 Uhr

    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

    Antworten
    1. Stefan Draeger sagt:
      20. Dezember 2022 um 11:01 Uhr

      Hi,

      ja, das ist eine gute Idee, alternativ könnte man dieses auch speichern und später erneut versuchen.

      Gruß

      Stefan Draeger

      Antworten
      1. Wolfgang S sagt:
        20. Dezember 2022 um 17:44 Uhr

        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

        Antworten
  8. iGPt sagt:
    28. Mai 2023 um 23:53 Uhr

    Vielen Dank für die Anleitung. Ich war vorher schon auf zig Seiten, deren Scripte haben nur Fehler ausgeworfen (scheinbar unlösbare Zertifikatsfehler bei SSL, imports die nicht existieren …). Das hier funktioniert super. Leider erst nach 3 Stunden suchen und probieren gefunden.

    Ich wollte übrigens auch an mehrere Adressen versenden. Dazu lass ich das Script einfach mehrfach durchlaufen. Da ich auch den Content über vars abgreife, lässt der sich dann noch für beide unterschiedlich zusammenstellen und formatieren:

    body = („Text\n\n“ + var1 + „\nText: “ + var2 + „\nText: “ + var3 + „\n\nText“)
    …

    Antworten
  9. Pingback: ESP32-CAM - Bewegung ermitteln mit Python3 - Technik Blog

Schreibe einen Kommentar Antworten abbrechen

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

Fragen oder Feedback?

Du hast eine Idee, brauchst Hilfe oder möchtest Feedback loswerden?
Support-Ticket erstellen

Newsletter abonnieren

Bleib auf dem Laufenden: Erhalte regelmäßig Updates zu neuen Projekten, Tutorials und Tipps rund um Arduino, ESP32 und mehr – direkt in dein Postfach.

Jetzt Newsletter abonnieren

Unterstütze meinen Blog

Wenn dir meine Inhalte gefallen, freue ich mich über deine Unterstützung auf Tipeee.
So hilfst du mit, den Blog am Leben zu halten und neue Beiträge zu ermöglichen.

draeger-it.blog auf Tipeee unterstützen

Vielen Dank für deinen Support!
– Stefan Draeger

Kategorien

Tools

  • Unix-Zeitstempel-Rechner
  • ASCII Tabelle
  • Spannung, Strom, Widerstand und Leistung berechnen
  • Widerstandsrechner
  • 8×8 LED Matrix Tool
  • 8×16 LED Matrix Modul von Keyestudio
  • 16×16 LED Matrix – Generator

Links

Blogverzeichnis Bloggerei.de TopBlogs.de das Original - Blogverzeichnis | Blog Top Liste Blogverzeichnis trusted-blogs.com

Stefan Draeger
Königsberger Str. 13
38364 Schöningen

Tel.: 01778501273
E-Mail: info@draeger-it.blog

Folge mir auf

  • Impressum
  • Datenschutzerklärung
  • Disclaimer
  • Cookie-Richtlinie (EU)
©2025 Technik Blog | Built using WordPress and Responsive Blogily theme by Superb
Cookie-Zustimmung verwalten
Wir verwenden Technologien wie Cookies, um Geräteinformationen zu speichern und/oder darauf zuzugreifen. Wir tun dies, um das Surferlebnis zu verbessern und um personalisierte Werbung anzuzeigen. Wenn Sie diesen Technologien zustimmen, können wir Daten wie das Surfverhalten oder eindeutige IDs auf dieser Website verarbeiten. Wenn Sie Ihre Zustimmung nicht erteilen oder zurückziehen, können bestimmte Funktionen beeinträchtigt werden.
Funktional Immer aktiv
Die technische Speicherung oder der Zugang ist unbedingt erforderlich für den rechtmäßigen Zweck, die Nutzung eines bestimmten Dienstes zu ermöglichen, der vom Teilnehmer oder Nutzer ausdrücklich gewünscht wird, oder für den alleinigen Zweck, die Übertragung einer Nachricht über ein elektronisches Kommunikationsnetz durchzuführen.
Vorlieben
Die technische Speicherung oder der Zugriff ist für den rechtmäßigen Zweck der Speicherung von Präferenzen erforderlich, die nicht vom Abonnenten oder Benutzer angefordert wurden.
Statistiken
Die technische Speicherung oder der Zugriff, der ausschließlich zu statistischen Zwecken erfolgt. Die technische Speicherung oder der Zugriff, der ausschließlich zu anonymen statistischen Zwecken verwendet wird. Ohne eine Vorladung, die freiwillige Zustimmung deines Internetdienstanbieters oder zusätzliche Aufzeichnungen von Dritten können die zu diesem Zweck gespeicherten oder abgerufenen Informationen allein in der Regel nicht dazu verwendet werden, dich zu identifizieren.
Marketing
Die technische Speicherung oder der Zugriff ist erforderlich, um Nutzerprofile zu erstellen, um Werbung zu versenden oder um den Nutzer auf einer Website oder über mehrere Websites hinweg zu ähnlichen Marketingzwecken zu verfolgen.
Optionen verwalten Dienste verwalten Verwalten von {vendor_count}-Lieferanten Lese mehr über diese Zwecke
Einstellungen anzeigen
{title} {title} {title}