MIERUNE Advent Calendar 2020 3日目の記事です。
国土数値情報のデータを一括ダウンロードしするスクリプトを作りました。
使い方だけ知りたいよ、って方はこちらからお読みください。
※この記事ではコードを一部簡略化しています。ツールの全コードはGitHubリポジトリを参照してください。
ことの発端
国土数値情報APIが消えた
ある日、国土数値情報から大量にファイルをダウンロードしたくなりました。
取得したいデータは都道府県別かつ時系列で大正9年まで提供されている行政区域です。1,000以上ファイルが提供されているのですが、これを1つづつダウンロードするのはツラすぎます。
ところが、2020年の夏ごろにUIが変更されると同時にAPIの提供をやめてしまったようです。(2020年11月現在)
ということで、自動で一括ダウンロードするツールを作ることにしました。
ツールを作る
ダウンロードを自動化する
まずはブラウザを操作してファイルをダウンロードします。
seleniumを使って、以下のブラウザ上での操作を自動化します。
- ダウンロードボタンをクリック
- モーダルで、はいをクリック
ダウンロードしたファイルはデフォルトのダウンロードフォルダではなく、カレントディレクトリに新しいフォルダを作って保存することにします。
# ファイルをダウンロードする関数
def file_dl(driver_path):
dl_dir = "../download"
# Seleniumをあらゆる環境で起動させるChromeオプション
options = Options()
options.add_argument('--disable-gpu')
options.add_argument('--disable-extensions')
options.add_argument('--proxy-server="direct://"')
options.add_argument('--proxy-bypass-list=*')
options.add_argument('--start-maximized')
options.add_experimental_option("prefs", {
"download.default_directory": dl_dir})
# options.add_argument('--headless'); # ※ヘッドレスモードを使用する場合、コメントアウトを外す
# ブラウザの起動
DRIVER_PATH = ChromeDriverのパス
driver = webdriver.Chrome(executable_path=DRIVER_PATH, chrome_options=options)
# 国土数値情報のダウンロードページにアクセスする
url = sys.argv[1] # コマンドラインで指定したページのurlを取得する
driver.get(url)
# 要素を指定する
selector = '#menu-button'
elements = driver.find_elements_by_css_selector(selector)
print(str(len(elements)) + " zip file is going to be DL")
# ブラウザの操作
for i, e in enumerate(elements):
print(i)
e.click()
time.sleep(1)
Alert(driver).accept()
time.sleep(2)
return dl_dir
zipファイルを解凍する
ついでにzipファイルの解凍も自動化しておきます。
それぞれのzipを解凍して得られるshpファイル群は1つのフォルダにまとめることにします。
def extraction(dl_dir):
extdir_name = 'shp' # 保存先フォルダ
extdir_path = pathlib.Path(os.getcwd(), extdir_name)
extdir_path.mkdir(exist_ok=True)
ext_dir = str(extdir_path.resolve())
print(ext_dir)
zip_files = glob.glob(dl_dir + "/*.zip")
print(zip_files)
for z in zip_files:
with zipfile.ZipFile(z) as existing_zip:
existing_zip.extractall(ext_dir)
return ext_dir
文字コード指定ファイルを作る
国土数値情報で取得できるshpファイルの文字コードは Shift_JIS です。
例えば、QGISでshpファイルを読み込むとOSのデフォルトの文字コードで読み込まれます。そのため、OSの文字コードがUTF-8だと属性テーブルが文字化けしてしまいます。
しかしshpファイルの文字コードを指定するcpgファイルは入っていません。
自作しましょう。
shpファイルと同じ名称のテキストファイルを作成し、.cpg で保存します。
def create_cpg(extent, encoding, ext_dir):
files = glob.glob(ext_dir + "/*." + shp)
for f in files:
basename = os.path.splitext(os.path.basename(f))[0]
path = os.path.join(ext_dir, basename + ".cpg")
cpg = open(path, 'w')
cpg.write("Shift_JIS")
cpg.close()
cpgファイルはこんな感じになります。
Shift_JIS
ツールの使い方
ダウンロードツール
- 必要なライブラリをインストールする
$ pip install selenium
- OSに合わせて、ここからChromeDriverをダウンロードする。
- ダウンロードしたWebDriverを mlit-ksj-dl-tool/WebDriver に保存する。
- 国土数値情報ダウンロードサービスからダウンロードしたいページのURLを取得する。
- 以下のコマンドを実行する。
$ python3 mlit_ksj_dl.py ダウンロードしたいページのURL
mlit-ksj-dl-tool/download にダウンロードしたzipファイルが、mlit-ksj-dl-tool/shp に展開したshpファイル群が保存されます。
まとめ
国土数値情報から大量のファイルをダウンロードして、いい感じに使えるようにしてみました。
ダウンロードだけするつもりが、あれもこれもと機能を追加したくなってしまうのはなぜなんでしょうか。
ツールはご自由にご利用ください。
https://github.com/mits003/mlit-ksj-dl-tool