全文约3900字,包含6幅图片,阅读时间约10分钟。
从对Python的imap、smtp邮件处理模块的介绍谈起,聊到了:
(1) 如何利用Python的邮件处理模块+网页爬虫,做一个你感兴趣的网站内容更新监控工具,每隔一段时间自动检测你收藏的 小说、博客、论文期刊、开源站点等网站是否有更新,将内容的更新信息通过邮件通知你。
(2) 基于邮件的在线PPP服务系统开发。从附件获取用户发送过来的观测值文件,做PPP解算,绘图显示、生成报告并用邮件发送给用户。
希望对有相关需求、爱好技术的你有所启发。
如同旧时代的纸质信件一样,在互联网时代,电子邮件成为了我们广泛使用的基础工具之一。人人都有一个甚至多个电子邮件。那么除了最基本的信息交流功能之外,电子邮件还能被我们用来做些什么呢?
公司里面,运维系统会实时监控系统运行状态,将异常和预警信息通过邮件、微信、短信等报告给系统负责人;
生活中,你或许想每天自动收集感兴趣的网站的信息,当有新信息时邮件通知自己;
科研中,或许你想提供这样一种服务——通过邮件接收用户文件,进行数据处理,再将结果和报告送达用户;
……
还有很多其他基于电子邮件的有趣应用等着你去发掘。
本文首先从Python的imap、smtp邮件处理模块谈起。再结合笔者的实践经验outlook邮箱登陆网页版,介绍了如何使用Python开发网站更新自动监控脚本,和GNSS PPP(精密单点定位)在线服务平台。
1 使用Python操作邮件
简单介绍
很多人都在使用邮件管理软件,如腾讯旗下的”Foxmail”,网易的”闪电邮”,微软的“Outlook”等等,不仅有PC端,也有移动端软件。以笔者使用的 Foxmail 为例,首先确认被管理邮箱已经打开了 POP3 / IMAP / SMTP 服务。
然后在 “账号管理” 菜单下输入邮箱地址、密码、收件服务器和发件服务器等信息,就可以将常用的邮箱管理起来。
上面的设置中涉及到了三种邮件有关的协议:POP3 / IMAP / SMTP。POP3全名为“Post Office Protocol – Version 3”,即“邮局协议版本3”,主要用于支持使用客户端远程管理在服务器上的电子邮件。IMAP的全称是 “Internet Mail Access Protocol”,意为 Internet 邮件访问协议,主要用来收取和下载电子邮件;SMTP 的全称是 “Simple Mail Transfer Protocol”,意为简单邮件传输协议,主要用来发送电子邮件。
简单地说,POP3/IMAP管‘收’,SMTP管‘发’。POP3协议允许电子邮件客户端下载服务器上的邮件,但是在客户端的操作(如移动邮件、标记已读等),不会反馈到服务器上。比如通过客户端收取了邮箱中的3封邮件并移动到其他文件夹,邮箱服务器上的这些邮件是没有同时被移动的 。
而IMAP提供webmail 与电子邮件客户端之间的双向通信,客户端的操作都会反馈到服务器上,对邮件进行的操作,服务器上的邮件也会做相应的动作。IMAP 因为其交互性逐渐取代了POP3成为了邮件服务器与客户端的交互选项。因此,收件服务我们通常选择IMAP。
Python的IMAP和SMTP模块
Python的2和3安装包都自带imaplib、smtplib和email库,用户无需额外安装。其处理邮件的基本思路与 Foxmail 等软件类似,需要用户提供邮箱地址、密码,设置收件和发件服务器信息。接着就可以遍历读取收件箱里的邮件,下载附件,也可以写好标题和内容后,向指定的邮箱发送邮件。
下面的例子给出了如何用 Python 的上述三个库,实现电子邮件和收取和发送。
'''
环境:
Win7 64位 Python 3.7.4
参考:
https://docs.python.org/3/library/smtplib.html
https://docs.python.org/3/library/imaplib.html
https://www.cnblogs.com/lsdb/p/9419036.html
https://www.docs4dev.com/docs/zh/python/3.7.2rc1/all/library-imaplib.html
'''
import smtplib
import imaplib
from email.mime.text import MIMEText
from email.header import Header
# 此函数通过使用smtplib实现发送邮件
def send_email_by_smtp():
sender_email_address = "xxxxxx@gmail.com"
sender_email_password = "xxxxxxxxxxxxxxxx"
smtp_server_host = "smtp.gmail.com" # 用于发送邮件的邮箱的smtp服务器地址
smtp_server_port = 465 # 修改成自己邮箱的sntp服务器监听的端口
receiver_email = "yyyyyy@qq.com" # 要发往的邮箱
message_subject = "Python smtp测试邮件"
message_context = "这是一封通过Python smtp发送的测试邮件..."
message = MIMEText(message_context, 'plain', 'utf-8') # 邮件对象,用于构建邮件
message["From"] = Header(sender_email_address, "utf-8")
message["To"] = Header(receiver_email, "utf-8")
message["Subject"] = Header(message_subject, "utf-8")
# 连接smtp服务器。如果没有使用SSL,将SMTP_SSL()改成SMTP()即可
email_client = smtplib.SMTP_SSL(smtp_server_host, smtp_server_port)
try:
# 验证邮箱及密码是否正确
email_client.login(sender_email_address, sender_email_password)
print("smtp----login success, now will send an email to receiver_email")
except:
print("smtp----sorry, username or password not correct or another problem occur")
else:
email_client.sendmail(sender_email_address, receiver_email, message.as_string()) # 发送邮件
print(f"smtp----send email to {receiver_email} finish")
finally:
email_client.close() # 关闭连接
# 此函数通过使用imaplib实现接收邮件
def recv_email_by_imap4():
email_address = "xxxxxx@gmail.com"
email_password = "xxxxxxxxxxxxxxxx"
imap_server_host = "imap.gmail.com" # 邮箱对应的imap服务器
imap_server_port = 993 # 邮箱对应的pop服务器的监听端口
email_server = ''
try:
# 连接imap服务器。如果没有使用SSL,将IMAP4_SSL()改成IMAP4()即可其他都不需要做改动
email_server = imaplib.IMAP4_SSL(host=imap_server_host, port=imap_server_port)
print("imap4----connect server success, now will check username")
except:
print("imap4----sorry the given email server address connect time out")
exit(1)
try:
email_server.login(email_address, email_password) # 验证邮箱及密码是否正确
print("imap4----username exist, now will check password")
except:
print("imap4----sorry the given email address or password seem do not correct")
exit(1)
# 邮箱中其收到的邮件的数量
email_server.select()
email_count = len(email_server.search(None, 'ALL')[1][0].split())
# 通过fetch(index)读取第index封邮件的内容;这里读取最后一封,也即最新收到的那一封邮件
typ, email_content = email_server.fetch(f'{email_count}'.encode(), '(RFC822)')
email_content = email_content[0][1].decode() # 将邮件内存由byte转成str
print(email_content)
email_server.close() # 关闭select
email_server.logout() # 关闭连接
if __name__ == "__main__":
# 调用通过smtp发送邮件的发送函数
send_email_by_smtp()
# 调用通过imap4接收邮件的接收函数
recv_email_by_imap4()
题外篇:Foxmail、张小龙和雷军的小故事
同是1969年出生的张小龙和雷军,分别来自洞庭湖两岸的湖南与湖北,大学时分别就读于武汉的两所相互争辉的高等学府——华中科技大学和武汉大学。两人都才华横溢,看似相似的人生经历却演化出完全不同的人生轨迹。
张小龙早年成名源于Foxmail,这款邮件客户端软件在短短四年间就吸引了200万用户,深受当时用户的好评,也一度与微软Outlook并行,并且被美国最知名的科技网站ZDnet评为5星软件。
早在1998年,雷军十分看好这款软件,两个人联系协商之后决定以15万元的价格完成交易,并打算邀请张小龙去珠海金山商谈具体细节。但可惜的是,因为当时雷军刚刚上任金山总经理一职,事务比较繁忙,派去和张小龙洽谈的研发人员不了解这款产品的价值。觉得这么个软件,金山用1-2个月也能做出来。后来这事就不了了之了。最后Foxmail在2000年4月被博大公司以1200万元收购,又于2005年3月最终被腾讯公司收购。而张小龙也随之加入了腾讯,负责并带领QQ邮箱团队。
这件事也一直被雷军称为是自己最遗憾的事之一。
多年后,两个人的命运再一次发生碰撞,则是在移动互联网的战场上直接交锋,小米米聊 vs 腾讯微信,成就的又是另一段精彩的故事。
参考:吴晓波《腾讯传》;
参考:维基百科;
2 应用一:网站更新监控
读书期间,笔者几乎每天都会打开几个特别关注的网站进行浏览。一个是某开源软件网站,笔者在科研中深度用到了该开源代码,因此特别关注作者是否开发了新的版本,或是报告了新的bugs。一个是某大牛日志网站,作者不定期,一般每1、2天,会分享一些他的软件开发、阅读论文、数据处理、行业动态方面的一些心得体会。笔者从中获益颇多。
后来笔者关注的网站越来越多——想扩宽视野,瞅瞅计算机视觉方面的网站,如OpenCV官网;想向更多大佬学习技术,就瞧瞧他们的博客;还有想及时了解科研动态,就打开多个期刊网站,看看最新刊出了哪些文章。
动机
这些网站有些有RSS订阅功能,有些没有。为了更灵活、更自动地发现这些网站的更新内容,笔者于是决定用Python开发自己的网站自动监控小助手。
技术要求
没错,思路就是这么简单。Python为我们提供了丰富且强大的基础功能模块,用户可以像搭积木一样方便快速地实现自己的需求。
相关截图
上面是一个样例配置文件的截图,里面有10+网站的网址,给哪几个邮件地址发送通知,设置的定时检查的时间间隔,还有网页上需要被过滤的标签等等信息。下面这幅图则是笔者在2019年4月9日收到的小助手发过来的邮件,显示OpenCV软件发布了最新4.1版本。
3 应用二:在线PPP服务
有一些科研机构提供在线数据处理服务,如CSRS-PPP、magicGNSS、GAPS、AUSPOS等,用户通过网页或邮箱上传GNSS观测值文件,对方就会在一段时间后,将处理结果和解算报告邮件发送给用户。邮件处理和定位软件是系统中重要的两个组成部分。
AUSPOS是笔者使用较多的服务创业项目,其调用著名的bernese软件outlook邮箱登陆网页版,自动寻找临近的IGS站点做静态网解,定位精度和可靠性很高。笔者也常用CSRS-PPP、magicGNSS的在线PPP服务,用于和自己计算的结果进行比较。
动机
开发此服务的动机,一是 “Just For Fun”。二是毕竟是工科男,还是希望自己的算法和程序能被更多人使用到,产生更大的价值。所以在空闲时间练手,初步实现了这样一套系统。
技术要求
没错,思路也是这么简单。
系统简介
以 “Static” 或 “Kinematic” 为主题,附上你的观测值文件(数量不超过10个),发送邮件到 “fox_0124@foxmail.com”。系统将对观测值进行事后最小二乘PPP解算,并将定位结果与报告文件发送给你。报告如下图所示:
PPP程序的基本特性有:(1) 支持GRECJ五大系统;(2) 双频观测值,无电离层组合模型;(3) 支持Rinex 2、3格式;(4) 使用GBM精密产品;(5) GMF投影函数+分段线性估计对流层延迟;(6) 支持估计GLONASS伪距频间偏差;(7) ……
(其实软件支持更多特性,如非差非组合模型,三频联合处理,无电离层组合与非差非组合的模糊度固定PPP-AR等等。在邮件服务系统中不方便设置,便固定为了最常用的双频无电离层组合观测模型,模糊度浮点解。后续有机会可以增加网页端的支持,这样就可以提供更多的参数选项了。)
如果大家有兴趣,欢迎多多使用。如果有什么意见和建议,可以发送邮件到上面的邮箱。大家用得越多,笔者就越有动力完善下去。