鱼C论坛

 找回密码
 立即注册
查看: 2169|回复: 18

[技术交流] 实用干货:Python 操作 .zip 文件

[复制链接]
发表于 2020-1-25 21:13:10 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 zltzlt 于 2020-1-27 13:12 编辑

Python 操作 .zip 文件


.zip 文件格式是一种数据压缩和文档储存的文件格式。Python 提供了一个名为 zipfile 的内置模块,它用于操作 .zip 文件。

zipfile 提供了创建、读取、写入、添加及访问压缩包文件的工具。

zipfile 的简单使用

请参考 Python 小技巧 059:操作 .zip 压缩文件

判断 .zip 文件是否有效

当打开了无效的 .zip 文件时,zipfile 会抛出 BadZipFile 异常。要想在打开 .zip 文件之前就判断 .zip 文件是否有效,可以使用 zipfile 提供的 is_zipfile() 函数。

例如,我们创建一个安全打开 .zip 文件的函数 safe_open():
def safe_open(filename, mode="r"):
    import zipfile
    if not zipfile.is_zipfile(filename):
        print("无法打开文件!")
    else:
        return zipfile.ZipFile(filename, mode=mode)

使用这个函数,当 .zip 文件无效时不会报错,而是打印提示信息。
safe_open("E:/1.py")    # 输出:无法打开文件!

注:之后的示例均使用 safe_open() 函数打开压缩包。

解压指定的文件

想要解压一部分文件而不是全部,可以使用 zipfile.ZipFile 提供的 extract() 方法。例如:
f = safe_open("E:/1.zip")

# 第一个参数是要解压的文件在压缩包中的完整路径;第二个参数指定解压到哪个文件夹(为 None 则解压到当前工作目录)
f.extract("demo.txt")    # 解压 demo.txt 到当前工作目录
f.extract("demo.txt", "E:/")    # 解压 demo.txt 到 E 盘

f.close()

打印压缩包文件目录

有时我们想知道 .zip 的大体结构,可以使用 ZipFile 对象提供的 printdir() 方法。例如:
f = safe_open("E:/1.zip")
f.printdir()    # 打印压缩包的目录

f.close()

执行效果:

1.png

不错,打印得很漂亮

说明:其中的 File Name 是文件名,Modified  是最后修改日期,Size 是文件大小(以字节为单位)。

将文件写入压缩包

我们终于要来学习如何将文件写入压缩包了将文件写入压缩包有两种方法:使用 writestr() 或 write() 方法。例如,写入内容为 '1234567890'、文件名为 '1.txt' 的文件到压缩包,可以使用这样的代码:
f = safe_open("E:/1.zip", mode="a")    # 使用追加模式

# 第一个参数指定文件名,第二个参数指定要写入的内容
f.writestr("1.txt", "1234567890")
f.close()

f = safe_open("E:/1.zip")
f.printdir()    # 打印压缩包目录
f.close()

执行效果:
File Name                                             Modified             Size
demo/1.txt                                     2020-01-25 16:12:22           22
demo.txt                                       2020-01-25 16:02:34           18
demo/                                          2020-01-25 16:12:16            0
1.txt                                          2020-01-25 20:45:28           10

write() 大多应用在将磁盘上的文件拷贝到压缩包中的情况。假设有这样一个文件:E:/a.txt,那么我可以使用这样的代码,将 E:/a.txt 拷贝到压缩包中:
f = safe_open("E:/1.zip", mode="a")    # 使用追加模式

# 第一个参数指定文件名
f.write("E:/a.txt")
f.close()

f = safe_open("E:/1.zip")
f.printdir()    # 打印压缩包目录
f.close()

执行效果:
File Name                                             Modified             Size
demo/1.txt                                     2020-01-25 16:12:22           22
demo.txt                                       2020-01-25 16:02:34           18
demo/                                          2020-01-25 16:12:16            0
1.txt                                          2020-01-25 20:45:28           10
a.txt                                          2020-01-25 20:47:44            0

获取压缩包中文件的信息

获取压缩包中指定文件的 info 可以使用 ZipFile 的 getinfo() 方法。getinfo() 方法返回的是 ZipInfo 对象,ZipInfo 对象有许多包含文件信息的属性。例如:
f = safe_open("E:/1.zip")

info = f.getinfo("demo.txt")    # 获取压缩包中 demo.txt 的 info
print(info.filename)     # 文件名
print(info.date_time)    # 上次修改的时间,是一个元组:(年, 月, 日, 时, 分, 秒)
print(info.file_size)    # 文件大小(以字节为单位)
print(info.is_dir())     # 该文件是否为文件夹

f.close()

执行效果:
demo.txt
(2020, 1, 25, 16, 2, 34)
18

更便捷地读取文件

使用先 open() 再 read() 的方法有点繁琐ZipFile 对象提供了更便捷的方法,读取压缩包中的文件。例如:
f = safe_open("E:/1.zip")

# 使用 ZipFile 对象的 read() 方法读取 demo.txt
print(f.read("demo.txt").decode())    # 由于 read() 返回的是 bytes,因此我们需要将它解码

f.close()

打印的就是压缩包中 demo.txt 文件中的内容。

打开带密码的压缩包

zipfile 虽然能打开带密码的压缩包,但是前提是需要知道密码打开了带密码的压缩包后,使用 setpassword() 设置压缩包的密码。例如:
f = safe_open("E:/1.zip")

# 设置密码为 123456
f.setpassword(b"123456")    # 密码必须为 bytes 类型
print(f.read("demo.txt").decode())    # 不设置解压密码,读取会报错

f.close()

评分

参与人数 2荣誉 +4 鱼币 +6 贡献 +6 收起 理由
不二如是 + 2 + 3 + 3 鱼C有你更精彩^_^
小甲鱼 + 2 + 3 + 3 鱼C有你更精彩^_^

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-1-25 21:13:42 | 显示全部楼层
@小甲鱼 @不二如是 这样能申精吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-1-25 21:16:30 | 显示全部楼层
首先“申精”的文章,一定被很多人看到认可。。。

除了内容实用外,写法一定备受大家喜欢,经得起时间的考验。

建议在观察观察
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-1-26 23:55:55 | 显示全部楼层
zltzlt 发表于 2020-1-25 21:13
@小甲鱼 @不二如是 这样能申精吗


内容不是很多的话,单独拆成章节目录,每一节看上去都好像很短哦……

建议如果内容不是特别多,可以一篇到底,比目录翻页效果要好很多哈。

不过你的排版我是越来越喜欢了~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-1-27 06:02:48 | 显示全部楼层
小甲鱼 发表于 2020-1-26 23:55
内容不是很多的话,单独拆成章节目录,每一节看上去都好像很短哦……

建议如果内容不是特别多,可以 ...

赞同~~排版“外形”很棒

但是全篇看完,感觉没有“灵魂”

这个是之前写的:0 1 5 2 ★ 一个极其牛X的‘连等赋值’玩法!

会有明显:原创实打实的干货感


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-29 15:38:31 | 显示全部楼层
小甲鱼 发表于 2020-1-26 23:55
内容不是很多的话,单独拆成章节目录,每一节看上去都好像很短哦……

建议如果内容不是特别多,可以 ...

改了,现在可以了吗?

@不二如是
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-1-29 15:40:17 | 显示全部楼层
zltzlt 发表于 2020-1-29 15:38
改了,现在可以了吗?

@不二如是

OK
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-1-29 15:49:41 | 显示全部楼层
zltzlt 发表于 2020-1-29 15:38
改了,现在可以了吗?

@不二如是


嗯嗯,等等看鱼油的反馈吧,经得起群众的考验才是好文章
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-1-29 16:16:58 | 显示全部楼层
搞一个暴力破解压缩包密码的程序。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-29 16:30:10 | 显示全部楼层
一个账号 发表于 2020-1-29 16:16
搞一个暴力破解压缩包密码的程序。

迭代?像这样:
for i in range(1, 101):
        for j in 'abcdefghijklmnopqrstuvwxyz':
                ...

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2020-1-29 16:33:41 | 显示全部楼层
zltzlt 发表于 2020-1-29 16:30
迭代?像这样:

对,指定长度,指定字符,指定起始位置。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-29 16:36:52 | 显示全部楼层
一个账号 发表于 2020-1-29 16:33
对,指定长度,指定字符,指定起始位置。

太繁琐了,要是密码复杂,三天三夜都破解不出
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-1-31 16:25:01 | 显示全部楼层
不二如是 发表于 2020-1-25 21:16
首先“申精”的文章,一定被很多人看到认可。。。

除了内容实用外,写法一定备受大家喜欢,经得起时间的 ...

嗯,隔离观察 14 天
@zltzlt
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-31 16:26:12 | 显示全部楼层
_2_ 发表于 2020-1-31 16:25
嗯,隔离观察 14 天
@zltzlt

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-1-31 16:27:46 | 显示全部楼层


尴尬而又不失礼貌的微笑
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-31 16:28:02 | 显示全部楼层
_2_ 发表于 2020-1-31 16:27
尴尬而又不失礼貌的微笑

呵呵
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-31 18:09:24 | 显示全部楼层
没下文了吗@小甲鱼 @不二如是

感觉好少人啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-1-31 18:23:24 | 显示全部楼层
zltzlt 发表于 2020-1-31 18:09
没下文了吗@小甲鱼 @不二如是

感觉好少人啊

隔离一阵子嘛,别着急
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-31 18:24:04 | 显示全部楼层
不二如是 发表于 2020-1-31 18:23
隔离一阵子嘛,别着急

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-25 14:50

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表