详解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实现把xml或xsl转换为html格式
Apr 08 Python
Python使用pymysql小技巧
Jun 04 Python
python爬虫获取淘宝天猫商品详细参数
Jun 23 Python
Python进阶之全面解读高级特性之切片
Feb 19 Python
在django view中给form传入参数的例子
Jul 19 Python
django数据库自动重连的方法实例
Jul 21 Python
PyTorch实现ResNet50、ResNet101和ResNet152示例
Jan 14 Python
python退出循环的方法
Jun 18 Python
python安装第三方库如xlrd的方法
Oct 31 Python
scrapy实践之翻页爬取的实现
Jan 05 Python
python如何利用cv2模块读取显示保存图片
Jun 04 Python
Python IO文件管理的具体使用
Mar 20 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笔记之:php数组相关函数的使用
2013/04/26 PHP
asp函数split()对应php函数explode()
2019/02/27 PHP
几行代码轻松搞定jquery实现flash8类似的连接效果
2007/05/03 Javascript
JavaScript去掉数组中的重复元素
2011/01/13 Javascript
判断是否安装flash player及当前版本的JS代码
2013/08/08 Javascript
JS获取当前日期和时间的简单实例
2013/11/19 Javascript
javascript中call,apply,bind的用法对比分析
2015/02/12 Javascript
AngularJS初始化静态模板详解
2016/01/14 Javascript
ES6生成器用法实例分析
2017/04/10 Javascript
微信小程序教程系列之视图层的条件渲染(10)
2017/04/19 Javascript
Vuex之理解Getters的用法实例
2017/04/19 Javascript
基于casperjs和resemble.js实现一个像素对比服务详解
2018/01/10 Javascript
vue计算属性及使用详解
2018/04/02 Javascript
使用 electron 实现类似新版 QQ 的登录界面效果(阴影、背景动画、窗体3D翻转)
2018/10/23 Javascript
vue实现类似淘宝商品评价页面星级评价及上传多张图片功能
2018/10/29 Javascript
vue webpack打包后图片路径错误的完美解决方法
2018/12/07 Javascript
详解vue项目中调用百度地图API使用方法
2019/04/25 Javascript
JavaScript键盘事件响应顺序详解
2019/09/30 Javascript
微信小程序 SOTER 生物认证DEMO 指纹识别功能
2019/12/13 Javascript
javascript实现京东快递单号的查询效果
2020/11/30 Javascript
python获取代理IP的实例分享
2018/05/07 Python
python f-string式格式化听语音流程讲解
2019/06/18 Python
python之信息加密题目详解
2019/06/26 Python
python的移位操作实现详解
2019/08/21 Python
Python3 无重复字符的最长子串的实现
2019/10/08 Python
python安装gdal的两种方法
2019/10/29 Python
西班牙宠物用品和食品网上商店:Tiendanimal
2019/06/06 全球购物
怎样创建、运行java程序
2014/08/01 面试题
理工科学生的自我评价
2013/12/15 职场文书
工程项目建议书范文
2014/03/12 职场文书
诉前财产保全担保书
2014/05/20 职场文书
大学生应聘导游自荐信
2014/06/02 职场文书
生活小常识广播稿
2014/09/16 职场文书
年度考核登记表个人总结
2015/03/06 职场文书
人生感悟经典句子
2019/08/20 职场文书
基于Redis zSet实现滑动窗口对短信进行防刷限流的问题
2022/02/12 Redis