Jak wysłać wiadomość e-mail z Gmailem jako dostawcą za pomocą Pythona?

Próbuję wysłać e-mail (Gmail) za pomocą Pythona, ale dostaję następujący błąd.

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.

Skrypt Pythona jest następujący.

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

12 answers

Musisz powiedzieć EHLO zanim po prostu wbiegniesz prosto w STARTTLS:

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

Również powinieneś naprawdę tworzyć From:, To: i Subject: nagłówki wiadomości, oddzielone od treści wiadomości pustą linią i używane CRLF jako znaczniki EOL.

Np.

msg = "\r\n".join([
  "From: [email protected]",
  "To: [email protected]",
  "Subject: Just a message",
  "",
  "Why, oh why"
  ])
 188
Author: MattH,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-13 20:05:35
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"

Jeśli chcesz użyć portu 465 musisz utworzyć SMTP_SSL obiekt:

# 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'
 262
Author: David Okwii,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-09 17:46:19

Natknąłem się na podobny problem i natknąłem się na to pytanie. Dostałem błąd uwierzytelniania SMTP, ale moja nazwa użytkownika / hasło było poprawne. Oto, co to naprawiło. Przeczytałem to:

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

W skrócie, google nie pozwala Ci zalogować się przez smtplib, ponieważ ma oznaczone tego rodzaju logowania jako "mniej bezpieczne" , więc to, co musisz zrobić, to przejść do tego linku, gdy jesteś zalogowany na swoje konto google, i zezwól na dostęp:

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

Po ustawieniu (patrz mój zrzut ekranu poniżej), powinno działać.

Tutaj wpisz opis obrazka

Login teraz działa:

smtpserver = smtplib.SMTP("smtp.gmail.com", 587)
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.ehlo()
smtpserver.login('[email protected]', 'me_pass')

Odpowiedź po zmianie:

(235, '2.7.0 Accepted')

Odpowiedź przed:

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

Nadal nie działa? jeśli nadal otrzymasz SMTPAuthenticationError, ale teraz kod to 534, ponieważ lokalizacja jest nieznana. Follow this link:

Https://accounts.google.com/DisplayUnlockCaptcha

Kliknij Kontynuuj, a to powinno dać ci 10 minut na rejestrację nowej aplikacji. Więc przystąp do kolejnej próby logowania teraz i powinno działać.

UPDATE: wydaje się, że to nie działa od razu, możesz utknąć na chwilę, otrzymując ten błąd w smptlib:

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

Wiadomość mówi, aby użyć przeglądarki, aby się zalogować:

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

Po włączeniu 'lesssecureapps', idź na kawę, wróć i spróbuj ponownie połączyć "DisplayUnlockCaptcha". Z doświadczenia użytkownika zmiana może potrwać do godziny. Następnie spróbuj ponownie zalogować się.

 115
Author: radtek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-29 17:49:04

Znajdziesz go tutaj: 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())
 14
Author: Froyo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-26 11:19:44

Zgadzasz się z OOP?

#!/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')
 12
Author: Ricky Wilson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-23 11:16:51

Nie związane bezpośrednio, ale warto zwrócić uwagę na to, że mój pakiet stara się, aby wysyłanie wiadomości gmail było naprawdę szybkie i bezbolesne. Stara się również utrzymywać listę błędów i stara się natychmiast wskazać rozwiązanie.

Wystarczy ten kod, aby zrobić dokładnie to, co napisałeś:

import yagmail
yag = yagmail.SMTP('[email protected]')
yag.send('[email protected]', 'Why,Oh why!')

Lub jedna linijka:

yagmail.SMTP('[email protected]').send('[email protected]', 'Why,Oh why!')

Dla pakietu / instalacji proszę spojrzeć na gitlub pip, dostępne dla Pythona 2 i 3.

 11
Author: PascalVKooten,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-19 19:42:47

Świetna odpowiedź od @ David, tutaj jest dla Pythona 3 bez ogólnej próby-z wyjątkiem:

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
Author: juan Isaza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-01 22:56:11

Wydaje się problemem starego smtplib. W python2.7 Wszystko działa dobrze.

Update : Tak, server.ehlo() również może pomóc.

 1
Author: mega.venik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-13 20:13:52

Istnieje teraz API gmail, które pozwala wysyłać wiadomości e-mail, czytać wiadomości e-mail i tworzyć wersje robocze za pośrednictwem REST. W przeciwieństwie do wywołań SMTP, nie blokuje się, co może być dobre dla serwerów internetowych opartych na wątkach wysyłających wiadomości e-mail w wątku żądania (jak serwery Pythona). API jest również dość potężny.

  • Oczywiście, e-mail powinien być przekazywany do kolejki non-webserver, ale miło jest mieć opcje.

Najłatwiej skonfigurować, jeśli masz uprawnienia administratora Google Apps na domeny, bo wtedy możesz dać klientowi pozwolenie. W przeciwnym razie musisz manipulować uwierzytelnieniem i pozwoleniem OAuth.

Oto gist demonstrujący to:

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

 1
Author: Tim Richardson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-31 04:12:18

To Działa

Utwórz hasło do aplikacji Gmail!

Po utworzeniu tego następnie utwórz plik o nazwie sendgmail.py

Następnie dodaj ten kod :

#!/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 = '[email protected]'
gmail_app_password = 'YOUR-GOOGLE-APPLICATION-PASSWORD!!!!'

# =============================================================================
# SET THE INFO ABOUT THE SAID EMAIL
# =============================================================================
sent_from = gmail_user
sent_to = ['[email protected]', '[email protected]']
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)

Więc, jeśli ci się uda, zobaczysz taki obrazek:

Przetestowałem wysyłając e-mail od I do siebie.

Pomyślne wysłanie e-maila.

Uwaga: mam włączone weryfikację dwuetapową na moim koncie. Hasło aplikacji działa z tym!

To ustawienie nie jest dostępne dla kont z włączoną weryfikacją dwuetapową. Takie konta wymagają hasła specyficznego dla aplikacji, aby uzyskać mniej bezpieczny dostęp do aplikacji.

Mniej bezpieczny dostęp do aplikacji... To ustawienie nie jest dostępne dla kont z włączoną weryfikacją dwuetapową.

 1
Author: JayRizzo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-03 01:38:40
    import smtplib

    fromadd='[email protected]'
    toadd='[email protected]'

    msg='''hi,how r u'''
    username='[email protected]'
    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
 -1
Author: Shyam Gupta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-14 18:52:39
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()
 -2
Author: Sam Divya Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-04 14:01:16