今回は、天気予報のデータをWebから取得して、解析するプログラムを試作してみます。今回は、Webサイトから天気予報の情報を取得して、解析してみます。天気予報データの取得と、LED点滅パターンを決定するための解析方法の検討をしてみます。今回の説明内容は以下になります。Hacks」のサイトは2019年5月時点ではブラウザでアクセスすると警告が表示されます。hacks」で検索するとトップにリンクが表示されます。天気予報のデータを提供しているサイトは海外も含めて数多くあるようです。Hacks」というサイトを利用してみたいと思います。天気予報データを取得することができます。一つは、データの利用は個人的な範囲のみで商用利用は不可となっています。一つは、このサイトから取得したデータを表示するウェブページには、Livedoor天気情報へのリンクと著作権表示が推奨されています。どちらも特に問題ありませんので、このサイトを利用させていただく、ということにします。それでは早速データ取得してみます。最初に天気予報データを取得したい地域コードを以下のページで調べます。お天気Webサービス仕様」で検索するとリンクがトップに表示されます。私の住んでいる神奈川県東部は横浜が定義されていて、以下のように定義されています。source="http://weather.livedoor.com/forecast/rss/area/140010.xml"/>このidが地域コードになります。次にこのコードを以下の文字列の最後につけてWebページのリクエストをすると、天気予報の情報が返ってきます。https://weather.livedoor.com/forecast/webservice/json/v1?city=横浜であれば、https://weather.livedoor.com/forecast/webservice/json/v1?city=140010という文字列になります。具体的に取得してみます。ブラウザでこのURLにアクセスすると、、、こんな感じで表示されます。内容の確認が難しいですが、これは文字コードがエスケープされたUTF-8のコードのためです(UTF-8をACSII文字のみで構成したもの)。プログラムでは問題なく扱えます。このデータ形式はjsonになっています。Notationの略なんですが、細かい説明は省略して使い方を確認しておきます。jsonのデータは非常に簡単な構成で、前回出てきましたPHPの連想配列、Pythonの辞書に似ています。jsonはキーと値から構成されていて、フォーマットは以下のようになっています。398}という感じです。これだけわかれば、先ほどの取得したデータは読めると思います。エスケープされたUTF-8文字は人間が読むにはなかなかむずかしいものがありますので、以下のページの下の方に取得データのサンプルがあるので確認してみてください。お天気Webサービス仕様この取得したデータをプログラムで扱うのも簡単です。PHPやPythonではjsonデータを連想配列や辞書に入れてくれる関数がありますので、前回出てきました連想配列や辞書と同じアクセス方法になります。それでは、サンプルプログラムで確認してみます。取得したデータから地域名と今日の天気予報を表示するプログラムを作ってみます。“title”キーに、今日の天気予報は、”forecasts”キーの最初の配列要素の”telop”キーに入っています。あとは特に新しい知識なしでわかると思います。以下がPHPのプログラムです。”get_weather.php”というファイル名で作成しました。天気情報取得URLはhttpsの場合証明書エラーになりますので、httpで取得しています。$weather["forecasts"][0]["telop"];?>指定したURLのレスポンスをもらうには、file_get_contents()関数を使用します。この関数で先ほどブラウザで確認したデータが$responseに格納されますので、そのデータをjson_decode()関数で連想配列に変換します。get_weather.php、覚えてますか?)、実行してみます。晴時々曇このように表示されればOKです。Pythonのプログラムは以下になります。response.close()指定URLのデータ取得にurllib2というモジュール、jsonデータ解析にjsonというモジュールを使用しています。‘....%s”)、その後に%に続いてそこに流し込む変数を書きます。他は特に難しいところはないと思いますが、不明点がありましたら問い合わせフォームかコメント欄でご質問ください。これで天気予報データの取得が確認できました。先ほどのサンプルプログラムで取得した天気予報は「晴時々曇」でした。天気予報からLEDの点滅パターンにどうやって変換していけばよいのか、これから考えてみます。やって解析すればよいか、いろいろ方法はあると思いますが、逆算で考えていきたいと思います。blink)を組み合わせて各LEDの点滅パターンを生成、それを元に点滅制御を行いました。天気予報データに基づいてLEDの点滅制御を行うために、各LEDがどのような組み合わせの基本パターンか決定できれば、前回のやり方でLEDを点滅制御できます。いうことで具体例を元に考えてみます。いうことは、最終的には、各LEDの基本点滅パターンの入った連想配列(PHP)あるいは辞書(Python)に変換しておけば、あとはなんとかなると思います。イメージとしてはこんな感じです。例としては「晴時々曇り」で、PHPの連想配列のケースです。"off"],};次に「晴時々曇り」という文字列から、どうやってこのパターンに変換するか考えてみます。晴れについて考えてみます。決定できればいいわけです。する、というのはダメです。いうのは、単なる「晴れ」という予報の時は晴れのLEDはつけたままになります。“off”となります。いうことは、予報に「晴」の文字があっても、これだけではLEDの点滅パターンは決定できません。“off”に決定という方法はどうでしょうか。なると「曇時々晴」とかいう場合はどうすればいいのか。いうことで、どんな予報文字列があるのか確認してみます。行きたいところですが、まとまった情報が見つかりませんでした。わかる範囲で調べたところ、以下の文字列があるようです。なんで予報ってこんなにあるんですかね。言っても状況は変わりませんので、引き続き解析の方針を検討します。“off”というルールでいけそうです。“off”でOKそうです。“off”でいけますよね。いうことで、ここまでの予報文字列の判定方法をまとめてみます。offあとは例外を解決していきます。このルールで漏れるパターンは幾つかタイプがあります。「晴のち一時雨」は上のルールでは「晴一時雨」と判定されます。今回は、「晴のち一時雨」のようなパターン表現は検討していませんでしたので、このような場合は、「晴一時雨」に集約してしまいたいと思います。「晴時々雨か雪」も同様で、これは上のルールでは「晴時々雨」に判定されます。これもこのように集約してしまいます。(「雨か雪」などの表現もする場合についてはチャレンジ課題にしたいと思います)このように集約されてしまってもOKな場合はよいでが、いずれの判定にも引っかからない予報文字列があります。「晴のち雷雨」は、「晴」については判定されますが、「のち雷雨」は上のいずれのパターンにも引っかかりません。上のパターンに引っかかりません。考えてみると、今回は雷は表現しませんし、「大雨」や「暴風雨」も表現しませんので、これらはいずれも「雨」になります。削除する処理を入れたいと思います。これでもうまく判別できない予報文字列があります。「雨か雪」と「雪か雨」です。パターンにしたほうが良いです。これを解決するために、完全一致パターンとして、「雨か雪」と「雪か雨」はそれぞれ「雨」と「雪」に変換しておきます。これでおそらく一通りの予報文字列が、今回表現するパターンに対応できると思います。細かく分けると、連想配列や辞書を使った対応表形式にしてしまったほうが早いと思いますのでこのぐらいにしておきたいと思います。このパターンの判定アルゴリズムと、全てのパターンの検証をするサンプルプログラムを作成してみます。最初に全ての予報文字列を用意して、それを判定させてみます。プログラムを作成それでは早速PHPでプログラムを作成してみます。解析方法は上に説明した通りですので、その流れに沿ってプログラムを作成してみました。プログラムの後に、必要と思われる箇所の説明をします。解析対象外の文字の削除、置換を行っています。str_replace()という関数を使用します。置換対象);という引数になります。$string);と書きます。置換対象文字列は配列でもOKです。strpos()関数を使用します。この関数は、検索文字が検索対象文字列の何文字目にあるか調べます。以下のようになります。aが0番目となりますので、cは2番目という意味です。日本語などのマルチバイトの場合は、マルチバイト単位でカウントした値ではないため注意が必要です。PHPの場合、0とfalseは別物なので特にif文などで注意が必要です。C言語では、if文などでは0とfalseは同じ意味で扱えますが、PHPの場合、if文での判定は一致確認の場合は「===」、不一致確認の場合は「!==」を使います。100行目でその判定をしていますので、参考にしてみてください。以下はPythonのプログラムです。プログラムのあとに、必要と思われる行に説明をしています。各LEDの点滅パターンはledPatという名前の辞書に格納することにします。文で、weatherリストに入っている天気予報文字列を一つずつ取り出して解析をします。今回のパターンで表現しない文字はここで削除します。置換文字列)と書くと、検索文字列を検索して、見つかったら置換文字列に置き換えます。検索対象文字列の全てに対して検索・置換を行います。先ほどはreplace()関数で文字を置換しましたが、今回は検索するだけです、find()関数は引数の文字あるいは文字列を検索して、何文字目に見つかったかを返します。最初も文字は0文字目、見つからなかったら-1を返します。補足プログラムを見ると、各天気の解析が同じコードになっていますよね。