Python 使用Python语言收发电子邮件
自从互联网诞生那一刻起,人们之间日常交互的方式便又多了一种新的渠道。从此以后,交流变得更加迅速快,更具有实时性。一时之间,很多网络通信产品出现在大家面前,例如 QQ、MSN和邮件系统,其中电子邮件更是经常被人们使用。使用Python语言可以开发出功能强大的邮件系统,在本节的内容中,将详细讲解使用Python语言开发邮件程序的过程。
一、开发POP3邮件程序
在计算机应用中,使用 POP3 协议可以登录E-mail 服务器收取邮件。在 Python程序中,内置模块poplib提供了对 POP3邮件协议的支持。现在市面中大多数邮箱软件都提供了POP3收取邮件的方式,例如 Outlook 等E-mail客户端就是如此。开发者可以使用 Python语言中的poplib模块开发出一个支持POP3邮件协议的客户端脚本程序。
1.类
在poplib模块中,通过如下所示的两个类实现POP3功能。
(1)类 poplib.POP3 (host,port=POP3_ PORT[,timeout]):实现了实际的POP3协议,当实例初始化时创建连接。
● 参数port:如果省略port 端口参数,则使用标准 POP3端口(110)。
● 参数timeout:可选参数timeout 用于设置连接超时的时间,以秒为单位。如果未指定,将使用全局默认超时值。
(2)类poplib.POP3_SSL(host, port=POP3_SSL_PORT, keyfile=None, certfile=None, timeout=None,context=None):是POP3的子类,通过SSL 加密的套接字连接到服务器。
● 参数port: 如果没有指定端口参数port,则使用标准的POP3 over SSL端口。
● 参数timeout: 超时的工作方式与上面的POP3构造函数中的相同。
● 参数context: 上下文对象,是可选的ssl.SSLContext对象,允许将SSL 配置选项,证书和私钥捆绑到单个(可能长期)结构中。
● 参数keyfile 和 certfile: 是上下文的传统替代方式,可以分别指向SSL的 PEM格式的
私钥和证书链文件连接。
在 Python程序中,可以使用类POP3创建一个POP3对象实例。其语法原型如下所示:
POP3 (host, port)
● 参数host: POP3邮件服务
● 参数port: 服务器端口,一个可选参数,默认值为110。
2.方法
在poplib模块中,常用的内置方法如下所示。
(1)方法user()
当创建一个POP3对象实例后,可以使用其中的方法user() 向POP3服务器发送用户名。其语法原型如下所示:
use (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 (whtch)
参数which用于指定要删除的邮件。
(9)方法top()
使用POP3对象中的方法top()可以收取某个邮件的部分内容。其语法原型如下所示:
top (which, howmuch)
● 参数which: 指定获取的邮件。
● 参数howmuch:指定获取的行数。
除了上面介绍的常用内置方法外,还可以使用POP3对象中的方法rset()清除收件箱中邮件的删除标记;使用POP3对象中的方法noop()保持同邮件服务器的连接;使用POP3对象中的方法quit()断开同邮件服务器的连接。
要想使用Python获取某个email邮箱中邮件主题和发件人的信息,首先应该知道自己所使用的email的POP3服务器地址和端口。一般来说, 邮箱服务器的地址格式如下所示:
pop.主机名.域名
而端口的默认值是110, 例如126邮箱的POP3服务器地址为pop.1214.com,端口为默认值110。
例如在下面的实例代码中,演示了使用poplib库获取指定邮件中的最新两封邮件的主题和发件人的方法。
from poplib import POP3 #导入内置邮件处理模块
import re,email,email.header #导入内置文件处理模块
def decode_email_content(msg_src,names): #定义解码邮件内容函数decode_email_content()
msg = email.message_from_bytes(msg_src) #email.message_from_bytes只可以在python 3中运行
result = { } #变量初始化
for name in names: #遍历name
content = msg.get(name) #获取name
info = email.header.decode_header(content) #解码
if info[0][1]:
print ('---------------------------------')
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("pop3.sina.com") #实例化邮件服务器类
pp.user('**********@sina.com') #传入邮箱地址(可更改)
pp.pass_('登录密码') #密码设置(邮箱的密码)
total,totalnum = pp.stat() #邮件的数量和邮件总的字节数
print (total,totalnum) #打印显示统计信息
for i in range(total-2,total): #遍历获取最近的两封邮件
hinfo,msgs,octet=pp.top(i+1,0) #得到指定邮件中的第一行内容(从0开始)
b=b'' #返回bytes类型的内容
for msg in msgs: #遍历msg
b += msg+b'\n'
items = decode_email_content(b,['subject','from']) #遍历函数返回邮件主题
print (items['subject'],'\nFrom:',items['from']) #调用函数返回收件人的信息
pp.quit() #关闭连接
在上述实例代码中,函数decode_email_content()的功能是使用email 包来解码邮件头,用POP3对象的方法连接POP3服务器井获取邮箱中的邮件总数。在程序中获取最近的两封邮件的邮件头,然后传递给函数decode_email_content()进行分析,并返回邮件的主题和发件人的信息。执行效果如图所示。
二、开发SMTP邮件程序
SMTP即简单邮件传输协议,是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。在Python语言中,通过模块smtplib对SMTP协议进行封装,通过这个模块可以登录SMTP服务器发送邮件。有两种使用SMTP协议发送邮件的方式。
(1)第一种:直接投递邮件,比如要发送邮件到邮箱aaa@163.com那么就直接连接163.com的邮件服务器,把邮件发送给aaa@163.com。
(2)第二种:验证通过后的发送邮件,如你要发送邮件到邮箱aaa@163.com,不是直接发送到163.com,而是通过自己在sina.com 中的另一个邮箱来发送。 这样就要先连接sina.com中的SMTP服务器,然后进行验证,之后把要发到163com的邮件投到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即可。
为了防止邮件被反垃圾邮件丢弃,这里采用前文中提到的第二种方法,即登录认证后再发送,例如下面的实例演示了这一用法。
import smtplib, email #导入内置模块
#使用email模块构建一封邮件
chst = email.charset.Charset(input_charset = 'utf-8')
header = ("From: %s\nTO: %s\nSubject: %s\n\n" #邮件主题
%("**********@sina.com", #邮箱地址
"********@qq.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('**********@sina.com','登录密码') #用户名和密码登邮箱
smtp.sendmail("**********@sina.com","********@qq.com",email_con)
smtp.quit() #退出系统
在上述实例代码中,使用新浪的SMTP服务器邮箱**********@sina.com发送邮件,收件人的邮箱地址是********@qq.com。首先使用email.charset.Charset()对象对邮件头进行编码,然后创建SMTP对象,并通过验证的方式给********@qq.com发送一封测试邮件 。因为在邮件的主体内容中含有中文字符,所以使用encode()函数进行编码。执行后的效果如图所示: