Wie sende ich E-Mails über Google Mail in Python?

Das manuelle Versenden zahlreicher E-Mails kann eine recht mühsame Aufgabe sein. Oft greift man auf Drittanbieterdienste zurück, um E-Mails in großen Mengen gleichzeitig zu versenden.

Wäre es nicht praktisch, ein eigenes, maßgeschneidertes Skript zu entwickeln, um E-Mails zu versenden?

Klingt das nicht fantastisch?

Absolut! Wir werden ein Python-Skript erstellen, um den E-Mail-Versand zu realisieren.

Python bietet eine Bibliothek namens `smtplib`, die speziell für das Senden von E-Mails entwickelt wurde. Diese Bibliothek basiert auf dem SMTP (Simple Mail Transport Protocol). SMTP ist das Standardprotokoll zum Versenden von E-Mails.

Gmail-Konfiguration

Wir verwenden Gmail als E-Mail-Provider für dieses Beispiel. Google erlaubt standardmäßig keine Skriptanmeldungen. Daher müssen wir die Sicherheitseinstellungen unseres Gmail-Kontos anpassen, damit Skripte sich anmelden können.

Die Änderung der Sicherheitseinstellungen birgt ein gewisses Risiko, da es anderen potenziell leichteren Zugriff auf Ihr Konto ermöglicht. Es wird daher empfohlen, ein separates Gmail-Konto zu diesem Zweck zu erstellen. In den Kontoeinstellungen können Sie die Option „Weniger sichere Apps zulassen“ aktivieren.

Alternativ zur Aktivierung dieser Einstellung können Sie auch die Google API nutzen, um sich bei Ihrem Gmail-Konto anzumelden. Ein entsprechendes Skript zur Verwendung der Google APIs für die Authentifizierung finden Sie hier.

Schritte für den E-Mail-Versand

Um eine E-Mail mithilfe der `smtplib`-Bibliothek zu versenden, sind einige Schritte notwendig. Zuerst betrachten wir die Schritte, danach schreiben wir das Skript.

#1. Verbindung zum SMTP-Server aufbauen

Jeder E-Mail-Provider verwendet einen eigenen Domänennamen und Port für den SMTP-Server. Wir müssen den Domänennamen und Port des SMTP-Servers unseres gewählten E-Mail-Anbieters im Skript verwenden. Für Gmail sind dies `smtp.gmail.com` und Port `465`.

Wir verwenden die SSL-Verschlüsselung für die SMTP-Serververbindung, da diese als sicherer als TSL gilt. Wenn Sie TSL verwenden möchten, verwenden Sie Port `587` anstelle von `465`. Der Domänenname des SMTP-Servers variiert je nach E-Mail-Anbieter.

Hier der Code für die Verbindung zum SMTP-Server:

server = smtplib.SMTP_SSL(smtp_server_domain_name, port, context=ssl_context)

#2. Anmeldung am Server

Sobald die Verbindung zum SMTP-Server hergestellt ist, können wir uns mit der Methode des Anmelde-SMTP-Objekts mithilfe unserer E-Mail-Adresse und dem Passwort anmelden. Der Code hierfür sieht wie folgt aus:

server.login(sender_email, password)

#3. E-Mail versenden

Nach erfolgreicher Anmeldung können wir nun die E-Mail versenden. Dazu verwenden wir die Methode `sendmail`. Achten Sie darauf, dass die E-Mail das folgende Format aufweist:

Betreff: Ihre_Betreffzeile_für_newline Mail_Inhalt

Leerzeichen sind hier nur zur Veranschaulichung und nicht zwingend notwendig. Hier ist ein Beispielcode:

server.sendmail(sender_mail, email, f"Subject: {subject}n{content}")

#4. Verbindung schließen

Vergessen Sie nicht, die SMTP-Verbindung zu beenden. Das geschieht mittels der `quit()` Methode.

Wir haben nun die Schritte zum Senden von E-Mails mit Python gesehen. Bisher haben wir jedoch nicht den gesamten Code besprochen. Schauen wir uns diesen nun an.

import smtplib, ssl

class Mail:

    def __init__(self):
        self.port = 465
        self.smtp_server_domain_name = "smtp.gmail.com"
        self.sender_mail = "GMAIL_ADDRESS"
        self.password = "SECURE_PASSWORD"

    def send(self, emails, subject, content):
        ssl_context = ssl.create_default_context()
        service = smtplib.SMTP_SSL(self.smtp_server_domain_name, self.port, context=ssl_context)
        service.login(self.sender_mail, self.password)
        
        for email in emails:
            result = service.sendmail(self.sender_mail, email, f"Subject: {subject}n{content}")

        service.quit()


if __name__ == '__main__':
    mails = input("Enter emails: ").split()
    subject = input("Enter subject: ")
    content = input("Enter content: ")

    mail = Mail()
    mail.send(mails, subject, content)

Wir haben hier eine Klasse namens `Mail` erstellt. Diese besitzt eine Methode namens `send`, welche die E-Mails versendet. Ob die Klasse genutzt wird oder nicht, bleibt Ihnen überlassen. Die Verwendung einer Klasse erhöht die Lesbarkeit. In der `send`-Methode haben wir alle zuvor besprochenen Schritte nacheinander implementiert.

Super! Sie haben nun eine E-Mail mithilfe eines Python-Skripts versendet.

HTML-Inhalt

Was, wenn Sie E-Mails mit HTML-Inhalt versenden möchten? Ist das möglich?

Ja, absolut. Wir können HTML-E-Mails mithilfe der Bibliothek `email.mime` versenden. Dies ist eine standardmäßig in Python integrierte Bibliothek.

MIME ist ein Standard zur Erweiterung von E-Mail-Formaten, um Anwendungsprogramme, Videos, Bilder etc. zu unterstützen.

Wir benötigen zwei Klassen aus dem `email.mime`-Modul: `MIMEText` und `MIMEMultipart`. Schauen wir uns diese kurz an.

#1. MIMEText

Die `MIMEText`-Klasse wird verwendet, um den E-Mail-Inhalt in HTML zu schreiben. Wir erstellen eine Instanz der `MIMEText`-Klasse, indem wir den HTML-Inhalt und den Inhalts-Typ übergeben. Hier ein Beispielcode:

html_content = MIMEText(html_template, 'html')

Einige E-Mail-Dienste unterstützen kein HTML-Rendering. Daher ist es empfehlenswert, zwei Instanzen der `MIMEText`-Klasse zu erstellen: eine für reinen Text und eine für HTML.

#2. MIMEMultipart

Die `MIMEMultipart`-Klasse wird verwendet, um Formatierung und das Schreiben des Betreffs, der Absenderadresse, Empfängeradresse, etc. zu vereinfachen. Wir übergeben den mit der `MIMEText`-Klasse erstellten Inhalt an `MIMEMultipart` mittels der Methode `attach`.

Wir müssen sicherstellen, dass die Instanz von `MIMEMultipart` mit dem Argument `alternative` erstellt wird, um reinen Text oder HTML zu rendern. Senden wir nun eine E-Mail mit HTML-Inhalt.

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


class Mail:

    def __init__(self):
        ...

    def send(self, emails):
        ssl_context = ssl.create_default_context()
        service = smtplib.SMTP_SSL(self.smtp_server_domain_name, self.port, context=ssl_context)
        service.login(self.sender_mail, self.password)
        
        for email in emails:
            mail = MIMEMultipart('alternative')
            mail['Subject'] = 'wdzwdz Celebrations'
            mail['From'] = self.sender_mail
            mail['To'] = email

            text_template = """
            wdzwdz

            Hi {0},
            We are delighted announce that our website hits 10 Million views this month.
            """
            html_template = """
            <h1>wdzwdz</h1>

            <p>Hi {0},</p>
            <p>We are delighted announce that our website hits <b>10 Million</b> views last month.</p>
            """

            html_content = MIMEText(html_template.format(email.split("@")[0]), 'html')
            text_content = MIMEText(text_template.format(email.split("@")[0]), 'plain')

            mail.attach(text_content)
            mail.attach(html_content)

            service.sendmail(self.sender_mail, email, mail.as_string())

        service.quit()


if __name__ == '__main__':
    mails = input("Enter emails: ").split()

    mail = Mail()
    mail.send(mails)

Sie können auch eine Blindkopie (Bcc) hinzufügen, indem Sie das Attribut `Bcc` in der `MIMEMultipart`-Instanz verwenden.

Anhänge hinzufügen

Anhänge können Bilder, PDFs, Dokumente, Tabellen usw. sein. Die Klasse `MIMEBase` aus dem Modul `email.mime` wird genutzt, um E-Mails Anhänge hinzuzufügen.

Fügen wir der obigen E-Mail einen Anhang hinzu.

import smtplib, ssl
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
from pathlib import Path


class Mail:

    def __init__(self):
        ...

    def send(self, emails):
        ## login...
        
        for email in emails:
            ## MIMEMultipart instance

            ## text and html templates

            ## MIMEText instances

            ## attaching messages to MIMEMultipart

            ## attaching an attachment
            file_path = "wdzwdz-logo.png"
            mimeBase = MIMEBase("application", "octet-stream")
            with open(file_path, "rb") as file:
                mimeBase.set_payload(file.read())
            encoders.encode_base64(mimeBase)
            mimeBase.add_header("Content-Disposition", f"attachment; filename={Path(file_path).name}")
            mail.attach(mimeBase)

            ## sending mail

        service.quit()


if __name__ == '__main__':
    mails = input("Enter emails: ").split()

    mail = Mail()
    mail.send(mails)

Massenversand von E-Mails

Wir haben eine Schleife verwendet, um die gleiche E-Mail an mehrere Empfänger zu senden. Dies ist geeignet, wenn Sie nicht möchten, dass die Empfänger voneinander wissen.

Nehmen wir an, Sie müssen die gleiche E-Mail an 1000 Mitglieder einer Gruppe senden. In solchen Fällen ist die Verwendung einer Schleife nicht sinnvoll. Wie man dies in Python erreicht?

Wir müssen die Liste der E-Mails als Zeichenkette kombinieren, wobei jede E-Mail durch ein Komma und ein Leerzeichen getrennt ist. Die `join`-Methode kann verwendet werden, um alle E-Mails als eine einzelne Zeichenkette zu verbinden. Hier ist der Code zum Kombinieren von E-Mails:

", ".join(emails)

Ersetzen Sie das Feld „An“ im obigen Skript durch die obige Zeichenkette. Das war’s, Sie haben die Mail gleichzeitig an mehrere Empfänger geschickt.

Fazit

Es gibt auch einige Drittanbieter-Bibliotheken für den E-Mail-Versand in Python. Einige davon sind Envelopes, Yagmail, Flanker, etc. Diese Bibliotheken erleichtern die Erstellung von Skripten mit nur wenigen Codezeilen. Sie können diese auch gerne erkunden.

Jetzt können Sie Ihre E-Mail-Aufgaben mithilfe von Python-Skripten automatisieren. Die Struktur des E-Mail-Versands variiert je nach Anwendungsfall. Wir haben verschiedene Szenarien zum Versenden von E-Mails besprochen. Sie können die im Tutorial behandelten Skripte leicht an Ihren Anwendungsfall anpassen. Die Inspiration für diesen Artikel stammt von diesem Artikel.

Viel Spaß beim Programmieren 🙂