详解python实现读取邮件数据并下载附件的实例


Posted in Python onAugust 03, 2017

详解python实现读取邮件数据并下载附件的实例

实现结果图:

详解python实现读取邮件数据并下载附件的实例

实现代码:

#!/usr/bin/python2.7
# _*_ coding: utf-8 _*_

"""
@Author: MarkLiu
"""

import poplib
import email
from email.parser import Parser
from email.header import decode_header
from email.utils import parseaddr


def decode_str(s):
  value, charset = decode_header(s)[0]
  if charset:
    value = value.decode(charset)
  return value


def guess_charset(msg):
  # 先从msg对象获取编码:
  charset = msg.get_charset()
  if charset is None:
    # 如果获取不到,再从Content-Type字段获取:
    content_type = msg.get('Content-Type', '').lower()
    pos = content_type.find('charset=')
    if pos >= 0:
      charset = content_type[pos + 8:].strip()
  return charset


def get_email_headers(msg):
  # 邮件的From, To, Subject存在于根对象上:
  headers = {}
  for header in ['From', 'To', 'Subject', 'Date']:
    value = msg.get(header, '')
    if value:
      if header == 'Date':
        headers['date'] = value
      if header == 'Subject':
        # 需要解码Subject字符串:
        subject = decode_str(value)
        headers['subject'] = subject
      else:
        # 需要解码Email地址:
        hdr, addr = parseaddr(value)
        name = decode_str(hdr)
        value = u'%s <%s>' % (name, addr)
        if header == 'From':
          from_address = value
          headers['from'] = from_address
        else:
          to_address = value
          headers['to'] = to_address
  content_type = msg.get_content_type()
  print 'head content_type: ', content_type
  return headers


# indent用于缩进显示:
def get_email_cntent(message, base_save_path):
  j = 0
  content = ''
  attachment_files = []
  for part in message.walk():
    j = j + 1
    file_name = part.get_filename()
    contentType = part.get_content_type()
    # 保存附件
    if file_name: # Attachment
      # Decode filename
      h = email.Header.Header(file_name)
      dh = email.Header.decode_header(h)
      filename = dh[0][0]
      if dh[0][1]: # 如果包含编码的格式,则按照该格式解码
        filename = unicode(filename, dh[0][1])
        filename = filename.encode("utf-8")
      data = part.get_payload(decode=True)
      att_file = open(base_save_path + filename, 'wb')
      attachment_files.append(filename)
      att_file.write(data)
      att_file.close()
    elif contentType == 'text/plain' or contentType == 'text/html':
      # 保存正文
      data = part.get_payload(decode=True)
      charset = guess_charset(part)
      if charset:
        charset = charset.strip().split(';')[0]
        print 'charset:', charset
        data = data.decode(charset)
      content = data
  return content, attachment_files


if __name__ == '__main__':
  # 输入邮件地址, 口令和POP3服务器地址:
  emailaddress = 'xxxxxx@163.com'
  # 注意使用开通POP,SMTP等的授权码
  password = 'xxxxxx'
  pop3_server = 'pop.163.com'

  # 连接到POP3服务器:
  server = poplib.POP3(pop3_server)
  # 可以打开或关闭调试信息:
  # server.set_debuglevel(1)
  # POP3服务器的欢迎文字:
  print server.getwelcome()
  # 身份认证:
  server.user(emailaddress)
  server.pass_(password)
  # stat()返回邮件数量和占用空间:
  messagesCount, messagesSize = server.stat()
  print 'messagesCount:', messagesCount
  print 'messagesSize:', messagesSize
  # list()返回所有邮件的编号:
  resp, mails, octets = server.list()
  print '------ resp ------'
  print resp # +OK 46 964346 响应的状态 邮件数量 邮件占用的空间大小
  print '------ mails ------'
  print mails # 所有邮件的编号及大小的编号list,['1 2211', '2 29908', ...]
  print '------ octets ------'
  print octets

  # 获取最新一封邮件, 注意索引号从1开始:
  length = len(mails)
  for i in range(length):
    resp, lines, octets = server.retr(i + 1)
    # lines存储了邮件的原始文本的每一行,
    # 可以获得整个邮件的原始文本:
    msg_content = '\n'.join(lines)
    # 把邮件内容解析为Message对象:
    msg = Parser().parsestr(msg_content)

    # 但是这个Message对象本身可能是一个MIMEMultipart对象,即包含嵌套的其他MIMEBase对象,
    # 嵌套可能还不止一层。所以我们要递归地打印出Message对象的层次结构:
    print '---------- 解析之后 ----------'
    base_save_path = '/media/markliu/Entertainment/email_attachments/'
    msg_headers = get_email_headers(msg)
    content, attachment_files = get_email_cntent(msg, base_save_path)

    print 'subject:', msg_headers['subject']
    print 'from_address:', msg_headers['from']
    print 'to_address:', msg_headers['to']
    print 'date:', msg_headers['date']
    print 'content:', content
    print 'attachment_files: ', attachment_files

  # 关闭连接:
  server.quit()

以上就是python读取邮件并下载邮件附件的实例,如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

Python 相关文章推荐
Python中用Ctrl+C终止多线程程序的问题解决
Mar 30 Python
Python实现去除代码前行号的方法
Mar 10 Python
Python基于有道实现英汉字典功能
Jul 25 Python
Python中生成Epoch的方法
Apr 26 Python
python中子类调用父类函数的方法示例
Aug 18 Python
浅谈使用Python内置函数getattr实现分发模式
Jan 22 Python
解决Mac安装scrapy失败的问题
Jun 13 Python
Python 一句话生成字母表的方法
Jan 02 Python
pandas读取CSV文件时查看修改各列的数据类型格式
Jul 07 Python
Python generator生成器和yield表达式详解
Aug 08 Python
python3.6连接mysql数据库及增删改查操作详解
Feb 10 Python
Python collections模块的使用方法
Oct 09 Python
详解 Python中LEGB和闭包及装饰器
Aug 03 #Python
Python 爬虫之超链接 url中含有中文出错及解决办法
Aug 03 #Python
python中MethodType方法介绍与使用示例
Aug 03 #Python
初学python的操作难点总结(新手必看篇)
Aug 03 #Python
python 禁止函数修改列表的实现方法
Aug 03 #Python
详解Python函数可变参数定义及其参数传递方式
Aug 02 #Python
详解Python import方法引入模块的实例
Aug 02 #Python
You might like
PHP 无限分类三种方式 非函数的递归调用!
2011/08/26 PHP
php实现常见图片格式的水印和缩略图制作(面向对象)
2016/06/15 PHP
PHP中new static()与new self()的比较
2016/08/19 PHP
JQuery 引发两次$(document.ready)事件
2010/01/15 Javascript
Jquery阻止事件冒泡 event.stopPropagation
2011/12/11 Javascript
js获取键盘按键响应事件(兼容各浏览器)
2013/05/16 Javascript
js简单实现让文本框内容逐个字的显示出来
2013/10/22 Javascript
简单的JavaScript互斥锁分享
2014/02/02 Javascript
基于豆瓣API+Angular开发的web App
2015/01/02 Javascript
jQuery中Ajax的load方法详解
2015/01/14 Javascript
Jquery实现遮罩层的方法
2015/06/08 Javascript
JavaScript基础篇(6)之函数表达式闭包
2015/12/11 Javascript
jQuery的实例及必知重要的jQuery选择器详解
2016/05/20 Javascript
微信小程序实现图片上传功能实例(前端+PHP后端)
2018/01/10 Javascript
node 命令方式启动修改端口的方法
2018/05/12 Javascript
jQuery发请求传输中文参数乱码问题的解决方案
2018/05/22 jQuery
vuejs使用axios异步访问时用get和post的实例讲解
2018/08/09 Javascript
jQuery实现经典的网页3D轮播图封装功能【附源码下载】
2019/02/15 jQuery
jquery实现Ajax请求的几种常见方式总结
2019/05/28 jQuery
详解webpack打包vue项目之后生成的dist文件该怎么启动运行
2019/09/06 Javascript
微信JSSDK实现打开摄像头拍照再将相片保存到服务器
2019/11/15 Javascript
element中el-container容器与div布局区分详解
2020/05/13 Javascript
如何实现小程序与小程序之间的跳转
2020/11/04 Javascript
python进阶教程之函数参数的多种传递方法
2014/08/30 Python
使用python和pygame绘制繁花曲线的方法
2018/02/24 Python
Python cookbook(字符串与文本)针对任意多的分隔符拆分字符串操作示例
2018/04/19 Python
TensorBoard 计算图的查看方式
2020/02/15 Python
Python之Matplotlib文字与注释的使用方法
2020/06/18 Python
基于python图书馆管理系统设计实例详解
2020/08/05 Python
用pip给python安装matplotlib库的详细教程
2021/02/24 Python
限量版运动鞋和街头服饰:TheDrop
2020/09/06 全球购物
.NET概念性的面试题
2012/02/29 面试题
机电一体化专业毕业生自荐信
2014/06/19 职场文书
办公室主任个人总结
2015/02/28 职场文书
上学路上观后感
2015/06/16 职场文书
LayUI+Shiro实现动态菜单并记住菜单收展的示例
2021/05/06 Javascript