今回は、グラフに描画するデータを整理する作業について説明する。

インターネット経由でさまざまなデータを取得できるようになったことで、Webで公開されているデータを利用する機会が増えている。PowerShellは、そうした厳密には構造化されているとは言えないデータから、目的の数値データを取り出す処理にも使うことができる。

→連載「PowerShell Core入門 - 基本コマンドの使い方」の過去回はこちらを参照。

データの準備

Webで公開されているデータにはさまざまなものがあるが、ここでは気象庁が「気象庁|最新の気象データ」で公開している気温データを取得してグラフに描画するケースを考える。このWebページは、執筆時点では次のようなレイアウトでデータが配置されている。

  • 気象庁|最新の気象データ

    気象庁|最新の気象データ

このデータの中から、東京都のデータを取り出すことを考える。東京都のデータは、次のように掲載されている。

  • 東京都の気温データ

    東京都の気温データ

Microsoft Edgeの開発者ツールで該当部分を見てみると、table要素の中に記載されていることがわかる。

  • 該当部分をMicrosoft Edgeの開発者ツールでチェック

    該当部分をMicrosoft Edgeの開発者ツールでチェック

該当ページのHTMLをダウンロードし、Visual Studio Codeで確認すると次のようになっている。

  • 該当部分のHTMLをVisual Studio Codeで確認

    該当部分のHTMLをVisual Studio Codeで確認

Visual Studio Codeで閲覧するとフォーマットが自動的に整えられてしまうので、メモ帳でも確認しておく。

  • 該当部分のHTMLをメモ帳で確認

    該当部分のHTMLをメモ帳で確認

要するに、この文字列から地名と気温を抽出するPowerShellスクリプトを書けばよいということになる。

なお、このページのデータはCSVデータとしても提供されているので、通常ならそちらのデータを使う方がロジカルな選択だ。しかし今回は、フォーマットが曖昧な状態のテキストから、目的とする数値を取り出す例を示したいので、あえてWebページからデータを取得している。

Webページを取得するPowerShellスクリプト

まず、対象のWebページを取得して表示するPowerShellスクリプトを作成する。Webページの取得には、Windowsにデフォルトでインストールされているcurlコマンドを使う。curlは強力なコマンドで、LinuxやMacでもよく使われている。

#!/usr/bin/env pwsh

#========================================================================
# 気温データを取得して整理する
#========================================================================
$URL = 'https://www.data.jma.go.jp/obd/stats/data/mdrr/tem_rct/alltable/mxtemsad00.html'
$SrcFile = New-TemporaryFile

curl        --get $URL                                      > $SrcFile 2> $null

#========================================================================
# 取得したデータの中身を確認
#========================================================================
Get-Content $SrcFile

#========================================================================
# 作業用の一時ファイルを削除
#========================================================================
Remove-Item $SrcFile

実行すると次のようになる。

PS C:\Users\daichi> .\test-1.ps1
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>気象庁|最新の気象データ</title>
<meta name="Author" content="気象庁 Japan Meteorological Agency" />
<meta name="keywords" content="気象庁 Japan Meteorological Agency" />
<meta name="description" content="各地の日最高気温、日最低気温を表示します" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<link rel="stylesheet" type="text/css" href="/com/css/define.css" media="all" />
<link rel="stylesheet" type="text/css" href="../../../css/default.css" media="all" />
<link rel="stylesheet" type="text/css" href="../../../css/print.css" media="print" />
<script type="text/javascript" src="../../js/jquery.js"></script>
<style type="text/css" media="all">
...
略
...
PS C:\Users\daichi> 

必要なデータを取り出すPowerShellスクリプト

次に、必要になる部分だけを抽出する処理を加える。取得したHTMLを中身を分析すると、「>東京都</td」という文字列を含んだ行に、欲しいデータが含まれていることがわかる。Select-Stringコマンドレットで東京都の気象データだけを抽出する処理を行うように、先ほどのPowerShellスクリプトを書き換える。

#!/usr/bin/env pwsh

#========================================================================
# 気温データを取得して整理する
#========================================================================
$URL = 'https://www.data.jma.go.jp/obd/stats/data/mdrr/tem_rct/alltable/mxtemsad00.html'
$SrcFile = New-TemporaryFile

curl        --get $URL                                      > $SrcFile 2> $null

#========================================================================
# 必要な部分のデータを抽出する
#========================================================================
Get-Content $SrcFile                                        |
Select-String '>東京都</td'

#========================================================================
# 作業用の一時ファイルを削除
#========================================================================
Remove-Item $SrcFile

実行すると次のようになる。

PS C:\Users\daichi> .\test-2.ps1

<tr class="mtx"><td style="white-space:nowrap">東京都</td><td style="white-space:nowrap">西多摩郡奥多摩町</td><td style="wh
ite-space:nowrap">小河内(オゴウチ)</td><td style="text-align:right;white-space:nowrap;">15.2 ]</td><td style="text-align:

/td><td style="text-align:left;white-space:nowrap;"></td></tr>
<tr class="mtx"><td style="white-space:nowrap">東京都</td><td style="white-space:nowrap">青梅市</td><td style="white-space:


"text-align:left;white-space:nowrap;"></td></tr>
<tr class="mtx"><td style="white-space:nowrap">東京都</td><td style="white-space:nowrap">練馬区</td><td style="white-space:
...
略
...
PS C:\Users\daichi> 

正規表現を使って不要なデータを削除する

必要な行を取り出したものの、HTMLのタグなど、グラフ化するには不要なデータを含んでいる。そこで次は、このタグを削除する処理を実装する。具体的には、「-replace」の正規表現指定で開始タグと終了タグを削除する処理を行う。

#!/usr/bin/env pwsh

#========================================================================
# 気温データを取得して整理する
#========================================================================
$URL = 'https://www.data.jma.go.jp/obd/stats/data/mdrr/tem_rct/alltable/mxtemsad00.html'
$SrcFile = New-TemporaryFile

curl        --get $URL                                      > $SrcFile 2> $null

#========================================================================
# 東京の気象データを抽出
#========================================================================
# 東京都の気象データを抽出
$s = (Get-Content $SrcFile | Select-String '>東京都</td')

# HTMLタグなどの不要なデータを削除
$s  -replace '</[^>]+>',' '                         `
    -replace '<[^>]+>',''

#========================================================================
# 作業用の一時ファイルを削除
#========================================================================
Remove-Item $SrcFile

実行すると次のようになる。

PS C:\Users\daichi> .\test-3.ps1
東京都 西多摩郡奥多摩町 小河内(オゴウチ) 15.2 ] 12:19] 14時までお待ちください
東京都 青梅市 青梅(オウメ) 18.2 ] 12:21] 14時までお待ちください
東京都 練馬区 練馬(ネリマ) 17.9 ] 11:52] 14時までお待ちください
東京都 八王子市 八王子(ハチオウジ) 18.6 ] 12:37] 14時までお待ちください
東京都 府中市 府中(フチュウ) 18.9 ] 12:19] 14時までお待ちください
東京都 千代田区 東京(トウキョウ)* 20.0 ] 12:45] 14時までお待ちください
東京都 江戸川区 江戸川臨海(エドガワリンカイ) 18.8 ] 09:57] 14時までお待ちください
東京都 大田区 羽田(ハネダ) 19.8 ] 11:50] 14時までお待ちください
東京都 大島町 大島(オオシマ)* 16.9 ] 12:52] 14時までお待ちください
東京都 大島町 大島北ノ山(オオシマキタノヤマ) 17.2 ] 12:55] 14時までお待ちください
東京都 新島村 新島(ニイジマ) 17.2 ] 06:08] 14時までお待ちください
東京都 神津島村 神津島(コウヅシマ) 16.4 ] 06:13] 14時までお待ちください
東京都 三宅村 三宅島(ミヤケジマ)* 16.8 ] 05:54] 14時までお待ちください
東京都 三宅村 三宅坪田(ミヤケツボタ) 17.6 ] 07:09] 14時までお待ちください
東京都 八丈町 八重見ヶ原(ヤエミガハラ) 18.6 ] 09:34] 14時までお待ちください
東京都 八丈町 八丈島(ハチジョウジマ)* 18.2 ] 09:30] 14時までお待ちください
東京都 小笠原村 父島(チチジマ)* 22.4 ] 11:21] 14時までお待ちください
PS C:\Users\daichi>

かなり得られるデータが絞られてきた。

さらに必要な列のデータだけを出力する

このデータだと3列目が地名、4列目が気温になっていることがわかる。この列だけを取り出す処理をさらに追加する。具体的には、行ごとに「-split」でデータを配列に分割し、3列目と4列目のみを出力するように処理を変更する。

#!/usr/bin/env pwsh

#========================================================================
# 気温データを取得して整理する
#========================================================================
$URL = 'https://www.data.jma.go.jp/obd/stats/data/mdrr/tem_rct/alltable/mxtemsad00.html'
$SrcFile = New-TemporaryFile

curl        --get $URL                                      > $SrcFile 2> $null

#========================================================================
# 東京の気象データを抽出
#========================================================================
# 東京都の気象データを抽出
$s = (Get-Content $SrcFile | Select-String '>東京都</td')

# HTMLタグなどの不要なデータを削除
$s = $s     -replace '</[^>]+>',' '                         `
    -replace '<[^>]+>',''

# 地名と気温を抽出
foreach ($l in $s) {
    $a = $l -split " "
    $a[2] + " " + $a[3]
}

#========================================================================
# 作業用の一時ファイルを削除
#========================================================================
Remove-Item $SrcFile

実行すると次のようになる。

PS C:\Users\daichi> .\test-4.ps1
小河内(オゴウチ) 15.2
青梅(オウメ) 18.2
練馬(ネリマ) 17.9
八王子(ハチオウジ) 18.6
府中(フチュウ) 18.9
東京(トウキョウ)* 20.0
江戸川臨海(エドガワリンカイ) 18.8
羽田(ハネダ) 19.8
大島(オオシマ)* 16.9
大島北ノ山(オオシマキタノヤマ) 17.2
新島(ニイジマ) 17.2
神津島(コウヅシマ) 16.4
三宅島(ミヤケジマ)* 16.8
三宅坪田(ミヤケツボタ) 17.6
八重見ヶ原(ヤエミガハラ) 18.6
八丈島(ハチジョウジマ)* 18.2
父島(チチジマ)* 22.4
PS C:\Users\daichi>

かなりいい感じだ。ただ、フリガナや注釈記号は必要ないので、それらのデータを削除する処理をさらに追加する。削除は先ほどの「-replace」による置換処理をそのまま利用すればよい。

#!/usr/bin/env pwsh

#========================================================================
# 気温データを取得して整理する
#========================================================================
$URL = 'https://www.data.jma.go.jp/obd/stats/data/mdrr/tem_rct/alltable/mxtemsad00.html'
$SrcFile = New-TemporaryFile

curl        --get $URL                                      > $SrcFile 2> $null

#========================================================================
# 東京の気象データを抽出
#========================================================================
# 東京都の気象データを抽出
$s = (Get-Content $SrcFile | Select-String '>東京都</td')

# HTMLタグなどの不要なデータを削除
$s = $s     -replace '</[^>]+>',' '                         `
    -replace '<[^>]+>',''                           `
    -replace '([^)]+)[*]*',''

# 地名と気温を抽出
foreach ($l in $s) {
    $a = $l -split " "
    $a[2] + " " + $a[3]
}

#========================================================================
# 作業用の一時ファイルを削除
#========================================================================
Remove-Item $SrcFile

実行すると次のようになる。

PS C:\Users\daichi> .\test-5.ps1
小河内 15.2
青梅 18.2
練馬 17.9
八王子 18.6
府中 18.9
東京 20.0
江戸川臨海 18.8
羽田 19.8
大島 16.9
大島北ノ山 17.2
新島 17.2
神津島 16.4
三宅島 16.8
三宅坪田 17.6
八重見ヶ原 18.6
八丈島 18.2
父島 22.4
PS C:\Users\daichi>

WebページからGoogle Charts向けの数値データを生成する

Google Chartsで利用するには、このデータがJavaScriptで使える形式になっている必要があるので、そのようにフォーマットを整える。

#!/usr/bin/env pwsh

#========================================================================
# 気温データを取得して整理する
#========================================================================
$URL = 'https://www.data.jma.go.jp/obd/stats/data/mdrr/tem_rct/alltable/mxtemsad00.html'
$SrcFile = New-TemporaryFile

curl        --get $URL                                      > $SrcFile 2> $null

#========================================================================
# 東京の気象データを抽出
#========================================================================
# 東京都の気象データを抽出
$s = (Get-Content $SrcFile | Select-String '>東京都</td')

# HTMLタグなどの不要なデータを削除
$s = $s     -replace '</[^>]+>',' '                         `
    -replace '<[^>]+>',''                           `
    -replace '([^)]+)[*]*',''

# 地名と気温を抽出
foreach ($l in $s) {
    $a = $l -split " "
    "['" + $a[2] + "'," + $a[3] + "],"
}

#========================================================================
# 作業用の一時ファイルを削除
#========================================================================
Remove-Item $SrcFile

実行すると次のようになる。

PS C:\Users\daichi> .\test-6.ps1
['小河内',15.2],
['青梅',18.2],
['練馬',17.9],
['八王子',18.6],
['府中',18.9],
['東京',20.0],
['江戸川臨海',18.8],
['羽田',19.8],
['大島',16.9],
['大島北ノ山',17.2],
['新島',17.2],
['神津島',16.4],
['三宅島',16.8],
['三宅坪田',17.6],
['八重見ヶ原',18.6],
['八丈島',18.2],
['父島',22.4],
PS C:\Users\daichi>

前回取り上げた、Google Charts用のHTMLで使用できるデータ形式になっていることがわかる。これで今回の目的とするデータが得られたことになる。

テキストデータをパパッと処理

今回行ったようなデータの加工処理は、一時的なものだ。Webページの構造が変われば使えなくなる。永続的に利用できるスクリプトではなく、あくまでもそのときにパパッと書いて使うもの、そういった種類のスクリプトだ。

このようにそもそも永続的に利用できるものではないので、テキスト処理もそれほど厳密にやる必要はない。そのとき動作する、なるべくシンプルでわかりやすい方法で実装しておけばよく、将来どこかのタイミングでWebページの方の書き方が変わったら、そのときにまたパパッと書き換えられるようにしておく。

このように、PowerShellはちょっとしたテキストデータの処理も手軽に行うことができる。結構いろいろなことに使える書き方なので、ぜひ一度お試しいただきたい。