使用 SMTP 从 Python 发送邮件

我使用以下方法使用 SMTP 从 Python 发送邮件。这是正确的方法,还是我遗漏了什么?

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\nThis is a mail from your server\n\nBye\n"


msg = "From: %s\nTo: %s\nSubject: %s\nDate: %s\n\n%s"
% ( from_addr, to_addr, subj, date, message_text )


smtp.sendmail(from_addr, to_addr, msg)
smtp.quit()
294458 次浏览

我看到的主要问题是,您没有处理任何错误: .login().sendmail()都有可以抛出的 有记录的例外情况,而且似乎 .connect()必须有某种方式来表明它无法连接——可能是底层套接字代码抛出的异常。

您应该确保将日期格式设置为正确的格式 -RFC2822

确保没有任何防火墙阻止 SMTP。我第一次尝试发送电子邮件时,被 Windows 防火墙和迈克菲都屏蔽了——我花了很长时间才找到他们。

我使用的脚本非常相似; 我在这里发布它作为如何使用电子邮件的例子。* 生成 MIME 消息的模块; 因此这个脚本可以很容易地修改,以附加图片等。

我依赖我的 ISP 来添加日期时间标题。

我的 ISP 要求我使用一个安全的 smtp 连接来发送邮件,我依赖 smtplib 模块(可在 http://www1.cs.columbia.edu/~db2501/ssmtplib.py下载)

与脚本中一样,用于在 SMTP 服务器上进行身份验证的用户名和密码(给定下面的虚拟值)在源代码中是纯文本。这是一个安全性弱点; 但是最好的替代方案取决于您需要(想要?)多么小心是为了保护这些。

=======================================

#! /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

另外,如果您想使用 TLS 而不是 SSL 执行 smtp auth,那么只需更改端口(使用587)并执行 smtp.starttls ()。这对我很有效:

...
smtp.connect('YOUR.MAIL.SERVER', 587)
smtp.ehlo()
smtp.starttls()
smtp.ehlo()
smtp.login('USERNAME@DOMAIN', 'PASSWORD')
...

这个怎么样?

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

就是这样

下面的代码对我来说很好用:

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

档号: http://www.mkyong.com/python/how-do-send-email-in-python-via-smtplib/

看到那些冗长的答案了吗? 请允许我用几行字来自我推销。

导入和连接:

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

当它超出范围时(或者可以手动关闭) ,它实际上会关闭。此外,它将允许您在您的 keyring 中注册您的用户名,这样您就不必在您的脚本中写出您的密码(在编写 yagmail之前,这确实让我感到困扰!)

对于软件包/安装,提示和技巧请查看 饭桶Pip,它们都适用于 Python 2和3。

你可以这么做

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)

下面是 Python3.x 的一个工作示例

#!/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)))

使用 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()

基于 这个例子,我发挥了以下作用:

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

如果你只传递 body,那么纯文本邮件将被发送,但是如果你传递 html参数和 body参数,html 电子邮件将被发送(对于不支持 html/mime 类型的电子邮件客户端,回退到文本内容)。

示例用法:

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 服务器, 启用临时或永久访问不太安全的应用程序:

或者

import smtplib
 

from email.message import EmailMessage
from getpass import getpass




password = getpass()


message = EmailMessage()
message.set_content('Message content here')
message['Subject'] = 'Your subject here'
message['From'] = "USERNAME@DOMAIN"
message['To'] = "you@mail.com"


try:
smtp_server = None
smtp_server = smtplib.SMTP("YOUR.MAIL.SERVER", 587)
smtp_server.ehlo()
smtp_server.starttls()
smtp_server.ehlo()
smtp_server.login("USERNAME@DOMAIN", password)
smtp_server.send_message(message)
except Exception as e:
print("Error: ", str(e))
finally:
if smtp_server is not None:
smtp_server.quit()

如果要使用端口465,必须创建一个 SMTP_SSL对象。

红邮呢?

安装:

pip install redmail

然后:

from redmail import EmailSender


# Configure the sender
email = EmailSender(
host="YOUR.MAIL.SERVER",
port=26,
username='me@example.com',
password='<PASSWORD>'
)


# Send an email:
email.send(
subject="An example email",
sender="me@example.com",
receivers=['you@example.com'],
text="Hello!",
html="<h1>Hello!</h1>"
)

它有很多特点:

相关网址:

基于 madman2890,更新了一些内容,并删除了对 mailserver.exit ()的需求

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text 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))


with smtplib.SMTP('smtp-mail.outlook.com',587) as mail_server:
# identify ourselves to smtp gmail client
mail_server.ehlo()
# secure our email with tls encryption
mail_server.starttls()
# re-identify ourselves as an encrypted connection
mail_server.ehlo()
mail_server.login('me@gmail.com', 'mypassword')
mail_server.sendmail('me@gmail.com','you@gmail.com',msg.as_string())