気象庁公式の天気予報の情報を Node.js で取得し中身を検索する（ライブラリに Got を用いる）

以下のシリーズの続きのようなものになります。

●気象庁公式の天気予報の情報（JSON）を curl・Node.js で取得し Node.js での処理を試す - Qiita
　https://qiita.com/youtoy/items/932bc48b03ced5a45c71

●curl で取得した気象庁公式の天気予報の情報（JSON）を jqコマンドで処理する - Qiita
　https://qiita.com/youtoy/items/db5b515d400d2aa96420

上記の 1つ目の記事で Node.js　による処理を行っていたものの、上記の 2つ目の記事に含まれるような中身の検索は行っていませんでした。
そこで、Node.js で取得した情報の中身を検索してみよう、というのがこの記事の内容です。

## 気象庁公式の天気予報の情報を Node.js で取得
冒頭の 1つ目の記事の中では、Node.js による情報取得に axios を使っていました。

```javascript
const axios = require("axios");

const url = "https://www.jma.go.jp/bosai/forecast/data/forecast/";
const area = "110000"; // 埼玉

(async function getWeatherForecast() {
  try {
    const response = await axios.get(`${url}${area}.json`);
    for(const area of response.data[0].timeSeries[0].areas){
        console.log(`----${area.area.name}----`);
        for(const weather of area.weathers){
            console.log(weather);
        }
    }
  } catch (error) {
    console.error(error);
  }
})();
```

同じことをやっても良いのですが、以前、以下のツイートをした時に見かけて気になっていたライブラリの「[Got](https://www.npmjs.com/package/got)」を試してみたいと思っていたので、こちらを使ってみます。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">gotモジュール、これかな。<br><br>●got - npm<br>　<a href="https://t.co/BOEhYC4PmH">https://t.co/BOEhYC4PmH</a><a href="https://twitter.com/hashtag/nodered?src=hash&amp;ref_src=twsrc%5Etfw">#nodered</a> <a href="https://twitter.com/hashtag/noderedjp?src=hash&amp;ref_src=twsrc%5Etfw">#noderedjp</a> <a href="https://twitter.com/hashtag/trackGlobal?src=hash&amp;ref_src=twsrc%5Etfw">#trackGlobal</a> <a href="https://t.co/hYMRLEyhS6">pic.twitter.com/hYMRLEyhS6</a></p>&mdash; you (@youtoy) <a href="https://twitter.com/youtoy/status/1451833906282450949?ref_src=twsrc%5Etfw">October 23, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

### Got による情報取得
`npm i got` を実行し、以下を利用できるようにします。

●got - npm
　https://www.npmjs.com/package/got

上記の axios を使った例と同じようなことができるよう試したところ、取得したデータに対して `JSON.parse(response.body)[0]` というように `JSON.parse()` を行ったくらいの違いで、上記の例と同じデータ出力を得ることができました。

```javascript
const got = require("got");

const url = "https://www.jma.go.jp/bosai/forecast/data/forecast/";
const area = "110000"; // 埼玉

(async () => {
  try {
    const response = await got(`${url}${area}.json`);
    for (const area of JSON.parse(response.body)[0].timeSeries[0].areas) {
      console.log(`----${area.area.name}----`);
      for (const weather of area.weathers) {
        console.log(weather);
      }
    }
  } catch (error) {
    console.log(error.response.body);
  }
})();
```

出力結果は、以下のとおりです。
![Gotによる出力結果1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/55f183cd-5af8-c9a4-a23b-9cec6e781639.png)

## Node.js で取得したデータの中身を検索する
冒頭に掲載した 2つ目の記事のほうで、jqコマンドを使った中身の部分的な取り出しや検索を行っていました。
それと同じことを、Node.js でやってみます。

### 配列内の特定の全要素を取得
まずは「地域名のみを取り出す」という処理を行ってみます。
jqコマンドで `jq .[0].timeSeries[0].areas[].area.name` という処理を行っていた部分です。

これは上記のプログラムで、天気予報の情報を取り出している部分を削ってやれば OK です。

```javascript
const got = require("got");

const url = "https://www.jma.go.jp/bosai/forecast/data/forecast/";
const area = "110000"; // 埼玉

(async () => {
  try {
    const response = await got(`${url}${area}.json`);
    for (const area of JSON.parse(response.body)[0].timeSeries[0].areas) {
      console.log(`${area.area.name}`);
    }
  } catch (error) {
    console.log(error.response.body);
  }
})();
```

以下のように、地域名だけを取り出せました。

![地域名のみ表示.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/87900c04-dddf-9500-076d-1a87b6600911.jpeg)

### 検索を利用する
今度は検索をやってみます。
jqコマンドだと `jq '.[0].timeSeries[0].areas[] | select(.area.name == "秩父地方")'` という処理を行っていた部分です。

結果を配列として取り出すなら [filter()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)、最初に見つかった 1つのみを取り出すなら [find()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/find) を用いれば良さそうな感じです。

以下に、filter() と find() のそれぞれを用いた場合の処理と、その出力結果とを載せておきます。

#### filter() を使った場合

```javascript
const got = require("got");

const url = "https://www.jma.go.jp/bosai/forecast/data/forecast/";
const area = "110000"; // 埼玉

(async () => {
  try {
    const response = await got(`${url}${area}.json`);
    const result = JSON.parse(response.body)[0].timeSeries[0].areas.filter(
      (a) => a.area.name === "秩父地方"
    );
    console.log(result);
  } catch (error) {
    console.log(error.response.body);
  }
})();
```

以下が出力結果です。
![filter()を使った場合の結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/790d8cfc-9628-91d2-bb35-7877aa066f01.jpeg)

#### find() を利用した場合

```javascript
const got = require("got");

const url = "https://www.jma.go.jp/bosai/forecast/data/forecast/";
const area = "110000"; // 埼玉

(async () => {
  try {
    const response = await got(`${url}${area}.json`);
    const result = JSON.parse(response.body)[0].timeSeries[0].areas.find(
      (a) => a.area.name === "秩父地方"
    );
    console.log(result);
  } catch (error) {
    console.log(error.response.body);
  }
})();
```

以下が出力結果です。

![find()を利用した場合の出力.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/96484ad6-1c13-be85-dce8-66e3eece4519.jpeg)

## おわりに
気象庁公式の天気予報の情報を Got を使って取得し、その中身を検索したりしてみました。

今のところ情報を取り出してみているだけなので、今後、取得できた中身の情報によって処理を変えるような何らかの仕組みなどを、試作したりできればと思います。

## 【追記】 XML で提供されているデータ
11/17 の IoTLT で、「XML で提供されているデータがあるかも？」というコメントをいただき、それについて以下の情報をまた別のコメントでいただきました。
詳細はまだ見られてないですが、仕様など見てみようと思います。

<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">ちなみにLT後に話題に出ていたXMLで提供されている防災情報や天気予報はこれですね。調べてるうちに出てきました。<a href="https://t.co/DTKg6XiDzs">https://t.co/DTKg6XiDzs</a></p>&mdash; まつした (@yskmjp) <a href="https://twitter.com/yskmjp/status/1460684210000510976?ref_src=twsrc%5Etfw">November 16, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>