政府統計 e-Stat
各省庁が提供しているデータがAPI経由で取得できるようです。
政府統計 e-Statというサイトのようです。
トレーニングも兼ねて種々のデータをElixirでロードしたい、と思いました。
提供されるデータ形式は、xmlとjsonの2通りあるそうです。(1)
Elixir、jsonのライブラリ等については、少しずつ触ってきて慣れてきたので、今後webスクレイピングするかも、ということでxmlのパーサライブラリに触ってみることにしました。
今回のサンプルコードは下記においています。
利用手順
1. mix.exsにdepsを追加して、mix deps.get
def application do
[applications: [:logger, :httpoison]]
end
defp deps do
[
{:mix_test_watch, "~> 0.2", only: [:dev, :test]},
{:poison, "~> 1.2"},
{:httpoison, "~> 0.7"},
{:floki, "~> 0.8"},
{:credo, "~> 0.3", only: [:dev, :test]}
]
end
httpアクセスするので、HTTPoisonも追加しています。
2. 統計表の一覧から、政府統計コードを指定して利用したい統計表IDを取得する
APIのversion 2.0のURLをconfig.exsで定義して、url文字列を生成しました。
use Mix.Config
config :crawl_estat, stats_list_url: "http://api.e-stat.go.jp/rest/2.0/app/getStatsList"
config :crawl_estat, stats_data_url: "http://api.e-stat.go.jp/rest/2.0/app/getStatsData"
url = Application.get_env(:crawl_estat, :stats_list_url) <>
"?appId=#{@api_id}&statsCode=#{stats_code}&surverYears=#{surver_years}"
指定しているパラメータ(2)は、以下となります。
- api_id(必須、利用者はe-Statに登録して習得する)
- statsCode(必須、サイトから選択して指定する)
- surverYears(任意、指定しないとたくさんデータが取れてしまう。。)
3. HTTPoisonでリクエストを発行し、XMLをパースする
以下のように、ノードにアクセスできるようです。
シンプルでわかりやすいですね^^
Floki.find(xml, "アトリビュート")
上記で指定したURLリクエストのレスポンスについては以下のように処理を施してみました。
prob_response = HTTPoison.get(url)
case prob_response do
{:ok, response} ->
Logger.info(inspect Floki.find(response.body, "table_inf"))
prob_ids = Floki.find(response.body, "table_inf")
Enum.reduce(prob_ids, [], fn(prob_id, acc) ->
case prob_id do
{_, [{"id", id}], _} ->
IO.inspect(id)
[id|acc]
end
end)
end
response.bodyが、以下のようなxmlの形式になっています。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<GET_STATS_DATA xsi:noNamespaceSchemaLocation="http://api.e-stat.go.jp/rest/2.0/schema/GetStatsData.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RESULT>
<STATUS>0</STATUS>
<ERROR_MSG>正常に終了しました。</ERROR_MSG>
<DATE>2016-04-04T11:23:30.692+09:00</DATE>
</RESULT>
<PARAMETER>
<LANG>J</LANG>
<STATS_DATA_ID>0003109558</STATS_DATA_ID>
<DATA_FORMAT>X</DATA_FORMAT>
<START_POSITION>1</START_POSITION>
<METAGET_FLG>Y</METAGET_FLG>
</PARAMETER>
<STATISTICAL_DATA>
<RESULT_INF>
<TOTAL_NUMBER>10944</TOTAL_NUMBER>
<FROM_NUMBER>1</FROM_NUMBER>
<TO_NUMBER>10944</TO_NUMBER>
</RESULT_INF>
<TABLE_INF id="0003109558">
<STAT_NAME code="00450012">生命表</STAT_NAME>
<GOV_ORG code="00450">厚生労働省</GOV_ORG>
<STATISTICS_NAME>生命表 簡易生命表</STATISTICS_NAME>
<TITLE>簡易生命表</TITLE>
<CYCLE>年次</CYCLE>
<SURVEY_DATE>0</SURVEY_DATE>
<OPEN_DATE>2015-09-30</OPEN_DATE>
<SMALL_AREA>0</SMALL_AREA>
<MAIN_CATEGORY code="02">人口・世帯</MAIN_CATEGORY>
<SUB_CATEGORY code="03">人口動態</SUB_CATEGORY>
<OVERALL_TOTAL_NUMBER>10944</OVERALL_TOTAL_NUMBER>
<UPDATED_DATE>2015-12-02</UPDATED_DATE>
</TABLE_INF>
のようになります。
ここから、いったん、Floki.find(response.body, "table_inf")をして、取り出しました。
以下のようなデータが取れます。
[{"table_inf", [{"id", "0003109570"}], [{"stat_name", [{"code", "00450012"}], ["生命表"]}, {"gov_org", [{"code", "00450"}], ["厚生労働省"]}, {"statistics_name", [], ["生命表 完全生命表"]},
{"title", [], ["完全生命表"]}, {"cycle", [], ["-"]}, {"survey_date", [], ["0"]}, {"open_date", [], ["2015-09-30"]}, {"small_area", [], ["0"]}, {"main_category", [{"code", "02"}], ["人口・世帯"]}, {"sub_category
", [{"code", "03"}], ["人口動態"]}, {"overall_total_number", [], ["3880"]}, {"updated_date", [], ["2015-12-02"]}]}, {"table_inf", [{"id", "0003109558"}], [{"stat_name", [{"code", "00450012"}], ["生命表"]}, {"go
v_org", [{"code", "00450"}], ["厚生労働省"]}, {"statistics_name", [], ["生命表 簡易生命表"]}, {"title", [], ["簡易生命表"]}, {"cycle", [], ["年次"]}, {"survey_date", [], ["0"]}, {"open_date", [], ["2015-09-30"]
}, {"small_area", [], ["0"]}, {"main_category", [{"code", "02"}], ["人口・世帯"]}, {"sub_category", [{"code", "03"}], ["人口動態"]}, {"overall_total_number", [], ["10944"]}, {"updated_date", [], ["2015-12-02"]}
]}]
tuple形式のデータがListで取れるようです。
そのあとは、<TABLE_INF id="0003109558">のidを取得したいので、Enum.reduceとcaseを利用しました。
ここらへんはもうちょっとシンプルにアクセスしたいのですが、ちょっとFlokiだと難しそうでした。
ソースコードも読んでみようと思います。
感想
- もうちょっとxml, htmlパース系のライブラリは探してみようと思いました。
- パターンマッチングが利用できるので、この手のスクレイピング系はElixirはRubyとは違う面白さがあるのかな、と思いました^^
- Parserコンビネータ、Elixirであったら触ってみたいです。
- 政府の統計情報、データベース直接触らせてもらえないのかしら。
参考
本日は以上となります。