Python | 自動化:ファイル変換自動化

Python
スポンサーリンク

概要(「○○を置いたら自動で△△に変換」を型にする)

ファイル変換自動化は、「特定のフォルダにファイルを置くだけで、Python が自動で別形式に変えてくれる」仕組みです。
例えば、Excel → CSV、CSV → Excel、画像のサイズ変更と形式変換、UTF-8 への文字コード統一、JSON → CSV など。

やること自体はシンプルで、次の三つに分解できます。

どのフォルダの、どんなファイルを対象にするか決める。
入ってきたファイルを、ライブラリを使って読み取る。
変換した結果を、決めたフォルダと名前で保存する。

大事なのは、「パスの扱い」「変換ルール」「エラーや例外時の動き」を最初にきちんと設計することです。
これを一度決めてしまえば、あとはいろいろな変換に横展開できます。


基本の型(Path でファイルを探して、拡張子で分岐して処理)

pathlib で扱いやすいフォルダ構成を決める

まずは、フォルダ構成とファイルパスの扱いから整えます。
相対パスではなく、スクリプトを起点とした絶対パスを持つのが定番です。

from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent
IN_DIR = BASE_DIR / "input"
OUT_DIR = BASE_DIR / "output"

IN_DIR.mkdir(exist_ok=True)
OUT_DIR.mkdir(exist_ok=True)
Python

この形にしておくと、どこから実行しても「input」「output」が迷子になりません。
cron やタスクスケジューラから実行するバッチでも安定します。

拡張子ごとに処理を切り替える最小例

次に、「input フォルダ内のファイルを全部なめて、拡張子に応じた変換を行う」基本形を作ります。

def main():
    for path in IN_DIR.glob("*"):
        if not path.is_file():
            continue

        ext = path.suffix.lower()
        if ext == ".xlsx":
            convert_excel_to_csv(path)
        elif ext == ".csv":
            convert_csv_to_excel(path)
        elif ext in [".jpg", ".jpeg", ".png"]:
            convert_image_to_webp(path)
        else:
            print(f"対象外: {path.name}")

if __name__ == "__main__":
    main()
Python

この「拡張子で分岐して関数を呼ぶ」という型を一度作っておくと、後は convert_xxx の中身を増やしていくだけで対応形式を増やせます。
重要なのは、各関数の責務をはっきりさせることです。
つまり、「受け取った1ファイルを変換し、どこにどういう名前で保存するか」を、関数の中で完結させます。


例1:Excel ⇔ CSV の変換を自動化する(pandas ベース)

Excel を CSV に変換する関数

pandas を使うと、Excel と CSV の変換はほぼ一行ずつで書けます。
ライブラリがインストールされていなければ先に入れておきます。

pip install pandas openpyxl

そして、Excel から CSV への変換。

import pandas as pd

def convert_excel_to_csv(path: Path):
    print(f"Excel → CSV: {path.name}")
    df = pd.read_excel(path, sheet_name=0, engine="openpyxl")

    out_name = path.stem + ".csv"
    out_path = OUT_DIR / out_name

    df.to_csv(out_path, index=False, encoding="utf-8-sig")
    print(f"  保存しました: {out_path.name}")
Python

ポイントはいくつかあります。

sheet_name=0 で最初のシートだけを対象にしています。複数シートを扱いたければループするか、名前指定にします。
Excel に日本語が含まれる想定なら、CSV を utf-8-sig で出すと、Excel でも文字化けしにくくなります。
out_path の生成で path.stem を使うことで、拡張子だけ差し替えたファイル名を作っています。

CSV を Excel に変換する関数

逆方向も、pandas で簡単です。

def convert_csv_to_excel(path: Path):
    print(f"CSV → Excel: {path.name}")
    df = pd.read_csv(path, encoding="utf-8")

    out_name = path.stem + ".xlsx"
    out_path = OUT_DIR / out_name

    df.to_excel(out_path, index=False, engine="openpyxl")
    print(f"  保存しました: {out_path.name}")
Python

ここで重要なのは、「どのエンコーディングで読むか」です。
Windows の Excel で保存した CSV なら cp932、UTF-8 で出力された CSV なら utf-8 と、データの実態に合わせる必要があります。
「毎回同じ形式で来るように運用で合わせる」か、「最初に try/except で候補のエンコーディングを試す」かを決めておくと安定します。


例2:画像の形式変換とリサイズ自動化(Pillow 使用)

Pillow の準備と基本的な変換

画像ファイルを一括で WebP や JPEG に変換したり、サムネイルを作ったりするのもよくある自動化です。
Pillow(PIL の後継)を使います。

pip install pillow

例えば、「input の jpg/png を横幅 800 にリサイズして WebP に変換する」処理は次のように書けます。

from PIL import Image

def convert_image_to_webp(path: Path, max_width=800):
    print(f"画像変換: {path.name}")
    img = Image.open(path)

    w, h = img.size
    if w > max_width:
        new_h = int(h * max_width / w)
        img = img.resize((max_width, new_h), Image.LANCZOS)

    out_name = path.stem + ".webp"
    out_path = OUT_DIR / out_name

    img.save(out_path, format="WEBP", quality=85)
    print(f"  保存しました: {out_path.name}")
Python

ここで深掘りしておきたいのはリサイズの扱いです。

横幅だけ指定して縦は比率で計算し直すことで、「縦横比を保ったまま縮小」しています。
元の画像より小さくするだけにしているので、無駄な引き伸ばしは起こしません。
Image.LANCZOS は品質重視のリサンプリング方法です。サイズと画質のバランスを意識します。

変換後の元ファイルの扱い(残すか、移動か、削除か)

画像や Excel の変換では、「変換が終わった元ファイルをどう扱うか」を決めておくことも大事です。

例えば、処理済みファイルを input/processed フォルダへ移動する関数を用意しておくと、同じファイルを何度も変換し続ける事故を防げます。

import shutil

PROCESSED_DIR = IN_DIR / "processed"
PROCESSED_DIR.mkdir(exist_ok=True)

def mark_as_processed(path: Path):
    dest = PROCESSED_DIR / path.name
    shutil.move(str(path), str(dest))
Python

そして convert_xxx の最後で mark_as_processed(path) を呼ぶようにすれば、
input フォルダには「まだ処理していないファイルだけ」が残っていく運用になります。


例3:文字コード変換(Shift_JIS → UTF-8)を自動化する

文字コード混在の「地獄」を避けるために

現場では、古いシステムから吐き出された Shift_JIS の CSV と、
自分で作った UTF-8 の CSV が混じる、ということがよく起きます。

Python 側で扱いやすくするために、「とりあえず全部 UTF-8 に統一する」バッチを挟んでおくと楽になります。

シンプルなエンコーディング変換

これは pandas なしでもいけます。

def convert_encoding_to_utf8(path: Path, src_encoding="cp932"):
    print(f"文字コード変換: {path.name}")
    text = path.read_text(encoding=src_encoding, errors="replace")
    out_name = path.stem + "_utf8" + path.suffix
    out_path = OUT_DIR / out_name
    out_path.write_text(text, encoding="utf-8")
    print(f"  保存しました: {out_path.name}")
Python

cp932 は Windows の Shift_JIS 互換です。
errors=”replace” にしておくと、どうしても読めない文字は「?」などに置き換えられ、例外でバッチが止まるのを防げます。
厳密にやりたい場合は errors=”strict” にして例外をログに出し、問題ファイルを個別対応する方針もあります。

拡張子で条件分岐して、「.csv や .txt だけを対象に変換する」ように main 側で制御します。


設計の重要ポイントの深掘り(パス、エラー、再実行、安全性)

パスは「BASE_DIR 起点で絶対パス」を徹底する

自動化・バッチ化を考えるなら、相対パスで書き散らかさないことが非常に重要です。
BASE_DIR を決めて、そこから input、output、ログ、テンプレ…とフォルダをぶら下げる。
これを定型化しておけば、環境が変わってもパス地獄になりません。

変換ルールを「関数名とファイル名」に刻んでおく

convert_excel_to_csv という名前の関数が
「input の .xlsx を、output の .csv にする」
というルールを持っている、というのが分かるだけで、後からコードを読んだときの理解が格段に楽になります。

出力ファイル名にも、変換内容を反映させておくとさらに親切です。

例えば Shift_JIS → UTF-8 変換なら _utf8 を付ける。
サムネイルなら _thumb、圧縮版なら _min など。

エラー時の動きとログ

自動変換では、「1ファイルでエラーが出ても、他のファイルは処理を続ける」設計が実務的です。
最外のループで try/except を入れて、エラー内容だけ表示またはログに残し、次のファイルへ進むようにします。

def main():
    for path in IN_DIR.glob("*"):
        if not path.is_file():
            continue
        try:
            handle_one_file(path)
        except Exception as e:
            print(f"エラー: {path.name}: {e}")
Python

こうしておくと、「問題児ファイルが1つ混じっていても、その他の変換が止まらない」状態を保てます。
本気で運用するなら logging モジュールでログファイルに出力するのがおすすめです。

再実行しても壊れないようにする(冪等性)

ファイル変換バッチは、途中で落ちたときに「もう一度実行したらどうなるか」を必ず考えます。

元ファイルの上書きは極力避ける。
出力ファイル名を工夫して、既にあるならスキップするか、別名で保存する。
処理済みファイルを別フォルダへ移動して、未処理のものだけ対象にする。

このあたりを先に設計しておくと、「再実行が怖くない」バッチになります。


監視・定期実行との組み合わせイメージ

ここまでで「input から output へ変換する1回分の処理」ができたら、
それを「どうトリガーするか」を決めれば、完全自動化になります。

フォルダ監視(watchdog)で、ファイルが置かれた瞬間に convert_xxx を呼ぶ。
cron / タスクスケジューラで、10分おきや1時間おきに main を実行する。

重要なのは、「トリガー側は時間やイベントだけを担当し、変換ロジックは今書いた Python スクリプトに集中させる」という役割分担です。
時間や監視の制御を Python の中に書き込むより、OSや監視ライブラリに任せた方がシンプルで壊れにくくなります。


まとめ(「ファイルを拾う → 拡張子で分岐 → ライブラリで変換 → 安全に保存」を型にする)

ファイル変換自動化の本質は、難しいアルゴリズムではなく設計です。

Path と BASE_DIR を使ってパスを安定させる。
input フォルダからファイルを拾い、拡張子で関数を呼び分ける。
pandas や Pillow などのライブラリで、「1ファイルをどう変換するか」を関数に閉じ込める。
出力先とファイル名、エラー時の挙動、再実行時の安全性を最初に決めておく。

この型さえ身につければ、Excel/CSV/画像/テキスト/JSON など、
今「手動で開いて保存し直している」変換作業のかなりの部分を、Python に任せられるようになります。

タイトルとURLをコピーしました