J-ALERTを個人で受信してみる

# はじめに
私自身今まで何度もQiitaに助けられたのですが、実際に記事を書くのは初めてです。
不慣れな点がありますがご参考程度に読んで頂けると幸いです。
※私個人の忘備録、及び手段なので実行する時は自己責任でお願いします。

# Jアラートとは
>全国瞬時警報システム（Jアラート）とは、弾道ミサイル情報、緊急地震速報、津波警報など、対処に時間的余裕のない事態に関する情報を携帯電話等に配信される緊急速報メール、市町村防災行政無線等により、国から住民まで瞬時に伝達するシステムです。
[総務省消防庁HP(全国瞬時警報システム（Jアラート）の概要)より](https://www.fdma.go.jp/about/organization/post-18.html)

簡単に要約してしまうと、自然災害やテロ・戦争などの人為的災害から即時に身を守る為の伝達システムってことです。
ちょっと前に北朝鮮の弾道ミサイルによってJアラートが発報されていたのが記憶に新しいでしょう。

# 受信に対応している端末
すぐに見聞きできるものとしてはテレビ・ラジオ、防災無線があります。
テレビ・ラジオに関しては自動で電源を付けてくれる機種もありますね。
防災無線も小学校や中学校、専用のアンテナ設備から大音量で発信するので直ぐに気づきます。

しかし、今時テレビを置かない家庭も増えていますし、防災無線が届かないといった場所も存在します。
(私の実家は聞き取れないどころか全く聞こえない地区でした。おまけに防災ラジオの販売配布も無いという…)

そんな届きにくい状態を補ってくれるのが**スマートフォン**です。今だとAndroidもiPhoneも標準搭載ですね。
おまけにJアラートに対応している防災アプリもあります。(NERV防災とかYahoo!防災速報とか)

一方でPC(Windows)の場合、緊急地震速報であったり地震情報と津波情報を知らせてくれる非公式や公式アプリは既に複数存在します**が**、Jアラートに対応するPCソフトウェアは全くないようです。**なんでやねん**

仕方ない、**ないなら私が作ればいいじゃん**。
という考えで作ってみる事にしました。

# どうやって取得するか
そもそもJアラート自体はマルチメディア振興センターを介して受信する為、技術的な資料は一切公開していない。
Google先生で検索したところ、既にAPIらしきドキュメントは存在していますが、APIの利用には契約締結が必須で初期費用＋月3万円以上かかる模様。
個人で受信する分にはあまりにも高すぎる為この方法は断念。

どうにかして取得できないか考えたところ、とあるサイトに行きついた。

[国民保護情報 - Yahoo!天気・災害 (emergency-weather.yahoo.co.jp/weather/jp/jalert/)](https://emergency-weather.yahoo.co.jp/weather/jp/jalert/)

https://emergency-weather.yahoo.co.jp/weather/jp/jalert/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1231024/6ae24685-5daa-3966-4347-b7ac64acb503.png)
なんともシンプル過ぎるページ。
開発者モードでHTMLを覗いたり、特定のリンクをダウンロードするソフトを活用すると驚くべきことが分かった。
* データ自体にJavascriptを使用していない
* Headerやクッキーも使用しない
* HTMLに直接データがある
* ただHTTP GETをするだけで利用可能

このウェブページをスクレイピングすれば行けるんじゃないか？
という事でこのYahoo!さんのページを利用してJアラートの情報を表示してみることにしてみた。

:::note warn
Yahoo!でのスクレイピングについての記載が見当たらないので今回利用していますが、サイトの種類によってはスクレイピングが明確に禁止されているサービス(例:Yahooファイナンス)もあります。
:::

# とりあえずデータを取り出してみる
今回Windows向けに開発していたのでC#で書いてみる。
```c#:C#ソースコード
///using System;
///using System.Net;
///using System.Text.RegularExpressions;
///using System.Diagnostics;
try
{
    WebClient wc = new WebClient();
    var html = wc.DownloadString("https://emergency-weather.yahoo.co.jp/weather/jp/jalert/");
    var results = Regex.Matches(html, "<p class=\\\"jalertInfo-item\\\">(.*)</p>");
    var index = string.Empty;
    if(results.Count>0)index = results[0].Value.Replace("\r", "").Replace("\n", "").Replace("<br>","\n").Trim();
        else index = "J-ALERTは72時間以内に発報されていません。";
    results = Regex.Matches(html, "<div class=\\\"header large title\\\">[\\s]*<h1>(.*)?</h1>");
    var title = results[0].Value.Replace("\r", "").Replace("\n", "");
    title = Regex.Replace(title, "<(\"[^\"]*\"|'[^']*'|[^'\">])*>", "").Trim();
    index = Regex.Replace(index, "<(\"[^\"]*\"|'[^']*'|[^'\">])*>", "").Trim();
    Console.WriteLine($"TITLE : {title}");
    Console.WriteLine($"---------------");
    Console.WriteLine($"INDEX : {index}");
}catch(Exception ex){
    Console.WriteLine(ex);
}
```
```:出力結果
TITLE : 国民保護に関する情報
---------------
INDEX : 【発表時間】
2022年11月3日 8時00分
政府発表

【内容】
ミサイル通過。ミサイル通過。先程のミサイルは、7時48分頃、太平洋へ通過したものとみられます。不審な物を発見した場合には、決して近寄らず、直ちに警察や消防などに連絡して下さい。

【対象地域】
 宮城県 
 山形県 
 新潟県
```

スクレイピングの手法が汚いという事はさておき、これでより簡単に取得することができました。
ここから``index.Split('\n');``なりしてデータを分割して自分好みの構造体に変えられます。

# おわりに
無事スクレイピングでJ-ALERTのデータを取得することができましたが、注意点がいくつかあります。
* サイトの**鯖落ちやメンテナンスなどで使用できない、あるいは誤動作する**ことがある。
* APIと違い**レイアウト変更すると使用できなくなる**
(2017年のJアラート初発出以降UIはずっと変わっていませんが、今後変わる可能性もあります。)
* そもそも**スクレイピング自体がグレーゾーン**
* 使用するにしても**サーバーを意図的に負荷を掛けている事**に留意する必要がある

以上の事が挙げられますので各自自己責任で取扱う必要があります。

ここまで読んで頂きありがとうございました！それでは良き防災ライフを！

## 追記(2022/11/08更新)
発報から72時間以上経過するとウェブサイト上ではデータが消えてしまうようです。(この記事書いて次の日気付いた)
以前のコードのままだと動かないので修正しました。