Python 允许您使用其内置模块自动执行发送电子邮件的任务。这样做可以让您摆脱手动向数千名用户发送电子邮件的繁琐且耗时的任务。
本教程将探讨一些快速、简单的发送电子邮件和使用 Python 内置电子邮件模块的方法。
检查电子邮件是否存在
通常,您可能想要检查用户输入的电子邮件是否有效或语法不正确。此外,您可能还想检查该电子邮件地址是否确实存在。使用 Python 可以快速完成此操作。
有效的电子邮件地址具有特定的格式。始终存在“@”符号。前缀是@符号之前的部分,后缀是@符号之后的部分。
后缀必须是经过验证的域名。电子邮件地址可以包含数字、字母、句点、破折号和下划线。
如果使用破折号或下划线,则后面需要跟字母或数字。这些是定义正确电子邮件地址的规则。
如果你想检查用户输入的电子邮件地址的语法,Python 的 re 模块会派上用场。 ‘re’是正则表达式的缩写形式。
您可以创建与有效电子邮件的语法相匹配的正则表达式。为此,您需要了解正则表达式的工作原理。下面是一个检查电子邮件地址语法的正则表达式。
import re
valid_regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
def check(email):
if(re.fullmatch(valid_regex, email)):
print("This is a valid email")
else:
print("This is an invalid email")
email = "correctemail@gmail.com"
check(email)
使用 re 模块需要您对正则表达式有深入的了解。
检查电子邮件是否存在的更好方法是使用名为 validate-email-address 的第三方包。您可以使用包管理器(例如 pip)安装此模块。
$ pip install py3-validate-email
from validate_email import validate_email
valid_email = validate_email(email_address='example@gmail.com')
这个包的伟大之处在于它检查电子邮件的语法,并通过模拟实际的电子邮件发送来检查给定的电子邮件地址是否存在。为此,您需要将 check_smtp 标志设置为 true。
from validate_email import validate_email
valid_email = validate_email(email_address='example@gmail.com', check_smtp = True)
Python 电子邮件服务器
要使用Python发送电子邮件,您需要设置一个电子邮件服务器第一的。发送电子邮件的最常见方式和行业标准协议是使用 SMTP 协议。
SMTP 是简单邮件传输协议的缩写。电子邮件服务提供商利用 SMTP 服务器和 SMTP 协议来发送或中继消息。
您可以使用 Python 的 smtplib 模块创建自己的 SMTP 电子邮件服务器。该模块允许您发送没有主题行或多媒体的简单消息。
Python 还有一个内置的电子邮件包,允许您随文本消息一起发送其他附件。与 smtplib 模块结合使用时,您可以发送带有附件和主题行的丰富电子邮件。
要使用 smtplib 模块创建电子邮件服务器,首先需要运行 import 语句。
import smtplib
然后,您可以创建封装 SMTP 连接的 SMTP 实例。您可以设置可选参数主机和端口来指定端口和主机,具体取决于您的特定电子邮件服务提供商。
要设置自动关闭的连接,您需要使用“with”语句。
from smtplib import SMTP
with SMTP(host= "exampledomain.com", port= 587) as smtp:
smtp.starttls()
smtp.noop()
当您使用 SMTP 时,发起的连接并不安全。这就是为什么您需要使用 starttls() 对其进行加密。
另一种方法是从头开始安全连接,而不是在连接启动后对其进行加密。 SMTP_SSL 实例用于本例。
from smtplib import SMTP
server = "smtp-mail.outlook.com"
port = 587
with smtplib.SMTP_SSL(server, port) as server:
server.login("example@outlook.com", password="StrongPassword")
使用 Python 发送电子邮件
设置电子邮件服务器后,您可以将电子邮件转发到有效地址。 sendmail() 函数执行此操作。它要求您指定发件人和收件人的电子邮件地址以及消息。
如果您的 SMTP 服务器需要身份验证才能发送邮件,您需要输入电子邮件帐户的凭据。
您可以将用户名和密码传递给 login() 函数,该函数将执行身份验证。
使用 smtplib 模块时,可以通过两种方式发送电子邮件。它们都确保您的 SMTP 连接是安全且加密的。
通过 SMTP 发送电子邮件
如前所述,您可以首先启动未通过 TLS 加密的连接,然后使用 starttls() 对其进行加密。在本例中,将创建 SMTP 类的实例。
import smtplib
import ssl
port = 587
smtp_server = "smtp-mail.outlook.com"
sender = "sender@outlook.com"
recipient = "receiver@gmail.com"
sender_password = "strongpassword"
message = """
Subject: This is a test message
Sent using Python."""
SSL_context = ssl.create_default_context()
with smtplib.SMTP(smtp_server, port) as server:
server.starttls(context=SSL_context)
server.login(sender, sender_password)
server.sendmail(sender, recipient, message)
使用 SMTP SSL 发送
发送电子邮件的第二种方法是通过 TLS 启动安全连接。在从连接开始就需要 SSL 的情况下,这是正确的选项。
import smtplib
import ssl
port = 465
smtp_server = "smtp-mail.outlook.com"
sender = "sender@outlook.com"
recipient = "receiver@gmail.com"
sender_password = "strongpassword"
message = """
Subject: This is a test message
Send using Python."""
SSL_context = ssl.create_default_context()
with smtplib.SMTP_SSL(smtp_server, port, context=SSL_context) as server:
server.login(sender, sender_password)
server.sendmail(sender, recipient, message)
无需 SMTP 服务器即可发送电子邮件
如果您不想设置 SMTP 服务器来发送电子邮件,chilkat 模块将是您的最佳选择。它包含 Chilkat MailMan 类,该类分别负责通过 SMTP 和 POP3 服务器发送和接收电子邮件。
该模块提供了 MxLookup 方法,该方法执行 DNS MX 查找,以使用收件人的电子邮件地址查找邮件服务器。您需要安装 chilkat 模块才能执行此操作。
import sys
import chilkat
mailman = chilkat.CkMailMan()
receiver_address = "example@domain.com"
smtpHost = mailman.mxLookup(receiver_address)
if (mailman.get_LastMethodSuccess() != True):
print(mailman.lastErrorText())
sys.exit()
mailman.put_SmtpHost(smtpHost)
mail = chilkat.CkEmail()
mail.put_Subject("A test subject")
mail.put_Body("Hello!")
mail.put_From("")
mail.AddTo("", receiver_address)
success = mailman.SendEmail(mail)
if (success != True):
print(mailman.lastErrorText())
else:
print("Sent!")
电子邮件 MIME 文本
如果您想发送没有主题或强调(粗体、斜体或下划线)的纯文本电子邮件,Python 中的 smtplib 模块足以完成这项工作。
但是,您经常希望使用纯文本在现实场景中添加附件(图像、超链接等)或响应内容。 Python 的内置电子邮件模块在这种情况下会派上用场。
MIME 是多用途互联网邮件扩展的缩写,是一种使用 HTML 与纯文本相结合的电子邮件类型。
它扩展了 SMTP 协议以支持图像、视频、音频和其他附件。 Python 的 email.mime 模块允许您在通过 SMTP 服务器发送电子邮件时包含 HTML 或附件。
为此,您需要通过运行以下语句来导入模块。
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import smtplib
import ssl
port = 587
server = "smtp-mail.outlook.com"
sender = "example@outlook.com"
recipient = "example@gmail.com"
password = "strongpassword"
msg = MIMEMultipart()
message = """Hi,
This is a MIME text
"""
msg['From']= sender_email
msg['To']= receiver_email
msg['Subject']="This is a text email for MIME"
msg.attach(MIMEText(message, "plain"))
text = msg.as_string()
SSLcontext = ssl.create_default_context()
with smtplib.SMTP(server, port) as server:
server.starttls(context=SSLcontext)
server.login(sender, password)
server.sendmail(sender, recipient, text)
发送 HTML 电子邮件
除了通过 SMTP 服务器发送 MIME 文本之外,email.mime 还可以很好地用于发送 HTML 电子邮件。该过程与上面完全相同,只是 MIMEText() 函数有细微的差别。
由于消息是简单的纯文本,因此您在前面的代码示例中传递了“plain”作为第二个参数。当您想要发送 HTML 文本时,您可以将文本和此参数更改为“html”。
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import smtplib
import ssl
port = 587
server = "smtp-mail.outlook.com"
sender = "example@outlook.com"
recipient = "example@gmail.com"
password = "strongpassword"
msg = MIMEMultipart()
html_message = """
<html>
<body>
<p>
This is HTML<br>
</p>
</body>
</html>
"""
msg.attach(MIMEText(html_message, "html"))
text = msg.as_string()
SSLcontext = ssl.create_default_context()
with smtplib.SMTP(server, port) as server:
server.starttls(context=SSLcontext)
server.login(sender, password)
server.sendmail(sender, recipient, text)
指定抄送和密件抄送
email.mime 模块还允许您在电子邮件中指定抄送和密件抄送收件人。为此,您需要在多部分消息中指定其他标头。
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import smtplib
import ssl
port = 587
server = "smtp-mail.outlook.com"
sender = "example@outlook.com"
recipient = "example@gmail.com"
password = "strongpassword"
msg = MIMEMultipart()
message = """
An email with CC and BCC
"""
msg['From']= sender
msg['To']= recipient
msg['Subject']= "This is TEST"
msg["Bcc"] = recipient
msg["Cc"] = 'example@gmail.com'
msg.attach(MIMEText(message, "plain"))
text = msg.as_string()
SSLcontext = ssl.create_default_context()
with smtplib.SMTP(server, port) as server:
server.starttls(context=SSLcontext)
server.login(sender, password)
server.sendmail(sender, recipient, text)
发送带有附件的电子邮件
附件以二进制文件的形式通过 SMTP 服务器发送。为此,您需要使用 base64 对附件进行编码,这是一种常见的二进制到文本编码方案,用于将二进制数据编码为 ASCII 字符。
例如,您可以通过使用 MIMEBase 实例将其作为八位字节流读取并使用 Python 电子邮件库中的编码器模块对其进行编码来发送 pdf 文件。
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import smtplib, ssl
from email import encoders
port = 587
server = "smtp-mail.outlook.com"
sender = "example@outlook.com"
recipient = "example@gmail.com"
password = "strongpassword"
msg = MIMEMultipart()
message = "This email includes an attachment"
msg.attach(MIMEText(message, "plain"))
filename = "example.pdf"
with open(filename, "rb") as pdf:
attachment = MIMEBase("application", "octet-stream")
attachment.set_payload(pdf.read())
encoders.encode_base64(attachment)
attachment.add_header(
"Content-Disposition",
f"attachment; filename= {filename}",
)
msg.attach(attachment)
SSLcontext = ssl.create_default_context()
with smtplib.SMTP(server, port) as server:
server.starttls(context=SSLcontext)
server.login(sender, password)
server.sendmail(sender, recipient, msg.as_string())
发送带有内嵌图像的电子邮件
有时您可能希望将图像嵌入 HTML 文本中。为此,您可以将图像转换为 Base64 编码格式并将其发送出去。
幸运的是,Python 有一个库可以帮你做到这一点。您可以导入 base64 库并使用 b64encode() 函数无缝地执行此操作。
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
import smtplib, ssl, base64
port = 587
server = "smtp-mail.outlook.com"
sender = "sender@outlook.com"
recipient = "receiver@gmail.com"
password = "strongPassword"
msg = MIMEMultipart()
msg['From']= sender
msg['To']= recipient
msg['Subject']= "My subject"
filename = "example.jpg"
image = base64.b64encode(open(filename, "rb").read())
image_base64 = image.decode()
html_img = """
<html>
<body>
<p>
<img src= "data:image/jpg;base64,{image_base64}">
</p>
</body>
</html>
"""
msg.attach(MIMEText(html_img, "html"))
text = msg.as_string()
context = ssl.create_default_context()
with smtplib.SMTP(smtp_server, port) as server:
server.starttls(context=context)
server.login(sender, password )
server.sendmail(sender, recipient, text)
发送电子邮件至国际化电子邮件地址(非 ASCII)
在电子邮件获得全世界认可之前,它们主要由 ASCII 字符组成,并用RFC 822标准。
如今,电子邮件以更多特定于语言的字符集在国际上发送。要发送国际化电子邮件,您需要使用 email.header 模块,它将非 ASCII 字符编码为符合 RFC 2822 的格式。
如果您的主题或发件人字段包含非 ASCII 字符,您可以使用 Header 类创建 Header 实例并传递字符串编码所用的字符集。
相应的decode_header()函数将编码字符串解码为原始字符集。
import email, smtplib, ssl
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header, decode_header
subject = "Some non ASCII text"
receiver_email = "Pelé@example.com"
message = MIMEMultipart('mixed')
message['Subject'] = Header(subject, 'utf-8')
message['To'] = Header(receiver_email, 'iso-8859-1')
text = message.as_string()
print(text)
decode_header(text)
发送 DKIM 签名的邮件
使用 Python,您可以使用您的私钥发送数字签名的电子邮件。这在必须对发件人进行身份验证的情况下非常有用。
为此,您需要安装名为 dkimpy 的第三方软件包。您需要使用 setup.py 文件安装该包。
完成后,您可以通过运行以下语句导入它:
import dkim
现在,您可以使用私钥生成消息签名(为此,您需要生成公钥/私钥对)。之后,您必须将数字签名附加到您的多部分消息中,然后一切就完成了。
import smtplib, dkim, time, os
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
port = 587
smtp_server = "smtp-mail.outlook.com"
sender_email = "sender@outlook.com"
receiver_email = "receiver@gmail.com"
password = "strongPassword"
msg = MIMEMultipart()
msg['From']= sender_email
msg['To']= receiver_email
msg['Subject']= "This is TEST"
message = "A digitally signed email"
msg.attach(message)
headers=[b'from', b'to', b'subject']
privateKey = open(os.path.join('private_kry.pem')).read()
signature = dkim.sign(msg.as_string(), b'key1', b'mydomain.com', privateKey.encode(), include_headers=headers)
signature = signature.decode()
msg['DKIM-Signature'] = signature[len("DKIM-Signature: "):]
context = ssl.create_default_context()
with smtplib.SMTP(smtp_server, port) as server:
server.starttls(context=context)
server.login(sender_email, password )
server.sendmail(sender_email, receiver_email,msg)
print('Sent')
向多个收件人发送电子邮件
当您想要向多个收件人发送个性化电子邮件时,就会获得电子邮件自动化的真正好处。也许您有一个 CSV 文件,其中包含许多用户的姓名和电子邮件地址。
You can 在Python中读取CSV文件并循环每一行以检索收件人的姓名和电子邮件。
获得收件人信息后,您可以使用 str.format() 和占位符使您的消息更加个性化。操作方法如下:
import csv
import smtplib
import ssl
body = "Hello {name}!"
port = 587
server = "smtp-mail.outlook.com"
sender = "sender@outlook.com"
password = "strongPassword"
SSLcontext = ssl.create_default_context()
with smtplib.SMTP(server, port) as server:
server.starttls(context = SSLcontext)
server.login(sender_email, password)
with open("file.csv") as file_handle:
content = csv.reader(file_handle)
next(content)
for name, email in content:
server.sendmail(sender, email, body.format(name = name))