Python实现邮件自动收发
前言
邮件是信息传递的一种很有效的方式,我们只需知道对方的邮箱地址,就可以给对方传文字、图片或者更复杂的信息。今天就用 Python 带大家来实现邮件的自动收发。 准备工作
在我们收发邮件时,需要输入邮箱和邮箱密码。但是直接使用密码会有安全隐患,所以我们选择用授权码登陆。
这个工作并非必要的,只是出于安全考虑。这里使用 163 邮箱进行收发,我们先登录自己的邮箱:https://mail.163.com/。登录后会看到如下页面:
我们点击设置->POP3 就可以开启 IMAP/SMTP 服务。按照提示要求发送验证码就可以获取授权码了,这个授权码需要我们记住。 使用 yagmail+keyring 进行邮件的发送
我们可以选择 Python 自带的 email 模块进行邮件的发送,但是操作起来会比较麻烦。所以在这里我们使用一个第三方模块 yagmail 来实现邮件的发送。而 keyring 模块可以和 yagmail 结合起来,保存密码信息。我们先来安装这两个模块: pip install yagmail pip install keyring
接下来我们看看 yagmail 如何发送邮件: import yagmail import keyring user = "你的邮箱" pwd = "你的授权码" ### 注册 yagmail.register(user, pwd) ### 连接 SMTP 服务器 yag = yagmail.SMTP(user=user, host="smtp.163.com") ### 设置邮件的内容 contents = [ "这是一封测试邮件" ] ### 发送邮件 yag.send("收件邮箱", "邮件主题", contents=contents)
在上面我们发送了一封简单的邮件。我们分了一下几个步骤: 注册邮箱 连接邮箱服务器 设置邮件内容 发送邮件
我们使用 register 方法进行注册。注册后我们就可以在 keyring 中获取我们的授权码了。
然后我们用 SMTP 方法连接邮箱服务器。因为我们使用的是 163 邮箱,所以也需要用 163 的服务器。我们把 host 设置为 163 的 ip,如果使用的是其它邮箱可以在设置中查看 SMTP 邮箱服务器 ip。
之后是设置邮件内容,内容是以列表的形式存放的。
最后调用 send 方法,传入收件人的邮箱和邮件主题,以及邮件内容就可以完成邮件的发送了。 发送图片邮件
传统的邮件发送图片我们需要先手动将图片上传到邮箱服务器,然后获取一个值后才能进行发送。而 yagmail 在这方面做了一些优化,我们不需要自己上传图片,只需要用 yagmali.inline() 包含图片路径就可以了。 import yagmail import keyring user = "你的邮箱" pwd = "你的授权码" ### 注册 yagmail.register(user, pwd) ### 连接 SMTP 服务器 yag = yagmail.SMTP(user=user, host="smtp.163.com") ### 设置邮件的内容 contents = [ "这是一张图片", yagmail.inline("im.jpg") ] ### 发送邮件 yag.send("收件邮箱", "邮件主题", contents=contents)
仔细一看,我们几乎没有额外添加什么代码。只是在内容里放了一个文件的名称,我们只需要这样就能实现图片的发送。
准确来说应该是放入图片的路径,但是我图片和 py 文件在同一目录下,所以不需要额外写根目录。 发送带有附件邮件
附件的发送同样不需要我们上传文件,我们只需要给一个文件路径就可以了。 import yagmail import keyring user = "你的邮箱" pwd = "你的授权码" ### 注册 yagmail.register(user, pwd) ### 连接 SMTP 服务器 yag = yagmail.SMTP(user=user, host="smtp.163.com") ### 设置邮件的内容 contents = [ "这是一张图片", "im.jpg" ] ### 发送邮件 yag.send("收件邮箱", "邮件主题", contents=contents)
而上传附件就更加简单,我们直接传入图片的路径就好了。
yagmail 会判断你的内容中是否包含了文件,如果包含了文件它就会自动上传然后发送给收件人。免去了我们大量的工作。 读取邮件
邮件的读取需要通过 imBox 模块实现,读取的时候我们肯定是需要密码的。这个时候 keyring 就起作用了,我们在注册的时候就把用户和密码存储了,然后即使我们的程序已经结束了,还是可以读取到密码,我们来看看代码怎么写: import keyring from imbox import Imbox ### 邮件 user = "你的邮箱" ### 获取密码 password = keyring.get_password("yagmail", user) ### 打开收件箱 with Imbox("imap.163.com", user, password, ssl=True) as imbox: msgs = imbox.messages()
其中 msgs 就是我们的邮件列表。但是我们通常是读取未读邮件,我们就可以进行一下简单的设置: import keyring from imbox import Imbox user = "你的邮箱" password = keyring.get_password("yagmail", user) with Imbox("imap.163.com", user, password, ssl=True) as imbox: msgs = imbox.messages(unread=True)
我们把 unread 属性设置为 True,就表示读取未读邮件。接下来我们来遍历一下邮箱: import keyring from imbox import Imbox user = "你的邮箱" password = keyring.get_password("yagmail", user) with Imbox("imap.163.com", user, password, ssl=True) as imbox: ### 读取未读邮件 msgs = imbox.messages(unread=False) ### 遍历邮件 for uid, msg in msgs: ### 把读到的邮件设置为已读 imbox.mark_seen(uid) ### 把邮件内容以文本的形式输出 print(msg.body["plain"])
在邮件中包含了一个独一无二的 id,我们用这个 id 来区分邮件。我们读取到某个邮件后,可以通过它的 id 将它设置为已读。然后输出邮件的 body["plain"],就是将邮件内容以文本的形式输出。 定时读取邮件
邮件的定时读取并不是什么难题,我们可以使用 schedule 模块,操作起来比较方便。也可以选择使用 time 模块,个人认为 time 模块更好理解: import time import keyring from imbox import Imbox user = "你的邮箱" password = keyring.get_password("yagmail", user) while True: with Imbox("imap.163.com", user, password, ssl=True) as imbox: msgs = imbox.messages(unread=False) for uid, msg in msgs: imbox.mark_seen(uid) print(msg.body["plain"]) time.sleep(10)
这里只加了几句代码,首先是把读取邮件部分的代码放到了 while 循环中,然后在每次循环结束前都延时 10 秒,这样就达到了没 10 秒读取一次邮件的效果。总体来说还是非常简单的。