python PDF
#ファイル整理
#python
ファイル整理
がんばったり
なまけたり
でんでん虫 の 歩みである;;
さて
PDF ふぁいる!
なんちゃら.pdf
だぶるくりっく!
開けね~~~
なんでやねん!
【Gemini】様に
開けない pdfファイルの 一括処理
すくりぷと を つくって いただいた
# ==== 【Gemini】様
import os
import shutil
from pypdf import PdfReader
# ==========================================
# 設定項目
# ==========================================
TARGET_DIR = r"E:\__WORK"
NG_DEST_DIR = r"E:\__WORK-PDF-NG"
LOG_FILE_PATH = os.path.join(NG_DEST_DIR, "pdf_check_log.txt") # ログの保存先
def check_pdf_status(file_path):
"""
PDFファイルの状態をチェックする関数
戻り値: (判定結果True/False, 理由のメッセージ)
"""
try:
# 【ステップ1】マジックナンバーのチェック(偽装対策)
with open(file_path, "rb") as f:
header = f.read(4)
if header != b"%PDF":
# 実際のヘッダーを文字として読める形式にしてログに残す
readable_header = header.hex()
return False, f"【拡張子偽装】ファイル先頭が %PDF ではありません(データ: 0x{readable_header})"
# 【ステップ2】pypdfによる構造チェック(破損対策)
reader = PdfReader(file_path)
_ = len(reader.pages) # ページ数を読めるかテスト
return True, "正常"
except Exception as e:
# 発生したエラーメッセージ(英語)をそのまま理由として返す
error_msg = str(e) if str(e) else "ファイルが完全に壊れているか、空っぽです。"
return False, f"【ファイル破損】PDF構造エラー(詳細: {error_msg})"
def main():
if not os.path.exists(NG_DEST_DIR):
os.makedirs(NG_DEST_DIR)
success_count = 0
ng_count = 0
# ログ記録用のリスト
log_lines = ["=== PDF判定 NG理由ログ ===", ""]
print("PDFのチェック(原因ログ記録モード)を開始します...")
print("-" * 50)
for root, dirs, files in os.walk(TARGET_DIR):
if os.path.commonpath([root, NG_DEST_DIR]) == os.path.normpath(NG_DEST_DIR):
continue
for file in files:
if not file.lower().endswith(".pdf"):
continue
# ログファイル自体を検索しないようにスキップ
if file == "pdf_check_log.txt":
continue
file_path = os.path.join(root, file)
# チェック実行(判定結果と理由を取得)
is_valid, reason = check_pdf_status(file_path)
if is_valid:
success_count += 1
else:
ng_count += 1
dest_path = os.path.join(NG_DEST_DIR, file)
if os.path.exists(dest_path):
base, ext = os.path.splitext(file)
dest_path = os.path.join(NG_DEST_DIR, f"{base}_duplicated{ext}")
# ログに記録する文章を作成
log_entry = f"【ファイル】: {file_path}\n【理由】: {reason}\n"
log_lines.append(log_entry)
# 画面にもリアルタイムで表示
print(f"![NG] {file}")
print(f" └ 理由: {reason}")
try:
shutil.move(file_path, dest_path)
except Exception as e:
print(f"【エラー】移動失敗: {e}")
# 最後にログファイルにまとめて書き出し
log_lines.append("-" * 50)
log_lines.append(f"正常: {success_count} 件 / 異常: {ng_count} 件")
with open(LOG_FILE_PATH, "w", encoding="utf-8") as log_file:
log_file.write("\n".join(log_lines))
print("-" * 50)
print("チェックが完了しました。")
print(f"正常(そのまま): {success_count} 件")
print(f"異常(NGへ移動): {ng_count} 件")
print(f"NGの原因ログを保存しました: {LOG_FILE_PATH}")
if __name__ == "__main__":
main()
# ==============================