1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Express経由でLivedoor Weather Web Service の RestAPI を呼んでみる

Last updated at Posted at 2020-04-23

※livedoor 天気サービスは2020/7/31で終了

代替サービス探します

はじめに

お天気情報とってくるAPIがいくつかあると知って、試した

Livedoor Weather Web Service

概要

  • livedoorがWeatherHackというお天気情報出してる
  • お天気情報取得RestAPIも出してる

準備

  • Node.js
    サーバー立てるのに使用

  • dataTables.js
    データ表示に使用(今回ソースはダウンロードせずimportして使う)

使用方法

公式ドキュメント

  • GET:http://weather.livedoor.com/forecast/webservice/json/v1 + cityID
  • City IDは公式のXMLから探してる使う模様
  • CORS許可がないので、HTMLから直Requestできない→サーバー立てる必要がある
  • JSONでかえってくる(Valueがすべてendcodeされているので、parseする)
    かえってきた中身は↓のような感じ
sampledata.json
{
    "pinpointLocations": [
        {
            "link": "http://weather.livedoor.com/area/forecast/0121400",
            "name": "稚内市"
        },
        {
            "link": "http://weather.livedoor.com/area/forecast/0151100",
            "name": "猿払村"
        },
        {
            "link": "http://weather.livedoor.com/area/forecast/0151200",
            "name": "浜頓別町"
        },
        {
            "link": "http://weather.livedoor.com/area/forecast/0151300",
            "name": "中頓別町"
        },
        {
            "link": "http://weather.livedoor.com/area/forecast/0151400",
            "name": "枝幸町"
        },
        {
            "link": "http://weather.livedoor.com/area/forecast/0151600",
            "name": "豊富町"
        },
        {
            "link": "http://weather.livedoor.com/area/forecast/0151700",
            "name": "礼文町"
        },
        {
            "link": "http://weather.livedoor.com/area/forecast/0151800",
            "name": "利尻町"
        },
        {
            "link": "http://weather.livedoor.com/area/forecast/0151900",
            "name": "利尻富士町"
        },
        {
            "link": "http://weather.livedoor.com/area/forecast/0152000",
            "name": "幌延町"
        }
    ],
    "link": "http://weather.livedoor.com/area/forecast/011000",
    "forecasts": [
        {
            "dateLabel": "今日",
            "telop": "曇り",
            "date": "2020-04-23",
            "temperature": {
                "min": null,
                "max": null
            },
            "image": {
                "width": 50,
                "url": "http://weather.livedoor.com/img/icon/8.gif",
                "title": "曇り",
                "height": 31
            }
        },
        {
            "dateLabel": "明日",
            "telop": "曇のち晴",
            "date": "2020-04-24",
            "temperature": {
                "min": {
                    "celsius": "2",
                    "fahrenheit": "35.6"
                },
                "max": {
                    "celsius": "7",
                    "fahrenheit": "44.6"
                }
            },
            "image": {
                "width": 50,
                "url": "http://weather.livedoor.com/img/icon/12.gif",
                "title": "曇のち晴",
                "height": 31
            }
        },
        {
            "dateLabel": "明後日",
            "telop": "曇時々晴",
            "date": "2020-04-25",
            "temperature": {
                "min": null,
                "max": null
            },
            "image": {
                "width": 50,
                "url": "http://weather.livedoor.com/img/icon/9.gif",
                "title": "曇時々晴",
                "height": 31
            }
        }
    ],
    "location": {
        "city": "稚内",
        "area": "北海道",
        "prefecture": "道北"
    },
    "publicTime": "2020-04-23T17:00:00+0900",
    "copyright": {
        "provider": [
            {
                "link": "http://tenki.jp/",
                "name": "日本気象協会"
            }
        ],
        "link": "http://weather.livedoor.com/",
        "title": "(C) LINE Corporation",
        "image": {
            "width": 118,
            "link": "http://weather.livedoor.com/",
            "url": "http://weather.livedoor.com/img/cmn/livedoor.gif",
            "title": "livedoor 天気情報",
            "height": 26
        }
    },
    "title": "道北 稚内 の天気",
    "description": {
        "text": " 北海道付近は、24日にかけて低気圧を含む気圧の谷の中で、はじめ気圧の傾きが大きいでしょう。\n\n 宗谷地方の23日15時の天気は、おおむね雪となっています。\n\n 23日夜は、曇りで、雪の降る所があるでしょう。\n\n 24日は、曇りで、昼前から晴れの見込みです。\n\n 海の波の高さは、23日夜は、2.5メートルのち2メートルとやや高いでしょう。24日は2メートルとやや高い見込みです。",
        "publicTime": "2020-04-23T16:39:00+0900"
    }
}

サーバーを立てる

仕様

  • /indexにアクセスしたらお天気検索ページへ飛ぶ
  • /forcastにアクセスしたらお天気情報のJSONを返す

ソースコード

  • expressでロールサーバー起動
  • requestでWeatherWebServiceAPIを叩く
package.json
{
  "name": "forcast_api",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node index.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1",
    "request": "^2.88.2"
  }
}

index.js
const express = require("express")
const server = express();
const port = 3000
const request = require('request');

server.get("/", function (req, res) {
    res.send("server is up")
})

server.get("/index", function (req, res) {
    res.sendFile("./index.html")
})

server.get("/forcast", function (req, res) {
    const base_url = "http://weather.livedoor.com/forecast/webservice/json/v1"
    const url = base_url + "?city=" + req.query.city

    request({ url: url, method: "GET" }, function (error, responce, data) {
        if (error) {
            res.status(400).send(error)
        } else {
            res.send(JSON.parse(data))
        }
    })
})

server.listen(port, function () {
    console.log("sever: " + port)
})

Webページを作る

仕様

  1. 公式に乗ってる全地域から1つ選択
  2. 天気情報を取得ボタン押下→天気情報の(全部表示するのは大変そうなので)一部が表示される

ソースコード

  • dataTable.jsの説明は今回省略
  • optionベタ書きのため長くなった
index.html
<!DOCTYPE html>
<html>

<head>
    <meta charset="urf-8">
    <title>forcast api test</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
        integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    <link rel="stylesheet" href="https://cdn.datatables.net/t/bs-3.3.6/jqc-1.12.0,dt-1.10.11/datatables.min.css" />
    <style>
        textarea {
            width: 600px;
            height: 8em;
            line-height: 1.5em;
        }
    </style>

</head>

<body>
    <select id="city_select">
        <option value=011000> 道北-稚内 </option>
        <option value=012010> 道北-旭川 </option>
        <option value=012020> 道北-留萌 </option>
        <option value=013010> 道東-網走 </option>
        <option value=013020> 道東-北見 </option>
        <option value=013030> 道東-紋別 </option>
        <option value=014010> 道東-根室 </option>
        <option value=014020> 道東-釧路 </option>
        <option value=014030> 道東-帯広 </option>
        <option value=015010> 道南-室蘭 </option>
        <option value=015020> 道南-浦河 </option>
        <option value=016010> 道央-札幌 </option>
        <option value=016020> 道央-岩見沢 </option>
        <option value=016030> 道央-倶知安 </option>
        <option value=017010> 道南-函館 </option>
        <option value=017020> 道南-江差 </option>
        <option value=020010> 青森県-青森 </option>
        <option value=020020> 青森県-むつ </option>
        <option value=020030> 青森県-八戸 </option>
        <option value=030010> 岩手県-盛岡 </option>
        <option value=030020> 岩手県-宮古 </option>
        <option value=030030> 岩手県-大船渡 </option>
        <option value=040010> 宮城県-仙台 </option>
        <option value=040020> 宮城県-白石 </option>
        <option value=050010> 秋田県-秋田 </option>
        <option value=050020> 秋田県-横手 </option>
        <option value=060010> 山形県-山形 </option>
        <option value=060020> 山形県-米沢 </option>
        <option value=060030> 山形県-酒田 </option>
        <option value=060040> 山形県-新庄 </option>
        <option value=070010> 福島県-福島 </option>
        <option value=070020> 福島県-小名浜 </option>
        <option value=070030> 福島県-若松 </option>
        <option value=080010> 茨城県-水戸 </option>
        <option value=080020> 茨城県-土浦 </option>
        <option value=090010> 栃木県-宇都宮 </option>
        <option value=090020> 栃木県-大田原 </option>
        <option value=100010> 群馬県-前橋 </option>
        <option value=100020> 群馬県-みなかみ </option>
        <option value=110010> 埼玉県-さいたま </option>
        <option value=110020> 埼玉県-熊谷 </option>
        <option value=110030> 埼玉県-秩父 </option>
        <option value=120010> 千葉県-千葉 </option>
        <option value=120020> 千葉県-銚子 </option>
        <option value=120030> 千葉県-館山 </option>
        <option value=130010> 東京都-東京 </option>
        <option value=130020> 東京都-大島 </option>
        <option value=130030> 東京都-八丈島 </option>
        <option value=130040> 東京都-父島 </option>
        <option value=140010> 神奈川県-横浜 </option>
        <option value=140020> 神奈川県-小田原 </option>
        <option value=150010> 新潟県-新潟 </option>
        <option value=150020> 新潟県-長岡 </option>
        <option value=150030> 新潟県-高田 </option>
        <option value=150040> 新潟県-相川 </option>
        <option value=160010> 富山県-富山 </option>
        <option value=160020> 富山県-伏木 </option>
        <option value=170010> 石川県-金沢 </option>
        <option value=170020> 石川県-輪島 </option>
        <option value=180010> 福井県-福井 </option>
        <option value=180020> 福井県-敦賀 </option>
        <option value=190010> 山梨県-甲府 </option>
        <option value=190020> 山梨県-河口湖 </option>
        <option value=200010> 長野県-長野 </option>
        <option value=200020> 長野県-松本 </option>
        <option value=200030> 長野県-飯田 </option>
        <option value=210010> 岐阜県-岐阜 </option>
        <option value=210020> 岐阜県-高山 </option>
        <option value=220010> 静岡県-静岡 </option>
        <option value=220020> 静岡県-網代 </option>
        <option value=220030> 静岡県-三島 </option>
        <option value=220040> 静岡県-浜松 </option>
        <option value=230010> 愛知県-名古屋 </option>
        <option value=230020> 愛知県-豊橋 </option>
        <option value=240010> 三重県-津 </option>
        <option value=240020> 三重県-尾鷲 </option>
        <option value=250010> 滋賀県-大津 </option>
        <option value=250020> 滋賀県-彦根 </option>
        <option value=260010> 京都府-京都 </option>
        <option value=260020> 京都府-舞鶴 </option>
        <option value=270000> 大阪府-大阪 </option>
        <option value=280010> 兵庫県-神戸 </option>
        <option value=280020> 兵庫県-豊岡 </option>
        <option value=290010> 奈良県-奈良 </option>
        <option value=290020> 奈良県-風屋 </option>
        <option value=300010> 和歌山県-和歌山 </option>
        <option value=300020> 和歌山県-潮岬 </option>
        <option value=310010> 鳥取県-鳥取 </option>
        <option value=310020> 鳥取県-米子 </option>
        <option value=320010> 島根県-松江 </option>
        <option value=320020> 島根県-浜田 </option>
        <option value=320030> 島根県-西郷 </option>
        <option value=330010> 岡山県-岡山 </option>
        <option value=330020> 岡山県-津山 </option>
        <option value=340010> 広島県-広島 </option>
        <option value=340020> 広島県-庄原 </option>
        <option value=350010> 山口県-下関 </option>
        <option value=350020> 山口県-山口 </option>
        <option value=350030> 山口県-柳井 </option>
        <option value=350040> 山口県-萩 </option>
        <option value=360010> 徳島県-徳島 </option>
        <option value=360020> 徳島県-日和佐 </option>
        <option value=370000> 香川県-高松 </option>
        <option value=380010> 愛媛県-松山 </option>
        <option value=380020> 愛媛県-新居浜 </option>
        <option value=380030> 愛媛県-宇和島 </option>
        <option value=390010> 高知県-高知 </option>
        <option value=390020> 高知県-室戸岬 </option>
        <option value=390030> 高知県-清水 </option>
        <option value=400010> 福岡県-福岡 </option>
        <option value=400020> 福岡県-八幡 </option>
        <option value=400030> 福岡県-飯塚 </option>
        <option value=400040> 福岡県-久留米 </option>
        <option value=410010> 佐賀県-佐賀 </option>
        <option value=410020> 佐賀県-伊万里 </option>
        <option value=420010> 長崎県-長崎 </option>
        <option value=420020> 長崎県-佐世保 </option>
        <option value=420030> 長崎県-厳原 </option>
        <option value=420040> 長崎県-福江 </option>
        <option value=430010> 熊本県-熊本 </option>
        <option value=430020> 熊本県-阿蘇乙姫 </option>
        <option value=430030> 熊本県-牛深 </option>
        <option value=430040> 熊本県-人吉 </option>
        <option value=440010> 大分県-大分 </option>
        <option value=440020> 大分県-中津 </option>
        <option value=440030> 大分県-日田 </option>
        <option value=440040> 大分県-佐伯 </option>
        <option value=450010> 宮崎県-宮崎 </option>
        <option value=450020> 宮崎県-延岡 </option>
        <option value=450030> 宮崎県-都城 </option>
        <option value=450040> 宮崎県-高千穂 </option>
        <option value=460010> 鹿児島県-鹿児島 </option>
        <option value=460020> 鹿児島県-鹿屋 </option>
        <option value=460030> 鹿児島県-種子島 </option>
        <option value=460040> 鹿児島県-名瀬 </option>
        <option value=471010> 沖縄県-那覇 </option>
        <option value=471020> 沖縄県-名護 </option>
        <option value=471030> 沖縄県-久米島 </option>
        <option value=472000> 沖縄県-南大東 </option>
        <option value=473000> 沖縄県-宮古島 </option>
        <option value=474010> 沖縄県-石垣島 </option>
        <option value=474020> 沖縄県-与那国島 </option>

    </select>

    <button onclick="getForcast()">天気情報を取得</button>

    <div>
        <h1><span id="title"></span></h1>
        <span id="publicTime"></span>
    </div>

    <div>
        <textarea id="description"></textarea>
    </div>

    <h3>天気情報</h3>
    <table id="forcast_table" class="table table-bordered">
        <thead>
            <tr>
                <th class="dateLabel"></th>
                <th class="date">日付</th>
                <th class="telop">天気</th>
                <th class="temperature.min.celsius">最低気温</th>
                <th class="temperature.max.celsius">最高気温</th>
            </tr>
        </thead>

    </table>

    <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
    <script src="https://cdn.datatables.net/t/bs-3.3.6/jqc-1.12.0,dt-1.10.11/datatables.min.js"></script>


    <script>
        // datatableのinitialize
        let dt = $('#forcast_table').DataTable(
            {
                dom: "t",
                paging: false,
                autoWidth: true,
                scrollY: "500px",
                scrollX: true,
                order: [],
                orderClasses: false,
                columnDefs: [{
                    className: "dt-right",
                }],
                columns: [
                    { data: "dateLabel", width: "50px" },
                    { data: "date", width: "50px" },
                    { data: "telop", width: "50px" },
                    { data: "temperature.min.celsius", width: "60px", "defaultContent": "-" },
                    { data: "temperature.max.celsius", width: "60px", "defaultContent": "-" },
                ]
            }
        );

        function getForcast() {
            console.log("clicled")
            const base_url = "http://localhost:3000/forcast"
            const city = document.getElementById("city_select").value
            const url = base_url + "?city=" + city

            const request = new XMLHttpRequest();
            request.open('GET', url, true);
            request.onreadystatechange = function () {
                if (request.readyState != 4) {
                } else if (request.status != 200) {
                    console.log("http request failed.")
                } else {
                    console.log("success", request.responseText);
                    const data = JSON.parse(request.responseText)
                    const newdate = new Date(data.publicTime)
                    document.getElementById("title").innerText = data.title
                    document.getElementById("publicTime").innerText = newdate.toLocaleDateString() + " " + newdate.toLocaleTimeString()
                    document.getElementById("description").value = data.description.text
                    // datatableを更新
                    dt.clear().draw();
                    dt.rows.add(data.forecasts);
                    dt.columns.adjust().draw();
                }
            };
            request.send();

        }
    </script>
</body>

</html>

結果

  1. npm installした後に
  2. npm startして
  3. http://localhost:3000/index にアクセス

image.png

4.天気情報を取得ボタン押下

うまくいきました
image.png

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?