这段代码工作,并向我发送电子邮件就好:

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

有人能告诉我为什么吗?


当前回答

它可能会在你的信息中添加标签。在你把它传递给sendMail之前打印出消息。

其他回答

我想通过建议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安装它。

使用gmail的另一个实现让我们说:

import smtplib

def send_email(email_address: str, subject: str, body: str):
"""
send_email sends an email to the email address specified in the
argument.

Parameters
----------
email_address: email address of the recipient
subject: subject of the email
body: body of the email
"""

server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login("email_address", "password")
server.sendmail("email_address", email_address,
                "Subject: {}\n\n{}".format(subject, body))
server.quit()

我建议您使用标准包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中有所了解,这是必须的——标准库的文档大部分都很出色。

它可能会在你的信息中添加标签。在你把它传递给sendMail之前打印出消息。

确保您已在电子邮件帐户中授予发件人和收件人发送和接收来自未知来源(外部来源)的电子邮件的权限。

import smtplib

#Ports 465 and 587 are intended for email client to email server communication - sending email
server = smtplib.SMTP('smtp.gmail.com', 587)

#starttls() is a way to take an existing insecure connection and upgrade it to a secure connection using SSL/TLS.
server.starttls()

#Next, log in to the server
server.login("#email", "#password")

msg = "Hello! This Message was sent by the help of Python"

#Send the mail
server.sendmail("#Sender", "#Reciever", msg)