Sending mail from Python using SMTP
我正在使用以下方法使用SMTP从Python发送邮件。 是使用的正确方法还是我缺少的陷阱?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| from smtplib import SMTP
import datetime
debuglevel = 0
smtp = SMTP()
smtp.set_debuglevel(debuglevel)
smtp.connect('YOUR.MAIL.SERVER', 26)
smtp.login('USERNAME@DOMAIN', 'PASSWORD')
from_addr ="John Doe <john@doe.net>"
to_addr ="foo@bar.com"
subj ="hello"
date = datetime.datetime.now().strftime("%d/%m/%Y %H:%M" )
message_text ="Hello\
This is a mail from your server\
\
Bye\
"
msg ="From: %s\
To: %s\
Subject: %s\
Date: %s\
\
%s"
% ( from_addr, to_addr, subj, date, message_text )
smtp.sendmail(from_addr, to_addr, msg)
smtp.quit() |
我使用的脚本非常相似。我将其发布在此处,作为如何使用email。*模块生成MIME消息的示例。因此可以轻松修改此脚本以附加图片等。
我依靠我的ISP添加日期时间标头。
我的ISP要求我使用安全的smtp连接发送邮件,我依靠smtplib模块(可从http://www1.cs.columbia.edu/~db2501/ssmtplib.py下载)
就像在脚本中一样,用于在SMTP服务器上进行身份验证的用户名和密码(下面提供了伪值)在源中为纯文本格式。这是一个安全漏洞。但是最好的选择取决于您对这些保护有多认真(想要?)。
=======================================
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| #! /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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
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() |
而已
另外,如果您想使用TLS(而不是SSL)进行smtp身份验证,则只需更改端口(使用587)并执行smtp.starttls()。这对我有用:
1 2 3 4 5 6 7
| ...
smtp.connect('YOUR.MAIL.SERVER', 587)
smtp.ehlo()
smtp.starttls()
smtp.ehlo()
smtp.login('USERNAME@DOMAIN', 'PASSWORD')
... |
那这个呢?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| 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() |
确保您没有任何阻止SMTP的防火墙。我第一次尝试发送电子邮件时,它同时被Windows防火墙和McAfee阻止-花了很长时间才找到它们。
我看到的主要问题是,您没有处理任何错误:.login()和.sendmail()都记录了可以抛出的异常,而且看来.connect()必须有某种方式表明它是无法连接-可能是底层套接字代码引发的异常。
以下代码对我来说工作正常:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| 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 + '\
' + 'From: ' + gmail_user + '\
' + 'Subject:testing \
'
print header
msg = header + '\
this is test msg from mkyong.com \
\
'
smtpserver.sendmail(gmail_user, to, msg)
print 'done!'
smtpserver.quit() |
参考:http://www.mkyong.com/python/how-do-send-email-in-python-via-smtplib/
我使用SMTP发送邮件的示例代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| 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() |
您应该确保将日期格式设置为RFC2822正确的格式。
查看所有这些宽大的答案?请允许我通过几行来自我推广。
导入并连接:
1 2
| import yagmail
yag = yagmail.SMTP('john@doe.net', host = 'YOUR.MAIL.SERVER', port = 26) |
然后,它只是一线:
1 2 3 4 5
| yag.send('foo@bar.com', 'hello', 'Hello\
This is a mail from your server\
\
Bye\
') |
当它超出范围时,它将实际上关闭(或可以手动关闭)。此外,它将允许您在密钥环中注册用户名,从而不必在脚本中写出密码(在写yagmail之前,这确实困扰了我!)
有关软件包/安装,技巧和窍门,请查看git或pip,它们可用于Python 2和3。
基于此示例,我做了以下功能:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| 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\
To: %s\
Subject: %s\
\
%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 |
如果仅传递body,则将发送纯文本邮件,但如果将html参数与body参数一起传递,则将发送html电子邮件(对于不支持html的电子邮件客户端,其文本内容将回退/ mime类型)。
用法示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 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" |
顺便说一句。如果您想将gmail用作测试或生产SMTP服务器,
启用对安全性较低的应用程序的临时或永久访问:
-
登录到Google邮件/帐户
-
转到:https://myaccount.google.com/lesssecureapps
-
使能
-
使用此功能或类似功能发送电子邮件
-
(推荐)转到:https://myaccount.google.com/lesssecureapps
-
(推荐)禁用
这是Python 3.x的工作示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| #!/usr/bin/env python3
from email.message import EmailMessage
from 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()
except Exception as E:
exit('Mail failed: {}'.format(str(E))) |
你可以那样做
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 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) |
|