如何在Python中从zip文件中提取文件而不保留目录结构?

40

我正在尝试使用Python从zip文件归档中提取特定文件。

在这种情况下,从apk本身中提取apk图标。

我目前正在使用

with zipfile.ZipFile('/path/to/my_file.apk') as z:
    # extract /res/drawable/icon.png from apk to /temp/...
    z.extract('/res/drawable/icon.png', 'temp/')

我的脚本目录中有一个 temp/res/drawable/icon.png 文件,它确实可以工作,这是将文件放在apk内相同路径的temp。

但是我真正想要的是最终得到 temp/icon.png

有没有直接使用zip命令完成此操作的方法,或者我需要先提取文件,然后移动文件,最后手动删除目录?

1个回答

63
您可以使用 zipfile.ZipFile.open
import shutil
import zipfile

with zipfile.ZipFile('/path/to/my_file.apk') as z:
    with z.open('/res/drawable/icon.png') as zf, open('temp/icon.png', 'wb') as f:
        shutil.copyfileobj(zf, f)

或者使用zipfile.ZipFile.read:

import zipfile

with zipfile.ZipFile('/path/to/my_file.apk') as z:
    with open('temp/icon.png', 'wb') as f:
        f.write(z.read('/res/drawable/icon.png'))

两个非常好的答案,比我简单地移动要优雅得多。为了适应问题的要求,稍作修改,代码为:with open(os.path.join(tDir,os.path.basename(icon[1])), 'wb') as f: 这样输出的图标就在临时目录中,而不是脚本所在的cwd()。谢谢。 - rcbevans
1
值得注意的是,extractextract_all的CPython实现使用"zipfile.ZipFile.open"版本:例如 https://github.com/python/cpython/blob/v3.7.0/Lib/zipfile.py#L1647 - Nzbuu
1
不客气,@falsetru。我尝试了你的实现并注意到一些问题,后来发现是缺少导入。除此之外,它像钟表一样运作良好。 - ivanleoncz
3
请注意,使用 zipfile.ZipFile.read 会在将文件写入磁盘之前将整个文件加载到内存中。 - darkheir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接