【Pythonで自動化】ZIPファイルをダウンロードして解凍する

【Pythonで自動化】ZIPファイルをダウンロードして解凍する プログラミング

Pythonが便利過ぎて、いろんな作業を自動化しています。
その一環として、ファイルのダウンロードを自動化します。

ただ、そのファイルはZIPなのです。
欲しいのは、そのZIPの中にあるCSVという状況になります。

この記事では、このCSVを取得するまでを解説します。
コピペで利用可能なサンプルコードも載せておきます。

本記事の内容

  • 機能の整理
  • ファイル保存先(作業場)の準備
  • ZIPファイルのダウンロード
  • ZIPファイルの解凍

それでは、上記に沿って解説していきます。

機能の整理

「ZIPファイルをダウンロードして解凍する」
この仕様を実現するための機能を洗い出します。

大げさですが、常に機能分解は意識しておくことが重要です。
そうやって、分解した機能は以下。

  • ファイル保存先(作業場)の準備
  • ZIPファイルのダウンロード
  • ZIPファイルの解凍

上記の3つの機能に分解できます。
これらを以下で説明していきます。

ファイル保存先(作業場)の準備

作業場を用意します。

ファイル1つをダウンロードするだけなら、わざわざその必要はありません。
プログラムと同じ階層にファイルも保存すればいいだけです。

でも、本来は保存用のディレクトリを設けるのが正しい姿になります。
そして、今回はダウンロードしたZIPを解凍します。
展開とも言いますね。

そうなると、別途ファイル保存先を用意するべきです。
ということで、最初にファイル保存先を準備することから始めます。

コードにすると、以下のようになります。
Python標準ライブラリで対応できます。

import os
import shutil

data_dir_path = "./temp/"

# 保存先ディレクトリ作成
if os.path.exists(data_dir_path):
    # 既にある場合は、先に丸ごと削除する
    shutil.rmtree(data_dir_path)

os.mkdir(data_dir_path)

プログラムの説明は、コメントのままです。
上記プログラムにより、作業場(tempディレクトリ)が作成されます。

以上、ファイル保存先(作業場)の準備についての説明でした。
次は、ZIPファイルのダウンロードを確認します。

ZIPファイルのダウンロード

プログラムの確認から、行います。
この部分もPython標準ライブラリで対応できます。

import urllib.error
import urllib.request

file_url = "https://disclosure.edinet-fsa.go.jp/E01EW/download?uji.verb=W1E62071EdinetCodeDownload&uji.bean=ee.bean.W1E62071.EEW1E62071Bean&TID=&PID=&SESSIONKEY=&downloadFileName=&lgKbn=2&dflg=0&iflg=0&dispKbn=1"

save_path = "./temp/download.zip"

try:
    with urllib.request.urlopen(file_url) as download_file:
        data = download_file.read()
        with open(save_path, mode='wb') as save_file:
            save_file.write(data)
except urllib.error.URLError as e:
    print(e)

ダウンロード先に指定しているのは、EDINETで公開されているZIPファイルです。
詳細は、次の記事で説明しています。

上記プログラムを作成すると、tempディレクトリにdownload.zipが保存されます。
tempは、先ほど用意した作業場ですね。

なお、ファイルダウンロードにはエラーが付き物です。
そのため、例外処理も加えています。
エラーを表示するだけですけどね。

以上、ZIPファイルのダウンロードの説明でした。
次は、ZIPファイルの解凍を行っていきます。

ZIPファイルの解凍

ZIPファイルの解凍は、Python標準ライブラリで対応できます。
本当にPythonは便利ですね。

ZIPファイルは、先ほどのdownload.zipファイルを使いましょう。
このZIPファイルには、1つのCSVだけが入っています。

「EdinetcodeDlInfo.csv」というファイルです。
この場合、次のコードで作業場tempに指定したファイルだけを保存できます。

import zipfile

with zipfile.ZipFile("./temp/download.zip") as obj_zip:
    # zipから指定ファイル(第1引数)を取得して、指定ディレクトリ(第2引数)に保存する
    obj_zip.extract("EdinetcodeDlInfo.csv", "./temp/")

ZIPファイルの中身すべてを保存する場合は、以下のコードになります。

import zipfile

with zipfile.ZipFile("./temp/download.zip") as obj_zip:
    # 指定ディレクトリにすべてを保存する
    obj_zip.extractall("./temp/")

今回は、EdinetcodeDlInfo.csvファイルだけなので、結果は同じとなります。
tempディレクトリの中にEdinetcodeDlInfo.csvファイルが保存されているはずです。

以上、ZIPファイルの解凍について説明しました。
最後は、一連のコードをすべて結合して動作させてみましょう。

【サンプルコード】ZIPファイルをダウンロードして解凍する

上記のコードを結合します。
そうすると、ZIPファイルをダウンロードして解凍することが可能になります。

import zipfile
import urllib.error
import urllib.request
import os
import shutil

ZIP_URL = "https://disclosure.edinet-fsa.go.jp/E01EW/download?uji.verb=W1E62071EdinetCodeDownload&uji.bean=ee.bean.W1E62071.EEW1E62071Bean&TID=&PID=&SESSIONKEY=&downloadFileName=&lgKbn=2&dflg=0&iflg=0&dispKbn=1"


# 指定URL(第1引数)からファイルを取得して、指定パス(第2引数)に保存する
def file_download(url, save_path):
    try:
        with urllib.request.urlopen(url) as download_file:
            data = download_file.read()
            with open(save_path, mode='wb') as save_file:
                save_file.write(data)
    except urllib.error.URLError as e:
        print(e)


if __name__ == "__main__":

    data_dir_path = "./temp/"
    zip_file_path = data_dir_path + "download.zip"
    csv_file_name = "EdinetcodeDlInfo.csv"
    csv_file_path = data_dir_path + csv_file_name

    # 保存先ディレクトリ作成
    if os.path.exists(data_dir_path):
        # 既にある場合は、先に丸ごと削除する
        shutil.rmtree(data_dir_path)

    os.mkdir(data_dir_path)

    # zip取得
    file_download(ZIP_URL, zip_file_path)

    if os.path.exists(zip_file_path):

        with zipfile.ZipFile(zip_file_path) as obj_zip:
            # zipから指定ファイル(第1引数)を取得して、指定ディレクトリ(第2引数)に保存する
            obj_zip.extract(csv_file_name, data_dir_path)
            #obj_zip.extractall(data_dir_path)

    if os.path.exists(csv_file_path):
        print(csv_file_path)

上記コードを実行すると、tempディレクトリが同じ階層に作成されます。
tempディレクトリの中身は、以下。

「ZIP_URL」の値と次の部分を変更すれば、上記サンプルコードを汎用的に使えます。

   data_dir_path = "./temp/"
    zip_file_path = data_dir_path + "download.zip"
    csv_file_name = "EdinetcodeDlInfo.csv"
    csv_file_path = data_dir_path + csv_file_name

以上、「ZIPファイルをダウンロードして解凍する」についての説明を終わります。

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