今天记录一下如何使用python收发邮件,知识要点在python内置的poplib和stmplib模块的使用上。
1. 准备工作
首先,我们需要有一个测试邮箱,我们使用新浪邮箱,而且要进行如下设置:
在新浪邮箱首页的右上角找到设置->更多设置,然后在左边选择“客户端/pop/imap/smtp”:
最后,将Pop3/smtp服务的服务状态打开即可:
2. poplib接收邮件
首先,介绍一下poplib登录邮箱和下载邮件的一些接口:
1
2
3
4
5
6
|
self .popHost = 'pop.sina.com'
self .smtpHost = 'smtp.sina.com'
self .port = 25
self .userName = 'xxxxxx@sina.com'
self .passWord = 'xxxxxx'
self .bossMail = 'xxxxxx@qq.com'
|
我们需要如上一些常量,用于指定登录邮箱以及pop,smtp服务器及端口。我们调用poplib的POP3_SSL接口可以登录到邮箱。
1
2
3
4
5
6
7
8
9
10
11
12
|
# 登录邮箱
def login( self ):
try :
self .mailLink = poplib.POP3_SSL( self .popHost)
self .mailLink.set_debuglevel( 0 )
self .mailLink.user( self .userName)
self .mailLink.pass_( self .passWord)
self .mailLink. list ()
print u 'login success!'
except Exception as e:
print u 'login fail! ' + str (e)
quit()
|
在登录邮箱的时候,很自然,我们需要提供用户名和密码,如上述代码所示,使用非常简单。
登录邮箱成功后,我们可以使用list方法获取邮箱的邮件信息。我们看到list方法的定义:
1
2
3
4
5
6
7
8
9
10
11
12
|
def list ( self , which = None ):
"""Request listing, return result.
Result without a message number argument is in form
['response', ['mesg_num octets', ...], octets].
Result when a message number argument is given is a
single response: the "scan listing" for that message.
"""
if which is not None :
return self ._shortcmd( 'LIST %s' % which)
return self ._longcmd( 'LIST' )
|
我们看到list方法的注释,其中文意思是,list方法有一个默认参数which,其默认值为None,当调用者没有给出参数时,该方法会列出所有邮件的信息,其返回形式为 [response, ['msg_number, octets', ...], octets],其中,response为响应结果,msg_number是邮件编号,octets为8位字节单位。我们看一看具体例子:
('+OK ', ['1 2424', '2 2422'], 16)
这是一个调用list()方法以后的返回结果。很明显,这是一个tuple,第一个值sahib响应结果'+OK',表示请求成功,第二个值为一个数组,存储了邮件的信息。例如'1 2424'中的1表示该邮件编号为1。
下面我们再看如何使用poplib下载邮件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
# 获取邮件
def retrMail( self ):
try :
mail_list = self .mailLink. list ()[ 1 ]
if len (mail_list) = = 0 :
return None
mail_info = mail_list[ 0 ].split( ' ' )
number = mail_info[ 0 ]
mail = self .mailLink.retr(number)[ 1 ]
self .mailLink.dele(number)
subject = u''
sender = u''
for i in range ( 0 , len (mail)):
if mail[i].startswith( 'Subject' ):
subject = mail[i][ 9 :]
if mail[i].startswith( 'X-Sender' ):
sender = mail[i][ 10 :]
content = { 'subject' : subject, 'sender' : sender}
return content
except Exception as e:
print str (e)
return None
|
poplib获取邮件内容的接口是retr方法。其需要一个参数,该参数为要获取的邮件编号。下面是retr方法的定义:
1
2
3
4
5
6
|
def retr( self , which):
"""Retrieve whole message number 'which'.
Result is in form ['response', ['line', ...], octets].
"""
return self ._longcmd( 'RETR %s' % which)
|
我们看到注释,可以知道,retr方法可以获取指定编号的邮件的全部内容,其返回形式为[response, ['line', ...], octets],可见,邮件的内容是存储在返回的tuple的第二个元素中,其存储形式为一个数组。我们测试一下,该数组是怎么样的。
我们可以看到,这个数组的存储形式类似于一个dict!于是,我们可以据此找到任何我们感兴趣的内容。例如,我们的示例代码是要找到邮件的主题以及发送者,就可以按照上面的代码那样编写。当然,你也可以使用正则匹配~~~ 下面是测试结果:
嗯...大家可以自己试一下。
3. smtp发送邮件
和pop一样,使用smtp之前也要先给它提供一些需要的常量:
1
2
|
self .mail_box = smtplib.SMTP( self .smtpHost, self .port)
self .mail_box.login( self .userName, self .passWord)
|
上面是使用smtp登录邮箱的代码,和pop类似。下面给出使用smtp发送邮件的代码,你会看到python是多么的简单优美!
1
2
3
4
5
6
7
8
9
10
|
# 发送邮件
def sendMsg( self , mail_body = 'Success!' ):
try :
msg = MIMEText(mail_body, 'plain' , 'utf-8' )
msg[ 'Subject' ] = mail_body
msg[ 'from' ] = self .userName
self .mail_box.sendmail( self .userName, self .bossMail, msg.as_string())
print u 'send mail success!'
except Exception as e:
print u 'send mail fail! ' + str (e)
|
这就是python用smtp发送邮件的代码!很简单有木有!很方便有木有!很通俗易懂有木有!这里主要就是sendmail这个方法,指定发送方,接收方和邮件内容就可以了。还有MIMEText可以看它的定义如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
class MIMEText(MIMENonMultipart):
"""Class for generating text/* type MIME documents."""
def __init__( self , _text, _subtype = 'plain' , _charset = 'us-ascii' ):
"""Create a text/* type MIME document.
_text is the string for this message object.
_subtype is the MIME sub content type, defaulting to "plain".
_charset is the character set parameter added to the Content-Type
header. This defaults to "us-ascii". Note that as a side-effect, the
Content-Transfer-Encoding header will also be set.
"""
MIMENonMultipart.__init__( self , 'text' , _subtype,
* * { 'charset' : _charset})
self .set_payload(_text, _charset)
|
看注释~~~ 这就是一个生成指定内容,指定编码的MIME文档的方法而已。顺便看看sendmail方法吧~~~
1
2
3
4
5
6
7
8
9
10
11
12
13
|
def sendmail( self , from_addr, to_addrs, msg, mail_options = [],
rcpt_options = []):
"""This command performs an entire mail transaction.
The arguments are:
- from_addr : The address sending this mail.
- to_addrs : A list of addresses to send this mail to. A bare
string will be treated as a list with 1 address.
- msg : The message to send.
- mail_options : List of ESMTP options (such as 8bitmime ) for the
mail command.
- rcpt_options : List of ESMTP options (such as DSN commands) for
all the rcpt commands.
|
嗯...使用smtp发送邮件的内容大概就这样了。
4. 源码及测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
# -*- coding:utf-8 -*-
from email.mime.text import MIMEText
import poplib
import smtplib
class MailManager( object ):
def __init__( self ):
self .popHost = 'pop.sina.com'
self .smtpHost = 'smtp.sina.com'
self .port = 25
self .userName = 'xxxxxx@sina.com'
self .passWord = 'xxxxxx'
self .bossMail = 'xxxxxx@qq.com'
self .login()
self .configMailBox()
# 登录邮箱
def login( self ):
try :
self .mailLink = poplib.POP3_SSL( self .popHost)
self .mailLink.set_debuglevel( 0 )
self .mailLink.user( self .userName)
self .mailLink.pass_( self .passWord)
self .mailLink. list ()
print u 'login success!'
except Exception as e:
print u 'login fail! ' + str (e)
quit()
# 获取邮件
def retrMail( self ):
try :
mail_list = self .mailLink. list ()[ 1 ]
if len (mail_list) = = 0 :
return None
mail_info = mail_list[ 0 ].split( ' ' )
number = mail_info[ 0 ]
mail = self .mailLink.retr(number)[ 1 ]
self .mailLink.dele(number)
subject = u''
sender = u''
for i in range ( 0 , len (mail)):
if mail[i].startswith( 'Subject' ):
subject = mail[i][ 9 :]
if mail[i].startswith( 'X-Sender' ):
sender = mail[i][ 10 :]
content = { 'subject' : subject, 'sender' : sender}
return content
except Exception as e:
print str (e)
return None
def configMailBox( self ):
try :
self .mail_box = smtplib.SMTP( self .smtpHost, self .port)
self .mail_box.login( self .userName, self .passWord)
print u 'config mailbox success!'
except Exception as e:
print u 'config mailbox fail! ' + str (e)
quit()
# 发送邮件
def sendMsg( self , mail_body = 'Success!' ):
try :
msg = MIMEText(mail_body, 'plain' , 'utf-8' )
msg[ 'Subject' ] = mail_body
msg[ 'from' ] = self .userName
self .mail_box.sendmail( self .userName, self .bossMail, msg.as_string())
print u 'send mail success!'
except Exception as e:
print u 'send mail fail! ' + str (e)
if __name__ = = '__main__' :
mailManager = MailManager()
mail = mailManager.retrMail()
if mail ! = None :
print mail
mailManager.sendMsg()
|
上述代码先登录邮箱,然后获取其第一封邮件并删除之,然后获取该邮件的主题和发送方并打印出来,最后再发送一封成功邮件给另一个bossMail邮箱。
测试结果如下:
好的,大家可以把上面的代码复制一下,自己玩一下呗
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:http://blog.csdn.net/ivan_zgj/article/details/51013833