#! /usr/local/bin/pythonSMTPserver='smtp.att.yahoo.com'
sender ='me@my_email_domain.net'
destination =['recipient@her_email_domain.com']
USERNAME ="USER_NAME_FOR_INTERNET_SERVICE_PROVIDER"
PASSWORD ="PASSWORD_INTERNET_SERVICE_PROVIDER"# typical values for text_subtype are plain, html, xml
text_subtype ='plain'
content="""\
Test message
"""
subject="Sent from Python"import sys
import os
import re
from smtplib import SMTP_SSL as SMTP # this invokes the secure SMTP protocol (port 465, uses SSL)# from smtplib import SMTP # use this for standard SMTP protocol (port 25, no encryption)# old version# from email.MIMEText import MIMETextfrom email.mime.text importMIMETexttry:
msg =MIMEText(content, text_subtype)
msg['Subject']= subject
msg['From']= sender # some SMTP servers will do this automatically, not all
conn = SMTP(SMTPserver)
conn.set_debuglevel(False)
conn.login(USERNAME, PASSWORD)try:
conn.sendmail(sender, destination, msg.as_string())finally:
conn.quit()except:
sys.exit("mail failed; %s"%"CUSTOM_ERROR")# give an error message
The script I use is quite similar; I post it here as an example of how to use the email.* modules to generate MIME messages; so this script can be easily modified to attach pictures, etc.
As in your script, the username and password, (given dummy values below), used to authenticate on the SMTP server, are in plain text in the source. This is a security weakness; but the best alternative depends on how careful you need (want?) to be about protecting these.
=======================================
#! /usr/local/bin/python
SMTPserver = 'smtp.att.yahoo.com'
sender = 'me@my_email_domain.net'
destination = ['recipient@her_email_domain.com']
USERNAME = "USER_NAME_FOR_INTERNET_SERVICE_PROVIDER"
PASSWORD = "PASSWORD_INTERNET_SERVICE_PROVIDER"
# typical values for text_subtype are plain, html, xml
text_subtype = 'plain'
content="""\
Test message
"""
subject="Sent from Python"
import sys
import os
import re
from smtplib import SMTP_SSL as SMTP # this invokes the secure SMTP protocol (port 465, uses SSL)
# from smtplib import SMTP # use this for standard SMTP protocol (port 25, no encryption)
# old version
# from email.MIMEText import MIMEText
from email.mime.text import MIMEText
try:
msg = MIMEText(content, text_subtype)
msg['Subject']= subject
msg['From'] = sender # some SMTP servers will do this automatically, not all
conn = SMTP(SMTPserver)
conn.set_debuglevel(False)
conn.login(USERNAME, PASSWORD)
try:
conn.sendmail(sender, destination, msg.as_string())
finally:
conn.quit()
except:
sys.exit( "mail failed; %s" % "CUSTOM_ERROR" ) # give an error message
回答 1
我通常使用的方法…没什么大的不同
import smtplib
from email.MIMEMultipartimportMIMEMultipartfrom email.MIMETextimportMIMEText
msg =MIMEMultipart()
msg['From']='me@gmail.com'
msg['To']='you@gmail.com'
msg['Subject']='simple email in python'
message ='here is the email'
msg.attach(MIMEText(message))
mailserver = smtplib.SMTP('smtp.gmail.com',587)# identify ourselves to smtp gmail client
mailserver.ehlo()# secure our email with tls encryption
mailserver.starttls()# re-identify ourselves as an encrypted connection
mailserver.ehlo()
mailserver.login('me@gmail.com','mypassword')
mailserver.sendmail('me@gmail.com','you@gmail.com',msg.as_string())
mailserver.quit()
Also if you want to do smtp auth with TLS as opposed to SSL then you just have to change the port (use 587) and do smtp.starttls(). This worked for me:
The main gotcha I see is that you’re not handling any errors: .login() and .sendmail() both have documented exceptions that they can throw, and it seems like .connect() must have some way to indicate that it was unable to connect – probably an exception thrown by the underlying socket code.
Make sure you don’t have any firewalls blocking SMTP. The first time I tried to send an email, it was blocked both by Windows Firewall and McAfee – took forever to find them both.
回答 5
那这个呢?
import smtplib
SERVER ="localhost"
FROM ="sender@example.com"
TO =["user@example.com"]# must be a list
SUBJECT ="Hello!"
TEXT ="This message was sent with Python's smtplib."# Prepare actual message
message ="""\
From: %s
To: %s
Subject: %s
%s
"""%(FROM,", ".join(TO), SUBJECT, TEXT)# Send the mail
server = smtplib.SMTP(SERVER)
server.sendmail(FROM, TO, message)
server.quit()
import smtplib
SERVER = "localhost"
FROM = "sender@example.com"
TO = ["user@example.com"] # must be a list
SUBJECT = "Hello!"
TEXT = "This message was sent with Python's smtplib."
# Prepare actual message
message = """\
From: %s
To: %s
Subject: %s
%s
""" % (FROM, ", ".join(TO), SUBJECT, TEXT)
# Send the mail
server = smtplib.SMTP(SERVER)
server.sendmail(FROM, TO, message)
server.quit()
回答 6
以下代码对我来说很好用:
import smtplib
to ='mkyong2002@yahoo.com'
gmail_user ='mkyong2002@gmail.com'
gmail_pwd ='yourpassword'
smtpserver = smtplib.SMTP("smtp.gmail.com",587)
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.ehlo()# extra characters to permit edit
smtpserver.login(gmail_user, gmail_pwd)
header ='To:'+ to +'\n'+'From: '+ gmail_user +'\n'+'Subject:testing \n'print header
msg = header +'\n this is test msg from mkyong.com \n\n'
smtpserver.sendmail(gmail_user, to, msg)print'done!'
smtpserver.quit()
You should make sure you format the date in the correct format – RFC2822.
回答 8
我使用SMTP发送邮件的示例代码。
import smtplib, ssl
smtp_server ="smtp.gmail.com"
port =587# For starttls
sender_email ="sender@email"
receiver_email ="receiver@email"
password ="<your password here>"
message =""" Subject: Hi there
This message is sent from Python."""# Create a secure SSL context
context = ssl.create_default_context()# Try to log in to server and send email
server = smtplib.SMTP(smtp_server,port)try:
server.ehlo()# Can be omitted
server.starttls(context=context)# Secure the connection
server.ehlo()# Can be omitted
server.login(sender_email, password)
server.sendmail(sender_email, receiver_email, message)exceptExceptionas e:# Print any error messages to stdoutprint(e)finally:
server.quit()
The example code which i did for send mail using SMTP.
import smtplib, ssl
smtp_server = "smtp.gmail.com"
port = 587 # For starttls
sender_email = "sender@email"
receiver_email = "receiver@email"
password = "<your password here>"
message = """ Subject: Hi there
This message is sent from Python."""
# Create a secure SSL context
context = ssl.create_default_context()
# Try to log in to server and send email
server = smtplib.SMTP(smtp_server,port)
try:
server.ehlo() # Can be omitted
server.starttls(context=context) # Secure the connection
server.ehlo() # Can be omitted
server.login(sender_email, password)
server.sendmail(sender_email, receiver_email, message)
except Exception as e:
# Print any error messages to stdout
print(e)
finally:
server.quit()
回答 9
查看所有这些宽大的答案?请允许我通过几行来自我推广。
导入并连接:
import yagmail
yag = yagmail.SMTP('john@doe.net', host ='YOUR.MAIL.SERVER', port =26)
然后,它只是一线:
yag.send('foo@bar.com','hello','Hello\nThis is a mail from your server\n\nBye\n')
yag.send('foo@bar.com', 'hello', 'Hello\nThis is a mail from your server\n\nBye\n')
It will actually close when it goes out of scope (or can be closed manually). Furthermore, it will allow you to register your username in your keyring such that you do not have to write out your password in your script (it really bothered me prior to writing yagmail!)
For the package/installation, tips and tricks please look at git or pip, available for both Python 2 and 3.
回答 10
你可以那样做
import smtplib
from email.mime.text importMIMETextfrom email.header importHeader
server = smtplib.SMTP('mail.servername.com',25)
server.ehlo()
server.starttls()
server.login('username','password')from='me@servername.com'
to ='mygfriend@servername.com'
body ='That A Message For My Girl Friend For tell Him If We will go to eat Something This Nigth'
subject ='Invite to A Diner'
msg =MIMEText(body,'plain','utf-8')
msg['Subject']=Header(subject,'utf-8')
msg['From']=Header(from,'utf-8')
msg['To']=Header(to,'utf-8')
message = msg.as_string()
server.sendmail(from, to, message)
import smtplib
from email.mime.text import MIMEText
from email.header import Header
server = smtplib.SMTP('mail.servername.com', 25)
server.ehlo()
server.starttls()
server.login('username', 'password')
from = 'me@servername.com'
to = 'mygfriend@servername.com'
body = 'That A Message For My Girl Friend For tell Him If We will go to eat Something This Nigth'
subject = 'Invite to A Diner'
msg = MIMEText(body,'plain','utf-8')
msg['Subject'] = Header(subject, 'utf-8')
msg['From'] = Header(from, 'utf-8')
msg['To'] = Header(to, 'utf-8')
message = msg.as_string()
server.sendmail(from, to, message)
回答 11
这是Python 3.x的工作示例
#!/usr/bin/env python3from email.message importEmailMessagefrom getpass import getpass
from smtplib import SMTP_SSL
from sys import exit
smtp_server ='smtp.gmail.com'
username ='your_email_address@gmail.com'
password = getpass('Enter Gmail password: ')
sender ='your_email_address@gmail.com'
destination ='recipient_email_address@gmail.com'
subject ='Sent from Python 3.x'
content ='Hello! This was sent to you via Python 3.x!'# Create a text/plain message
msg =EmailMessage()
msg.set_content(content)
msg['Subject']= subject
msg['From']= sender
msg['To']= destination
try:
s = SMTP_SSL(smtp_server)
s.login(username, password)try:
s.send_message(msg)finally:
s.quit()exceptExceptionas E:
exit('Mail failed: {}'.format(str(E)))
import smtplib
from email.mime.multipart importMIMEMultipartfrom email.mime.text importMIMETextdef send_email(host, port, user, pwd, recipients, subject, body, html=None, from_=None):""" copied and adapted from
/programming/10147455/how-to-send-an-email-with-gmail-as-provider-using-python#12424439
returns None if all ok, but if problem then returns exception object
"""
PORT_LIST =(25,587,465)
FROM = from_ if from_ else user
TO = recipients if isinstance(recipients,(list, tuple))else[recipients]
SUBJECT = subject
TEXT = body.encode("utf8")if isinstance(body, unicode)else body
HTML = html.encode("utf8")if isinstance(html, unicode)else html
ifnot html:# Prepare actual message
message ="""From: %s\nTo: %s\nSubject: %s\n\n%s
"""%(FROM,", ".join(TO), SUBJECT, TEXT)else:# /programming/882712/sending-html-email-using-python#882770
msg =MIMEMultipart('alternative')
msg['Subject']= SUBJECT
msg['From']= FROM
msg['To']=", ".join(TO)# Record the MIME types of both parts - text/plain and text/html.# utf-8 -> /programming/5910104/python-how-to-send-utf-8-e-mail#5910530
part1 =MIMEText(TEXT,'plain',"utf-8")
part2 =MIMEText(HTML,'html',"utf-8")# Attach parts into message container.# According to RFC 2046, the last part of a multipart message, in this case# the HTML message, is best and preferred.
msg.attach(part1)
msg.attach(part2)
message = msg.as_string()try:if port notin PORT_LIST:raiseException("Port %s not one of %s"%(port, PORT_LIST))if port in(465,):
server = smtplib.SMTP_SSL(host, port)else:
server = smtplib.SMTP(host, port)# optional
server.ehlo()if port in(587,):
server.starttls()
server.login(user, pwd)
server.sendmail(FROM, TO, message)
server.close()# logger.info("SENT_EMAIL to %s: %s" % (recipients, subject))exceptException, ex:return ex
returnNone
ex = send_email(
host ='smtp.gmail.com'#, port = 465 # OK, port =587#OK, user ="xxx@gmail.com", pwd ="xxx", from_ ='xxx@gmail.com', recipients =['yyy@gmail.com'], subject ="Test from python", body ="Test from python - body")if ex:print("Mail sending failed: %s"% ex)else:print("OK - mail sent"
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
def send_email(host, port, user, pwd, recipients, subject, body, html=None, from_=None):
""" copied and adapted from
https://stackoverflow.com/questions/10147455/how-to-send-an-email-with-gmail-as-provider-using-python#12424439
returns None if all ok, but if problem then returns exception object
"""
PORT_LIST = (25, 587, 465)
FROM = from_ if from_ else user
TO = recipients if isinstance(recipients, (list, tuple)) else [recipients]
SUBJECT = subject
TEXT = body.encode("utf8") if isinstance(body, unicode) else body
HTML = html.encode("utf8") if isinstance(html, unicode) else html
if not html:
# Prepare actual message
message = """From: %s\nTo: %s\nSubject: %s\n\n%s
""" % (FROM, ", ".join(TO), SUBJECT, TEXT)
else:
# https://stackoverflow.com/questions/882712/sending-html-email-using-python#882770
msg = MIMEMultipart('alternative')
msg['Subject'] = SUBJECT
msg['From'] = FROM
msg['To'] = ", ".join(TO)
# Record the MIME types of both parts - text/plain and text/html.
# utf-8 -> https://stackoverflow.com/questions/5910104/python-how-to-send-utf-8-e-mail#5910530
part1 = MIMEText(TEXT, 'plain', "utf-8")
part2 = MIMEText(HTML, 'html', "utf-8")
# Attach parts into message container.
# According to RFC 2046, the last part of a multipart message, in this case
# the HTML message, is best and preferred.
msg.attach(part1)
msg.attach(part2)
message = msg.as_string()
try:
if port not in PORT_LIST:
raise Exception("Port %s not one of %s" % (port, PORT_LIST))
if port in (465,):
server = smtplib.SMTP_SSL(host, port)
else:
server = smtplib.SMTP(host, port)
# optional
server.ehlo()
if port in (587,):
server.starttls()
server.login(user, pwd)
server.sendmail(FROM, TO, message)
server.close()
# logger.info("SENT_EMAIL to %s: %s" % (recipients, subject))
except Exception, ex:
return ex
return None
if you pass only body then plain text mail will be sent, but if you pass html argument along with body argument, html email will be sent (with fallback to text content for email clients that don’t support html/mime types).
Example usage:
ex = send_email(
host = 'smtp.gmail.com'
#, port = 465 # OK
, port = 587 #OK
, user = "xxx@gmail.com"
, pwd = "xxx"
, from_ = 'xxx@gmail.com'
, recipients = ['yyy@gmail.com']
, subject = "Test from python"
, body = "Test from python - body"
)
if ex:
print("Mail sending failed: %s" % ex)
else:
print("OK - mail sent"
Btw. If you want to use gmail as testing or production SMTP server,
enable temp or permanent access to less secured apps:
Send the email to a real SMTP server. If you don’t want to set up your own then you can find companies that will run one for you, such as Google themselves.
I use Gmail as my SMTP server for Django. Much easier than dealing with postfix or whatever other server. I’m not in the business of managing email servers.
NOTE: In 2016 Gmail is not allowing this anymore by default. You can either use an external service like Sendgrid, or you can follow this tutorial from Google to reduce security but allow this option: https://support.google.com/accounts/answer/6010255
from django.core.mail import EmailMessage
email = EmailMessage('Subject', 'Body', to=['def@domain.com'])
email.send()
Then I got “1” as the O/P i.e. Success. And I received the mail too. :)
What is the meaning of domain.com?
回答 4
对于Django 1.7版,如果上述解决方案不起作用,请尝试以下操作
在settings.py中添加
#For email
EMAIL_BACKEND ='django.core.mail.backends.smtp.EmailBackend'
EMAIL_USE_TLS =True
EMAIL_HOST ='smtp.gmail.com'
EMAIL_HOST_USER ='sender@gmail.com'#Must generate specific password for your app in [gmail settings][1]
EMAIL_HOST_PASSWORD ='app_specific_password'
EMAIL_PORT =587#This did the trick
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
If you are using gmail for this, setup 2-step verification and Application specific password and copy and paste that password in above EMAIL_HOST_PASSWORD value.
In addition to the DEFAULT_FROM_EMAIL fix others have mentioned, and allowing less-secure apps to access the account, I had to navigate to https://accounts.google.com/DisplayUnlockCaptcha while signed in as the account in question to get Django to finally authenticate.
I went to that URL through a SSH tunnel to the web server to make sure the IP address was the same; I’m not totally sure if that’s necessary but it can’t hurt. You can do that like so: ssh -D 8080 -fN <username>@<host>, then set your web browser to use localhost:8080 as a SOCKS proxy.
After much searching I couldn’t find out how to use smtplib.sendmail to send to multiple recipients. The problem was every time the mail would be sent the mail headers would appear to contain multiple addresses, but in fact only the first recipient would receive the email.
In short, to send to multiple recipients you should set the header to be a string of comma delimited email addresses. The sendmail() parameter to_addrs however should be a list of email addresses.
You need to understand the difference between the visible address of an email, and the delivery.
msg["To"] is essentially what is printed on the letter. It doesn’t actually have any effect. Except that your email client, just like the regular post officer, will assume that this is who you want to send the email to.
The actual delivery however can work quite different. So you can drop the email (or a copy) into the post box of someone completely different.
There are various reasons for this. For example forwarding. The To: header field doesn’t change on forwarding, however the email is dropped into a different mailbox.
The smtp.sendmail command now takes care of the actual delivery. email.Message is the contents of the letter only, not the delivery.
In low-level SMTP, you need to give the receipients one-by-one, which is why a list of adresses (not including names!) is the sensible API.
For the header, it can also contain for example the name, e.g. To: First Last <email@addr.tld>, Other User <other@mail.tld>. Your code example therefore is not recommended, as it will fail delivering this mail, since just by splitting it on , you still not not have the valid adresses!
So actually the problem is that SMTP.sendmail and email.MIMEText need two different things.
email.MIMEText sets up the “To:” header for the body of the e-mail. It is ONLY used for displaying a result to the human being at the other end, and like all e-mail headers, must be a single string. (Note that it does not actually have to have anything to do with the people who actually receive the message.)
SMTP.sendmail, on the other hand, sets up the “envelope” of the message for the SMTP protocol. It needs a Python list of strings, each of which has a single address.
So, what you need to do is COMBINE the two replies you received. Set msg[‘To’] to a single string, but pass the raw list to sendmail:
I came up with this importable module function. It uses the gmail email server in this example. Its split into header and message so you can clearly see whats going on:
I figured this out a few months back and blogged about it. The summary is:
If you want to use smtplib to send email to multiple recipients, use email.Message.add_header('To', eachRecipientAsString) to add them, and then when you invoke the sendmail method, use email.Message.get_all('To') send the message to all of them. Ditto for Cc and Bcc recipients.
Well, the method in this asnwer method did not work for me. I don’t know, maybe this is a Python3 (I am using the 3.4 version) or gmail related issue, but after some tries, the solution that worked for me, was the line
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
def sender(recipients):
body = 'Your email content here'
msg = MIMEMultipart()
msg['Subject'] = 'Email Subject'
msg['From'] = 'your.email@gmail.com'
msg['To'] = (', ').join(recipients.split(','))
msg.attach(MIMEText(body,'plain'))
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login('your.email@gmail.com', 'yourpassword')
server.send_message(msg)
server.quit()
if __name__ == '__main__':
sender('email_1@domain.com,email_2@domain.com')
It only worked for me with send_message function and using the join function in the list whith recipients, python 3.6.
回答 12
您可以在文本文件上写收件人电子邮件时尝试使用此方法
from email.mime.text importMIMETextfrom email.header importHeaderimport smtplib
f = open('emails.txt','r').readlines()for n in f:
emails = n.rstrip()
server = smtplib.SMTP('smtp.uk.xensource.com')
server.ehlo()
server.starttls()
body ="Test Email"
subject ="Test"from="me@example.com"
to = emails
msg =MIMEText(body,'plain','utf-8')
msg['Subject']=Header(subject,'utf-8')
msg['From']=Header(from,'utf-8')
msg['To']=Header(to,'utf-8')
text = msg.as_string()try:
server.send(from, emails, text)print('Message Sent Succesfully')except:print('There Was An Error While Sending The Message')
you can try this when you write the recpient emails on a text file
from email.mime.text import MIMEText
from email.header import Header
import smtplib
f = open('emails.txt', 'r').readlines()
for n in f:
emails = n.rstrip()
server = smtplib.SMTP('smtp.uk.xensource.com')
server.ehlo()
server.starttls()
body = "Test Email"
subject = "Test"
from = "me@example.com"
to = emails
msg = MIMEText(body,'plain','utf-8')
msg['Subject'] = Header(subject, 'utf-8')
msg['From'] = Header(from, 'utf-8')
msg['To'] = Header(to, 'utf-8')
text = msg.as_string()
try:
server.send(from, emails, text)
print('Message Sent Succesfully')
except:
print('There Was An Error While Sending The Message')
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 raiseSMTPException("SMTP AUTH extension not supported by server.")
smtplib.SMTPException: SMTP AUTH extension not supported by server.
I am trying to send email (Gmail) using python, but I am getting following error.
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.
You need to say EHLO before just running straight into STARTTLS:
server = smtplib.SMTP('smtp.gmail.com:587')
server.ehlo()
server.starttls()
Also you should really create From:, To: and Subject: message headers, separated from the message body by a blank line and use CRLF as EOL markers.
E.g.
msg = "\r\n".join([
"From: user_me@gmail.com",
"To: user_you@gmail.com",
"Subject: Just a message",
"",
"Why, oh why"
])
回答 1
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"
如果要使用端口465,则必须创建一个SMTP_SSL对象:
# 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'
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"
if you want to use Port 465 you have to create an SMTP_SSL object:
# 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'
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')
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')
I ran into a similar problem and stumbled on this question. I got an SMTP Authentication Error but my user name / pass was correct. Here is what fixed it. I read this:
In a nutshell, google is not allowing you to log in via smtplib because it has flagged this sort of login as “less secure”, so what you have to do is go to this link while you’re logged in to your google account, and allow the access:
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')
Still not working? If you still get the SMTPAuthenticationError but now the code is 534, its because the location is unknown. Follow this link:
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')
After enabling ‘lesssecureapps’, go for a coffee, come back, and try the ‘DisplayUnlockCaptcha’ link again. From user experience, it may take up to an hour for the change to kick in. Then try the sign-in process again.
#!/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!')exceptExceptionas exception:print("Error: %s!\n\n"% exception)
This setting is not available for accounts with 2-Step Verification enabled. Such accounts require an application-specific password for less secure apps access.
Not directly related but still worth pointing out is that my package tries to make sending gmail messages really quick and painless. It also tries to maintain a list of errors and tries to point to the solution immediately.
It would literally only need this code to do exactly what you wrote:
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow importInstalledAppFlowfrom google.auth.transport.requests importRequestfrom email.mime.text importMIMETextimport 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.ifnot creds ornot 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 runwith 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',[])ifnot 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()
You’ll need create a project with Google’s API interfaces through their website. Next you’ll need to enable the GMAIL API for your app. Create credentials and then download those creds, save it as 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()
There is a gmail API now, which lets you send email, read email and create drafts via REST.
Unlike the SMTP calls, it is non-blocking which can be a good thing for thread-based webservers sending email in the request thread (like python webservers). The API is also quite powerful.
Of course, email should be handed off to a non-webserver queue, but it’s nice to have options.
It’s easiest to setup if you have Google Apps administrator rights on the domain, because then you can give blanket permission to your client. Otherwise you have to fiddle with OAuth authentication and permission.
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()
great answer from @David, here is for Python 3 without the generic try-except:
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()
Seems like problem of the old smtplib. In python2.7 everything works fine.
Update: Yep, server.ehlo() also could help.
回答 12
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