python中zipfile模块实例化解析

文章内容由--“脚本之家“--提供,在此感谢脚本之家的贡献,该网站网址为:https://www.jb51.net/html

简介:


 

  zipfile是python里用来作zip格式编码的压缩和解压缩的,因为是很常见的zip格式,因此这个模块使用频率也是比较高的,python

在这里对zipfile的使用方法作一些记录。即方便本身也方便别人。编程

  Python zipfile模块用来作zip格式编码的压缩和解压缩的,要进行相关操做,首先须要实例化一个 ZipFile 对象。ZipFile 接受一个字符串格式压缩包名称做为它的必选参数,第二个参数为可选参数,表示打开模式,相似于文件操做,有r/w/a三种模式,分别表明读、写、添加,默认为r,即读模式。app

  zipfile里有两个很是重要的class, 分别是ZipFile和ZipInfo, 在绝大多数的状况下,咱们只须要使用这两个class就能够了。ZipFile是主要的类,用来建立和读取zip文件而ZipInfo是存储的zip文件的每一个文件的信息的。函数

 

1、下面咱们就来介绍这两个类的基本操做:

好比要读取一个Python zipfile 模块,这里假设filename是一个文件的路径:测试

import zipfile z =zipfile.ZipFile(filename, 'r') # 这里的第二个参数用r表示是读取zip文件,w是建立一个zip文件 
for f in z.namelist(): print f

  上面的代码是读取一个zip压缩包里全部文件的名字。z.namelist() 会返回压缩包内全部文件名的列表。
再看看下面一个:优化

import zipfile z = zipfile.ZipFile(filename, 'r') for i in z.infolist(): print i.file_size, i.header_offset

  这里使用了z.infolist(), 它返回的就是压缩包内全部文件的信息,就是一个ZipInfo的列表。一个ZipInfo对象中包含了压缩包内一个文件的信息,其中比较经常使用的是 filename, file_size, header_offset, 分别为文件名,文件大小,文件数据在压缩包中的偏移。其实以前的z.namelist()就是读取的ZipInfo中的filename,组成一个 list返回的。
从压缩包里解压缩出一个文件的方法是使用ZipFile的read方法:网站

import zipfile z = zipfile.ZipFile(filename, 'r') print z.read(z.namelist()[0])

  这样就读取出z.namelist()中的第一个文件,而且输出到屏幕,固然也能够把它存储到文件。下面是建立zip压缩包的方法,与读取的方法其实很相似的:编码

import zipfile, os z = zipfile.ZipFile(filename, 'w') # 注意这里的第二个参数是w,这里的filename是压缩包的名字

  假设要把一个叫testdir中的文件所有添加到压缩包里(这里只添加一级子目录中的文件):加密

if os.path.isdir(testdir): for d in os.listdir(testdir): z.write(testdir+os.sep+d) # close() 是必须调用的! 
         z.close()

  面的代码很是的简单。想一想还有一个问题,若是我把一个test/111.txt 添加到压缩包里以后我但愿在包里它放到test22/111.txt怎么办呢?其实这个就是Python ZipFile模块的write方法中第二个参数的做用了。只须要这样调用:

z.write("test/111.txt", "test22/111.txt")

 

2、ZipFile和Zipinfo这两个类的基本操做

一、class zipfile.ZipFile(file[, mode[, compression[, allowZip64]]])

  建立一个ZipFile对象,表示一个zip文件。参数file表示文件的路径或类文件对象(file-like object);参数mode指示打开zip文件的模式,

默认值为'r',表示读已经存在的zip文件,也能够为'w'或'a','w'表示新建一个zip文档或覆盖一个已经存在的zip文档,

import zipfile f = zipfile.ZipFile(filename, 'r') # 这里的第二个参数用r表示是读取zip文件,w或a是建立一个zip文件
 
for f_name in f.namelist(): #z.namelist() 会返回压缩包内全部文件名的列表。
 print(f_name) #上面的代码是读取一个zip压缩包里全部文件的名字。

  'a'表示将数据附加到一个现存的zip文档中。参数compression表示在写zip文档时使用的压缩方法,它的值能够是zipfile. ZIP_STORED 或zipfile. ZIP_DEFLATED。若是要操做的zip文件大小超过2G,应该将allowZip64设置为True。

ZipFile还提供了以下经常使用的方法和属性:

ZipFile.getinfo(name)

获取zip文档内指定文件的信息。返回一个zipfile.ZipInfo对象,它包括文件的详细信息。

ZipFile.infolist()

获取zip文档内全部文件的信息,返回一个zipfile.ZipInfo的列表。

ZipFile.namelist()

获取zip文档内全部文件的名称列表。

ZipFile.extract(member[, path[, pwd]])

  将zip文档内的指定文件解压到当前目录。参数member指定要解压的文件名称或对应的ZipInfo对象;参数path指定了解析文件保存的文件夹;

参数pwd为解压密码。下面一个例子将保存在程序根目录下的duoduo.zip内的全部文件解压到D:/Work目录:

import zipfile, os f = zipfile.ZipFile(os.path.join(os.getcwd(), 'duoduo.zip')) #拼接成一个路径
for file in f.namelist():   f.extract(file, r'd:/Work')  #在d:/Work中解压文件
f.close()

 

上面是os.getcwd的用法!!

 

ZipFile.extractall([path[, members[, pwd]]])

解压zip文档中的全部文件到当前目录。参数members的默认值为zip文档内的全部文件名称列表,也能够本身设置,选择要解压的文件名称。

ZipFile.printdir()

将zip文档内的信息打印到控制台上。

ZipFile.setpassword(pwd)

设置zip文档的密码。

ZipFile.read(name[, pwd])

获取zip文档内指定文件的二进制数据。下面的例子演示了read()的使用,zip文档内包括一个duoduo.txt的文本文件,使用read()方法读取其二进制数据,而后保存到D:/duoduo.txt。

 

import zipfile, os zipFile = zipfile.ZipFile(os.path.join(os.getcwd(), 'duoduo.zip')) data = zipFile.read('duoduo.txt') # (lambda f, d: (f.write(d), f.close()))(open(r'd:/duoduo.txt', 'wb'), data) #一行语句就完成了写文件操做。仔细琢磨哦~_~
with open(r'd:/duoduo.txt','wb') as f: for d in data: f.write(d) zipFile.close()

ZipFile.write(filename[, arcname[, compress_type]])

将指定文件添加到zip文档中。filename为文件路径,arcname为添加到zip文档以后保存的名称, 参数compress_type表示压缩方法,它的值能够是zipfile. ZIP_STORED 或zipfile. ZIP_DEFLATED。下面的例子演示了如何建立一个zip文档,并将文件D:/test.doc添加到压缩文档中。

import zipfile, os zipFile = zipfile.ZipFile(r'D:/test.zip'), 'w') zipFile.write(r'D:/test.doc', '保存的名字', zipfile.ZIP_DEFLATED) zipFile.close()

ipFile.writestr(zinfo_or_arcname, bytes)

writestr()支持将二进制数据直接写入到压缩文档。

 

二、Class ZipInfo

ZipFile.getinfo(name) 方法返回的是一个ZipInfo对象,表示zip文档中相应文件的信息。它支持以下属性:

ZipInfo.filename: 获取文件名称。
ZipInfo.date_time: 获取文件最后修改时间。返回一个包含6个元素的元组:(年, 月, 日, 时, 分, 秒)
ZipInfo.compress_type: 压缩类型。
ZipInfo.comment: 文档说明。
ZipInfo.extr: 扩展项数据。
ZipInfo.create_system: 获取建立该zip文档的系统。
ZipInfo.create_version: 获取 建立zip文档的PKZIP版本。
ZipInfo.extract_version: 获取 解压zip文档所需的PKZIP版本。
ZipInfo.reserved: 预留字段,当前实现老是返回0。
ZipInfo.flag_bits: zip标志位。
ZipInfo.volume: 文件头的卷标。
ZipInfo.internal_attr: 内部属性。
ZipInfo.external_attr: 外部属性。
ZipInfo.header_offset: 文件头偏移位。
ZipInfo.CRC: 未压缩文件的CRC-32。
ZipInfo.compress_size: 获取压缩后的大小。
ZipInfo.file_size: 获取未压缩的文件大小。

下面一个简单的例子说明这些属性的意思:

import zipfile, os zipFile = zipfile.ZipFile(os.path.join(os.getcwd(), 'duoduo.zip')) zipInfo = zipFile.getinfo('文件中的文件.txt') print ('filename:', zipInfo.filename) #获取文件名称
print ('date_time:', zipInfo.date_time) #获取文件最后修改时间。返回一个包含6个元素的元组:(年, 月, 日, 时, 分, 秒)
print ('compress_type:', zipInfo.compress_type) #压缩类型
print ('comment:', zipInfo.comment) #文档说明
print ('extra:', zipInfo.extra) #扩展项数据
print ('create_system:', zipInfo.create_system) #获取建立该zip文档的系统。
print ('create_version:', zipInfo.create_version) #获取 建立zip文档的PKZIP版本。
print ('extract_version:', zipInfo.extract_version) #获取 解压zip文档所需的PKZIP版本。
print ('extract_version:', zipInfo.reserved) # 预留字段,当前实现老是返回0。
print ('flag_bits:', zipInfo.flag_bits) #zip标志位。
print ('volume:', zipInfo.volume) # 文件头的卷标。
print ('internal_attr:', zipInfo.internal_attr) #内部属性。
print ('external_attr:', zipInfo.external_attr) #外部属性。
print ('header_offset:', zipInfo.header_offset) # 文件头偏移位。
print ('CRC:', zipInfo.CRC) # 未压缩文件的CRC-32。
print ('compress_size:', zipInfo.compress_size) #获取压缩后的大小。
print ('file_size:', zipInfo.file_size) #获取未压缩的文件大小。
zipFile.close() #

 

3、python使用内存zipfile对象在内存中打包文件示例

import zipfile import StringIO class InMemoryZip(object): def __init__(self): # Create the in-memory file-like object
        self.in_memory_zip = StringIO.StringIO() def append(self, filename_in_zip, file_contents): '''Appends a file with name filename_in_zip and contents of file_contents to the in-memory zip.'''
        # Get a handle to the in-memory zip in append mode
        zf = zipfile.ZipFile(self.in_memory_zip, "a", zipfile.ZIP_DEFLATED, False) # Write the file to the in-memory zip
 zf.writestr(filename_in_zip, file_contents) # Mark the files as having been created on Windows so that
        # Unix permissions are not inferred as 0000
        for zfile in zf.filelist: zfile.create_system = 0 return self def read(self): '''Returns a string with the contents of the in-memory zip.''' self.in_memory_zip.seek(0) return self.in_memory_zip.read() def writetofile(self, filename): '''Writes the in-memory zip to a file.''' f = file(filename, "w") f.write(self.read()) f.close() if __name__ == "__main__": # Run a test
    imz = InMemoryZip() imz.append("test.txt", "Another test").append("test2.txt", "Still another") imz.writetofile("test.zip")

 

Python读zip文件

下面的代码给出了用Python读取zip文件,打印出压缩文件里面全部的文件,并读取压缩文件中的第一个文件。

import zipfile z = zipfile.ZipFile("zipfile.zip", "r") #打印zip文件中的文件列表
for filename in z.namelist( ): print 'File:', filename #读取zip文件中的第一个文件
first_file_name = z.namelist()[0] content = z.read(first_file_name) print first_file_name print content

 

Python写/建立zip文件

Python写Zip文件主要用到ZipFile的write函数。

import zipfile z = zipfile.ZipFile('test.zip', 'w', zipfile.ZIP_DEFLATED) z.write('test.html') z.close( )

在建立ZipFile实例的时候,有2点药注意:

1.要用'w'或'a'模式,用可写的方式打开zip文件
2.压缩模式有ZIP_STORED 和 ZIP_DEFLATED,ZIP_STORED只是存储模式,不会对文件进行压缩,这个是默认值,若是你须要对文件进行压缩,必须使用ZIP_DEFLATED模式。

 

4、python破解zip加密文件的方法

首先咱们先来桌面建立一个文件

 

咱们建立了一个名为q的txt文件而后咱们将它压缩,压缩的时候记得设置上密码

我这边将密码设置为123456

使用python的zipfile的模块,编写zip文件口令破解机。须要用到 Zip File类中的 extractall方法。这个类和这个方法对咱们编程破解有口令保护的Zip文件是颇有用的。请注意 extractant(方法用可选参数指定密码的方式。

导入库后,用带有口令保护的Zip文件的文件名,实例化一个新的 Zipfile类。要解压这个Zip文件,咱们使用 extractall方法,并在可选参数pwd上填入口令。

建立一个.py文件,在根目录而后在将咱们的压缩文件放入同目录里面,项目结构目录:

咱们.py文件的代码:

import zipfile zipFile = zipfile.ZipFile("q.zip","r")//这里是咱们的压缩文件 zipFile.extractall(pwd="123456")//这里是咱们的密码

这段代码其实就是拿着密码去解压咱们刚刚压缩的文件,网上大多数教程都是这样写的,可是我这边使用python3.6就会发现运行的时候报错了:

反正错误大概的意思就是pwd的接收的数据应该是bytes类型可是它获得的倒是str类型的反正就是类型错了,那咱们就将密码转换为bytes类型,咱们的py文件的代码以下:

import zipfile zipFile = zipfile.ZipFile("q.zip","r") password = '123456' zipFile.extractall(pwd=str.encode(password) )

这时候咱们再次运行项目

此次没有报错

 

 

咱们能够看到在咱们的项目根目录下多了一个文件就是咱们以前压缩的那个文件


接下来咱们继续改造,若是用一个错误密码执行这个脚本会发生什么状况?让咱们在脚本中增长一些捕获和处理异常的代码,显示错误的信息。

import zipfile zipFile = zipfile.ZipFile("q.zip","r") try: password = '123s456' zipFile.extractall(pwd=str.encode(password)) except Exception as ex: print(ex)

这时候咱们的py文件代码,而且咱们还将密码故意写错来测试一下,来看一下运行结果

在这里咱们能够看到错误 信息,就是告诉咱们密码错误

咱们能够用因口令不正确而抛出的异常来测试咱们的字典文件(接下来的zidian.text)中是否有Zip文件的口令。实例化一个 Zip File类以后,咱们打开字典文件,遍历并测试字典中的每一个单词。若是 extractall0函数的执行没有出错,则打印一条消息,输出正确的口令。可是,若是 extractall()函数抛出了一个口令错误的异常,就忽略这个异常,并继续测试字典中的下一个口令。

咱们先建立一个zidian.text文件

接下来咱们在zidian.text文件中编写咱们的密码字典,每一行一个密码,红色部分是咱们的正确密码

而后将咱们的密码字典放入项目中

接着咱们继续修改咱们的脚本

zipFile = zipfile.ZipFile("q.zip","r") #打开咱们的字典表 
passFile = open('zidian.txt') for line in passFile.readlines(): #读取每一行数据(每个密码) 
 password = line.strip('\n') try: zipFile.extractall(pwd=str.encode(password)) print('=========密码是:'+password+'\n') #若是密码正确退出程序 
 exit(0) except Exception as ex: #跳过 
 pass

接下来咱们看一下运行结果

哈哈咱们已经成功破解了zip文件的密码,到这里咱们不难发现只要咱们字典里面有密码咱们就能够破解出来

咱们继续将咱们的项目优化一下:

import zipfile def extractFile(zFile,password): try: zFile.extractall(pwd=str.encode(password)) #若是成功返回密码 
 return password except: return
def main(): zFile = zipfile.ZipFile("q.zip","r") #打开咱们的字典表 
 passFile = open('zidian.txt') for line in passFile.readlines(): #读取每一行数据(每个密码) 
 password = line.strip('\n') guess = extractFile(zFile,password) if (guess): print("=========密码是:"+password+"\n") exit(0) if __name__=='__main__': main()

这样就好多了!

 

接下来再给你们贴一个生成所有六位数数字密码的代码:

f = open('zidian.txt','w') for id in range(1000000): password = str(id).zfill(6)+'\n' f.write(password) f.close()

运行成功后咱们能够看到再咱们的zidian.txt已经生成好了从000000到999999都有了这样咱们只要是6位数数字密码的zip文件咱们均可以破解了!

相关文章
相关标签/搜索