# 电子邮件
- 用户使用邮件客户端,可以从邮件服务器接收、发送电子邮件(Email)。
- 电子邮件地址一般由邮箱名和邮件服务器的域名组成,中间用@隔开。比如:
[email protected]
- 邮件服务器的主要配置内容:
- 域:可以将一个邮件服务器分成多个独立的虚拟服务器,每个虚拟服务器都是一个域。
- 用户:需要配置账号、密码,用于登录邮件服务器。
- 每个用户会被分配一个唯一的电子邮件地址。
- 用户组:将多个用户分为一组,给组地址(也是一个电子邮件地址)发邮件,该组的所有用户都会收到。
# 邮件协议
常见的邮件协议如下,它们都属于应用层协议。
- 简单邮件传输协议(Simple Mail Transfer Protocol ,SMTP):用于发送邮件到邮件服务器,只能发送纯 ASCII 码文本。
- 采用 C/S 架构,默认使用 TCP 25 端口。
- MIME 是 SMTP 协议的一个扩展,使它能够发送非 ASCII 码的内容(包括汉字、二进制文件、音视频文件)。
- 邮局协议(Post Office Protocol ,POP):用于从邮件服务器拉取邮件。
- 采用 C/S 架构,默认使用 TCP 110 端口。
- 目前通常使用 POP3 版本。
- 因特网邮件访问协议(Internet Mail Access Protocal ,IMAP):用于从邮件服务器拉取邮件。
- 比 POP 协议的功能更强,允许用户在下载邮件之前查看邮件的首部、检索邮件的内容、将客户端邮箱的状态同步到服务器。
- 采用 C/S 架构,默认使用 TCP 143 端口。
- 目前通常使用 IMAP4 版本。
一般的邮件收发流程:
- 发送方的用户启动邮箱软件(此时是作为 SMTP 客户端),将邮件发送到 SMTP 服务器。
- SMTP 服务器将邮件转发到 POP 服务器或 IMAP 服务器。
- 接收方的用户启动邮箱软件,通过 POP 或 IMAP 协议从服务器拉取邮件。
# import smtplib
:Python 的标准库,提供了 SMTP 客户端的功能。
例:
import smtplib
from email.header import Header
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
# 连接到 SMTP 服务器
# server = smtplib.SMTP(host="localhost", port=25) # 连接到 SMTP 服务器
server = smtplib.SMTP_SSL(host="smtp.163.com", port=994, timeout=3) # 基于 SSL 协议连接到 SMTP 服务器
server.set_debuglevel(1) # 显示与 SMTP 服务器的详细通信过程,便于调试
server.login("[email protected]", "******") # 登录
# 创建邮件
email = MIMEMultipart()
email["From"] = Header("python smtplib", "utf-8") # 发送者
email["To"] = Header("Leo", "utf-8") # 设置邮件显示的接收者,不过实际的接收者取决于给 server.sendmail() 输入的 to_addrs 参数
# email["To"] = Header("Leo", "utf-8") # 可以多次执行该语句,在邮件中附加多个接收者
email["Subject"] = Header("这是一封测试邮件", "utf-8") # 标题
content = "Python 邮件发送测试..."
email.attach(MIMEText(content, "plain", "utf-8")) # 添加一段邮件内容(可以添加多段)
# 将内容类型设置为"html",就可以发送 HTML 格式的文本
# 上传附件(可照这样 attach 多个附件)
with open("1.jpg", "rb") as f:
attachment = MIMEApplication(f.read())
attachment.add_header("Content-Disposition", "attachment", filename="1.jpg")
email.attach(attachment)
# 发送邮件
try:
sender = "[email protected]" # 发送方,填一个有效的邮箱地址
receiver = "[email protected]" # 接收方,是一个邮箱地址,或者是一个包含多个邮箱地址的 list
server.sendmail(sender, receiver, email.as_string())
finally:
server.quit() # 关闭连接
# import smtpd
:Python 的标准库,可用于运行一个简单的 SMTP 服务器。
例:
import asyncore
import smtpd
class CustomSMTPServer(smtpd.SMTPServer):
def process_message(self, peer, mailfrom, rcpttos, data, **kwargs): # 重载处理邮件的方法
print("\n\n# Received email")
print("From: ", mailfrom, peer)
print("To: ", rcpttos)
print("raw_data: ", data)
server = CustomSMTPServer(("127.0.0.1", 25), None) # 创建 SMTP 服务器,设置监听的 IP 和端口
asyncore.loop() # 异步循环运行
# import poplib
:Python 的标准库,提供了 POP 客户端的功能。
- 官方文档 (opens new window)
- 下载邮件之后,通常还要通过 email 模块解析邮件的内容。
- 邮件可能有多种 Content-Type ,比如附件、嵌套的回复邮件,需要分别解析,比较麻烦。
例:
server = poplib.POP3_SSL(host="pop.163.com", port=995, timeout=3) # 连接到 POP 服务器
server.user("[email protected]")
server.pass_("******")
res, _list, octets = server.list() # 获取服务器上的邮件列表(只是每个邮件的序号加邮件大小)
res, raw_data, octets = server.retr(i) # 下载服务器上的第 n 条邮件(raw_data 是 bytes 类型)
server.dele(n) # 删除服务器上的第 n 条邮件
server.quit() # 断开连接