详解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的词法分析与语法分析
May 18 Python
python中实现精确的浮点数运算详解
Nov 02 Python
使用C++扩展Python的功能详解
Jan 12 Python
Python使用matplotlib和pandas实现的画图操作【经典示例】
Jun 13 Python
flask框架jinja2模板与模板继承实例分析
Aug 01 Python
python自动化测试无法启动谷歌浏览器问题
Oct 10 Python
pygame实现俄罗斯方块游戏(基础篇2)
Oct 29 Python
python 读取更新中的log 或其它文本方式
Dec 24 Python
详解opencv中画圆circle函数和椭圆ellipse函数
Dec 27 Python
为什么是 Python -m
Jun 19 Python
谈谈python垃圾回收机制
Sep 27 Python
python基础详解之if循环语句
Apr 24 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最常用的ini函数分析 针对PHP.ini配置文件
2010/04/22 PHP
php中可能用来加密字符串的函数[base64_encode、urlencode、sha1]
2012/01/16 PHP
PHP不用递归实现无限分级的例子分享
2014/04/18 PHP
ThinkPHP公共配置文件与各自项目中配置文件组合的方法
2014/11/24 PHP
php调用淘宝开放API实现根据卖家昵称获取卖家店铺ID的方法
2015/07/29 PHP
Jqyery中同等与js中windows.onload的应用
2011/05/10 Javascript
JavaScript 模式之工厂模式(Factory)应用介绍
2012/11/15 Javascript
基于Bootstrap+jQuery.validate实现Form表单验证
2014/12/16 Javascript
jQuery验证元素是否为空的两种常用方法
2015/03/17 Javascript
js中通过getElementsByName访问name集合对象的方法
2016/10/31 Javascript
js实现自定义进度条效果
2017/03/15 Javascript
nodejs基础之buffer缓冲区用法分析
2018/12/26 NodeJs
微信小程序实现的自定义分享功能示例
2019/02/12 Javascript
vue实现购物车抛物线小球动画效果的方法详解
2019/02/13 Javascript
用Vue.js在浏览器中实现裁剪图像功能
2019/06/18 Javascript
JS实现电脑虚拟键盘打字测试
2020/06/24 Javascript
在Python3中使用asyncio库进行快速数据抓取的教程
2015/04/02 Python
Django如何配置mysql数据库
2018/05/04 Python
python实现支付宝转账接口
2019/05/07 Python
使用Flask-Cache缓存实现给Flask提速的方法详解
2019/06/11 Python
python中while和for的区别总结
2019/06/28 Python
python用match()函数爬数据方法详解
2019/07/23 Python
flask/django 动态查询表结构相同表名不同数据的Model实现方法
2019/08/29 Python
如何使用python实现模拟鼠标点击
2020/01/06 Python
django form和field具体方法和属性说明
2020/07/09 Python
CSS3使用transition实现的鼠标悬停淡入淡出
2015/01/09 HTML / CSS
澳大利亚领先的在线美容商城:Adore Beauty
2017/04/14 全球购物
Java基础知识面试要点
2016/07/29 面试题
广州品高软件.net笔面试题目
2012/04/18 面试题
Python文件操作的面试题
2013/06/22 面试题
Python中如何定义一个函数
2016/09/06 面试题
大学生应聘自荐信
2013/10/11 职场文书
企业挂职心得体会
2014/09/10 职场文书
三八妇女节标语
2014/10/09 职场文书
运动会广播稿200米(5篇)
2014/10/15 职场文书
2015中秋节慰问信范文
2015/03/23 职场文书