Google Apps Script (GAS) でスクレイピングじゃなくてAPIを使って天気情報ゲット~OpenWeatherMap~(後編)

Others

前回は「OpenWeatherMap」のAPIを使ってJSONデータを取り出すところまで作りました。

今回はそこから天気予報の形に置き換え、自分にメールを毎朝送るところまで作ります。

前回のコードで出てきた、川越市の天気予報を求めて出てきたJSONがこんな感じです。

(中略しています)


{“cod”:”200″,”message”:0.0082,”cnt”:40,”list”:[

{“dt”1513522800,”main”:{“temp”:-5.01,”temp_min”:-7.21,”temp_max”:-5.01,”pressure”:995.02,”sea_level”:1036.35,”grnd_level”:995.02,”humidity”:63,”temp_kf”:2.19},”weather”:[{“id”:800,”main”:”Clear”,”description”:”clear sky”,”icon”:”02n”}],”clouds”:{“all”:8},”wind”:{“speed”:1.41,”deg”:257.504},”sys”:{“pod”:”n”},”dt_txt”:”2017-12-17 15:00:00″},

{“dt”1513533600,”main”:{“temp”:-7,”temp_min”:-8.47,”temp_max”:-7,”pressure”:995.5,”sea_level”:1036.86,”grnd_level”:995.5,”humidity”:59,”temp_kf”:1.46},”weather”:[{“id”:800,”main”:”Clear”,”description”:”clear sky”,”icon”:”01n”}],”clouds”:{“all”:0},”wind”:{“speed”:1.81,”deg”:252.001},”sys”:{“pod”:”n”},”dt_txt”:”2017-12-17 18:00:00″},

{“dt”1513544400,”main”:{“temp”:-7.71,”temp_min”:-8.45,”temp_max”:-7.71,”pressure”:996.22,”sea_level”:1037.49,”grnd_level”:996.22,”humidity”:59,”temp_kf”:0.73},”weather”:[{“id”:800,”main”:”Clear”,”description”:”clear sky”,”icon”:”01n”}],”clouds”:{“all”:0},”wind”:{“speed”:1.66,”deg”:249.001},”sys”:{“pod”:”n”},”dt_txt”:”2017-12-17 21:00:00″},

~(中略)~

{“dt”1513944000,”main”:{“temp”:-6.07,”temp_min”:-6.07,”temp_max”:-6.07,”pressure”:994.49,”sea_level”:1035.27,”grnd_level”:994.49,”humidity”:66,”temp_kf”:0},”weather”:[{“id”:800,”main”:”Clear”,”description”:”clear sky”,”icon”:”01n”}],”clouds”:{“all”:0},”wind”:{“speed”:1.07,”deg”:239.509},”sys”:{“pod”:”n”},”dt_txt”:”2017-12-22 12:00:00″}],

“city”:{“id”:1859740,”name”:”Kawagoe”,”coord”:{“lat”:35.9086,”lon”:139.4853},”country”:”JP”}}


なお、変数jsonにparseしたJSONのデータを格納した場合、「list」の中にある最初のdt(0番目)の「dt_txt」の文字を出したいのなら、「json.list[0].dt_txt」というように書けば出てきます。

「list」の中に同じ形式の配列が複数あり、どうやらこれが天気予報部分のようです。

このうち、「dt_txt」が日時(datetime_text?)、「weather」が天気予報部分、「wind」が風関係で「main」が気温気圧などかなあ、といった感じです。

気になるのは、天気予報の主要部分である「weather」の中の「main」及び「description」が英語である点と、風向きを示す「wind」の中の「deg」が角度表示な点です。

これについては日本語化するようにしましょう。

中略していますが、向こう5日分、3時間ごとの数字ですので40回くらい日本語変換の必要があります。

ですので、それぞれの日本語化用の関数を作って処理をすることにします。

ちなみに、それぞれの数字の意味はこちらから調べることができます。

天気日本語化用のweatherのidを見るには

そんなこんなで書いてみたのがこちら。

API_KEY = "*********************";//https://home.openweathermap.org/api_keys
BASE_URL = "http://api.openweathermap.org/data/2.5/forecast?units=metric&id=";
CITY_ID="1859740";//川越市のID。自分の自宅や職場近くの都市に変えてみましょう。緯度経度指定なんかもできます。

function getJSON_OPENWEATHERMAP(){
  var mailTo ="***********@*********";
  var opt = {"contentType":"application/json;","muteHttpExceptions":true};
  var postText = "";
  var url_gethtml = BASE_URL + CITY_ID+"&APPID="+API_KEY;

  var data_html = UrlFetchApp.fetch(url_gethtml,opt);
  var content_html = data_html.getContentText();
  var json = JSON.parse(content_html);
  var mailbody="OPENWEATHERMAPによる天気予報";
  for(var i = 0; i < json.list.length;i++){
    var dtime = json.list[i].dt_txt;
    var wText = getWeatherText(json.list[i].weather[0].id);
    var Maxtemp = json.list[i].main.temp_max;
    var Mintemp = json.list[i].main.temp_min;
    var windSpeed = json.list[i].wind.speed;
    var windDeg = getDegText(json.list[i].wind.deg);
    mailbody = mailbody + "\n"+dtime+","+ wText+","+Maxtemp + "℃/" + Mintemp+"℃"+","+"風速"+windSpeed+"m/sec("+windDeg+")";
  }

  var mailsubject = "天気予報:From("+ json.list[0].dt_txt+")";
  MailApp.sendEmail(mailTo,mailsubject,mailbody);

}

function getWeatherText(weathercode){
  var weatherText = "";
  switch (weathercode){
    case 200:weatherText="軽めの雨を伴う雷雨";break;
    case 201:weatherText="雷雨";break;
    case 202:weatherText="豪雨を伴う雷雨";break;
    case 210:weatherText="軽めの雷雨";break;
    case 211:weatherText="雷雨";break;
    case 212:weatherText="重い雷雨";break;
    case 221:weatherText="荒れた雷雨";break;
    case 230:weatherText="軽い霧雨を伴う雷雨";break;
    case 231:weatherText="霧雨を伴う雷雨";break;
    case 232:weatherText="重い霧雨を伴う雷雨";break;
    case 300:weatherText="光度の霧雨";break;
    case 301:weatherText="霧雨";break;
    case 302:weatherText="重い霧雨の霧";break;
    case 310:weatherText="光度降雨雨";break;
    case 311:weatherText="霧雨";break;
    case 312:weatherText="強い霧雨";break;
    case 313:weatherText="シャワーの雨と霧雨";break;
    case 314:weatherText="重いシャワーの雨と霧雨";break;
    case 321:weatherText="シャワーの霧雨";break;
    case 500:weatherText="小雨";break;
    case 501:weatherText="中程度の雨";break;
    case 502:weatherText="強い雨";break;
    case 503:weatherText="非常に豪雨";break;
    case 504:weatherText="極端な雨";break;
    case 511:weatherText="凍る雨";break;
    case 520:weatherText="光度シャワー雨";break;
    case 521:weatherText="シャワーの雨";break;
    case 522:weatherText="激しいシャワーの雨";break;
    case 531:weatherText="荒れたシャワーレイン";break;
    case 600:weatherText="小雪";break;
    case 601:weatherText="雪";break;
    case 602:weatherText="大雪";break;
    case 611:weatherText="ぬいぐるみ";break;
    case 612:weatherText="シャワー寝室";break;
    case 615:weatherText="明るい雨と雪";break;
    case 616:weatherText="雨と雪";break;
    case 620:weatherText="光シャワー雪";break;
    case 621:weatherText="シャワーを浴びる";break;
    case 622:weatherText="大雪シャワー";break;
    case 701:weatherText="ミスト";break;
    case 711:weatherText="煙";break;
    case 721:weatherText="ヘイズ";break;
    case 731:weatherText="砂、粉塵旋回";break;
    case 741:weatherText="霧";break;
    case 751:weatherText="砂";break;
    case 761:weatherText="ほこり";break;
    case 762:weatherText="火山灰";break;
    case 771:weatherText="スコール";break;
    case 781:weatherText="竜巻";break;
    case 800:weatherText="晴天";break;
    case 801:weatherText="雲が少ない";break;
    case 802:weatherText="散った雲";break;
    case 803:weatherText="壊れた雲";break;
    case 804:weatherText="曇った雲";break;
    case 900:weatherText="竜巻";break;
    case 901:weatherText="熱帯低気圧";break;
    case 902:weatherText="ハリケーン";break;
    case 903:weatherText="コールド";break;
    case 904:weatherText="ホット";break;
    case 905:weatherText="風が強い";break;
    case 906:weatherText="雹";break;
    case 951:weatherText="落ち着いた";break;
    case 952:weatherText="そよ風";break;
    case 953:weatherText="そよ風";break;
    case 954:weatherText="中風";break;
    case 955:weatherText="新鮮な風";break;
    case 956:weatherText="強い風";break;
    case 957:weatherText="高風、近くの暴風";break;
    case 958:weatherText="ガール";break;
    case 959:weatherText="深刻な暴風";break;
    case 960:weatherText="嵐";break;
    case 961:weatherText="暴風雨";break;
    case 962:weatherText="ハリケーン";break;
    default:weatherText="その他";break;
  }
  return weatherText;
}

function getDegText(windDeg){
  var DegText = "";
  if(windDeg <=11.25){
    DegText="北";
  }else if(windDeg <=33.75){
    DegText="北北東";
  }else if(windDeg <=56.25){
    DegText="北東";
  }else if(windDeg <=78.75){
    DegText="東北東";
  }else if(windDeg <=101.25){
    DegText="東";
  }else if(windDeg <=123.75){
    DegText="東南東";
  }else if(windDeg <=146.25){
    DegText="南東";
  }else if(windDeg <=168.75){
    DegText="南南東";
  }else if(windDeg <=191.25){
    DegText="南";
  }else if(windDeg <=213.75){
    DegText="南南西";
  }else if(windDeg <=236.25){
    DegText="南西";
  }else if(windDeg <=258.75){
    DegText="西南西";
  }else if(windDeg <=281.25){
    DegText="西";
  }else if(windDeg <=303.75){
    DegText="西北西";
  }else if(windDeg <=326.25){
    DegText="北西";
  }else if(windDeg <=348.75){
    DegText="北北西";
  }else{
    DegText="北";
  }
  return DegText;
}

これで、以下のようなメールが届くようになります。

1日1回か、3時間おきに自分に送るようにすればまあ良いでしょう。

180113_mail

受け取って思った課題が3つあります。

1.長い。5日分もいらない

→繰り返し部分を8回にすればOKそう。

2.東京の時間になっていないっぽい

→dt_txtを時間として認識させて、9時間遡らせる計算が必要。

3.時間の「:00:00」がいらない

→replaceなどで試行したものの上手く削れず、断念。

これに加えて、できれば「rain{3h=〇〇}」を活かしたかったのですが、これも上手く値を格納できず断念しています。

しかし、ここまでくれば後はこまごました加工なので、こちらのコードについては今回はここまで。

気象庁データについてもちゃんと完結させないといけませんしね。

コメント