简单实现python收发邮件功能


Posted in Python onJanuary 05, 2018

今天记录一下如何使用python收发邮件,知识要点在python内置的poplib和stmplib模块的使用上。

1. 准备工作

首先,我们需要有一个测试邮箱,我们使用新浪邮箱,而且要进行如下设置:

简单实现python收发邮件功能

在新浪邮箱首页的右上角找到设置->更多设置,然后在左边选择“客户端/pop/imap/smtp”:

简单实现python收发邮件功能

最后,将Pop3/smtp服务的服务状态打开即可:

简单实现python收发邮件功能

2. poplib接收邮件

首先,介绍一下poplib登录邮箱和下载邮件的一些接口:

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接口可以登录到邮箱。

# 登录邮箱 
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方法的定义:

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下载邮件。

# 获取邮件 
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方法的定义:

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的第二个元素中,其存储形式为一个数组。我们测试一下,该数组是怎么样的。

简单实现python收发邮件功能

我们可以看到,这个数组的存储形式类似于一个dict!于是,我们可以据此找到任何我们感兴趣的内容。例如,我们的示例代码是要找到邮件的主题以及发送者,就可以按照上面的代码那样编写。当然,你也可以使用正则匹配~~~ 下面是测试结果:

简单实现python收发邮件功能

嗯...大家可以自己试一下。

3. smtp发送邮件

和pop一样,使用smtp之前也要先给它提供一些需要的常量:

self.mail_box = smtplib.SMTP(self.smtpHost, self.port) 
self.mail_box.login(self.userName, self.passWord)

上面是使用smtp登录邮箱的代码,和pop类似。下面给出使用smtp发送邮件的代码,你会看到python是多么的简单优美!

# 发送邮件 
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可以看它的定义如下:

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方法吧~~~

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. 源码及测试

# -*- 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邮箱。

测试结果如下:

简单实现python收发邮件功能

好的,大家可以把上面的代码复制一下,自己玩一下呗

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python 调用VC++的动态链接库(DLL)
Sep 06 Python
python获取Linux下文件版本信息、公司名和产品名的方法
Oct 05 Python
python将文本转换成图片输出的方法
Apr 28 Python
使用Python编写一个最基础的代码解释器的要点解析
Jul 12 Python
pandas DataFrame数据转为list的方法
Apr 11 Python
python实现监控某个服务 服务崩溃即发送邮件报告
Jun 21 Python
python保存网页图片到本地的方法
Jul 24 Python
python实现将多个文件分配到多个文件夹的方法
Jan 07 Python
手把手教你使用Python创建微信机器人
Apr 29 Python
Python 测试框架unittest和pytest的优劣
Sep 26 Python
python 中yaml文件用法大全
Jul 04 Python
python 判断字符串当中是否包含字符(str.contain)
Jun 01 Python
5款非常棒的Python工具
Jan 05 #Python
Python基于列表模拟堆栈和队列功能示例
Jan 05 #Python
Django 2.0版本的新特性抢先看!
Jan 05 #Python
微信跳一跳游戏python脚本
Apr 01 #Python
Python基于列表list实现的CRUD操作功能示例
Jan 05 #Python
django 2.0更新的10条注意事项总结
Jan 05 #Python
OpenCV2.3.1+Python2.7.3+Numpy等的配置解析
Jan 05 #Python
You might like
配置Apache2.2+PHP5+CakePHP1.2+MySQL5运行环境
2009/04/25 PHP
PHP使用Pear发送邮件(Windows环境)
2016/01/05 PHP
php计算给定日期所在周的开始日期和结束日期示例
2017/02/06 PHP
thinkphp5 URL和路由的功能详解与实例
2017/12/26 PHP
针对thinkPHP5框架存储过程bug重写的存储过程扩展类完整实例
2018/06/16 PHP
javascript下有关dom以及xml节点访问兼容问题
2007/11/26 Javascript
javascript 建设银行登陆键盘
2008/06/10 Javascript
Jquery 插件开发笔记整理
2011/01/17 Javascript
jQuery输入城市查看地图使用介绍
2013/05/08 Javascript
javascript模拟订火车票和退票示例
2014/04/24 Javascript
JavaScript插件化开发教程 (一)
2015/01/27 Javascript
JavaScript实现的Tween算法及缓冲特效实例代码
2015/11/03 Javascript
AngularJS Module方法详解
2015/12/08 Javascript
jquery 判断selection range 是否在容器中的简单实例
2016/08/02 Javascript
angular实现form验证实例代码
2017/01/17 Javascript
vue 数组和对象不能直接赋值情况和解决方法(推荐)
2017/10/25 Javascript
webpack4 + react 搭建多页面应用示例
2018/08/03 Javascript
JavaScript面向对象程序设计中对象的定义和继承详解
2019/07/29 Javascript
Vue调用后端java接口的实例代码
2019/10/28 Javascript
[33:19]完美世界DOTA2联赛PWL S2 PXG vs InkIce 第一场 11.26
2020/11/30 DOTA
python发送伪造的arp请求
2014/01/09 Python
Collatz 序列、逗号代码、字符图网格实例
2017/06/22 Python
Python实现简单的列表冒泡排序和反转列表操作示例
2019/07/10 Python
Python数据可视化:幂律分布实例详解
2019/12/07 Python
html5音频_动力节点Java学院整理
2018/08/22 HTML / CSS
基于HTML5+tracking.js实现刷脸支付功能
2020/04/16 HTML / CSS
乌克兰数字设备、配件和智能技术的连锁商店:KTC
2020/08/18 全球购物
澳洲的UGG雪地靴超级市场:Uggs.com.au
2020/04/06 全球购物
测试驱动开发的主要步骤是什么
2014/12/10 面试题
行政人员工作职责
2013/12/05 职场文书
人事部主管岗位职责
2013/12/26 职场文书
cf收人广告词大全
2014/03/14 职场文书
幼儿教师师德承诺书
2014/05/23 职场文书
三八妇女节趣味活动方案
2014/08/23 职场文书
nginx请求限制配置方法
2021/07/09 Servers
特别篇动画《总之就是非常可爱 ~制服~》PV公开,2022年夏季播出
2022/04/04 日漫