Python - 发送电子邮件



在 Python 中发送电子邮件

您可以使用多个库在 Python 中发送电子邮件,但最常见的是 smtplib email

Python 中的 “smtplib” 模块定义了一个 SMTP 客户端会话对象,该对象可用于将邮件发送到任何具有 SMTP 或 ESMTP 侦听器守护程序的 Internet 计算机。电子邮件“包”是一个用于管理电子邮件消息的库,包括 MIME 和其他基于 RFC 2822 的消息文档。

通过 Internet 处理和传递电子邮件的应用程序称为“邮件服务器”。简单邮件传输协议 (SMTP) 是一种协议,用于处理电子邮件的发送和邮件服务器之间的路由电子邮件。它是电子邮件传输的 Internet 标准。

Python smptlib 的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 地址或域名,例如 qikepu.com。这是一个可选参数。
  • port − 如果您提供 host 参数,则需要指定一个端口,SMTP 服务器正在侦听该端口。通常此端口为 25。
  • local_hostname − 如果您的 SMTP 服务器在本地计算机上运行,则只需指定 localhost 作为选项。

以下脚本连接到端口 25 上“smtp.example.com”处的 SMTP 服务器,可以选择识别并保护连接、登录(如果需要)、发送电子邮件,然后退出会话 -


import smtplib

# Create an SMTP object and establish a connection to the SMTP server
smtpObj = smtplib.SMTP('smtp.example.com', 25)

# Identify yourself to an ESMTP server using EHLO
smtpObj.ehlo()

# Secure the SMTP connection
smtpObj.starttls()

# Login to the server (if required)
smtpObj.login('username', 'password')

# Send an email
from_address = 'your_email@example.com'
to_address = 'recipient@example.com'
message = """\
Subject: Test Email

This is a test email message.
"""

smtpObj.sendmail(from_address, to_address, message)

# Quit the SMTP session
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("Enter message, end with ^D (Unix) or ^Z (Windows):")

# Add the From: and To: headers at the start!
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("Message length is", 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() 方法使用指定的发件人、收件人和邮件内容将电子邮件发送到在端口“1025”的“localhost”上运行的本地 SMTP 调试服务器。

输出

运行程序时,控制台将输出程序与 SMTP 服务器之间的通信。同时,运行 SMTPD 服务器的终端会显示传入的消息内容,帮助您调试和验证邮件发送过程。

python example.py
From: abc@xyz.com
To: xyz@abc.com
Enter message, end with ^D (Unix) or ^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

# Email content
sender = 'from@fromdomain.com'
receivers = ['to@todomain.com']

# Create message container - the correct MIME type is multipart/alternative.
msg = MIMEMultipart('alternative')
msg['From'] = 'From Person <from@fromdomain.com>'
msg['To'] = 'To Person <to@todomain.com>'
msg['Subject'] = 'SMTP HTML e-mail test'

# HTML message content
html = """\
<html>
	 <head></head>
	 <body>
	 	 <p>This is an e-mail message to be sent in <b>HTML format</b></p>
	 	 <p><b>This is HTML message.</b></p>
	 	 <h1>This is headline.</h1>
	 </body>
</html>
"""

# Attach HTML content to the email
part2 = MIMEText(html, 'html')
msg.attach(part2)

# Connect to SMTP server and send email
try:
	 	smtpObj = smtplib.SMTP('localhost')
	 	smtpObj.sendmail(sender, receivers, msg.as_string())
	 	print("Successfully sent email")
except smtplib.SMTPException as e:
	 	print(f"Error: unable to send email. Error message: {str(e)}")

以电子邮件形式发送附件

要在 Python 中发送电子邮件附件,您可以使用 smtplib 库连接到 SMTP 服务器,并使用 email.mime 模块来构建和格式化您的电子邮件内容,包括附件。

构建带有附件的电子邮件

发送带有附件的电子邮件时,您需要使用 MIME(多用途 Internet 邮件扩展)正确格式化电子邮件。这涉及将 Content-Type 标头设置为 multipart/mixed 以表示电子邮件同时包含文本和附件。电子邮件的每个部分(文本和附件)都由边界分隔。

以下是示例,该示例发送一封附件为 /tmp/test.txt 的电子邮件 -


import smtplib
import base64

filename = "/tmp/test.txt"

# Read a file and encode it into base64 format
fo = open(filename, "rb")
filecontent = fo.read()
encodedcontent = base64.b64encode(filecontent) 	# base64

sender = 'webmaster@tutorialpoint.com'
reciever = 'amrood.admin@gmail.com'

marker = "AUNIQUEMARKER"

body ="""
This is a test email to send an attachment.
"""
# Define the main headers.
part1 = """From: From Person <me@fromdomain.net>
To: To Person <amrood.admin@gmail.com>
Subject: Sending Attachment
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=%s
--%s
""" % (marker, marker)

# Define the message action
part2 = """Content-Type: text/plain
Content-Transfer-Encoding:8bit

%s
--%s
""" % (body,marker)

# Define the attachment section
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 "Successfully sent email"
except Exception:
	 	print "Error: unable to send email"

使用 Gmail 的 SMTP 服务器发送电子邮件

要在 Python 中使用 Gmail 的 SMTP 服务器发送电子邮件,您需要使用“TLS”加密在端口“587”上设置与 smtp.gmail.com 的连接,使用您的 Gmail 凭据进行身份验证,使用 Python 的 smtplib 和 email.mime 库构建电子邮件,并使用 sendmail() 方法发送它。最后,使用 quit() 关闭 SMTP 连接。

下面是一个示例脚本,演示如何使用 Gmail 的 SMTP 服务器发送电子邮件 -


import smtplib

# Email content
content = "Hello World"

# Set up SMTP connection to Gmail's SMTP server
mail = smtplib.SMTP('smtp.gmail.com', 587)
# Identify yourself to the SMTP server
mail.ehlo() 	
# Start TLS encryption for the connection
mail.starttls() 	

# Gmail account credentials	
sender = 'your_email@gmail.com'
password = 'your_password'

# Login to Gmail's SMTP server
mail.login(sender, password)

# Email details
recipient = 'recipient_email@example.com'
subject = 'Test Email'

# Construct email message with headers
header = f'To: {recipient}\nFrom: {sender}\nSubject: {subject}\n'
content = header + content

# Send email
mail.sendmail(sender, recipient, content)

# Close SMTP connection
mail.quit()

在运行上述脚本之前,必须将发件人的 gmail 帐户配置为允许访问“less 保护应用程序”。请访问以下链接。

https://myaccount.google.com/lesssecureapps 将显示的切换按钮设置为 ON。

切换按钮

如果一切顺利,请执行上述脚本。邮件应投递到收件人的收件箱。