17.5、收发电子邮件
自从互联网诞生那一刻起,人们之间日常交互的方式又多了一种新的渠道。从此以后,交流变得更加迅速快捷,更具有实时性。一时之间,很多网络通信产品出现在人们面前,例如QQ、MSN和邮件系统,其中电子邮件更是深受人们的追捧。使用Python语言可以开发出功能强大的邮件系统。本节将详细讲解使用Python语言开发邮件系统的过程。
17.5.1、开发POP3邮件协议程序
在计算机应用中,使用POP3协议可以登录Email服务器收取邮件。在Python程序中,内置模块poplib提供了对POP3邮件协议的支持。现在市面中大多数邮箱软件都提供了POP3收取邮件的方式,例如Outlook等Email客户端就是如此。开发者可以使用Python语言中的poplib模块开发出一个支持POP3邮件协议的客户端脚本程序。
在poplib模块中,可以使用类POP3创建一个POP3对象实例。其语法格式如下所示。
POP3 (host, port) |
" 参数host:POP3邮件服务器。
" 参数port:服务器端口,一个可选参数,默认值为110。
在poplib模块中,常用的内置方法如下所示。
(1)方法user()。
当创建一个POP3对象实例后,可以使用其中的方法user()向POP3服务器发送用户名。其语法格式如下所示。
user (username) |
参数username表示登录服务器的用户名。
(2)方法pass_()。
可以使用POP3对象中的方法pass_()(注意,在pass后面有一个下划线字符)向POP3服务器发送密码。其语法格式如下所示。
pass- (password) |
参数password是指登录服务器的密码。
(3)方法getwelcome()。
当成功登录邮件服务器后,可以使用POP3对象中的方法getwelcome()获取服务器的欢迎信息。其语法格式如下所示。
getwelcome() |
(4)方法set_debuglevel()。
可以使用POP3对象中的方法set_debuglevel()设置调试级别。其语法格式如下所示。
set_debuglevel (level) |
参数level表示调试级别,用于显示与邮件服务器交互的相关信息。
(5)方法stat()。
使用POP3对象中的方法stat()可以获取邮箱的状态,例如邮件数、邮箱大小等。其语法格式如下所示。
stat() |
(6)方法list()。
使用POP3对象中的方法list()可以获得邮件内容列表。其语法格式如下所示。
list (which) |
参数which是一个可选参数,如果指定,则仅列出指定的邮件内容。
(7)方法retr()。
使用POP3对象中的方法retr()可以获取指定,的邮件。其语法格式如下所示。
retr (which) |
参数which用于指定要获取的邮件。
(8)方法dele()。
使用POP3对象中的方法dele()可以删除指定的邮件。其语法格式如下所示。
dele (which) |
参数which用于指定要删除的邮件。
(9)方法top()。
使用POP3对象中的方法top()可以收取某个邮件的部分内容。其语法格式如下所示。
top (which,howmuch) |
" 参数which:指定获取的邮件。
" 参数howmuch:指定获取的行数。
除了上面介绍的常用内置方法外,还可以使用POP3对象中的方法rset()清除收件箱中邮件的删除标记;使用POP3对象中的方法noop()保持同邮件服务器的连接;使用POP3对象中的方法quit()断开同邮件服务器的连接。
下面的实例代码演示了使用poplib库获取指定邮件中的最新两封邮件的主题和发件人的过程。
实例17-6 获取指定邮件中的最新两封邮件的主题和发件人
源码路径 daima\17\17-6
要想使用Python获取某个Email邮箱中邮件主题和发件人的信息,首先应该知道自己所使用的Email的POP3服务器地址和端口。一般来说,邮箱服务器的地址格式如下。
pop.主机名.域名
而端口的默认值是110,例如126邮箱的POP3服务器地址为pop.126.com,端口为默认值110。本实例文件pop.py的具体实现代码如下所示。
from poplib import POP3 #导入内置邮件处理模块 import re,email,email.header #导入内置文件处理模块 from p_email import mypass #导入内置模块 def jie(msg_src,names): #定义解码邮件内容的函数jie() msg = email.message_from_bytes(msg_src) result = {} #变量初始化 for name in names: #遍历name content = msg.get(name) #获取name info = email.header.decode_header (content) #定义变量info if info[0][1]: if info[0][1].find('unknown-') == -1: #如果是已知编码 result[name] = info[0][0].decode(info[0][1]) else: #如果是未知编码 try: #异常处理 result[name] = info[0][0].decode('gbk') except: result[name] = info[0][0].decode('utf-8') else: result[name] = info[0][0] #获取解码结果 return result #返回解码结果 if __name__ == "__main__": pp = POP3("pop.sina.com") #实例化邮件服务器类 pp.user('guanxijing820111@sina.com') #传入邮箱地址 pp.pass_ (mypass) #密码设置 total,totalnum = pp.stat() #获取邮箱的状态 print(total,totalnum) #显示统计信息 for i in range(total-2,total): #遍历获取最近的两封邮件 hinfo,msgs,octet = pp.top(i+1,0)#返回bytes类型的内容 b=b'' for msg in msgs: #遍历msg b += msg+b'\n' items = jie(b,['subject','from']) #调用函数jie()返回邮件主题 print(items['subject'],'\nFrom:',items['from'])#调用函数jie()返回发件人的信息 print() #显示空行 pp.close() #关闭连接 |
在上述实例代码中,函数jie()的功能是使用email包来解码邮件头,用POP3对象的方法连接POP3服务器并获取邮箱中的邮件总数。在程序中获取最近的两封邮件的邮件头,然后传递给函数jie()进行分析,并返回邮件的主题和发件人的信息。执行效果如图17-8所示。
17.5.2、开发SMTP邮件协议程序
SMTP即简单邮件传输协议,是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。在Python语言中,通过smtplib模块对SMTP协议进行了封装,通过这个模块可以登录SMTP服务器发送邮件。有两种使用SMTP协议发送邮件的方式。
" 第一种:直接投递邮件,比如要发送邮件到邮箱aa*@163.com,就直接连接163.com的邮件服务器,把邮件发送给aa*@163.com。
" 第二种:验证通过后的发送邮件,如果要发送邮件到邮箱aa*@163.com,不是直接发送到163.com,而是通过自己在sina.com中的另一个邮箱来发送。这样就要先连接sina.com中的SMTP服务器,然后进行验证,之后把要发送到l63.com的邮件投到sina.com上,sina.com会帮我们把邮件发送到163.com。
在smtplib模块中,使用类SMTP可以创建一个SMTP对象实例。具体语法格式如下所示。
import smtplib smtpObj = smtplib.SMTP(host , port , local_hostname) |
各个参数的具体说明如下所示。
" host:表示SMTP 服务器主机,可以指定主机的IP地址或者域名,例如w3cschool.cc,这是一个可选参数。
" port:如果提供了 host 参数,需要指定 SMTP 服务使用的端口号。在一般情况下,SMTP端口号为25。
" local_hostname:如果SMTP在本机上,只需要指定服务器地址为localhost 即可。
在smtplib模块中,比较常用的内置方法如下所示。
(1)方法connect()。
在Python程序中,如果在创建SMTP对象时没有指定host和port,可以使用SMTP对象中的方法connect()连接到服务器。方法connect()的语法格式如下所示。
connect (host, port)
" host:连接的服务器名,可选参数。
" port:服务器端口,可选参数。
(2)方法login()。
在SMTP对象中,方法login()的功能是可以使用用户名和密码登录SMTP服务器。其语法格式如下所示。
login(user, password)
" user:登录服务器的用户名。
" password:登录服务器的密码。
(3)方法set_debuglevel()。
使用SMTP对象的方法set_debuglevel()可以设置调试级别。其语法格式如下所示。
set_debuglevel (level)
参数"level"是指设定的调试级别。
(4)方法docmd()。
使用SMTP对象中的docmd()可以向SMTP服务器发送命令。其语法格式如下所示。
docmd (cmd, argstring)
" cmd:向SMTP服务器发送的命令。
" argstring:一个命令参数,可选参数。
(5)方法sendmail()。
使用SMTP对象中的sendmail()可以发送邮件。其语法格式如下所示。
sendmail(from_addr, to_addrs, msg, mail_options, rcpt_options)
" from_addr:发送者邮件地址。
" to_ addrs:接收者邮件地址。
" msg:邮件内容。
" mail_options:可选参数,邮件ESMTP操作。
" rcpt_options:可选参数,RCPT操作。
(6)方法quit()。
使用SMTP对象中的方法quit()可以断开与服务器的连接。
下面的实例代码演示了向指定邮箱发送邮件的过程。
实例17-7 向指定邮箱发送邮件
源码路径 daima\17\17-7
当使用Python语言发送Email邮件时,需要找到所使用Email的SMTP服务器的地址和端口。对于新浪邮箱,其SMTP服务器的地址为smtp.sina.com,端口默认值为25。为了防止邮件被反垃圾邮件丢弃,这里采用前文提到的第二种方法,即登录认证后再发送。实例文件sm.py的具体实现代码如下所示。
import smtplib,email #导入内置模块 from p_email import mypass #导入内置模块 #使用email模块构建一封邮件 chst = email.charset.Charset(input_charset= 'utf-8') header = ("From: %s\nTo: %s\nSubject: %s\n\n" #邮件主题 % ("guanxijing820111@sina.com", #邮箱地址 "好人" , #收件人 chst.header_encode("Python smtplib 测试!"))) #邮件头 body = "你好!" #邮件内容 email_con = header.encode('utf-8') + body.encode('utf-8')#构建邮件完整内容,中文编码处理 smtp = smtplib.SMTP("smtp.sina.com") #邮件服务器 smtp.login("guanxijing820111@sina.com",mypass)#用户名和密码登录邮箱 #开始发送邮件 smtp.sendmail("guanxijing820111@sina.com","37197248*@qq.com",email_con) smtp.quit() #退出系统 |
在上述实例代码中,使用新浪的SMTP服务器邮箱guanxijing820111@sina.com发送邮件,收件人的邮箱地址是37197248*@qq.com。首先使用email.charset.Charset()对象对邮件头进行编码,然后创建SMTP对象,并通过验证的方式给37197248*@qq.com发送一封测试邮件。因为在邮件的主体内容中含有中文字符,所以使用encode()函数进行编码。执行后的效果如图17-9所示。
相关阅读:
版权声明:51Testing软件测试网获人民邮电出版社和作者授权连载本书部分章节。
任何个人或单位未获得明确的书面许可,不得对本文内容复制、转载或进行镜像,否则将追究法律责任。