LoginSignup
3

More than 3 years have passed since last update.

インターネット上のzipファイルをリクエストして変数に取り込む

Posted at

この記事は Python Advent Calendar の17日目の記事 になります。

TL;DR

# 使用ライブラリ
import io
import json
import urllib.request
import zipfile
# データは国土交通省にある行政区域の情報を引っ張ってくる
# ゴールは中身の.geojsonを取り出す
url = 'https://nlftp.mlit.go.jp/ksj/gml/data/N03/N03-2019/N03-190101_47_GML.zip'

req = urllib.request.Request(url)
with urllib.request.urlopen(req) as res:
    data = res.read()
# データがzipファイルになっているので中身を抽出して変数に格納する
with zipfile.ZipFile(io.BytesIO(data), 'r') as zip_data:
    geojson_filepath = [name for name in zip_data.namelist() if '.geojson' in name][0]
    with zip_data.open(geojson_filepath, 'r') as gj:
        geojson_data = gj.read()
    geojson = json.loads(geojson_data)

はじめに

誰しもエンジニアとして携わるとおそらく必ず一度はぶち当たる「 インターネット上のデータを取り込む 」という行為。例えばテキストファイルとかであれば直接読み出すこととかも可能ですが、いかんせんデータによってはデータ圧縮された形になっており、うまく読み出せないこともあるかと思います。

ライブラリによってはそのライブラリに特化した形で読み込むことも可能ですが、今回は汎用性を考えてPythonの持つ標準ライブラリのみで必要データを「引っ張って変数に取り込む」ことをゴールとしてコードを書きました。解説も交えて何をしているかを紹介していこうと思います。

データを引っ張ってくる

みんな大好きカエルアイコンのパイセン( @hoto17296 )の記事がまんまです。パイセンいつもありがとうございます。

# データは国土交通省にある行政区域の情報を引っ張ってくる
# ゴールは中身の.geojsonを取り出す
url = 'https://nlftp.mlit.go.jp/ksj/gml/data/N03/N03-2019/N03-190101_47_GML.zip'

req = urllib.request.Request(url)
with urllib.request.urlopen(req) as res:
    data = res.read()

初めにURLを載せたリクエストを作成して投げ込み返ってきたデータを読み出しています。

zipファイルを変数に取り込む

# データがzipファイルになっているので中身を抽出して変数に格納する
with zipfile.ZipFile(io.BytesIO(data), 'r') as zip_data:
    geojson_filepath = [name for name in zip_data.namelist() if '.geojson' in name][0]
    with zip_data.open(geojson_filepath, 'r') as gj:
        geojson_data = gj.read()
    geojson = json.loads(geojson_data)

標準ファイルフォーマットのzipファイルを取り扱うことができるPythonライブラリです。Pythonにはzipfile以外にもgzipやbz2(bzip2)やlzma、tar(tarfile)もあるので、1行目の with zipfile.ZipFile(io.BytesIO(data), 'r') as zip_data: については、各圧縮ファイルフォーマットごとに書き換えれば同様に対応可能です。

また今回はデータを引っ張ったときに格納した data にあるzipのバイナリデータをioライブラリを使って取り込んでいます。これによってローカルストレージからzipファイルを読む感覚で、変数にあるzipデータを読み込むことができます。

2行目ではzip_dataに含まれるgeojsonファイルを抽出して、これを3行目で取り出しています。このときの open() はzipfileライブラリ由来なので注意。read() できたらファイルの中身がバイナリで取り出せているはずなので、後は用途に応じて煮るなり焼くなり好きにすると良いと思います。

まとめ

この取り出し方であれば多くの圧縮ファイルフォーマットに対応もできて、取り出したデータについてはローカルストレージにおいてよし、分析に使うならそのままpandasで読み込んでもよしって感じなので、とりあえず困ったらコピペで解決できるかと思います。

最近業務で全然Python書いていなかったので、どうしようかどうしようかと思っていたのですが、学生時代からずっとPython書いてると全然忘れないですね。素晴らしいです。今年は1番乗りでAdvent Calendarを作れたので満々満足です。来年もまた書いていくぞ!

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3