你可以通过使用多个库在 Python 中发送电子邮件,但最常用的库是 smtplib 和 email。
Python 中的 "smtplib" 模块定义了一个 SMTP 客户端会话对象,可以用来向任何具有 SMTP 或 ESMTP 监听守护进程的 Internet 机器发送邮件。email "包" 是一个管理电子邮件消息的库,包括 MIME 和其他基于 RFC 2822 的消息文档。
处理并通过互联网传递电子邮件的应用程序称为“邮件服务器”。简单邮件传输协议(SMTP)是一种处理发送邮件并在邮件服务器之间路由邮件的协议。它是电子邮件传输的互联网标准。
Python smtplib.SMTP() 函数
Python 的 smtplib.SMTP() 函数用于创建一个 SMTP 客户端会话对象,该对象建立与 SMTP 服务器的连接。这种连接使你能够通过服务器发送电子邮件。
设置 SMTP 服务器
在发送电子邮件之前,你需要设置一个 SMTP 服务器。常见的 SMTP 服务器包括由 Gmail、Yahoo 或其他邮件服务提供商提供的服务器。
创建 SMTP 对象
要发送电子邮件,你需要获取 SMTP 类的对象,使用以下函数:
import smtplib
smtpObj = smtplib.SMTP([host [, port [, local_hostname]]])
这里参数的详细信息如下:
-
host
— 运行你的 SMTP 服务器的主机。你可以指定主机的 IP 地址或像 tutorialspoint.com 这样的域名。这是一个可选参数。
-
port
— 如果你提供 host
参数,那么你需要指定 SMTP 服务器监听的端口。通常这个端口是 25。
-
local_hostname
— 如果你的 SMTP 服务器运行在本地机器上,那么你可以指定 localhost 作为选项。
示例
下面的脚本连接到位于 "smtp.example.com" 的 SMTP 服务器,在端口 25 上,可选地识别并保护连接,登录(如果需要),发送电子邮件,然后退出会话:
import smtplib
smtpObj = smtplib.SMTP('smtp.example.com', 25)
smtpObj.ehlo()
smtpObj.starttls()
smtpObj.login('username', 'password')
from_address = 'your_email@example.com'
to_address = 'recipient@example.com'
message = """\
Subject: 测试邮件
这是一封测试邮件。
"""
smtpObj.sendmail(from_address, to_address, message)
smtpObj.quit()
Python smtpd 模块
Python 的 smtpd 模块用于创建和管理一个简单的邮件传输协议(SMTP)服务器。此模块允许你设置一个可以接收和处理传入电子邮件消息的 SMTP 服务器,使其在应用程序内测试和调试电子邮件功能变得有价值。
设置 SMTP 调试服务器
smtpd 模块随 Python 预装,并包含一个本地 SMTP 调试服务器。此服务器对于测试电子邮件功能而不实际将电子邮件发送到指定地址非常有用;相反,它将电子邮件内容打印到控制台。
启动 SMTP 调试服务器
你可以使用以下命令在命令提示符或终端中启动本地 SMTP 调试服务器:
python -m smtpd -c DebuggingServer -n localhost:1025
示例
下面的例子演示了如何使用 smtplib 功能加上本地 SMTP 调试服务器发送一个假邮件:
import smtplib
def prompt(prompt):
return input(prompt).strip()
fromaddr = prompt("From: ")
toaddrs = prompt("To: ").split()
print("输入消息,以 ^D (Unix) 或 ^Z (Windows) 结束:")
msg = ("From: %s\r\nTo: %s\r\n\r\n"
% (fromaddr, ", ".join(toaddrs)))
while True:
try:
line = input()
except EOFError:
break
if not line:
break
msg = msg + line
print("消息长度为", len(msg))
server = smtplib.SMTP('localhost', 1025)
server.set_debuglevel(1)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()
在这个例子中:
-
From
— 输入发件人的电子邮件地址 (fromaddr
)。
-
To
— 输入收件人的电子邮件地址 (toaddrs
),可以是多个由空格分隔的地址。
-
Message
— 输入消息内容,以 ^D (Unix) 或 ^Z (Windows) 结束。
smtplib
的 sendmail()
方法使用指定的发件人、收件人以及消息内容将电子邮件发送到在 "localhost" 上运行的本地 SMTP 调试服务器,端口为 "1025"。
输出
当你运行程序时,控制台输出程序与 SMTP 服务器之间的通信。同时,在运行 SMTPD 服务器的终端中显示传入的消息内容,帮助你调试并验证电子邮件发送过程。
python example.py
From: abc@xyz.com
To: xyz@abc.com
输入消息,以 ^D (Unix) 或 ^Z (Windows) 结束:
Hello World
^Z
控制台反映的日志如下:
From: abc@xyz.com
reply: retcode (250); Msg: b'OK'
send: 'rcpt TO:<xyz@abc.com>\r\n'
reply: b'250 OK\r\n'
reply: retcode (250); Msg: b'OK'
send: 'data\r\n'
reply: b'354 End data with <CR><LF>.<CR><LF>\r\n'
reply: retcode (354); Msg: b'End data with <CR><LF>.<CR><LF>'
data: (354, b'End data with <CR><LF>.<CR><LF>')
send: b'From: abc@xyz.com\r\nTo: xyz@abc.com\r\n\r\nHello
World\r\n.\r\n'
reply: b'250 OK\r\n'
reply: retcode (250); Msg: b'OK'
data: (250, b'OK')
send: 'quit\r\n'
reply: b'221 Bye\r\n'
reply: retcode (221); Msg: b'Bye'
在运行 SMTPD 服务器的终端中显示的输出如下:
---------- MESSAGE FOLLOWS ----------
b'From: abc@xyz.com'
b'To: xyz@abc.com'
b'X-Peer: ::1'
b''
b'Hello World'
------------ END MESSAGE ------------
使用 Python 发送 HTML 电子邮件
要使用 Python 发送 HTML 电子邮件,你可以使用 smtplib 库连接到 SMTP 服务器,并使用 email.mime 模块构建和格式化电子邮件内容。
构建 HTML 电子邮件消息
当发送 HTML 电子邮件时,你需要指定某些头部并相应地构建消息内容,以确保它被收件人的电子邮件客户端识别并呈现为 HTML。
示例
下面是一个使用 Python 发送 HTML 内容作为电子邮件的例子:
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
sender = 'from@fromdomain.com'
receivers = ['to@todomain.com']
msg = MIMEMultipart('alternative')
msg['From'] = 'From Person <from@fromdomain.com>'
msg['To'] = 'To Person <to@todomain.com>'
msg['Subject'] = 'SMTP HTML 电子邮件测试'
html = """\
<html>
<head></head>
<body>
<p>这是一封将以<b>HTML 格式</b>发送的电子邮件消息。</p>
<p><b>这是 HTML 消息。</b></p>
<h1>这是标题。</h1>
</body>
</html>
"""
part2 = MIMEText(html, 'html')
msg.attach(part2)
try:
smtpObj = smtplib.SMTP('localhost')
smtpObj.sendmail(sender, receivers, msg.as_string())
print("成功发送电子邮件")
except smtplib.SMTPException as e:
print(f"错误:无法发送电子邮件。错误信息:{str(e)}")
作为电子邮件发送附件
要使用 Python 发送带有附件的电子邮件,你可以使用 smtplib 库连接到 SMTP 服务器,并使用 email.mime 模块构建和格式化电子邮件内容,包括附件。
构建带有附件的电子邮件
当发送带有附件的电子邮件时,你需要正确格式化电子邮件,使用 MIME(多用途因特网邮件扩展)。这涉及到设置 Content-Type 头部为 multipart/mixed,以表明电子邮件包含文本和附件。电子邮件的每一部分(文本和附件)都由边界分开。
示例
下面是一个例子,它发送一封带有 /tmp/test.txt 文件作为附件的电子邮件:
import smtplib
import base64
filename = "/tmp/test.txt"
fo = open(filename, "rb")
filecontent = fo.read()
encodedcontent = base64.b64encode(filecontent)
sender = 'webmaster@tutorialpoint.com'
reciever = 'amrood.admin@gmail.com'
marker = "AUNIQUEMARKER"
body="""
这是一封测试电子邮件以发送附件。
"""
part1 = """From: From Person <me@fromdomain.net>
To: To Person <amrood.admin@gmail.com>
Subject: 发送附件
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=%s
--%s
""" % (marker, marker)
part2 = """Content-Type: text/plain
Content-Transfer-Encoding:8bit
%s
--%s
""" % (body,marker)
part3 = """Content-Type: multipart/mixed; name="%s"
Content-Transfer-Encoding:base64
Content-Disposition: attachment; filename=%s
%s
--%s--
""" %(filename, filename, encodedcontent, marker)
message = part1 + part2 + part3
try:
smtpObj = smtplib.SMTP('localhost')
smtpObj.sendmail(sender, reciever, message)
print("成功发送电子邮件")
except Exception:
print("错误:无法发送电子邮件")
使用 Gmail 的 SMTP 服务器发送电子邮件
要使用 Python 通过 Gmail 的 SMTP 服务器发送电子邮件,你需要连接到 smtp.gmail.com 的 "587" 端口,并使用 "TLS" 加密,使用你的 Gmail 凭据进行身份验证,使用 Python 的 smtplib 和 email.mime 库构建电子邮件消息,并使用 sendmail() 方法发送它。最后,使用 quit() 关闭 SMTP 连接。
示例
下面是一个示例脚本,演示了如何使用 Gmail 的 SMTP 服务器发送电子邮件:
import smtplib
content = "Hello World"
mail = smtplib.SMTP('smtp.gmail.com', 587)
mail.ehlo()
mail.starttls()
sender = 'your_email@gmail.com'
password = 'your_password'
mail.login(sender, password)
recipient = 'recipient_email@example.com'
subject = 'Test Email'
header = f'To: {recipient}\nFrom: {sender}\nSubject: {subject}\n'
content = header + content
mail.sendmail(sender, recipient, content)
mail.quit()
在运行上述脚本之前,发件人的 Gmail 账户必须配置为允许 'less secure apps' 访问。请访问以下链接:
https://myaccount.google.com/lesssecureapps 设置显示的切换按钮为开启状态。
如果一切顺利,请执行上述脚本。消息应该会被送达收件人的收件箱。