I am LAZY bones? AN ancient AND boring SITE

2009年 08月 16日 的归档

用python来收发邮件

由于python的模块很强大,用python来收发邮件,就显得很轻松了。
python不仅有email模块,还有专门处理popsmtp甚至imap的模块。
下面就来演示一下这几个的用法,先看看怎么用pop3和email模块来收邮件。

>>> import poplib
>>> p=poplib.POP3_SSL('pop.gmail.com')  #如果服务器不需要启用SSL,那么只需要用 poplib.POP3('xxx.com') 就好了。
>>> p.user('linuxcn.ibot')
'+OK send PASS'
>>> p.pass_('密码')
'+OK Welcome.'
>>> p.stat() #统计状态,返回一个元组,第一个表示几封邮件,第二个表示一共几个字节
(2, 4543)
>>> p.list() #返回每个邮件的状态
('+OK 2 messages (4543 bytes)', ['1 3679', '2 864'], 15)
>>> p.retr(2) #获取某个邮件的全文,这个邮件就是我自己给另一个测试账号发的邮件,元组里包含了邮件头和邮件的正文。
('+OK message follows', ['Delivere
...为了排版方便,此处有删节...
e--'], 869)
>>> mailsrc='\n'.join([l for l in p.retr(2)[1]])
>>> print mailsrc #如果上面还看不出啥的话,这样看应该就明显了。
Delivered-To: linuxcn.ibot@gmail.com
Received: by 10.216.47.83 with SMTP id s61cs422102web;
        Sat, 15 Aug 2009 07:58:32 -0700 (PDT)
MIME-Version: 1.0
Received: by 10.114.180.16 with SMTP id c16mr2819847waf.57.1250348310512; Sat, 
	15 Aug 2009 07:58:30 -0700 (PDT)
Date: Sat, 15 Aug 2009 22:58:30 +0800
Message-ID: <ae14629e0908150758n49649527xf326b8c1a60f36bf@mail.gmail.com>
Subject: =?UTF-8?B?5rWL6K+V5Li76aKY?=
From: LLY <bones7456@gmail.com>
To: linuxcn.ibot@gmail.com
Content-Type: multipart/alternative; boundary=001636417e2fe4c3a904712f669e
 
--001636417e2fe4c3a904712f669e
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: base64
 
5rWL6K+V5q2j5paHCg==
--001636417e2fe4c3a904712f669e
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: base64
 
5rWL6K+V5q2j5paHPGJyPgo=
--001636417e2fe4c3a904712f669e--
>>> p.quit() #收完邮件了,理论上是要退出一下的
'+OK Farewell.'
>>> import email #源码得到了,现在轮到email模块登场了
>>> e=email.message_from_string(mailsrc) #这个就可以把邮件源码转换成一个email的对象了。
>>> print e['subject'] #这个是编码后的主题
=?UTF-8?B?5rWL6K+V5Li76aKY?=
>>> print email.header.decode_header(e['subject'])[0][0] #这个是解码后的主题
测试主题
>>> e.get_payload() #获取当前email的有效部分,可以看到有这个邮件有两个部分,从上面的邮件源码,我们也可以得知,此邮件确实有text/plain 和 text/html 两部分
[<email.message.Message instance at 0xb751102c>, <email.message.Message instance at 0xb751172c>]
>>> e.get_payload(0) #获取有效部分的第一个,这个还是一个email对象的实例。
<email.message.Message instance at 0xb751102c>
>>> type(e)
<type 'instance'>
>>> type(e.get_payload(0))
<type 'instance'>
>>> import base64 #解码邮件正文还得用上base64模块
>>> print base64.decodestring(e.get_payload(0).get_payload()) #解码正文的第一部分
测试正文
 
>>> print base64.decodestring(e.get_payload(1).get_payload()) #解码正文的第二部分,是html,看来只多了个br而已,哈哈
测试正文<br>

当然,上面的例子只是最简单的,复杂的附件什么的,也可以用库里的相关函数一一搞定的。另外,看文档的意思,传了get_payload的第二个参数按理应该能自动调用base64模块解码的,但是不知道为什么,我没有试验成功,只能自己手工解了~
下面,再来看看怎么用smtp发邮件,如果是复杂的邮件,也需要建立一个email对象的实例,把正文/附件等一一放上去就好,但是作为演示,我们就用邮件的源码来发一个纯手工的,哈哈

>>> import smtplib #加载模块
>>> msg='To: linuxcn.ibot@gmail.com\r\nFrom: my@localhost\r\nSubject: test\r\n\r\nthis is msg body\r\n' #邮件的源码
>>> s=smtplib.SMTP('smtp.163.com') #同样这里也有SMTP_SSL,到底用什么要看服务器的设置
>>> s.login('bones7456','密码') #一般都要登录了,才能发邮件,login里提供两个参数,用户名和密码
(235, 'Authentication successful')
>>> s.sendmail('bones7456@163.com','linuxcn.ibot@gmail.com',msg) #发送邮件,三个参数分别是 from/to/msg,就这名简单就成功了。。
{}
>>> s.quit()
(421, 'closing transmission channel')

就这么几行,一封邮件就发出去了,够简单吧。。。更详细的内容就看官方文档吧~