Python で ZIP ファイルを作成・展開する(zipfile)

ZIP ファイルの作成や展開には zipfile モジュールを使う。

ZIP ファイルを作成する

ZipFile をライトモード('w')で開き、write() でファイルを追加する。

import zipfile

with zipfile.ZipFile('archive.zip', 'w') as zf:
    zf.write('file1.txt')
    zf.write('file2.txt')

arcname 引数で、ZIP 内でのファイル名を指定できる。

import zipfile

with zipfile.ZipFile('archive.zip', 'w') as zf:
    zf.write('data/report.txt', arcname='report.txt')

ディレクトリを丸ごと圧縮する

ディレクトリ内のすべてのファイルを ZIP にするには、再帰的にファイルを追加する。

import zipfile
from pathlib import Path

def zip_directory(folder_path, zip_path):
    with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zf:
        for file in Path(folder_path).rglob('*'):
            if file.is_file():
                arcname = file.relative_to(folder_path)
                zf.write(file, arcname)

zip_directory('mydir', 'mydir.zip')

zipfile.ZIP_DEFLATED を指定すると圧縮される。デフォルトの ZIP_STORED は圧縮なしで格納される。

ZIP ファイルを展開する

extractall() で ZIP ファイルを展開する。

import zipfile

with zipfile.ZipFile('archive.zip', 'r') as zf:
    zf.extractall('output_dir')

特定のファイルだけを取り出すには extract() を使う。

import zipfile

with zipfile.ZipFile('archive.zip', 'r') as zf:
    zf.extract('file1.txt', 'output_dir')

ZIP ファイルの中身を確認する

namelist() で ZIP 内のファイル一覧を取得できる。

import zipfile

with zipfile.ZipFile('archive.zip', 'r') as zf:
    for name in zf.namelist():
        print(name)

infolist() を使うと、ファイルサイズや圧縮率などの詳細情報も取得できる。

import zipfile

with zipfile.ZipFile('archive.zip', 'r') as zf:
    for info in zf.infolist():
        print(f'{info.filename}: {info.file_size} bytes')

ZIP 内のファイルを直接読む

展開せずに ZIP 内のファイルを読み取ることもできる。

import zipfile

with zipfile.ZipFile('archive.zip', 'r') as zf:
    content = zf.read('file1.txt')
    print(content.decode('utf-8'))

テキストファイルとして読むには open() を使う。

import zipfile

with zipfile.ZipFile('archive.zip', 'r') as zf:
    with zf.open('file1.txt') as f:
        for line in f:
            print(line.decode('utf-8').strip())

パスワード付き ZIP を扱う

パスワード付き ZIP の展開は pwd 引数で指定する。

import zipfile

with zipfile.ZipFile('protected.zip', 'r') as zf:
    zf.extractall(pwd=b'secret123')

ただし、zipfile モジュールではパスワード付き ZIP の作成はサポートされていない。作成する場合は pyminizip などのサードパーティライブラリを使う。