Python 邮箱服务

最近在封装一些自己用的通讯服务,例如有短信/邮件/Slack 这些,但是,在编写邮件的时候突然发现自己以前都是只使用了邮件的发送功能,也就是简单得通过 smtplib 来发送的,但是,好像收邮件就没有那么简单了,发现收邮件有 POP3 和 IMAP 两种协议比较常用,虽然这两个名字都很熟悉,但是,说不上来有啥区别,分别是啥特点,所以需要小结一番。

邮件的操作出了 SMTP/POP3/IMAP 这些协议之外,还有其他同步方式,例如 Exchange Activesync,据说这是一种 Microsoft Exchange 同步协议,可以同步移动设备的邮件、通讯录等,但是,我觉得我平时用的业务场景应该还不会用到这个,所以就先忽略。

SMTP

SMTP 的全称是 Simple Mail Transfer Protocol(简单邮件传输协议),它是一个简单的基于文本的应用层协议,有一个很重要的特点那就是它是一个"推"的协议,也就是说它不能远程服务器上"拉"消息,因此通常用于发送邮件,而且是交互式的。SMTP 服务器通常运行在 25 端口,早期的 SMTP 是没有验证发件人的功能的,后期增加了 SMTP-AUTH 扩展。

SMTP 协议因为是基于文本的,所以我们可以很简单得通过 telnet 来操作,例如下面这个发送一个邮件的例子:

这里我们可以看到 Line 4 里面,我们可以制定发送的邮箱,当别人收到之后,显示的发送者就是这个邮箱,这就带来了一个问题,那就是可以 伪造发件人,这是一件大事情啊,不过好像现在我用的几个邮箱系统都没有这个问题了,例如 QQ 邮箱,它就拒绝发件人和登录用户不一致的邮件,不过这个问题的解决办法好像不是 SMTP 做的,所以我就先不深入了,真的有需要再继续吧。

提到 SMTP 有个东西很重要,那就是 MX 记录,在域名的设置的时候我们会看到有一个 MX 记录,当我们发送邮件的时候,邮件客户端得知道它要和哪个服务器建立 SMTP 连接呀,其实 MX 记录就是 DNS 记录的一种子类型,就是将邮箱后缀名转换成 IP 的纪录。

但是,SMTP 也有一个很致命得缺点,那就是前面说的它是基于ASCII文本的,所以当我们要发送非 ASCII 字符,或者图片/视频这些的时候就很尴尬了。为了解决这个问题,SMTP 曾经做过一些改变

  1. 在头部字段中添加编码格式
  2. 正文作了邮件扩充(MIME)

其实就是将邮件正文分割成一块一块,然后每一块都在自己头部定义 MIME 信息,然后在后面加上自己的内容,这样就支持了各种类型的信息了,所以我们可以在后面看到,解析邮件的时候就比较蛋疼了。

POP3/IMAP

POP 和 IMAP 类似,都是重邮件服务器上获取邮件信息和下载邮件用的协议。

  • POP允许电子邮件客户端下载服务器上的邮件,但是您在电子邮件客户端的操作(如:移动邮件、标记已读等),这是不会反馈到服务器上的。
  • 但是IMAP就不同了,电子邮件客户端的操作都会反馈到服务器上,您对邮件进行的操作,服务器上的邮件也会做相应的动作。也就是说,IMAP是“双向”的。

这是一个比较大的区别,另外一个区别就是:

  • IMAP 可以只下载邮件的主题,只有当您真正需要的时候,才会下载邮件的所有内容
  • POP 直接把所有邮件都下下来了

Python 示例

SMTP 发送邮件(Python3)

POP3 收邮件

IMAP 收邮件

Reference

  1. Exchange top features
  2. SMTP——简单邮件传输协议
  3. MIME——多用途互联网邮件扩展

· EOF ·

最近爬虫很是凶猛,标注下文章的原文地址: https://liuliqiang.info/post/mail-operation-in-python/