Pythonでzipファイルを圧縮・解凍するzipfile

Python標準ライブラリのzipfileモジュールを使うと、ファイルをzipに圧縮したり、zipファイルを解凍したりすることができます。標準ライブラリに含まれているので追加のインストールは不要。

13.5. zipfile — ZIP アーカイブの処理 — Python 3.6.3 ドキュメント

以下の内容について説明します。

複数のファイルをzipファイルに圧縮 既存のzipファイルに新たなファイルを追加 ディレクトリ(フォルダ)をzipファイルに圧縮 パスワード付きのzipファイルに圧縮 zipファイルの中身を確認 zipファイルの中身をすべて解凍(展開) zipファイルの中身を選択して解凍(展開)

複数のファイルをzipファイルに圧縮

ZipFileオブジェクトを作成し、write()メソッドで圧縮したいファイルを追加していく。 zipファイルを新規作成する場合は、ZipFileオブジェクトのコンストラクタの第一引数fileに作成するzipファイルのパスを指定し、第二引数modeを'w'とします。 さらに、第三引数compressionで圧縮方式を指定できます。

zipfile.ZIP_STORED: 圧縮せず複数ファイルをまとめるだけ(デフォルト) zipfile.ZIP_DEFLATED: 通常のZIP圧縮(要zlibモジュール) zipfile.ZIP_BZIP2: BZIP2圧縮(要bz2モジュール) zipfile.ZIP_LZMA: LZMA圧縮(要lzmaモジュール)

BZIP2、LZMAのほうが圧縮率が高い(より小さいサイズに圧縮できる)が、圧縮にかかる時間が長くなります。

A Quick Benchmark: Gzip vs. Bzip2 vs. LZMA

write()メソッドでは、第一引数filenameのファイルを第二引数arcnameという名前でzipファイルに書き込む。arcnameは省略するとfilenameがそのまま使われる。arcnameにディレクトリ構造を指定することもできます。 ZipFileオブジェクトはclose()メソッドでクローズする必要があるが、with文を使うとブロックが終了したときに自動的にクローズされます。

import zipfile

with zipfile.ZipFile('data/temp/new_comp.zip', 'w', compression=zipfile.ZIP_DEFLATED) as new_zip:
    new_zip.write('data/temp/test1.txt', arcname='test1.txt')
    new_zip.write('data/temp/test2.txt', arcname='zipdir/test2.txt')
    new_zip.write('data/temp/test3.txt', arcname='zipdir/sub_dir/test3.txt') 

write()メソッドの引数compress_typeを指定することで、ファイルごとに圧縮方式を選択することもできます。
with zipfile.ZipFile('data/temp/new_comp_single.zip', 'w') as new_zip:
    new_zip.write('data/temp/test1.txt', arcname='test1.txt', compress_type=zipfile.ZIP_DEFLATED)
    new_zip.write('data/temp/test2.txt', arcname='zipdir/test2.txt')
    new_zip.write('data/temp/test3.txt', arcname='zipdir/sub_dir/test3.txt')

既存のzipファイルに新たなファイルを追加

既存のzipファイルに新たなファイルを追加するには、ZipFileオブジェクトを作成する際に、コンストラクタの第一引数fileを既存のzipファイルのパス、第二引数modeを'a'とします。 あとは上の例と同じく、write()メソッドでファイルを追加すれば問題ありません。

with zipfile.ZipFile('data/temp/new_comp.zip', 'a') as existing_zip:
    existing_zip.write('data/temp/test4.txt', arcname='test4.txt')

ディレクトリ(フォルダ)をzipファイルに圧縮

ディレクトリ(フォルダ)をまるごと一つのzipファイルに圧縮する場合、os.scandir()やos.listdir()でファイルのリストを作って行うこともできるが、shutilモジュールのmake_archive()を使うほうが簡単。

パスワード付きのzipファイルに圧縮

zipfileモジュールでは、パスワードで保護されたzipを作成することはできません。ファイルをパスワード付きのzipファイルに圧縮したい場合は、サードパーティのライブラリpyminizipを使います。

pyminizip 0.2.1 : Python Package Index

なお、パスワード保護されたzipの解凍はzipfileモジュールで行うことが可能(後述)。

zipファイルの中身を確認

既存のzipファイルの中身を確認することができます。 ZipFileオブジェクトを、コンストラクタの第一引数fileを既存のzipファイルのパス、第二引数modeを'r'として作成します。引数modeはデフォルトがrなので省略できます。 ZipFileオブジェクトのnamelist()メソッドで、アーカイブされているファイルのリストを取得できます。

with zipfile.ZipFile('data/temp/new_comp.zip') as existing_zip:
    print(existing_zip.namelist())
# ['test1.txt', 'zipdir/test2.txt', 'zipdir/sub_dir/test3.txt', 'test4.txt']

zipファイルの中身をすべて解凍(展開)

zipファイルの中身を解凍する場合も、上の中身を確認する例と同じく、ZipFileオブジェクトを、コンストラクタの第一引数fileを既存のzipファイルのパス、第二引数modeを'r'として作成します。引数modeはデフォルトがrなので省略できます。 ZipFileオブジェクトのextractall()メソッドで、zipファイルの中身がすべて解凍(展開)されます。第一引数pathに展開先のディレクトリのパスを指定します。省略するとカレントディレクトリに解凍されます。

with zipfile.ZipFile('data/temp/new_comp.zip') as existing_zip:
    existing_zip.extractall('data/temp/ext')

パスワード付きのzipファイルはextractall()メソッドの引数pwdにパスワードを指定すると解凍できます。

with zipfile.ZipFile('data/temp/new_comp_with_pass.zip') as pass_zip:
    pass_zip.extractall('data/temp/ext_pass', pwd='password')

zipファイルの中身を選択して解凍(展開)

ある特定のファイルだけを解凍して取り出したい場合は、extract()メソッドを使います。 extract()メソッドの第一引数に解凍するファイル名(zipファイル内のディレクトリに格納されている場合はそれも含めたパス)、第二引数pathに展開先のディレクトリのパスを指定します。引数pathは省略するとカレントディレクトリに解凍されます。

with zipfile.ZipFile('data/temp/new_comp.zip') as existing_zip:
    existing_zip.extract('test1.txt', 'data/temp/ext2')

extract()メソッドもextractall()メソッドと同様、引数pwdにパスワードを指定できます。

with zipfile.ZipFile('data/temp/new_comp_with_pass.zip') as pass_zip:
    pass_zip.extract('test1.txt', 'data/temp/ext_pass2', pwd='password')
Last Updated: 6/26/2019, 10:34:03 PM