I am LAZY bones? AN ancient AND boring SITE

用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')

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

最后修改时间: 2009年09月22日 11:44

本文章发表于: 2009年08月16日 11:16 | 所属分类:编程相关. | 您可以在此订阅本文章的所有评论. | 您也可以发表评论, 或从您的网站trackback.

12 个评论 关于: “用python来收发邮件”

  1. Xuander 在 2009年08月16日 16:15 说:回复

    嘿嘿 传说中的沙发 你做GUI出来好了

  2. Xuander 在 2009年08月16日 16:16 说:回复

    或者跟MUTT那样 我很兴奋 昨天晚上不得不在WIN下又实用OUTLOOK的同时就想能否让你用PYTHON折腾个类似MUTT的东西 今天就看到这个

    • bones7456 在 2009年08月17日 09:12 说:回复

      呵呵,已经有这么多邮件客户端了啊~ 不知道还能做出什么特色来。。。

  3. MeaCulpa 在 2009年08月16日 16:57 说:回复

    Ahh… 有空把irc机器人也武装上email spam :P

    • bones7456 在 2009年08月17日 09:14 说:回复

      倒是可以搞个订阅irc之类的功能,按频率把一天的log都邮件发出来。。。不过有人肯定又会觉得有log不自在了,哈哈。

  4. Keengle 在 2009年08月19日 21:31 说:回复

    这个教程好,原来垃圾邮件还可以这样产生的。学习了

    • bones7456 在 2009年08月20日 09:16 说:回复

      我可没教你发垃圾邮件哦~~

  5. 菜鸟飘过 在 2009年08月30日 19:38 说:回复

    话说email.header应该写成 email.Header 才对

    • bones7456 在 2009年08月30日 20:11 说:回复

      非也,Header应该是email.header下面的一个对象。虽然在python2.6下,为了兼容老的写法,用email.Header也可以引用到email.header,但是在python3下已经不行了,所以还是推荐用小写的。

      Python 2.6.2 (r262:71600, Jul 10 2009, 22:49:39) 
      [GCC 4.3.3] on linux2
      Type "help", "copyright", "credits" or "license" for more information.
      >>> import email.header
      >>> type(email.header.Header)
      <type 'classobj'>
      >>> type(email.header.decode_header)
      <type 'function'>
      >>> type(email.Header.decode_header)
      <type 'function'>
      Python 3.1.1 (r311:74480, Aug 24 2009, 09:58:56) 
      [GCC 4.4.1] on linux2
      Type "help", "copyright", "credits" or "license" for more information.
      >>> import email.header
      >>> type(email.header.Header)
      <class 'type'>
      >>> type(email.header.decode_header)
      <class 'function'>
      >>> type(email.Header.decode_header)
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
      AttributeError: 'module' object has no attribute 'Header'
  6. D.B.Cooper 在 2009年11月15日 01:32 说:回复

    我在发送的时候怎么老是来链接不上服务器??s.login(‘bones7456′,’密码’) 参数我是对的,, 真实郁闷

  7. googya 在 2010年01月28日 14:14 说:回复

    怎如何显示中文呢.我看这是一个比较大的问题!

    • bones7456 在 2010年01月28日 21:38 说:回复

      直接按编码print,没啥问题啊。

发表评论