FuelPHPでe-StatのAPIから国勢調査の人口集計を取得する

概要

FuelPHPに慣れてきたので、外部APIからデータを取得する処理を書いてみたいと思います。
試しに、e-Stat の APIから国勢調査の人口集計を取得してみます。前半ではFuelPHPを使わずに、e-Stat の APIの使い方を確認していきます。
なお、取得するデータの形式はいくつか選べますが、今回はJSON形式で取得します。

www.e-stat.go.jp

環境

  • FuelPHP 1.8.2
  • php 5.6

準備

e-Stat の APIを使用するためには、上記のリンクからユーザ登録をして、アプリケーションIDを取得する必要があります。アプリケーションIDは、ログイン後に「マイページ」>「アプリケーションID発行」と進むと発行できます。

e-Stat API の使い方

まずは、e-Stat API の使い方を確認します。

リクエストURLの生成

APIで提供されているデータは、こちらのページからアクセスできます。

提供データ | 政府統計の総合窓口(e-Stat)−API機能

今回は、次のリンク先の表00310「年齢(各歳),男女別人口,年齢別割合,平均年齢及び年齢中位数(総数及び日本人)」を使います。

国勢調査 平成27年国勢調査 人口等基本集計(男女・年齢・配偶関係,世帯の構成,住居の状態など) | データベース | 統計データを探す | 政府統計の総合窓口

右端の「表示・ダウンロード」列の「API」を押すと、次のようにリクエストURLの雛形が生成されます。

f:id:ishii-akihiro:20191030150507p:plain

appId=の後に、各自で発行したアプリケーションIDを貼り付けます。また、JSON形式で取得する場合は、https://api.e-stat.go.jp/rest/2.1/appの後に/jsonを付け加えます。

https://api.e-stat.go.jp/rest/2.1/app/json/getStatsData?appId=[発行したアプリケーションID]&lang=J&statsDataId=0003149249&metaGetFlg=Y&cntGetFlg=N&sectionHeaderFlg=1

これをブラウザのURL入力欄に貼り付ければAPIにリクエストを送信できますが、ちょっと待ってください。このままでは全国のデータが1歳階級別で取得しようとするため、相当なデータ量になります

リクエストパラメータの指定

データを絞り込むため、パラメータを設定します。ドキュメントを読んでもよいですが、手っ取り早い方法があったので紹介します。

先ほど選んだ「API」ボタンの横にある「DB」ボタンを押します。「統計表・グラフ表示」のページに移りますが、次のようなメッセージが表示されていると思います。

画面表示セル数 176,400 は最大画面表示セル数 50,000 を超えました。項目の絞り込みや表示位置のページ上部(欄外)への変更を行ってください。

データ量が多くて表示できないということです。統計表表示エリアの「表示項目選択」をクリックします。
f:id:ishii-akihiro:20191030151759p:plain

すると、現在選択されている項目が表示されます。
f:id:ishii-akihiro:20191030152017p:plain

年齢と地域の種類が150以上あるので、データ量を減らすために絞り込みます。「項目を選択」をクリックして設定します。はじめは全選択されているので、「全解除」をしてから必要な項目を選ぶとよいです。

本記事では、年齢は3階級別のみとし、地域は大阪市だけにします。
f:id:ishii-akihiro:20191030152428p:plain
f:id:ishii-akihiro:20191030152442p:plain

「確定」を押すと、年齢3回級別の大阪市の人口が表示されます。

f:id:ishii-akihiro:20191030152757p:plain

表の右上にある「API」を選択すると、同様に絞り込むためのパラメータが設定されたリクエストURLが取得できます。先ほどのように、アプリケーションIDを加えて、JSON形式の指定をします。

https://api.e-stat.go.jp/rest/2.1/app/getStatsData?cdArea=27100&cdCat02=1560%2C1760%2C1770&appId=[発行したアプリケーションID]&lang=J&statsDataId=0003149249&metaGetFlg=Y&cntGetFlg=N&sectionHeaderFlg=1

大阪市を示すcdArea=27100と、年齢の3項目を示すcdCat02=1560%2C1760%2C1770が追加されています(%2Cはカンマをエンコーディングしたものなので、年齢を示すコードは 1560,1760,1770 の3種類です)。
このリクエストURLをブラウザのURL欄に貼り付けてリクエストすると、次のような結果が得られます(折りたたんで一部を表示しています)。
f:id:ishii-akihiro:20191030153647p:plain

FuelPHPでコントローラからAPIリクエストを送信する

ようやく本題です。前置きが長くなったので、早速コントローラとビューのサンプルコードを載せます。

コントローラ

わかりやすくするために、パラメータは配列で設定してからhttp_build_queryで組み立てています。得られたレスポンスは配列に変換してビューに渡します。

<?php
class Controller_Home extends Controller
{
public function action_index()
{
//リクエストURL
$request_url = 'https://api.e-stat.go.jp/rest/3.0/app/json/getStatsData';
//リクエストパラメータ
$params = array(
'cdArea' => '27100',
'cdCat02' => '1560,1760,1770',
'appId' => '[アプリケーションID]',
'lang' => 'J',
'statsDataId' => '0003149249',
'metaGetFlg' => 'Y',
'cntGetFlg' => 'N',
'sectionHeaderFlg' => '1'
);
//リクエストURLにパラメータを追記
$request_url .= '?'.http_build_query($params);
//Request_Curlを生成
$curl = Request::forge($request_url, 'curl');
//HTTPメソッドを指定
$curl->set_method('get');
//パラメータを設定
$curl->set_params($params);
//実行
$response = $curl->execute()->response();
//レスポンスコードチェック
if($response->status == 200)
{
//Formatクラスを利用して、JSONからPHPの配列に変換
$data = Format::forge($response->body,'json')->to_array();
$view = View::forge('index');
$view->set_global('data', $data);
return $view;
}
}
}

ビュー

コードの内容は、レスポンスの[‘GET_STATS_DATA’][‘STATISTICAL_DATA’][‘CLASS_INF’]に含まれています。データの内容は、レスポンスの[‘GET_STATS_DATA’][‘STATISTICAL_DATA’][‘DATA_INF’]に含まれています。
詳細の説明は本題から外れるので省きますが、一部の項目だけ表示するテーブルを作成しています。

<!DOCTYPE html>
<htmllang="ja">
<head>
 <metacharset="UTF-8">
 <title>Document</title>
 <?php echo Asset::css('style.css'); ?>
</head>
<body>
<p>---------------------- コード表 ----------------------</p>
<?php foreach($data['GET_STATS_DATA']['STATISTICAL_DATA']['CLASS_INF']['CLASS_OBJ'] as $key => $class_obj): ?>
<!-- 取得したデータに複数のコードが含まれていれば表示 -->
<?php if(!empty($class_obj['CLASS'][0])): ?>
<?php echo $class_obj['@id'].':'.$class_obj['@name']; ?>
<table>
<thead>
<tr>
<th>@code</th>
<th>@name</th>
<th>@level</th>
<th>@unit</th>
</tr>
</thead>
<tbody>
<?php foreach($class_obj['CLASS'] as $key => $value): ?>
<tr>
<td><?php if(!empty($value['@code'])){ echo $value['@code']; } ?></td>
<td><?php if(!empty($value['@name'])){ echo $value['@name']; } ?></td>
<td><?php if(!empty($value['@level'])){ echo $value['@level']; } ?></td>
<td><?php if(!empty($value['@unit'])){ echo $value['@unit']; } ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
<?php endforeach; ?>
<p>---------------------- データ内容 ----------------------</p>
<table>
<thead>
<th>@cat01</th>
<th>@cat02</th>
<th>@cat03</th>
<th>@cat04</th>
<th>@unit</th>
<th></th>
</thead>
<tbody>
<?php foreach($data['GET_STATS_DATA']['STATISTICAL_DATA']['DATA_INF']['VALUE'] as $key => $value): ?>
<tr>
<td><?php if(!empty($value['@cat01'])){ echo $value['@cat01']; } ?></td>
<td><?php if(!empty($value['@cat02'])){ echo $value['@cat02']; } ?></td>
<td><?php if(!empty($value['@cat03'])){ echo $value['@cat03']; } ?></td>
<td><?php if(!empty($value['@cat04'])){ echo $value['@cat04']; } ?></td>
<td><?php if(!empty($value['@unit'])){ echo $value['@unit']; } ?></td>
<td><?php if(!empty($value['$'])){ echo $value['$']; } ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php
$data['GET_STATS_DATA']['STATISTICAL_DATA']['DATA_INF']['VALUE']
?>
</body>
</html>

ブラウザの出力結果

レスポンスの内容を表示できました。
f:id:ishii-akihiro:20191030154654p:plain

感想

今回参照したデータは、全国の市町村に対して1歳階級別に用意されていたため、必要なデータを抽出するのが大変でした。データもコードによって整理されているため、視覚的にわかりやすくするにはコードの内容と結合した方がよいです。

また、本記事のようにビューで整理しようとすると面倒になるので、コントローラで整理してから表示した方がよいと思います。できたら一旦DBに格納した方が、その後の集計は楽になると思います。

タイトルとURLをコピーしました