近年、中国の大気汚染問題がますます深刻になって、日本でも注目されるようになりました。今の中国はどんな状況なのでしょうか?日本は大丈夫でしょうか?世界中の有名な都市の大気汚染の現状はどうなのでしょうか?
ASTERIA WARPのフローサービスを利用し、気になる都市の大気汚染状況のリアルタイム比較サイトを作りましょう。
今回利用するコンポーネントとマッパー関数は下記のものを利用します:
目的
URL にアクセスするだけで、各都市の最近のPM2.5の指数が折れ線グラフで表示され状況が一目で分かります。
作り方
1. データのソース
理想的な作り方は大気汚染の状況を取得する API を利用することですが、残念ながらそういう API は存在しないようです(ちなみに中国には大気汚染の状況を取得する API が存在していますが、中国国内のデータしかないので今回は利用できません)。
そこで、今回は「aqicn.org」というサイトのデータを利用します。このサイトには全世界の大気汚染のデータがありますが、API はないので当サイトの HTML を解析してデータを取得します。
2. データの保存
上記の aqicn サイトからは現在のデータしか取得できないので、データの推移を描くため、過去のデータを保存する必要があります。データを保存する方法はいろいろありますが、今回は簡単に行うためCSVファイルにデータを保存します。
定期的にデータを取得しないとならないので、「一定間隔で実行」の実行設定を利用します。
3. その他
データを観測する都市を気軽に追加できるようにするため、気になる都市のリストはCSVファイルに保存します。
4. 流れ
上記の方法に基づく、サイト作りの流れは下記のようになります:
データ収集
1. 準備
まずはフローデザイナーで「AirPolution」のプロジェクトを作ります。そして都市リストの CSV ファイルを下記のように書きます:
東京 | japan/chiyodaku/chiyodakukandatsukasamachi | 0 |
北京 | beijing | 1 |
上海 | shanghai | 1 |
香港 | hongkong | 1 |
ニューヨーク | usa/newyork/is-52 | 13 |
パリ | france/paris/paris-18eme | 7 |
ロンドン | united-kingdom/london-bexley | 8 |
サンパウロ | brazil/sao-paulo/americana | 12 |
ニューデリー | delhi/mandir-marg | 3 |
1列目は表示用の都市名、2列目は aqicn サイトの都市コード、3列目は当都市の日本時間との時差です。
この例では CSV ファイル名を「cities.csv」にします。
2. フロー
「DataCollector」というフローを作ります:
① 都市リストの取得
都市リストは CSV ファイルに保存してあるので、RecordGetコンポーネントを利用して読み込みます。
「ファイルパス」と「ファイルのエンコーディング」を設定してください。出力ストリームは「CSV」で、ファイル内容の3列に対して3つのフィールドを定義します。
② 都市データの処理とURLのマッピング
「city」というフロー変数を追加してそこに都市の名前をマッピングしておきます。そして都市のコードによって大気汚染データの取得 URL を生成します。Embedマッパー関数を利用し、その関数の「データ」プロパティーを「http://aqicn.org/city/${input1}/jp/」に設定します。ここの「${input1}」は一番目の入力の意味です。入力は都市のコードにして、出力は次のHTTPGetコンポーネントの「URL」プロパティーにマッピングします。そうすると、例えば東京の場合は、${input1}に「japan/chiyodaku/chiyodakukandatsukasamachi」が入ってきますので、Embed関数の結果は「http://aqicn.org/city/japan/chiyodaku/chiyodakukandatsukasamachi/jp/」となります。
③ HTTP通信
HTTPGetコンポーネントで aqicn にアクセスします。URL は既にマッピング済みなので「コネクションを使用」プロパティーを「いいえ」にします。それ以外はデフォルトのままで構いません。
④ 結果の分析
通信の結果の HTML はHTTPGetコンポーネントの出力ストリームとなっています。HTMLParseコンポーネントでHTMLの結果を解析します。
まずは「ベースセレクター」を設定し、データのDIVを取得します。次に画像のように「data」と「time」のフィールドを追加し、PM2.5 の値と更新時刻の文字列を取得します。PM2.5 の値は数字なので「Decimal」のデータ型に設定します。セレクターの書き方はヘルプを参照してください。
⑤ 時刻の処理
Regexpマッパー関数で上記の更新時刻の文字列から更新時間の数字を取得します。文字列の内容によって「正規表現」と「出力するグループ」を設定します。ここで取得した時間は日本時間ではなく、各都市の時間です。各都市のデータを正確に比較するため、日本時間に変換する必要があります。ここではAddとMod関数を利用して変換します。例えば、当地の時間が 15 時、時差が 13 の場合、「(15 + 13) % 24 = 4」の計算で日本時間の 4 時に変換できます。
取得した時間の数字で測定時刻の文字列を生成します。例えば、取得した時間が15 時、当日の日付が「2010-01-01」 の場合、「2010-01-01T15:00:00.000 JST」の文字列を生成します。まずはNow関数で現在の時刻を取得します。時、分、秒の数字が必要ないので、「時刻を設定しない」を「はい」にします。そしてデータ型の変換(String → DateTime)のために「日付フォーマット」を「DateTime型」に設定します。これで「2010-01-01T15:00:00.000 JST」の形式の時刻文字列を取得できます。それからRegexpReplace関数で最初の「00」を先ほど取得した時間の数字に置換します。「正規表現」と「置換対象」を画像のように設定します。
ここまでHTMLの分析は完了です。次は出力フィールドを3つ追加し、都市名、測定時刻、PM2.5 の値をマッピングします。
⑥ 日付のチェック
データを保存する前に、日付のチェックを行います。
aqicn のデータは現在のデータではなく、1時間か2時間前のデータです。そのため、毎日の深夜の 24 時~ 26 時ぐらいに取得したデータの日付は現在の日付ではないかもしれません。aqicn から測定の日付を取れるなら楽なのですが、残念ながら取れません。そのため、ここで日付をチェックします。
まずは先ほど生成した測定時刻とNow関数の現在時刻(「時刻を設定しない」を「いいえ」にします)をGreater関数で比較します。そしてBoolIf関数を利用し、比較結果で分岐します。結果が「false」の場合(測定時刻は現在時刻より小さい)、測定時刻をそのまま出力します。逆に「true」の場合、つまりデータの日付が実際1日前の日付の場合、DateCalc関数を利用して測定時刻の日付を「-1」してから出力します。
都市名と PM2.5 の値はそのまま出力します。
⑦ データの保存
最後に、データを保存します。「ファイルパス」にファイル名を設定します。毎回データを追加するので「書込み処理」を「追加」にします。
このフローには戻り値がないので、Endコンポーネントで終了します。
3. 定期的に実行
このフローに「一定間隔で実行」の実行設定を設定します。aqicn サイトのデータは1時間ごとに更新されますので、30 分で実行間隔を設定します。その他のプロパティーはそのままで構いません。
これで、データ収集のフローは完成です。30 分ごとに aqicn サイトにアクセスし、PM2.5 の値を取得して保存します。
データの表示
1. フロー
「Display」というフローを作ります:① データの読み込みと変換
まずはデータを読み込みます。ここでループしたくないので、RecordGetではなくFileGetコンポーネントを利用します。「ファイルパス」と「ファイルのエンコーディング」を設定してください。
出力ストリームは画像のように設定します。これは次のLineGraphコンポーネントの入力に使用するためです。CSV ファイルの中身は実際には3列しかないので、4番目のフィールドの値は空になりますが、LineGraphは「Color」が必須ではないので大丈夫です。
② チャートの生成
折れ線グラフが一番見やすいので、ここではLineGraphコンポーネントを利用して比較チャートを生成します。自分の好みによってチャートのプロパティーを設定してください。
最後に、チャートをブラウザーで見たいので、HttpEndコンポーネントでフローを終了します。
2. 実行設定
これで大気汚染の比較サイトが完成です。
後記と感想
- 上記の例の都市リストにたくさんの都市を入れて実行すると、大量アクセスの理由でブロックされる可能性があります。そういう状況を防ぐため、データ収集のフローにSleepコンポーネントを使用しデータの取得間隔を広げることをおすすめします。
- このサイトのアジア圏以外の都市の測定データは一時的に取得できないことがありますのでご注意ください。データを取得できないときは、当都市のデータを保存しないようにします。
- やはり北京の大気の状況は深刻です。東京は大体問題ないですが、油断できない数字ですね。
AirPolution.zip