3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[PowerShell] e-Gov データポータルで検索してみる

Last updated at Posted at 2023-06-15

はじめに

先日、e-Gov データポータルを利用する機会がありました。

このサイト(e-Govデータポータル)は、行政機関等が保有する公共データのうち、オープンデータとして提供するものを対象としてカタログを整備し、横断的な検索を可能とするとともに、提供されるオープンデータの内容をわかりやすく提示することにより、オープンデータの活用に資することを目的としてデジタル庁が整備、運営するWebサイトです。
 
(https://data.e-gov.go.jp/info/ja/about-site から引用)

ある統計データを探していたのですが、各機関のリソースが無秩序に突っ込まれている感があり、残念ながらWebサイトでの検索は使い勝手がいいとはいえません。

PowerShellでの検索操作を試行したところ、それなりに活用できそうなので備忘録も兼ねて投稿します。

動作確認環境

PowerShell 7.3.4

データセットの検索

例として「人口動態」に関するデータセットを検索してみます。
APIの使い方はCKANのAPIガイドが参考になります。

とりあえず「人口動態」をキーワードに検索してみます。
URLで呼び出しが可能なAPI関数は多数ありますが、今回はpackage_searchのみを使っています。

Invoke-WebRequestでAPIを呼び出した結果はJSONで得られるのでPSCustomObjectに変換します。

PowerShell 7.3
$egovApi = 'https://data.e-gov.go.jp/data/api/3/action/package_search?'
$query = 'q=人口動態'
$dataset = Invoke-WebRequest "$egovApi$query" | ConvertFrom-Json

引っかかったデータセットの数です。(※ 以下、ヒット数は 2023.6.15 現在の値)
当然、Webサイトで検索した結果も同数です。

PowerShell 7.3
$dataset.result.count
# 2171

公開されているデータセットは複数のリソース(個別データ等)から成り立っています。
検索結果はデータセットの表題以外に、リソースの名前や説明文などにもヒットしているので、その数は大きくなります。

なお、ヒット数に関係なく、Invoke-WebRequestが返すデータセットは「関連性」順の上位10セット(既定値:変更可能)です。

PowerShell 7.3
$dataset.result.results | % title
# 人口動態調査_人口動態統計_確定数_総覧_年次_2012年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2013年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2011年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2019年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2018年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2016年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2017年
# 人口動態調査_人口動態統計_確定数_死亡_年次_2016年
# 人口動態調査_人口動態統計_確定数_用語及び比率の解説_年次_2020年
# 人口動態調査_人口動態統計_確定数_用語及び比率の解説_年次_2019年

雰囲気がわかったので、次の条件でクエリを書き直し、再度検索してみます。
 ● 表題に「人口動態」と「総覧」を含む
 ● 結果を表題で降順ソートする
 ● ソートされたデータセットの先頭から最大20セットのデータを取得する

各パラメータのフィールドや値はWebサイトで検索した際のアドレスバーから推測して動作確認しています。

PowerShell 7.3
$query = 'q=title:人口動態+title:総覧&sort=title_string desc&start=0&rows=20'
$dataset = Invoke-WebRequest "$egovApi$query" | ConvertFrom-Json
$dataset.result.count
# 16

ヒット数は16まで絞られました。
20セットに収まったので、全表題を書き出してみます。

PowerShell 7.3
$dataset.result.results | % title
# 人口動態調査_人口動態統計_確定数_総覧_年次_2021年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2020年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2019年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2019年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2018年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2018年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2017年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2017年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2016年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2016年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2015年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2014年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2014年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2013年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2012年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2011年

何故か同じ表題のデータセットが複数あります。
Webサイトで同条件を検索すると(下のリンクカード)残念な事実が判明します。

データセットをフォーマットで分割した年としない年もあれば、 XLSXLSX も混在しています。😩

リソースの取得

気を取り直してリソースの取得まで頑張ります。

例1 Excelファイルの場合

幸い、クエリにはフォーマットも指示できます。
Excel データを検索する場合はqパラメータにres_format:XLS*を追加します。
XLSは大文字です。また、res_format:XLSでは XLSX にヒットしません。

PowerShell 7.3
$query = 'q=title:人口動態+title:総覧+res_format:XLS*&sort=title_string desc&start=0&rows=20'
$dataset = Invoke-WebRequest "$egovApi$query" | ConvertFrom-Json
$dataset.result.results | % title
# 人口動態調査_人口動態統計_確定数_総覧_年次_2019年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2018年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2017年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2016年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2015年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2014年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2013年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2012年
# 人口動態調査_人口動態統計_確定数_総覧_年次_2011年

検索結果中、フォーマットが混在していた2015年のデータセットを例にしてExcelファイルを探します。

PowerShell 7.3
$dataset.result.results[4].resources | ? format -match XLS | Format-Table position, name, format
#
# position name                              format
# -------- ----                              ------
#        6 上巻_3-4_世界各国における人口動態 XLSX

リソースの位置や見出しがわかったのでファイルを保存します。
先にデータのアドレスを取得します。

PowerShell 7.3
$url = $dataset.result.results[4].resources[6].url

ユーザーの環境(拡張子の関連づけ)にもよりますが、通常は次の1行でブラウザが起動し、ファイルのダウンロードまで完了します。

PowerShell 7.3
Start-Process $url

任意の場所や名前で保存したい場合はInvoke-WebRequest-OutFileオプションをつけて保存します。

PowerShell 7.3
# 例
$filename = "$($dataset.result.results[4].resources[6].name)2015.xlsx"
Invoke-WebRequest $url -OutFile $filename

# 保存されたか確認
Get-ChildItem $filename | Format-Table Name, LastWriteTime, Length
#
# Name                                       LastWriteTime      Length
# ----                                       -------------      ------
# 上巻_3-4_世界各国における人口動態2015.xlsx 2023/06/15 5:55:00  33370

例2 csvファイルの場合

ファイルの保存は、Excelの場合と同様ですので省略します。
ここではcsvの直接処理を試みます。

先の検索結果から、最新になる2021年のデータを題材にします。

PowerShell 7.3
$query = 'q=title:人口動態+title:総覧+title:2021'
$dataset = Invoke-WebRequest "$egovApi$query" | ConvertFrom-Json
$dataset.result.count
# 1
$dataset.result.results[0].num_resources
# 54

ヒットしたデータセットは想定どおり1つで、そのリソース数は54です。

少し多いのでリソースの先頭10項目を表示してみます。

PowerShell 7.3
$dataset.result.results[0].resources[0..9] | Format-Table position, name, format
#
# position name                                                                             format
# -------- ----                                                                             ------
#        0 上巻_3-1-1_人口動態総覧及び平均発生間隔 -対前年比較-                           CSV
#        1 上巻_3-1-2_本報告において別掲とした件数                                          CSV
#        2 上巻_3-2-1_年次別にみた人口動態総覧                                              CSV
#        3 上巻_3-2-2_年次別にみた人口動態総覧(率)                                        CSV
#        4 上巻_3-3-1_都道府県(特別区-指定都市再掲)別にみた人口動態総覧                  CSV
#        5 上巻_3-3-2_都道府県(特別区-指定都市再掲)別にみた人口動態総覧(率)            CSV
#        6 中巻_1_人口動態総覧,都道府県(特別区-指定都市再掲)別                          CSV
#        7 中巻_2_人口動態総覧(件数),都道府県・市部-郡部-保健所-市区町村別_01 北海道 CSV
#        8 中巻_2_人口動態総覧(件数),都道府県・市部-郡部-保健所-市区町村別_02 青森県 CSV
#        9 中巻_2_人口動態総覧(件数),都道府県・市部-郡部-保健所-市区町村別_03 岩手県 CSV

残りは都道府県別データと推測できます。
新潟県のデータを探してみます。

PowerShell 7.3
$dataset.result.results[0].resources | ? name -Match 新潟県 | Format-Table position, name, format
#
# position name                                                                             format
# -------- ----                                                                             ------
#       21 中巻_2_人口動態総覧(件数),都道府県・市部-郡部-保健所-市区町村別_15 新潟県 CSV

上記リソースのurlからデータを読み込みます。

PowerShell 7.3
$url = $dataset.result.results[0].resources[21].url
$response = Invoke-WebRequest $url

csvテキストと想定されるデータについて最初の100文字を表示します。

PowerShell 7.3
$response.Content.Substring(0, 99)
# �ߘa�R�N,�l�����ԓ��v,,
# �����@�����@��Q�\�i15�V�����j�@�l�����ԑ����i�����j�C�s���{���E�s���|�S���|�ی

お察しのとおり、シフトJISが原因で文字化けしていますが、化け方に違和感があります。
この手の文字化け対策は過去にも記事が投稿されていますが、この方法が通用しません。

違和感の原因はこれです。

PowerShell 7.3
$response.Headers.'Content-Type'
# text/csv; charset=UTF-8

あろうことか、シフトJISのバイト列をUTF-8でデコードするように指示されています。😩😩
Invoke-WebRequestは、指示どおりシフトJISのバイト列をUTF-8として解釈しようとするので、2バイト文字の大半は'�'U+FFFD<REPLACEMENT CHARACTER>に置き換えられています。

つまり$response.Contentで取得した文字列から、元のシフトJISバイト列への復元は不可能です。

なお、上記の記事のように、charsetがISO-8859-1(未指定時の既定文字コード)であれば、1バイト文字コードなのでバイト列の復元は可能です。

ここでは、System.Net.Http.HttpClientを使うことにします。
本体をバイト列で受け取り、シフトJISでデコードします。

PowerShell 7.3
$httpClient = New-Object System.Net.Http.HttpClient
$dataBin = $httpClient.GetByteArrayAsync($url).GetAwaiter().GetResult()
$encSJIS = [System.Text.Encoding]::GetEncoding(932)
$dataCsv = $encSJIS.GetString($dataBin)

先頭の10行を表示してみます。

PowerShell 7.3
($dataCsv -split "`r`n")[0..9]
# 令和3年,人口動態統計,,
# 中巻 総覧 第2表(15新潟県) 人口動態総覧(件数),都道府県・市部-郡部-保健所-市区町村別
# ,出生数,(再掲),死亡数,(再掲), ,死産数, ,周産期死亡, , ,婚姻件数,離婚件数
# ,   ,2500g未満,   ,乳児死亡数,新生児,自然死産,人工死産,総 数,22週以後,早期新生児,   ,   
# ,,,,,死亡数,,,,の死産数,死亡数,,
# 15 新潟県  ,12608,1114,30990,21,12,138,124,59,47,12,7088,2617
#   新潟市  ,5132,472,9595,7,4,50,52,24,20,4,2906,1023
#   その他の市,7131,627,20111,14,8,87,70,35,27,8,3980,1511
#   郡 部  ,345,15,1284,-,-,1,2,-,-,-,202,83
# 1501新潟市       ,5132,472,9595,7,4,50,52,24,20,4,...,...

データを正しく取得できました。
csvデータとしてはかなり汚い(おそらく、Excelの表をそのままcsvで保存した?)ものですが、とりあえず文字列を取得できればPowerShellで加工できます。

なお、現在は非推奨とされていますがSystem.Net.WebClientでもデータを読むことができます。

PowerShell 7.3
$webClient = New-Object System.Net.WebClient
$webClient.Encoding = $encSJIS
$dataCsv = $webClient.DownloadString($url)

例3 csvファイルで「正統派?」文字化けの例

もう一例、「国民の祝日」を取り上げますが、こちらは正統派の文字化けです。

PowerShell 7.3
$query = 'q=title:祝日'
$dataset = Invoke-WebRequest "$egovApi$query" | ConvertFrom-Json
$dataset.result.count
# 1
$dataset.result.results[0].num_resources
# 1

ヒットしたデータセットは1つで、そのリソースも1つです。

PowerShell 7.3
$dataset.result.results[0].resources[0] | Format-Table name, format
#
# name                                                                                             format
# ----                                                                                             ------
# 昭和30年(1955年)から令和2年(2020年)国民の祝日等(いわゆる振替休日等を含む)(csv形式:19KB) CSV

目的のデータで間違いありません。

文字化けを見るために先頭100文字を表示します。

PowerShell 7.3
$url = $dataset.result.results[0].resources[0].url
$response = Invoke-WebRequest $url
$response.Content.Substring(0, 99)
# ¯ÌjúExúú,¯ÌjúExú¼Ì
# 1955/1/1,³ú
# 1955/1/15,Ìú
# 1955/3/21,tªÌú
# 1

前の例と文字化けの質が違います。「正統派」の文字化けです。
charsetは未指定なので、ISO-8859-1(Latin-1)が適用されています。

PowerShell 7.3
$response.Headers.'Content-Type'
# text/csv
$response.Encoding.WebName
# iso-8859-1

あらためて$response.Contentを見ると、2バイト文字がISO-8859-1の上位領域に割り振られている文字に化けています。

復元は前例のようにHttpClientを使うこともできますが、こちらは先ほど参照した記事の手法を検証します。

PowerShell 7.3
$enc8859 = [System.Text.Encoding]::Latin1
$dataBin = $enc8859.GetBytes($response.Content)
$dataCsv = $encSJIS.GetString($dataBin)

先頭10行を見ます。

PowerShell 7.3
($dataCsv -split "`r`n")[0..9]
# 国民の祝日・休日月日,国民の祝日・休日名称
# 1955/1/1,元日
# 1955/1/15,成人の日
# 1955/3/21,春分の日
# 1955/4/29,天皇誕生日
# 1955/5/3,憲法記念日
# 1955/5/5,こどもの日
# 1955/9/24,秋分の日
# 1955/11/3,文化の日
# 1955/11/23,勤労感謝の日

しっかり復元できています。

データのフォーマットも世間の荒波に揉まれて前例より行儀のよいcsvになっています。
その推移についてはこちらにまとめられています。 → 「祝日オープンデータを巡って」

ついでにデータをいじってみます。
今年度(2023.4 〜 2024.3)の祝日一覧を抽出し、クリップボードにコピーします。

PowerShell 7.3
-split $dataCsv -match '2023|2024/[1-3]/' -notmatch '2023/[1-3]/' | % replace ',' `t | Set-Clipboard

タブ区切りにしたのでスプレッドシートにそのままペーストできます。

まだまだ整備が不十分なe-Govデータポータルですが、データ処理の練習材料にできそうです。

3
4
0

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
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?