如何用Python发送电子邮件?
这段代码运行得很好,能顺利给我发邮件:
import smtplib
#SERVER = "localhost"
FROM = 'monty@python.com'
TO = ["jon@mycompany.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('myserver')
server.sendmail(FROM, TO, message)
server.quit()
但是如果我试着把它放进一个函数里,像这样:
def sendMail(FROM,TO,SUBJECT,TEXT,SERVER):
import smtplib
"""this is some test documentation in the function"""
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()
然后调用这个函数时,我就会遇到以下错误:
Traceback (most recent call last):
File "C:/Python31/mailtest1.py", line 8, in <module>
sendmail.sendMail(sender,recipients,subject,body,server)
File "C:/Python31\sendmail.py", line 13, in sendMail
server.sendmail(FROM, TO, message)
File "C:\Python31\lib\smtplib.py", line 720, in sendmail
self.rset()
File "C:\Python31\lib\smtplib.py", line 444, in rset
return self.docmd("rset")
File "C:\Python31\lib\smtplib.py", line 368, in docmd
return self.getreply()
File "C:\Python31\lib\smtplib.py", line 345, in getreply
raise SMTPServerDisconnected("Connection unexpectedly closed")
smtplib.SMTPServerDisconnected: Connection unexpectedly closed
有没有人能帮我理解一下为什么会这样?
20 个回答
我想帮你发送邮件,推荐一个叫yagmail的工具包(我是这个工具的维护者,抱歉有点广告,但我觉得它真的很有用!)。
你需要的完整代码是:
import yagmail
yag = yagmail.SMTP(FROM, 'pass')
yag.send(TO, SUBJECT, TEXT)
注意,我为所有参数提供了默认值,比如如果你想发邮件给自己,可以不写TO
,如果你不想写主题,也可以省略。
而且,这个工具的目标是让你很容易地附加html代码、图片或其他文件。
在你放内容的地方,你可以这样做:
contents = ['Body text, and here is an embedded image:', 'http://somedomain/image.png',
'You can also find an audio file attached.', '/local/path/song.mp3']
哇,发送附件是多么简单啊!如果没有yagmail,这可能需要20行代码呢;)
而且,如果你设置一次,以后就不用再输入密码了(而且密码会安全存储)。在你的情况下,你可以这样做:
import yagmail
yagmail.SMTP().send(contents = contents)
这样写起来简洁多了!
我邀请你去看看这个工具的github页面,或者直接用pip install yagmail
来安装它。
当我需要在Python中发送邮件时,我会使用mailgun这个API,它能帮我解决很多发送邮件时的麻烦。他们提供了一个很棒的应用程序/API,让你每个月可以免费发送5000封邮件。
发送一封邮件的代码大概是这样的:
def send_simple_message():
return requests.post(
"https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages",
auth=("api", "YOUR_API_KEY"),
data={"from": "Excited User <mailgun@YOUR_DOMAIN_NAME>",
"to": ["bar@example.com", "YOU@YOUR_DOMAIN_NAME"],
"subject": "Hello",
"text": "Testing some Mailgun awesomness!"})
你还可以跟踪邮件的各种事件,了解更多信息可以查看快速入门指南。
我建议你使用标准的 email
和 smtplib
这两个包来发送邮件。请看下面的例子(这个例子来自于 Python文档)。注意,如果你按照这种方式操作,发送邮件这个“简单”的任务确实很简单,而一些更复杂的任务(比如附加二进制文件或发送纯文本/HTML的多部分消息)也能很快完成。
# Import smtplib for the actual sending function
import smtplib
# Import the email modules we'll need
from email.mime.text import MIMEText
# Open a plain text file for reading. For this example, assume that
# the text file contains only ASCII characters.
with open(textfile, 'rb') as fp:
# Create a text/plain message
msg = MIMEText(fp.read())
# me == the sender's email address
# you == the recipient's email address
msg['Subject'] = 'The contents of %s' % textfile
msg['From'] = me
msg['To'] = you
# Send the message via our own SMTP server, but don't include the
# envelope header.
s = smtplib.SMTP('localhost')
s.sendmail(me, [you], msg.as_string())
s.quit()
如果你想给多个收件人发送邮件,你也可以参考 Python文档中的例子:
# Import smtplib for the actual sending function
import smtplib
# Here are the email package modules we'll need
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
# Create the container (outer) email message.
msg = MIMEMultipart()
msg['Subject'] = 'Our family reunion'
# me == the sender's email address
# family = the list of all recipients' email addresses
msg['From'] = me
msg['To'] = ', '.join(family)
msg.preamble = 'Our family reunion'
# Assume we know that the image files are all in PNG format
for file in pngfiles:
# Open the files in binary mode. Let the MIMEImage class automatically
# guess the specific image type.
with open(file, 'rb') as fp:
img = MIMEImage(fp.read())
msg.attach(img)
# Send the email via our own SMTP server.
s = smtplib.SMTP('localhost')
s.sendmail(me, family, msg.as_string())
s.quit()
如你所见,在 MIMEText
对象中的 To
头部必须是一个字符串,这个字符串由用逗号分隔的邮箱地址组成。另一方面,sendmail
函数的第二个参数必须是一个字符串列表(每个字符串都是一个邮箱地址)。
所以,如果你有三个邮箱地址: person1@example.com
、person2@example.com
和 person3@example.com
,你可以这样做(省略了一些明显的部分):
to = ["person1@example.com", "person2@example.com", "person3@example.com"]
msg['To'] = ",".join(to)
s.sendmail(me, to, msg.as_string())
这里的 ",".join(to)
部分会把列表中的邮箱地址合并成一个字符串,用逗号分隔。
从你的问题来看,我觉得你可能还没有学习过 Python教程 - 如果你想在Python上有所进展,这个教程是必须的 - 文档对于标准库来说大部分都非常优秀。