Wie sende ich mit Python eine E-Mail mit Google Mail als Anbieter?


289

Ich versuche, E-Mails (Google Mail) mit Python zu senden, erhalte jedoch die folgende Fehlermeldung.

Traceback (most recent call last):  
File "emailSend.py", line 14, in <module>  
server.login(username,password)  
File "/usr/lib/python2.5/smtplib.py", line 554, in login  
raise SMTPException("SMTP AUTH extension not supported by server.")  
smtplib.SMTPException: SMTP AUTH extension not supported by server.

Das Python-Skript ist das folgende.

import smtplib
fromaddr = 'user_me@gmail.com'
toaddrs  = 'user_you@gmail.com'
msg = 'Why,Oh why!'
username = 'user_me@gmail.com'
password = 'pwd'
server = smtplib.SMTP('smtp.gmail.com:587')
server.starttls()
server.login(username,password)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()

16
Diese Frage sollte jetzt entsperrt werden, da Google auf eine interne API zum Senden von Nachrichten über Google Mail umstellt. Dieser Schritt macht alle bis auf eine dieser Antworten veraltet, und die eine relevante Antwort ist sehr leicht für die tatsächliche Lösung des Problems.
Andrew

Deaktivieren Sie für VPN-Benutzer Ihr VPN, wenn das Problem weiterhin besteht. Das hat bei mir funktioniert.
Paul

Antworten:


211

Sie müssen sagen, EHLObevor Sie direkt auf Folgendes stoßen STARTTLS:

server = smtplib.SMTP('smtp.gmail.com:587')
server.ehlo()
server.starttls()

Auch sollten Sie wirklich schaffen From:, To:und Subject:Nachrichten - Header, getrennt von dem Nachrichtentext durch eine Leerzeile und die Verwendung CRLFals EOL - Markierungen.

Z.B

msg = "\r\n".join([
  "From: user_me@gmail.com",
  "To: user_you@gmail.com",
  "Subject: Just a message",
  "",
  "Why, oh why"
  ])

2
Aufrufen von server.sendmail (fromaddr, toaddrs, msg), dem zweiten Parameter, toaddrs muss eine Liste sein, toaddrs = ['user_me@gmail.com']
Massimo Fazzolari

14
Ab August 2014 wird jetzt smtplib.SMTPAuthenticationError ausgelöst: (534, '5.7.9 Anwendungsspezifisches Passwort erforderlich.
anon58192932

7
Für mich musste ich jedoch ein 'App'-Passwort aktivieren, um mich mit einem
@ google-

1
Hier ist ein Link zum Versenden mehrerer Personen: stackoverflow.com/questions/8856117/…
anon58192932

1
Ich habe mich einmal per Telnet bei einem SMTP-Server angemeldet und EHLOper Tippfehler gesendet . Nachdem ich HELO viele Male ausprobiert hatte, war die Reaktion anders. Es hat Stunden gedauert, um herauszufinden, dass EHLO tatsächlich ein Befehl ist, den SMTP versteht, und ich habe den Tippfehler gemacht.
Shiplu Mokaddim

297
def send_email(user, pwd, recipient, subject, body):
    import smtplib

    FROM = user
    TO = recipient if isinstance(recipient, list) else [recipient]
    SUBJECT = subject
    TEXT = body

    # Prepare actual message
    message = """From: %s\nTo: %s\nSubject: %s\n\n%s
    """ % (FROM, ", ".join(TO), SUBJECT, TEXT)
    try:
        server = smtplib.SMTP("smtp.gmail.com", 587)
        server.ehlo()
        server.starttls()
        server.login(user, pwd)
        server.sendmail(FROM, TO, message)
        server.close()
        print 'successfully sent the mail'
    except:
        print "failed to send mail"

Wenn Sie Port 465 verwenden möchten, müssen Sie ein SMTP_SSLObjekt erstellen :

# SMTP_SSL Example
server_ssl = smtplib.SMTP_SSL("smtp.gmail.com", 465)
server_ssl.ehlo() # optional, called by login()
server_ssl.login(gmail_user, gmail_pwd)  
# ssl server doesn't support or need tls, so don't call server_ssl.starttls() 
server_ssl.sendmail(FROM, TO, message)
#server_ssl.quit()
server_ssl.close()
print 'successfully sent the mail'

2
Sehr schöne Probe danke. Ein Gedanke, den ich bemerkt habe, ist, wenn ich eine SSL-Verbindung verwenden möchte, musste ich server.starttls ()
Dowlers

18
Funktioniert leider nicht mehr: smtplib.SMTPAuthenticationError: (534, '5.7.14 < accounts.google.com/… ... Bitte melden Sie sich über Ihren Webbrowser an und \ n5.7.14 versuchen Sie es erneut. \ N5.7.14 Erfahren Sie mehr mehr unter \ n5.7.14 support.google.com/mail/bin/answer.py?answer=78754 ... Dann habe ich eine E-Mail von Google erhalten, dass es einen verdächtigen Verbindungsversuch gegeben hat.
royskatt

13
@royskatt - Sie müssen lediglich ein App-Passwort erstellen und es anstelle Ihres Kontopassworts verwenden. Erstellen Sie hier ein App-Passwort: security.google.com/settings/security/apppasswords
Jared

15
@royskatt: Ich habe gerade eine Lösung für das Problem gefunden, mit dem Sie konfrontiert waren. Google hat eine Einstellung, die den Zugriff für weniger sichere Apps ermöglicht. Sie müssen sie nur aktivieren. Sie können dorthin gelangen von: Google -> Mein Konto -> Anmelden & Sicherheit -> Verbundene Apps & Websites ->
Scrollen

2
Wenn Ihr Google Mail-Konto durch Zwei-Faktor-Authentifizierung geschützt ist, müssen Sie zuerst ein anwendungsspezifisches Kennwort generieren -> und dann dieses App-Kennwort für den obigen Beispielcode verwenden (dies ist sehr wichtig, da Sie Ihr Kennwort dann nirgendwo aufschreiben im Klartext UND Sie können das App-Passwort jederzeit widerrufen).
Trevor Boyd Smith

136

Ich stieß auf ein ähnliches Problem und stolperte über diese Frage. Ich habe einen SMTP-Authentifizierungsfehler erhalten, aber mein Benutzername / Pass war korrekt. Hier ist, was es behoben hat. Ich lese das:

https://support.google.com/accounts/answer/6010255

Kurz gesagt, Google erlaubt Ihnen nicht, sich über smtplib anzumelden, da diese Art der Anmeldung als "weniger sicher" gekennzeichnet wurde. Sie müssen also zu diesem Link gehen, während Sie in Ihrem Google-Konto angemeldet sind. und erlauben Sie den Zugriff:

https://www.google.com/settings/security/lesssecureapps

Sobald dies eingestellt ist (siehe meinen Screenshot unten), sollte es funktionieren.

Geben Sie hier die Bildbeschreibung ein

Login funktioniert jetzt:

smtpserver = smtplib.SMTP("smtp.gmail.com", 587)
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.ehlo()
smtpserver.login('me@gmail.com', 'me_pass')

Antwort nach Änderung:

(235, '2.7.0 Accepted')

Antwort vor:

smtplib.SMTPAuthenticationError: (535, '5.7.8 Username and Password not accepted. Learn more at\n5.7.8 http://support.google.com/mail/bin/answer.py?answer=14257 g66sm2224117qgf.37 - gsmtp')

Funktioniert immer noch nicht? Wenn Sie immer noch den SMTPAuthenticationError erhalten, der Code jetzt jedoch 534 lautet, liegt dies daran, dass der Speicherort unbekannt ist. Folgen Sie diesem Link:

https://accounts.google.com/DisplayUnlockCaptcha

Klicken Sie auf Weiter. Dies sollte Ihnen 10 Minuten Zeit geben, um Ihre neue App zu registrieren. Fahren Sie jetzt mit einem weiteren Anmeldeversuch fort und es sollte funktionieren.

UPDATE : Dies scheint nicht sofort zu funktionieren. Möglicherweise stecken Sie eine Weile fest und erhalten diesen Fehler in smptlib:

235 == 'Authentication successful'
503 == 'Error: already authenticated'

In der Nachricht heißt es, dass Sie sich mit dem Browser anmelden sollen:

SMTPAuthenticationError: (534, '5.7.9 Please log in with your web browser and then try again. Learn more at\n5.7.9 https://support.google.com/mail/bin/answer.py?answer=78754 qo11sm4014232igb.17 - gsmtp')

Nachdem Sie "lesssecureapps" aktiviert haben, gehen Sie auf einen Kaffee, kehren Sie zurück und versuchen Sie es erneut mit dem Link "DisplayUnlockCaptcha". Aufgrund der Benutzererfahrung kann es bis zu einer Stunde dauern, bis die Änderung wirksam wird. Versuchen Sie dann erneut, sich anzumelden.


3
JA DANKESCHÖN ! Geschah bei der Verwendung von Flask-Mail
Giannis

1
danke Mann nur Problem für mich: Accounts.google.com/DisplayUnlockCaptcha
Limitless isa

6
Lassen Sie außerdem eine halbe bis eine Stunde Zeit, damit sich die Einstellungen ändern können. Ich habe ein neues Konto erstellt, die gesamte zusätzliche Sicherheit deaktiviert und trotzdem den gleichen Fehler erhalten. Ungefähr eine Stunde später funktionierte alles.
jkgeyti

2
Das Aktivieren weniger sicherer Apps ist nicht möglich, wenn Sie die "Bestätigung in zwei Schritten" aktiviert haben. Die beste und sicherste Option ist das Aktivieren des "apppassword" security.google.com/settings/security/apppasswords, wie bereits vorgeschlagen, und es funktioniert wie ein Zauber
Omiod

2
Wenn ich dem Link "Kennwörter" folge, wird für alle meine Google-Konten der Fehler "Die gesuchte Einstellung ist für Ihr Konto nicht verfügbar" angezeigt.
Suzanne

18

Bist du mit OOP fertig?

#!/usr/bin/env python


import smtplib

class Gmail(object):
    def __init__(self, email, password):
        self.email = email
        self.password = password
        self.server = 'smtp.gmail.com'
        self.port = 587
        session = smtplib.SMTP(self.server, self.port)        
        session.ehlo()
        session.starttls()
        session.ehlo
        session.login(self.email, self.password)
        self.session = session

    def send_message(self, subject, body):
        ''' This must be removed '''
        headers = [
            "From: " + self.email,
            "Subject: " + subject,
            "To: " + self.email,
            "MIME-Version: 1.0",
           "Content-Type: text/html"]
        headers = "\r\n".join(headers)
        self.session.sendmail(
            self.email,
            self.email,
            headers + "\r\n\r\n" + body)


gm = Gmail('Your Email', 'Password')

gm.send_message('Subject', 'Message')

33
Wenn Ihre Klasse nur zwei Methoden hat, von denen eine __init__ ist, verwenden Sie einfach eine Funktion.
JoeQuery

Wie würden Sie mit dieser Methode einen Anhang hinzufügen?
Sgerbhctim

Die Verwendung einer Klasse wäre gut, wenn Sie den Client initiieren und an andere Teile des Codes weitergeben möchten, anstatt eine E-Mail und ein Kennwort weiterzugeben. Oder wenn Sie mehrere Nachrichten senden möchten, ohne jedes Mal die E-Mail und das Passwort einzugeben.
Sami Start

15

Das funktioniert

Erstellen Sie ein Google Mail-App-Passwort!

Nachdem Sie das erstellt haben, erstellen Sie eine Datei mit dem Namen sendgmail.py

Fügen Sie dann diesen Code hinzu :

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# =============================================================================
# Created By  : Jeromie Kirchoff
# Created Date: Mon Aug 02 17:46:00 PDT 2018
# =============================================================================
# Imports
# =============================================================================
import smtplib

# =============================================================================
# SET EMAIL LOGIN REQUIREMENTS
# =============================================================================
gmail_user = 'THEFROM@gmail.com'
gmail_app_password = 'YOUR-GOOGLE-APPLICATION-PASSWORD!!!!'

# =============================================================================
# SET THE INFO ABOUT THE SAID EMAIL
# =============================================================================
sent_from = gmail_user
sent_to = ['THE-TO@gmail.com', 'THE-TO@gmail.com']
sent_subject = "Where are all my Robot Women at?"
sent_body = ("Hey, what's up? friend!\n\n"
             "I hope you have been well!\n"
             "\n"
             "Cheers,\n"
             "Jay\n")

email_text = """\
From: %s
To: %s
Subject: %s

%s
""" % (sent_from, ", ".join(sent_to), sent_subject, sent_body)

# =============================================================================
# SEND EMAIL OR DIE TRYING!!!
# Details: http://www.samlogic.net/articles/smtp-commands-reference.htm
# =============================================================================

try:
    server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
    server.ehlo()
    server.login(gmail_user, gmail_app_password)
    server.sendmail(sent_from, sent_to, email_text)
    server.close()

    print('Email sent!')
except Exception as exception:
    print("Error: %s!\n\n" % exception)

Wenn Sie also erfolgreich sind, sehen Sie ein Bild wie das folgende:

Ich habe getestet, indem ich eine E-Mail von und an mich selbst gesendet habe.

Erfolgreiche E-Mail gesendet.

Hinweis: In meinem Konto ist die Bestätigung in zwei Schritten aktiviert. App Passwort funktioniert damit! (Für die Einrichtung von Google Mail-SMTP müssen Sie unter https://support.google.com/accounts/answer/185833?hl=de die folgenden Schritte ausführen. )

Diese Einstellung ist nicht für Konten mit aktivierter Bestätigung in zwei Schritten verfügbar. Für solche Konten ist ein anwendungsspezifisches Kennwort für einen weniger sicheren Zugriff auf Apps erforderlich.

Weniger sicherer App-Zugriff ... Diese Einstellung ist nicht für Konten mit aktivierter Bestätigung in zwei Schritten verfügbar.


1
Fantastische Lösung und sehr gut im Code erklärt. Vielen Dank, Jay, sehr geschätzt. Dumme Frage: Würdest du wissen, wie viele E-Mails pro Tag maximal gesendet werden können (mit Google Mail)?
Angelo

Vielen Dank an Angelo, aber es gibt ein Limit, GMail = 500 E-Mails oder 500 Empfänger / Tag ref: support.google.com/mail/answer/22839 G SUITE ist anders und hat 2000 Nachrichten / Tag und kann hier gefunden werden: Support .google.com / a / answer / 166852 Viel Glück!
JayRizzo

2
Alle anderen sind ältere Beiträge und funktionieren möglicherweise nicht, aber dies funktioniert zu 100%. Generieren Sie App-Passwörter. Vielen Dank für die Antwort
Shubh

1
Ich bin ein wenig überrascht, dass diese Lösung nicht mehr positive Stimmen hat. Ich habe nicht alle anderen ausprobiert , aber ich habe mehrere ausprobiert, und nur dieser hat sofort funktioniert, mit 0 Basteln.
Mcouthon

14

Sie finden es hier: http://jayrambhia.com/blog/send-emails-using-python

smtp_host = 'smtp.gmail.com'
smtp_port = 587
server = smtplib.SMTP()
server.connect(smtp_host,smtp_port)
server.ehlo()
server.starttls()
server.login(user,passw)
fromaddr = raw_input('Send mail by the name of: ')
tolist = raw_input('To: ').split()
sub = raw_input('Subject: ')

msg = email.MIMEMultipart.MIMEMultipart()
msg['From'] = fromaddr
msg['To'] = email.Utils.COMMASPACE.join(tolist)
msg['Subject'] = sub  
msg.attach(MIMEText(raw_input('Body: ')))
msg.attach(MIMEText('\nsent via python', 'plain'))
server.sendmail(user,tolist,msg.as_string())

2
plus 1, weil es besser ist, ein MIME zu erstellen, als eine eigene Formatzeichenfolge fest zu codieren. Wird MIMEMultipart für eine einfache Textnachricht benötigt? Oder ist das Folgende auch richtig: stackoverflow.com/a/6270987/895245
Ciro Santilli 22 冠状 病 六四 事件 22

Wo instanziieren Sie die E-Mail-Variable?
Madcat

11

Nicht direkt verwandt, aber dennoch erwähnenswert ist, dass mein Paket versucht, das Senden von Google Mail-Nachrichten wirklich schnell und schmerzlos zu machen. Es wird auch versucht, eine Fehlerliste zu führen und sofort auf die Lösung zu verweisen.

Es würde buchstäblich nur diesen Code benötigen, um genau das zu tun, was Sie geschrieben haben:

import yagmail
yag = yagmail.SMTP('user_me@gmail.com')
yag.send('user_you@gmail.com', 'Why,Oh why!')

Oder ein Einzeiler:

yagmail.SMTP('user_me@gmail.com').send('user_you@gmail.com', 'Why,Oh why!')

Für das Paket / die Installation schauen Sie sich bitte git oder pip an , die sowohl für Python 2 als auch für Python 3 verfügbar sind.


9

Hier ist ein Beispiel für eine Google Mail-API. Obwohl komplizierter, ist dies die einzige Methode, die ich gefunden habe und die 2019 funktioniert. Dieses Beispiel wurde genommen und modifiziert von:

https://developers.google.com/gmail/api/guides/sending

Sie müssen ein Projekt mit den API-Schnittstellen von Google über deren Website erstellen. Als Nächstes müssen Sie die GMAIL-API für Ihre App aktivieren. Erstellen Sie Anmeldeinformationen, laden Sie diese Creds herunter und speichern Sie sie als credentials.json.

import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request

from email.mime.text import MIMEText
import base64

#pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib

# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/gmail.readonly', 'https://www.googleapis.com/auth/gmail.send']

def create_message(sender, to, subject, msg):
    message = MIMEText(msg)
    message['to'] = to
    message['from'] = sender
    message['subject'] = subject

    # Base 64 encode
    b64_bytes = base64.urlsafe_b64encode(message.as_bytes())
    b64_string = b64_bytes.decode()
    return {'raw': b64_string}
    #return {'raw': base64.urlsafe_b64encode(message.as_string())}

def send_message(service, user_id, message):
    #try:
    message = (service.users().messages().send(userId=user_id, body=message).execute())
    print( 'Message Id: %s' % message['id'] )
    return message
    #except errors.HttpError, error:print( 'An error occurred: %s' % error )

def main():
    """Shows basic usage of the Gmail API.
    Lists the user's Gmail labels.
    """
    creds = None
    # The file token.pickle stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)

    service = build('gmail', 'v1', credentials=creds)

    # Example read operation
    results = service.users().labels().list(userId='me').execute()
    labels = results.get('labels', [])

    if not labels:
        print('No labels found.')
    else:
        print('Labels:')
    for label in labels:
        print(label['name'])

    # Example write
    msg = create_message("from@gmail.com", "to@gmail.com", "Subject", "Msg")
    send_message( service, 'me', msg)

if __name__ == '__main__':
    main()

smtplib ist nicht vollständig threadsicher, daher treten beim gleichzeitigen Senden von Nachrichten Probleme auf. Dies ist der richtige Ansatz.
dsbajna

2

Es gibt jetzt eine Google Mail-API, mit der Sie E-Mails senden, E-Mails lesen und Entwürfe über REST erstellen können. Im Gegensatz zu den SMTP-Aufrufen ist es nicht blockierend, was für threadbasierte Webserver, die E-Mails im Anforderungsthread senden (wie Python-Webserver), eine gute Sache sein kann. Die API ist auch ziemlich leistungsfähig.

  • Natürlich sollte E-Mail an eine Nicht-Webserver-Warteschlange weitergeleitet werden, aber es ist schön, Optionen zu haben.

Die Einrichtung ist am einfachsten, wenn Sie über Administratorrechte für Google Apps für die Domain verfügen, da Sie Ihrem Client dann eine pauschale Berechtigung erteilen können. Andernfalls müssen Sie mit der OAuth-Authentifizierung und -Berechtigung herumspielen.

Hier ist ein Kern, der dies demonstriert:

https://gist.github.com/timrichardson/1154e29174926e462b7a


2

tolle Antwort von @David, hier ist für Python 3 ohne den generischen try-außer:

def send_email(user, password, recipient, subject, body):

    gmail_user = user
    gmail_pwd = password
    FROM = user
    TO = recipient if type(recipient) is list else [recipient]
    SUBJECT = subject
    TEXT = body

    # Prepare actual message
    message = """From: %s\nTo: %s\nSubject: %s\n\n%s
    """ % (FROM, ", ".join(TO), SUBJECT, TEXT)

    server = smtplib.SMTP("smtp.gmail.com", 587)
    server.ehlo()
    server.starttls()
    server.login(gmail_user, gmail_pwd)
    server.sendmail(FROM, TO, message)
    server.close()

2

Aktivieren Sie weniger sichere Apps in Ihrem Google Mail-Konto und verwenden Sie (Python> = 3.6):

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

gmailUser = 'XXXXX@gmail.com'
gmailPassword = 'XXXXX'
recipient = 'XXXXX@gmail.com'

message = f"""
Type your message here...
"""

msg = MIMEMultipart()
msg['From'] = f'"Your Name" <{gmailUser}>'
msg['To'] = recipient
msg['Subject'] = "Subject here..."
msg.attach(MIMEText(message))

try:
    mailServer = smtplib.SMTP('smtp.gmail.com', 587)
    mailServer.ehlo()
    mailServer.starttls()
    mailServer.ehlo()
    mailServer.login(gmailUser, gmailPassword)
    mailServer.sendmail(gmailUser, recipient, msg.as_string())
    mailServer.close()
    print ('Email sent!')
except:
    print ('Something went wrong...')

1
Wirklich fantastische Antwort. Das Beste aus dem Haufen, super prägnant. Danke dir.
Bruce Dean

Danke Pedro, deine Antwort hat es gelöst. Übrigens für alle, die Gsuite mit mehreren Aliasen verwenden. fügen Sie einfach den Alias zu Ihrem Google Mail - Konto folgenden support.google.com/mail/answer/22370?hl=en und Sie können durch den Austausch mit dem Alias senden <{gmailUser}>mit <YourAlias>.
LucSpan

1

Scheint wie ein Problem der alten smtplib. In python2.7allem funktioniert gut.

Update : Ja, server.ehlo()könnte auch helfen.


-1
    import smtplib

    fromadd='from@gmail.com'
    toadd='send@gmail.com'

    msg='''hi,how r u'''
    username='abc@gmail.com'
    passwd='password'

    try:
        server = smtplib.SMTP('smtp.gmail.com:587')
        server.ehlo()
        server.starttls()
        server.login(username,passwd)

        server.sendmail(fromadd,toadd,msg)
        print("Mail Send Successfully")
        server.quit()

   except:
        print("Error:unable to send mail")

   NOTE:https://www.google.com/settings/security/lesssecureapps that                                                         should be enabled

Ich veröffentliche den einfachen Code, mit dem E-Mails von einem Google Mail-Konto gesendet werden. Wenn Sie Informationen benötigen, lassen Sie es mich wissen. Ich hoffe, dass der Code allen Benutzern hilft.
Shyam Gupta

-2
import smtplib
server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()
server.starttls()
server.login("fromaddress", "password")
msg = "HI!"
server.sendmail("fromaddress", "receiveraddress", msg)
server.quit()

Einfacher Code zum Senden einer E-Mail über Google Mail mit Python-Code. Von Adresse ist Ihre Google Mail-ID und Empfängeradresse ist die E-Mail-ID, die Sie senden.
Sam Divya Kumar
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.