大気汚染世界一のハノイのAQI, PM2.5の状況をMacのデスクトップにGeekToolで表示する


前置き

先日、AirVisual というサービス?が発表する大気汚染ランキングでハノイが世界第1位、ホーチミンが世界第3位を記録したことがニュースで取り上げられ、Facebook 等でも連日話題になっています。ランキングの内容をよく見るに、瞬間最大風速的な話しで、恒常的に大気汚染されているということではないようなので、あまり気にする必要はないのかも知れませんが、会社経営側としては、安全配慮義務的に、大気汚染をどう捉えるべきか考える機会となりました。というわけで、大気汚染の状況をウォッチして行くことにしました。

(参考)

ただ、アプリや機能拡張をインストールしたり、毎回ウェブサイトにアクセスするほどのモチベーションはなく、気にしなくても見えてるくらいにしたいので、GeekTool でデスクトップに表示することにします。grep とか sed とか正規表現とか、しばらく使わないと忘れるし。

システム要件

今回はこんな環境でやりました。

Item Version
OS MacOS Mojave 10.14.6
bash 3.2.57(1)-release (x86_64-apple-darwin18)
curl curl 7.54.0 (x86_64-apple-darwin18.0)
grep 2.5.1-FreeBSD
sed 不明
GeekTool 3.1.1

(Mac の sed のバージョンってどうやって調べるの?)

ソースコードを眺めて方針を検討する

Hanoi Air Quality Index (AQI) and PM2.5...
欲しい値は、現時点の AQIの値とレベル(Good, Moderate, Unhealthy for Sensitive Groups, Unhealthy, Very Unhealthy, Hazardous)、PM2.5 の濃度の3つです。
ソースコードを開いてみると…あぁ難読ですね。行を抽出しても使えない。しばし眺めてみると、AQIに関しては、h1タグで囲われており、PM2.5 に関しては単位の µg/m³ が特徴的なことが分かります。

  • curl でソースコードを取得する
  • grep の E オプションを使い正規表現で <h1~µg/m³ を検索し、o オプションで該当箇所を抽出する。
  • sed で整形する。

こんな感じにしましょう。

curl でソースコードを取得する

ここは省略で良いですかね。

curl -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X)' --silent https://www.airvisual.com/vietnam/hanoi

ホーチミンの場合は、hanoi の部分を ho-chi-minh-city に変えればOKです。

grep で抽出する

grep の o オプションは、マッチした箇所だけを抽出するオプションです。ソースコードには改行がほとんどないので、oオプションで抽出します。
E オプションは、正規表現。
試しに、

curl .... | grep -oE '<h1(.+)µg/m³'

としてみると、PM2.5 の値が繰り返し出てくるため、加工に入るにはまだちょっと長いです。なので、短くします。

curl .... | grep -oE '<h1([^µ]+)µg/m³'

70%くらいになりました。まぁ良しとします。

sed で整形する

まずは、h1 の閉じタグから、PM2.5の数値までを正規表現でゴッソリ消したいと思います。

curl ... | grep ... | sed -E 's/<\/h1>(.+)\| //g'

...for Sensitive Groups53.7 µg/m³ こんな感じになりました。改行しましょう。

改行は、`\\nなどと入れればできそうですが、できないので、's/xxx/\'$'\n/' のように書きます。

curl ... | grep ... | sed -E 's/<\/h1>(.+)\| /\'$'\n/g'

PM2.5 の文字は消しましたが、必要なので戻したいと思います。オリジナルの表記は、PM2.5 | 53.7 µg/m³ で、| がいやなので、: に置換して整えます。改行時についでにやってしまいましょう。

curl ... | grep ... | sed -E 's/<\/h1>(.+)\| /\'$'\nPM2.5: /g'

結果は、こうなりました。

<h1 _ngcontent-sc26="" title="<b>Hanoi</b> air quality index (AQI) and PM2.5 air pollution is 146, Unhealthy for Sensitive Groups"><b>Hanoi</b> air quality index (AQI) and PM2.5 air pollution is 146, Unhealthy for Sensitive Groups
PM2.5: 53.7 µg/m³

h1 の title 属性にも同じ文言が入っていて邪魔なので、後方の AQI の値の手前までざっくり消しましょう。行頭から is まで消せば良いですかね。複数の正規表現は、; でつなげましょう。ついでにAQI:も付けときます。

curl ...| grep ... | sed -E 's/.../.../g; s/^(.+) is /AQI: /g'

指標には、単位を付けたいところですが、AQI の単位が AQI だとしつこいので省略しました。

スクリプト完成

curl -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X)' --silent https://www.airvisual.com/vietnam/hanoi | grep -oE '<h1([^µ]+)µg/m³' | sed -E 's/<\/h1>(.+)\| /\'$'\nPM2.5: /g; s/^(.+) is /AQI: /g'

AQI: 146, Unhealthy for Sensitive Groups
PM2.5: 53.7 µg/m³

GeekTool に設定

GeekTool の Shell スクリプトでは標準出力とかないので、最初の curl 部分を echo します。

echo "`curl -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X)' --silent https://www.airvisual.com/vietnam/hanoi`" | grep -oE '<h1([^µ]+)µg/m³' | sed -E 's/<\/h1>(.+)\| /\'$'\nPM2.5: /g; s/^(.+) is /AQI: /g'

Refresh は30分おき、タイムアウトは30秒くらいで良いかな?

こんな感じになりました。あぁ...Font face......ま、いっか。

ベトナムに来る際は、マスクを忘れずに。→ Amazon.co.jp: マスク PM2.5

では〜。

余談

私が GeekTool で表示しているのは、

  • 日付 → デフォルトだと見えないので。
  • 時刻 → デフォルトだと小さいので。
  • ネットワーク接続速度(DL/UL) → ベトナムだとネットワークの速度は重要なので。
  • 接続ネットワーク情報 → VPN 接続したり、あれこれ切り替えるので。

などです。気温や天気は、ホーチミンでは見るまでもないので、私には不要。