Pythonでrarファイルを解凍する
はじめに
rarfileのパッケージを使ってPythonでrarファイルを展開する方法の紹介です。
いろいろ嵌ったので、自分の備忘録も含んでいます。
ソースコード
とりあえず、結論としてはこんな感じで動きます。
extract(), extractall()は引数に展開先フォルダを指定できるので、必要に応じて設定してください。
import rarfile # Set to full path of unrar.exe if it is not in PATH # rarfile.pyでは unrar.exe があることを前提に動くので、 # パスを切っていなければパラメーターとして設定する。 rarfile.UNRAR_TOOL = r"D:\Unrar\Unrar.exe" # Set to '\\' to be more compatible with old rarfile rarfile.PATH_SEP = '/' rf = rarfile.RarFile('D:\\Work\\TEST.rar') # rarファイルを展開する rf.extractall() # ファイル情報を取得する場合 for f in rf.infolist(): # rarファイルの内容を出力 print(f.filename, f.file_size) # 1ファイルずつ展開 # ただし、ディレクトリを展開すると、フォルダ構成がおかしくなるので、 # 必要に応じて展開をスキップするようにすること。 rf.extract(f.filename)
嵌ったこと(その他メモ)
その1. rarfileパッケージのインストール
rarfule.pyを使うためには、パッケージのインストールが必要です。以下のコマンドでインストールしてください。
pip install rarfile
そうすると、以下のようなメッセージが表示されてインストールが完了します。
Downloading https://files.pythonhosted.org/packages/de/a4/8b4abc72310da6fa53b6de8de1019e
100% |████████████████████████████████| 112kB 1.4MB/s
Building wheels for collected packages: rarfile
Running setup.py bdist_wheel for rarfile ... done
Stored in directory: C:\Users\XXXXX\AppData\Local\pip\Cache\wheels\dc\84\da\8aff50941f5
Successfully built rarfile
Installing collected packages: rarfile
Successfully installed rarfile-3.0
その2. unrar.exeのインストール
rarfileパッケージはファイルの展開時にunrar.exeがあることを前提に動作します。
unrar.exeへのパスを切っていない場合はパスを切るか、"rarfile.UNRAR_TOOL"パラメータでunrar.exeへのフルパスを定義する必要があります。
そもそも 「unrar.exeをインストールしていないよ」という方は以下からダウンロードしてください。
www.rarlab.com
・左のメニュー [ RAR ] - [ extras ] から [ UnRAR for Windows ] をクリックするとダウンロードできます。
・unrarw32.exe は自己解凍形式の圧縮形式のファイルなので、ダブルクリックして展開してください。unrar.exeが展開されます。
その3. rarfile.pyが動かない
今回一番嵌ったことです。本記事を書いている2019/2/19時点では、unrar.exeへのパスを定義してもunrar.exeの実行でエラーが発生します。
rarfile.pyの中でunrar.exeのコマンドラインを生成しているのですが、そのロジックに誤りがありそうです。
具体的には、860行目あたりの_extract()メソッドが以下のようになっているのですが、
# call unrar to extract a file def _extract(self, fnlist, path=None, psw=None): cmd = [UNRAR_TOOL] + list(EXTRACT_ARGS) # pasoword psw = psw or self._password add_password_arg(cmd, psw) cmd.append('--')
こうしないと動きません。
# call unrar to extract a file def _extract(self, fnlist, path=None, psw=None): #EXTRACT_ARGS = ('x', '-y', '-idq') cmd = [UNRAR_TOOL] cmd.append('x') cmd.append('-y') cmd.append('-idq') # pasoword psw = psw or self._password add_password_arg(cmd, psw) cmd.append('--')
listでEXTRACT_ARGSを設定しますが、Popen()にわたるときにcmdのリストの中にEXTRACT_ARGSのリストが設定され、リストが二重になっている状態と思われます。
そのため、python側でunrar.exeに渡す引数を上手く設定できていないようです。
回避策として、cmdにひとつづつ引数を渡すように変更しています。もう少し良い方法があるかもしれませんが、個人利用なので暫定対応としています。
・・・本当に最後の問題には時間をとられました・・・