Python CookBook之zipfile:一次性解压多层嵌套的压缩包
2017-12-13 11:55
267 查看
使用zipfile进行解压缩非常方便,这里不赘述zipfile模块的使用,使用方法自行百度。在做自动化测试的过程中,碰到一个问题,就是提供的zip包里的结构不是固定的,有可能只需要解压一次就完成了,有可能解压后里面还存在zip文件,需要继续进行解压缩,zipfile貌似不支持这样的操作,于是乎经过研究,找到了解决方案,一起来看下吧。
测试用的zip目录结构如下,日常应该没有这么多层的结构,仅为了展示效果:
解决思路是这样的,zipfile进行一次解压缩之后,会有新的目录产生,要继续遍历目录查看是否存在新的zip文件,于是乎想到了os.walk(),但os.walk()在遍历到只剩文件的时候就停止了,例如上面的例子,先将test_zip文件进行解压,然后os.walk()在获取到test_zip目录下只有1.zip和2.zip文件后,就终止循环了,那么就暴力一点吧,在os.walk()的外层添加while循环,然后找到合适的条件跳出循环即可,示例代码:
运行结果如下:
开始while循环
D:\TestSamples\samples\extractfile\test_zip1 ['test_zip1'] []
D:\TestSamples\samples\extractfile\test_zip1\test_zip1 ['1', '2'] ['1.zip', '2.zip']
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1.zip
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\2.zip
D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1 [] ['3.zip', 'QQ\xbd\xd8\xcd\xbc20150208222141.png']
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1\3.zip
开始while循环
D:\TestSamples\samples\extractfile\test_zip1 ['test_zip1'] []
D:\TestSamples\samples\extractfile\test_zip1\test_zip1 ['1', '2'] ['1.zip', '2.zip']
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1.zip
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\2.zip
D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1 ['3'] ['3.zip', 'QQ\xbd\xd8\xcd\xbc20150208222141.png']
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1\3.zip
D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1\3 [] ['4.zip', 'QQ\xbd\xd8\xcd\xbc20150619073658.png']
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1\3\4.zip
开始while循环
D:\TestSamples\samples\extractfile\test_zip1 ['test_zip1'] []
D:\TestSamples\samples\extractfile\test_zip1\test_zip1 ['1', '2'] ['1.zip', '2.zip']
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1.zip
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\2.zip
D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1 ['3'] ['3.zip', 'QQ\xbd\xd8\xcd\xbc20150208222141.png']
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1\3.zip
D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1\3 ['4'] ['4.zip', 'QQ\xbd\xd8\xcd\xbc20150619073658.png']
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1\3\4.zip
D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1\3\4 [] ['QQ\xbd\xd8\xcd\xbc20150208222155.png', 'QQ\xbd\xd8\xcd\xbc20150619073634.png']
D:\TestSamples\samples\extractfile\test_zip1\test_zip1\2 [] ['5.zip', 'QQ\xbd\xd8\xcd\xbc20150619073658.png']
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\2\5.zip
开始while循环
D:\TestSamples\samples\extractfile\test_zip1 ['test_zip1'] []
D:\TestSamples\samples\extractfile\test_zip1\test_zip1 ['1', '2'] ['1.zip', '2.zip']
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1.zip
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\2.zip
D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1 ['3'] ['3.zip', 'QQ\xbd\xd8\xcd\xbc20150208222141.png']
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1\3.zip
D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1\3 ['4'] ['4.zip', 'QQ\xbd\xd8\xcd\xbc20150619073658.png']
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1\3\4.zip
D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1\3\4 [] ['QQ\xbd\xd8\xcd\xbc20150208222155.png', 'QQ\xbd\xd8\xcd\xbc20150619073634.png']
D:\TestSamples\samples\extractfile\test_zip1\test_zip1\2 ['5'] ['5.zip', 'QQ\xbd\xd8\xcd\xbc20150619073658.png']
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\2\5.zip
D:\TestSamples\samples\extractfile\test_zip1\test_zip1\2\5 [] ['QQ\xbd\xd8\xcd\xbc20150208222155.png', 'QQ\xbd\xd8\xcd\xbc20150619073634.png']
这里重点说明下这两行代码的作用:
if len(dirs) == 0 and not isEnd:
break
假如文件结构是文章开头示例的那样,那这两行代码实际上是没有作用的,如果在示例的文件结构上,在4.zip下再加一层压缩包6.zip,没有这两行代码的话,最后一次while循环的结果是这样的:
开始while循环
D:\TestSamples\samples\extractfile\test_zip2 ['test_zip2'] []
D:\TestSamples\samples\extractfile\test_zip2\test_zip2 ['1', '2'] ['1.zip', '2.zip']
开始解压:D:\TestSamples\samples\extractfile\test_zip2\test_zip2\1.zip
开始解压:D:\TestSamples\samples\extractfile\test_zip2\test_zip2\2.zip
D:\TestSamples\samples\extractfile\test_zip2\test_zip2\1 ['3'] ['3.zip', 'QQ\xbd\xd8\xcd\xbc20150208222141.png']
开始解压:D:\TestSamples\samples\extractfile\test_zip2\test_zip2\1\3.zip
D:\TestSamples\samples\extractfile\test_zip2\test_zip2\1\3 [] ['4.zip', 'QQ\xbd\xd8\xcd\xbc20150619073658.png']
开始解压:D:\TestSamples\samples\extractfile\test_zip2\test_zip2\1\3\4.zip
D:\TestSamples\samples\extractfile\test_zip2\test_zip2\2 ['5'] ['5.zip', 'QQ\xbd\xd8\xcd\xbc20150619073658.png']
开始解压:D:\TestSamples\samples\extractfile\test_zip2\test_zip2\2\5.zip
D:\TestSamples\samples\extractfile\test_zip2\test_zip2\2\5 [] ['QQ\xbd\xd8\xcd\xbc20150208222155.png', 'QQ\xbd\xd8\xcd\xbc20150619073634.png']
可以看到在1\3文件夹下存在4.zip文件,但此时1\3文件夹下已经没有目录了,所以os.walk()将终止对该层目录的遍历,虽然此时isEnd被设置成False,但在遍历2.zip解压出来的目录及子目录时,已经没有压缩包了,所以isEnd成了True,while循环结束,6.zip并未被解压。这两行代码的作用实际是在控制目录的遍历深度,也就是某个目录下不存在目录但仍然存在压缩包时,解压该文件后仍然需要继续遍历,直到子目录下没有压缩包,再进行下一个目录的遍历。
优点:可适应任何目录结构的压缩包,一次性解压出所有嵌套的压缩包
缺点:从运行结果就很容易看出,上层的zip每进行一次while循环,就解压一次,效率差
测试用的zip目录结构如下,日常应该没有这么多层的结构,仅为了展示效果:
test_zip.zip --1.zip --3.zip --4.zip --文件xxxx --文件xxxx --文件xxxx --2.zip --5.zip --文件xxxx --文件xxxx
解决思路是这样的,zipfile进行一次解压缩之后,会有新的目录产生,要继续遍历目录查看是否存在新的zip文件,于是乎想到了os.walk(),但os.walk()在遍历到只剩文件的时候就停止了,例如上面的例子,先将test_zip文件进行解压,然后os.walk()在获取到test_zip目录下只有1.zip和2.zip文件后,就终止循环了,那么就暴力一点吧,在os.walk()的外层添加while循环,然后找到合适的条件跳出循环即可,示例代码:
# -*- coding:utf-8 -*- import zipfile import os path = r'D:\TestSamples\samples\extractfile\test_zip1.zip' # zipfile模块解压一个zip包的基本代码,只需4行即可解压 # 先将目标zip文件进行一次解压,指定解压目录,类似winrar的解压到test_zip\功能 srcfile = zipfile.ZipFile(path) desdir = path[:path.index('.zip')] for filename in srcfile.namelist(): srcfile.extract(filename, desdir) while True: print '开始while循环' for root, dirs, files in os.walk(desdir): isEnd = True # 判定是否还存在zip文件的标志位 print root, dirs, files for subfile in files: if subfile.endswith('.zip'): isEnd = False subpath = root + '\\' + subfile if zipfile.is_zipfile(subpath): print '开始解压:' + subpath subsrcfile = zipfile.ZipFile(subpath) for subfilename in subsrcfile.namelist(): subsrcfile.extract(subfilename, root) if len(dirs) == 0 and not isEnd: break if isEnd: break
运行结果如下:
开始while循环
D:\TestSamples\samples\extractfile\test_zip1 ['test_zip1'] []
D:\TestSamples\samples\extractfile\test_zip1\test_zip1 ['1', '2'] ['1.zip', '2.zip']
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1.zip
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\2.zip
D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1 [] ['3.zip', 'QQ\xbd\xd8\xcd\xbc20150208222141.png']
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1\3.zip
开始while循环
D:\TestSamples\samples\extractfile\test_zip1 ['test_zip1'] []
D:\TestSamples\samples\extractfile\test_zip1\test_zip1 ['1', '2'] ['1.zip', '2.zip']
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1.zip
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\2.zip
D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1 ['3'] ['3.zip', 'QQ\xbd\xd8\xcd\xbc20150208222141.png']
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1\3.zip
D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1\3 [] ['4.zip', 'QQ\xbd\xd8\xcd\xbc20150619073658.png']
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1\3\4.zip
开始while循环
D:\TestSamples\samples\extractfile\test_zip1 ['test_zip1'] []
D:\TestSamples\samples\extractfile\test_zip1\test_zip1 ['1', '2'] ['1.zip', '2.zip']
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1.zip
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\2.zip
D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1 ['3'] ['3.zip', 'QQ\xbd\xd8\xcd\xbc20150208222141.png']
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1\3.zip
D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1\3 ['4'] ['4.zip', 'QQ\xbd\xd8\xcd\xbc20150619073658.png']
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1\3\4.zip
D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1\3\4 [] ['QQ\xbd\xd8\xcd\xbc20150208222155.png', 'QQ\xbd\xd8\xcd\xbc20150619073634.png']
D:\TestSamples\samples\extractfile\test_zip1\test_zip1\2 [] ['5.zip', 'QQ\xbd\xd8\xcd\xbc20150619073658.png']
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\2\5.zip
开始while循环
D:\TestSamples\samples\extractfile\test_zip1 ['test_zip1'] []
D:\TestSamples\samples\extractfile\test_zip1\test_zip1 ['1', '2'] ['1.zip', '2.zip']
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1.zip
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\2.zip
D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1 ['3'] ['3.zip', 'QQ\xbd\xd8\xcd\xbc20150208222141.png']
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1\3.zip
D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1\3 ['4'] ['4.zip', 'QQ\xbd\xd8\xcd\xbc20150619073658.png']
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1\3\4.zip
D:\TestSamples\samples\extractfile\test_zip1\test_zip1\1\3\4 [] ['QQ\xbd\xd8\xcd\xbc20150208222155.png', 'QQ\xbd\xd8\xcd\xbc20150619073634.png']
D:\TestSamples\samples\extractfile\test_zip1\test_zip1\2 ['5'] ['5.zip', 'QQ\xbd\xd8\xcd\xbc20150619073658.png']
开始解压:D:\TestSamples\samples\extractfile\test_zip1\test_zip1\2\5.zip
D:\TestSamples\samples\extractfile\test_zip1\test_zip1\2\5 [] ['QQ\xbd\xd8\xcd\xbc20150208222155.png', 'QQ\xbd\xd8\xcd\xbc20150619073634.png']
这里重点说明下这两行代码的作用:
if len(dirs) == 0 and not isEnd:
break
假如文件结构是文章开头示例的那样,那这两行代码实际上是没有作用的,如果在示例的文件结构上,在4.zip下再加一层压缩包6.zip,没有这两行代码的话,最后一次while循环的结果是这样的:
开始while循环
D:\TestSamples\samples\extractfile\test_zip2 ['test_zip2'] []
D:\TestSamples\samples\extractfile\test_zip2\test_zip2 ['1', '2'] ['1.zip', '2.zip']
开始解压:D:\TestSamples\samples\extractfile\test_zip2\test_zip2\1.zip
开始解压:D:\TestSamples\samples\extractfile\test_zip2\test_zip2\2.zip
D:\TestSamples\samples\extractfile\test_zip2\test_zip2\1 ['3'] ['3.zip', 'QQ\xbd\xd8\xcd\xbc20150208222141.png']
开始解压:D:\TestSamples\samples\extractfile\test_zip2\test_zip2\1\3.zip
D:\TestSamples\samples\extractfile\test_zip2\test_zip2\1\3 [] ['4.zip', 'QQ\xbd\xd8\xcd\xbc20150619073658.png']
开始解压:D:\TestSamples\samples\extractfile\test_zip2\test_zip2\1\3\4.zip
D:\TestSamples\samples\extractfile\test_zip2\test_zip2\2 ['5'] ['5.zip', 'QQ\xbd\xd8\xcd\xbc20150619073658.png']
开始解压:D:\TestSamples\samples\extractfile\test_zip2\test_zip2\2\5.zip
D:\TestSamples\samples\extractfile\test_zip2\test_zip2\2\5 [] ['QQ\xbd\xd8\xcd\xbc20150208222155.png', 'QQ\xbd\xd8\xcd\xbc20150619073634.png']
可以看到在1\3文件夹下存在4.zip文件,但此时1\3文件夹下已经没有目录了,所以os.walk()将终止对该层目录的遍历,虽然此时isEnd被设置成False,但在遍历2.zip解压出来的目录及子目录时,已经没有压缩包了,所以isEnd成了True,while循环结束,6.zip并未被解压。这两行代码的作用实际是在控制目录的遍历深度,也就是某个目录下不存在目录但仍然存在压缩包时,解压该文件后仍然需要继续遍历,直到子目录下没有压缩包,再进行下一个目录的遍历。
优点:可适应任何目录结构的压缩包,一次性解压出所有嵌套的压缩包
缺点:从运行结果就很容易看出,上层的zip每进行一次while循环,就解压一次,效率差
相关文章推荐
- python笨办法解决zipfile解压会改变文件最后修改时间的问题
- python用zipfile模块打包文件或是目录、解压zip文件实例
- Python-zipfile解压中文问题
- python 加压/解压 zip(zipfile模块的使用)
- python用zipfile模块打包文件或是目录、解压zip文件实例
- python用zipfile模块打包文件或是目录、解压zip文件实例
- python用zipfile模块打包文件或是目录、解压zip文件实例
- Python读取某个目录下的zip压缩包解压开后计算每个小文件的md5值,并将压缩包名字、里面小文件名字、以及对应的md5值写入csv文件
- python zipfile 创建处理压缩包
- Python ZipFile模块功能特点讲解
- Python Cookbook学习记录 ch2_1_2013/10/27
- 【Python】 压缩文件处理 zipfile & tarfile
- python中将zip压缩包转为gz.tar
- 《Modern Python Cookbook》(Python编程范例)笔记——1.4 浮点数、小数、分数
- python笔记--下载时各版本区别说明:web-based installer 、executable installer 、embeddable zip file
- Mac系统下的zip压缩包解压到Windows下出现乱码的解决方法
- 《Modern Python Cookbook》(Python编程范例)笔记1.2 命名
- python 函数嵌套支持多层嵌套,但不支持嵌套并列函数调用
- Python Cookbook 第二版 汉化版 [00-2-Preface] Part 2
- python cookbook 学习笔记 -- 1.4 字符串对齐