2021/12/07(火) [n年前の日記]
#1 [python] Pythonでzipからファイルを取り出したい
Pythonを使って、zipファイルから任意のxmlファイルを取り出して処理をさせたい。
環境は、Windows10 x64 21H1 + Python 3.9.7 x64。
ググってみたところ、Python で zipファイルを扱うなら、zipfile というモジュールが使えるらしい。また、xml を扱うなら、xml.etree.ElementTree というモジュールを使えばいいらしい。
ということで、あちこちの解説記事からコピペして、以下のような感じになった。python 01_getziplist.py hoge.zip といった指定で動く。
_01_getziplist.py
出力結果は以下。
これで、Pythonを使えば以下の処理ができることが分かった。
環境は、Windows10 x64 21H1 + Python 3.9.7 x64。
ググってみたところ、Python で zipファイルを扱うなら、zipfile というモジュールが使えるらしい。また、xml を扱うなら、xml.etree.ElementTree というモジュールを使えばいいらしい。
ということで、あちこちの解説記事からコピペして、以下のような感じになった。python 01_getziplist.py hoge.zip といった指定で動く。
_01_getziplist.py
import zipfile
import sys
import xml.etree.ElementTree as ET
target = "manifest.xml"
# get input file name
if len(sys.argv) < 2:
print("Usage: python ThisScript.py INFILE")
sys.exit()
infile = sys.argv[1]
print("Input File : %s\n" % infile)
# Open zip
zipf = zipfile.ZipFile(infile)
# Get filenames
if True:
# use .namelist()
names = zipf.namelist()
else:
# use .infolist()
names = []
for info in zipf.infolist():
names.append(info.filename)
# print filenames
for fn in names:
print(fn)
print()
if target in names:
print("Found %s\n" % target)
else:
print("Not found %s\n" % target)
sys.exit()
# Read target file
xmldata = zipf.read(target)
# print(xmldata)
# Parse xml
root = ET.fromstring(xmldata)
print("---- %s" % target)
ET.dump(root)
print()
for i in root.iter():
print(i.tag, i.attrib, i.text)
print()
# get game tag
elem = root.find("game")
if elem is None:
print("Not found <game> tag")
else:
# get game tag text
kind = elem.text
if kind is None:
print("<game></game>")
elif kind == "":
print("<game></game>")
else:
print("<game>%s</game>" % kind)
出力結果は以下。
> python 01_getziplist.py hogezip.zipmod
Input File : hogezip.zipmod
abdata/chara/
abdata/chara/hoge.unity3d
abdata/chara/thumb/
abdata/chara/thumb/hoge_thumb.unity3d
abdata/list/
abdata/list/characustom/
abdata/list/characustom/00/
abdata/list/characustom/00/hoge_list_ao_head_00.csv
manifest.xml
Found manifest.xml
---- manifest.xml
<manifest schema-ver="1">
<guid>com.fuga.hoge</guid>
<name>hogemod</name>
<version>1.0.0</version>
<author>fuga</author>
<description>description</description>
<website>https://example.com</website>
<game>AI Girl</game>
</manifest>
manifest {'schema-ver': '1'}
guid {} com.fuga.hoge
name {} hogemod
version {} 1.0.0
author {} fuga
description {} description
website {} https://example.com
game {} AI Girl
<game>AI Girl</game>
これで、Pythonを使えば以下の処理ができることが分かった。
- zipファイルの中に入っているファイル一覧を取得。
- ファイル一覧内に、特定のファイル名が存在するか調べる。
- zipファイル内のファイルを1つだけ読み込む。
- xml内に記述されている特定タグの情報を取得。
◎ 動機。 :
何故こんな処理をやりたいかというと…。某3Dゲームのmodファイルが、どのタイトル向けのmodなのかを知りたいなと。
某3Dゲームのmodは、拡張子が .zipmod で統一されているのだけど、実態は只のzipファイル。そのzipの中に、決まったファイル名でxmlファイルが1つ入っていて、そのxmlに、どのタイトル向けのmodなのか記述されていて…。某3Dゲームでそのmodを読み込んだ際、タイトルが一致すれば利用可、一致しなければ利用不可になるけれど、modを入手してインストールしたのに反映されなくて悩んだら別タイトル向けの指定がされていた、といった場面がたまにあって。
今までは、そのあたりを確認する際、以下の作業をしていたのだけど。
しかし、この確認作業が地味に面倒臭い。そこで、.zipmod のファイルパスを渡したら、中からxmlを読み込んで特定のタグ情報だけ出力して終わる、という処理をスクリプトで書けたら、少しだけ楽にならないかと思った次第。
できれば、xml内の記述タイトルが違ってたら、zipを展開して、xmlファイルを書き換えて、またzipに圧縮して、.zipmod にリネーム、という処理までさせたいけれど…。そのあたりは今後の課題。
某3Dゲームのmodは、拡張子が .zipmod で統一されているのだけど、実態は只のzipファイル。そのzipの中に、決まったファイル名でxmlファイルが1つ入っていて、そのxmlに、どのタイトル向けのmodなのか記述されていて…。某3Dゲームでそのmodを読み込んだ際、タイトルが一致すれば利用可、一致しなければ利用不可になるけれど、modを入手してインストールしたのに反映されなくて悩んだら別タイトル向けの指定がされていた、といった場面がたまにあって。
今までは、そのあたりを確認する際、以下の作業をしていたのだけど。
- ファイラー(あふ)で .zipmod を .zip にリネーム。
- ファイラーで .zip の中を覗く。
- xmlファイルがあることを確認して、内容を閲覧表示。
- タグ内容を把握。
- 問題がなければ .zip を .zipmod にリネームし直す。
しかし、この確認作業が地味に面倒臭い。そこで、.zipmod のファイルパスを渡したら、中からxmlを読み込んで特定のタグ情報だけ出力して終わる、という処理をスクリプトで書けたら、少しだけ楽にならないかと思った次第。
できれば、xml内の記述タイトルが違ってたら、zipを展開して、xmlファイルを書き換えて、またzipに圧縮して、.zipmod にリネーム、という処理までさせたいけれど…。そのあたりは今後の課題。
[ ツッコむ ]
以上、1 日分です。