やっほー!国内のAI狂いだよ!✨
PythonでZipファイルやExcelを操作してて、「ファイルはあるのに読み込めない!?」ってパニックになったことない? それ、もしかしたら「偽物」のファイルを掴まされているかも…!😱
スクレイピングでダウンロードしたファイルを解凍したり、フォルダ内のファイルを一括処理したりしている時に、突然こんなエラーが出て止まること、ありますよね。
「えっ、拡張子は .zip (または .xlsx)になってるよ!? ファイル壊れてないよ!?」
と、PCに向かって叫んでもエラーは消えません。
実はこのエラー、単にファイルが壊れているだけでなく、「中身が別物(HTMLなど)」だったり、「パスワードによる暗号化」が原因だったりすることが多いんです。
この記事では、私が過去に大量のファイル処理で踏み抜いた「BadZipFile」の全パターンと、その特定・回避方法を徹底解説します!🚀
1. そもそも `BadZipFile` とは何なのか?
このエラーは、Python標準ライブラリの zipfile モジュール(またはそれを使用している openpyxl など)が、「これはZipファイルとして解釈できないよ!」と判断した時に発生します。
Pythonはファイルの「拡張子(.zip)」を見ているのではありません。
ファイルの中身(バイナリデータ)の先頭にあるはずの「署名(シグネチャ)」を見ています。
- 正常なZip: ファイルの先頭が
PK(0x50, 0x4B) で始まっている。 - BadZipFile: 先頭が違う文字(例えば
<!DOCTYPE html>とか)になっている。
つまり、PC上ではZipファイルに見えても、中身がZipのルールに従っていないとこのエラーが出るんだね。
2. 【原因①】中身が別物(拡張子詐欺)のパターン
スクレイピングなどの自動化処理で一番多いのがこれです。
事例:ダウンロードに失敗してエラーページを保存
例えば、requests でZipファイルをダウンロードするコードを書いたとします。
もしURLが間違っていたりサーバーエラーだった場合、Pythonは「404 Not Found」と書かれたHTMLファイルをダウンロードし、それを「data.zip」という名前で保存してしまうことがあります。
これを zipfile で開こうとすると…
Python「拡張子はZipだけど、中身HTMLじゃん!読めないよ!(BadZipFile)」
となるわけです。
【対策】中身をバイナリで確認するコード
「このファイル、怪しいな?」と思ったら、メモ帳で開くか、以下のコードで先頭を確認してみて!
# ファイルの先頭を確認する魔法のコード
file_path = "suspicious_file.zip" # 怪しいファイル
with open(file_path, "rb") as f:
# 先頭の2バイトを読み込む
header = f.read(2)
print(header)
# 結果の判定
# b'PK' -> Zipファイルの可能性大(正常)
# b'<!' -> HTMLファイルかも(失敗)
# b'' -> 空ファイル(ダウンロード失敗)
3. 【原因②】ファイルが単純に壊れている(ダウンロード中断)
次に多いのが、通信環境が悪くて「ダウンロードが途中で切れた」パターン。
ファイルサイズが極端に小さい(0KBや1KBなど)場合はこれを疑ってください。
知恵袋でも「特定のファイルを除外したら直った」という事例がありましたが、フォルダ内のファイルループ処理をする時は、必ず「壊れたファイルをスキップする処理(例外処理)」を入れるのが鉄則だよ!🛡️
import os
import zipfile
zip_dir = "./zipfolder"
for filename in os.listdir(zip_dir):
file_path = os.path.join(zip_dir, filename)
try:
# 解凍を試みる
with zipfile.ZipFile(file_path, 'r') as z:
z.extractall("./output")
print(f"成功: {filename}")
except zipfile.BadZipFile:
# エラーが出ても止まらず、報告だけして次へ!
print(f"❌ 失敗(壊れてるかも): {filename}")
except PermissionError:
print(f"❌ 権限エラー: {filename}")
これで、1つのファイルが壊れていてもプログラム全体が止まることはなくなるよ!✨
4. 【原因③】Excelファイル(openpyxl)で出る場合
「私はZipじゃなくてExcelを操作してるのに、このエラーが出るんだけど!?」
という人。実は Excelファイル(.xlsx)の実体はZipファイル なんです。
だから、openpyxl は内部で zipfile を使ってExcelを読み込んでいます。
パスワード付きExcelの罠
ここで最大の罠なのが、「読み取りパスワードが付いたExcelファイル」。
パスワードがかかるとファイル全体が暗号化されるため、標準のZip構造が見えなくなり、Pythonは「これZipじゃない(BadZipFile)」と判断します。
openpyxl はパスワード付きExcelを開けません。
【対策】msoffcrypto-tool を使う
パスワード付きExcelを扱いたい場合は、msoffcrypto-tool というライブラリを使って、一度パスワードを解除(復号)する必要があります。
# pip install msoffcrypto-tool
import msoffcrypto
import openpyxl
import io
password = "secret_password"
encrypted_file = open("encrypted.xlsx", "rb")
# メモリ上でパスワードを解除したファイルを作成
decrypted_file = io.BytesIO()
office_file = msoffcrypto.OfficeFile(encrypted_file)
office_file.load_key(password=password)
office_file.decrypt(decrypted_file)
# openpyxlで読み込む
wb = openpyxl.load_workbook(decrypted_file)
print("パスワード付きExcel、攻略完了!😎")
5. 【原因④】Zipの暗号化方式が対応していない(AES)
これもマニアックだけどハマるやつ。
Pythonの標準 zipfile モジュールは、古い「ZipCrypto」という暗号化方式には対応していますが、最近の主流である「AES暗号化」されたパスワード付きZipには対応していません。
(※この場合は BadZipFile ではなく RuntimeError になることが多いですが、ツールによってはファイル構造が読み取れずBadZipFileになることもあります)
この場合は、強化版ライブラリである pyzipper を使うと解決します。
# pip install pyzipper
import pyzipper
with pyzipper.AESZipFile('secret.zip') as z:
z.pwd = b'password'
z.extractall()
6. エラーと戦う時間を減らそう(まとめ)
BadZipFile エラーが出た時のチェックリストをまとめるね!
- 中身確認: メモ帳で開いてHTMLになってない?(拡張子詐欺)
- サイズ確認: 0KBとかになってない?(ダウンロード失敗)
- パスワード: ExcelやZipにパスワードかかってない?
こういう「コードの書き方じゃなくて、ファイルの状態が原因」のエラーって、独学だと本当に気づきにくいんだよね。
「なんで動かないのー!😭」って3時間悩んだ挙句、原因がただのダウンロードミスだった時の脱力感といったら…。
もしあなたが、「こういうトラブルシューティングにかかる時間を『お金』で解決したい(=プロに即レスで聞きたい)」と思うタイプなら、質問し放題の環境を持つのが最強の時短術だよ。
私が厳選した、「実務レベルのエラーも相談できるスクール」の記事を置いておくから、「もう無駄な時間を使いたくない!」って人はチェックしてみてね👇
🐍「エラーで1日終わった…」と絶望する前に
独学の壁は「環境構築」と「ロードマップ選び」で9割決まります。
時間を溶かす前に、現役エンジニアが選んだ「プロの環境」を覗いてみませんか?
※自分に合った「勝ちパターン」を見つけるのが、挫折しない唯一のコツだよ!
正しいファイルを見極めて、エラーを秒殺しよう!🔫 by 国内のAI狂い





