Python 简明教程

Python - Sending Email

Sending Email in Python

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

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

Python smptlib.SMTP() Function

Python smtplib.SMTP() 函数用于创建 SMTP 客户端会话对象,该会话对象会建立到 SMTP 服务器的连接。此连接允许您通过服务器发送电子邮件。

Setting Up an SMTP Server

在发送电子邮件之前,您需要设置 SMTP 服务器。常见的 SMTP 服务器包括 Gmail、Yahoo 或其他邮件服务提供商提供的服务器。

Creating an SMTP Object

要发送电子邮件,您需要使用以下函数获取 SMTP 类的对象−

import smtplib

smtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] )

以下是参数的说明:

  1. host − 这是运行您的 SMTP 服务器的主机。您可以指定主机的 IP 地址或域名称,如 tutorialspoint.com 。这是一个可选参数。

  2. port − 如果您提供主机参数,那么您需要指定 SMTP 服务器正在侦听的端口。通常此端口为 25。

  3. local_hostname − 如果您的 SMTP 服务器在您的本地机器上运行,那么您可以只指定 localhost 作为选项。

Example

以下脚本在端口 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()

The Python smtpd Module

Python smtpd 模块用于创建和管理简单的邮件传输协议 (SMTP) 服务器。此模块允许你设置一台 SMTP 服务器,其可以接收和处理传入的电子邮件,使其对于在应用程序内测试和调试电子邮件功能十分有价值。

Setting Up an SMTP Debugging Server

smtp 模块随 Python 预安装,并包含一个本地 SMTP 调试服务器。此服务器对在不实际向指定地址发送电子邮件的情况下测试电子邮件功能十分有用;它会将电子邮件内容打印到控制台。

运行此本地服务器无需处理消息加密或使用凭据登录到电子邮件服务器。

Starting the SMTP Debugging Server

你可以通过以下命令在命令提示符或终端中启动本地 SMTP 调试服务器 -

python -m smtpd -c DebuggingServer -n localhost:1025

Example

以下示例演示如何使用 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()

在此示例中 -

  1. From - 你输入发件人的电子邮件地址(fromaddr)。

  2. To - 你输入接收者的电子邮件地址(toaddrs),它可以是多个地址,用空格分隔。

  3. Message - 你输入消息内容,以 ^D(Unix)或 ^Z(Windows)结尾。

"smtplib" 的 sendmail() 方法使用指定的发送者、收件者和消息内容向运行在 "localhost" 上的端口 "1025" 的本地 SMTP 调试服务器发送电子邮件。

Output

当你运行程序时,控制台会输出程序与 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 服务器的终端显示以下 output -

---------- MESSAGE FOLLOWS ----------
b'From: abc@xyz.com'
b'To: xyz@abc.com'
b'X-Peer: ::1'
b''
b'Hello World'
------------ END MESSAGE ------------

Sending an HTML e-mail using Python

要使用 Python 发送 HTML 邮件,你可以使用 smtplib 库连接到 SMTP 服务器,并使用 email.mime 模块适当构建并格式化你的电子邮件内容。

Constructing the HTML Email Message

发送 HTML 邮件时,你需要指定某些标题,并相应地构造消息内容,以确保接收者的电子邮件客户端能够识别并呈现为 HTML。

Example

以下是通过 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)}")

Sending Attachments as an E-mail

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

Constructing an Email with Attachments

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

Example

以下是发送电子邮件的示例,其中 /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"

Sending Email Using Gmail’s SMTP Server

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

Example

以下是一个演示如何使用 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 帐户以允许“安全性较低的应用”访问。访问以下链接。

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

toggle button

如果一切顺利,执行上述脚本。消息应发送到收件人的收件箱。