JavaRush /Java Blog /Random-JA /数晩のうちに Telegram 用のシンプルな天気予報ボットを作成します
Philip J.
レベル 40
Днепр

数晩のうちに Telegram 用のシンプルな天気予報ボットを作成します

Random-JA グループに公開済み
こんにちは、みんな!Telegram 用のボットの作成というトピックはややありきたりで、多くのガイドが書かれています (たとえば、 これ)。したがって、サードパーティ API の使用については、Web 開発者にとって重要なスキルであるため、詳しく検討する必要があります。すぐに言えるのは、このアプリケーションは最も機能的で役立つ天気予報を提供することを目的として作られたものではない、気象サイトと競合しても意味がない、Java を使用したリモート接続とデータ解析の操作方法を学ぶことが重要だった、ということです。それでは、まず何が必要かを調べてみましょう。私たちのアプリケーションは基本的に 3 つの論理部分で構成されています。
  • ユーザーからのメッセージを受け入れる
  • メッセージを処理し、それが有効なコマンドである場合は、応答用のデータを準備します。この例では、ユーザーが正しい都市を入力した場合に天気予報を準備します。
  • 準備ができた情報をチャットでユーザーに送信する
1 つ目と 3 つ目のポイントは非常に単純で、Telegram API の操作に関するものだけです。興味のある方は、上に残ったリンクを参照してください。2 番目の点に焦点を当てます。API は、一部の開発者が自分のデータへのアクセスを他の開発者に提供したい場合に使用されます。VKontakteを例に考えてみましょう。誰もが友人のリストを持っており、VK サーバー上のデータベースのどこかに保存されています。あるプログラマーが友人とチェッカー ゲームを作成することに決めたとしましょう。彼のアプリケーションが正しく動作するには、プログラムが任意のプレイヤーの友達のリストを取得できなければなりません。これを行うために、プログラマは VK API のドキュメントを見つけて、このリストを取得するためにどのようなリクエストを行う必要があるかを調べます。このリクエストをHTTPリクエストと呼びます。そして、最も一般的な 2 つの HTTP リクエストは GET と POST です。彼らについてはインターネット上にも十分な情報があるので、私はあなたを止めません。天気予報データを取得するという目的には、単純な GET リクエストで十分です。通常の Web サーバーに GET リクエストを行うと、HTML コードが返されることが多く、ブラウザはスタイルやスクリプトなどを適用してユーザーフレンドリーなページに変換します。このようなリクエストを API サーバーに行うと、応答が返されます。通常、スタイルやスクリプトなしで生データのみが返されます。ブラウザ ウィンドウでは次のように表示されます。 数晩かけて Telegram 用のシンプルな天気予報ボットを作成します - 1このデータは人向けではなく、他のプログラム向けであるため、そのようなページには情報自体以外に余分なものは何もありません。生データは、ほとんどの場合、JSON または XML の 2 つの標準のいずれかを使用して送信されます。それぞれに長所と短所がありますが、両方を理解することが重要です。上のスクリーンショットですでに JSON を確認しましたが、XML は次のようになります。 数晩かけて Telegram 用のシンプルな天気予報ボットを作成します - 2短い検索の後、英語の Open Weather Map プロジェクトが見つかりました。このプロジェクトは、1 分あたり 50 件を超えるリクエストを行わない場合、無料でデータを提供します。私たちにとってはこれで十分です。登録すると、サーバーが私たちが詐欺師ではなく、将来のまともな開発者であることを知るための固有のトークン (コード) を受け取ります。API ドキュメント ( tyts )が含まれるページに移動し、フォームのリクエストを送信することで任意の都市の 5 日間の天気予報を取得できることがわかります。
https://api.openweathermap.org/data/2.5/forecast?q=(город)&APPID=(уникальный токен, полученный при регистрации)
このようなリクエストに対する応答がブラウザーでどのように表示されるかを確認できます 、実際には、正しいリンクをたどるだけで、サーバーが必要なデータを提供してくれることがすでにわかっています。残っているのは、Java を使用してこれを行う方法を学ぶことだけです。Java での単純な GET リクエストは次のようになります。
//создаём строку со ссылкой на нужную page,
//я тут её склеиваю из заранее определённых констант, меняя только сам город
String urlString = API_CALL_TEMPLATE + city + API_KEY_TEMPLATE;
//создаём an object который будет содержать ссылку
URL urlObject = new URL(urlString);
//создаём соединение, используя an object
HttpURLConnection connection = (HttpURLConnection) urlObject.openConnection();
//выбираем тип requestа (GET)
connection.setRequestMethod("GET");
//тут мы указываем, данные о себе, что мы можем принять всё то,
//что примет и любой современный браузер
connection.setRequestProperty("User-Agent", "Mozilla/5.0");
//В начало ответа server всегда вставляет число, по которому можно судить, прошло ли всё хорошо.
//200 - значит OK
int responseCode = connection.getResponseCode();
//на несуществующий город or город с опечаткой, server выдаст code ответа 404,
//бросаем на него исключение, чтобы обработать на уровне повыше и предложить
//пользователю ввести город заново
if (responseCode == 404) {
     throw new IllegalArgumentException();
}
// создаём поток, вычитываем все строки, и склеиваем в одну большую строку,
//которую будем потом обрабатывать в других методах
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
     response.append(inputLine);
}
in.close();
return response.toString();
リクエストが正しくサーバーが利用可能であれば、有益な情報と今は必要のない情報が混在したシート状のデータを受け取ります。JSON や XML から必要なデータを簡単に抽出するために、あらゆる好みに合わせて Java 用のライブラリが数多く作成されています。私は JSON を好んだため、それを処理するために Jackson という非常に人気のあるライブラリを選択しました。ちなみに、JavaRush ではいくつかの高いレベルで少し研究されています。大量の JSON データを処理するには、ドキュメントの構造を理解することが重要です。このような役立つサイトが役に立ちます。左側に元の JSON、右側に構造化された JSON があり 数晩かけて Telegram 用のシンプルな天気予報ボットを作成します - 3 ます。応答は 5 つのトップレベル JSON オブジェクトで構成されており、そのうちの 2 つは複雑で、次のブランチのノードであることがわかります。関心のあるデータはリストノードに保存されます。リスト内には38 行の JSON 行の配列があり、それぞれが特定の時刻の天気を記述しています。つまり、根、枝、小枝、さらには葉がある一種の木のような構造です:)そしてノードで分岐が起こります。幸いなことに、Jackson は有効な JSON をツリーとして表すことができます。したがって、必要な属性の名前 (気温など) と、それがツリーのどのレベルにあるかがわかれば、それを取得するのはそれほど問題になりません。まず、「list」配列からすべての行を抽出し、別のリストに追加しました。大まかに言うと、データが含まれたシートを細かく切り取り、それぞれが個別の予測になります。小さなパーツは覚えやすく、操作しやすいです。
//JsonNode - это один из узлов в древовидной иерархии, от которого идут ветви
//получаем узел, который называется "list"
JsonNode arrNode = new ObjectMapper().readTree(data).get("list");
//если это действительно массив узлов
if (arrNode.isArray()) {
//выполняем для каждого узла, который содержится в массиве
      for (final JsonNode objNode : arrNode) {
//в атрибуте "dt_txt" каждого маленького узла хранилось время прогноза, я отобрал данные за 9 утра и 6 вечера
                String forecastTime = objNode.get("dt_txt").toString();
                if (forecastTime.contains("09:00") || forecastTime.contains("18:00")) {
                weatherList.add(objNode.toString());
            }
      }
}
そこで、各行が特定の時刻の JSON 天気予報を表す文字列のリストを取得しました。残っているのは、必要なものを抽出してフォーマットすることだけです。次のような行があるとします。
"main":{"temp":261.45,"temp_min":259.086,"temp_max":261.45,"pressure":1023.48,"sea_level":1045.39,"grnd_level":1023.48,"humidity":79,"temp_kf":2.37}
これは「main」と呼ばれるノードです。そこから海面などのデータを取得するには、次のコードで十分です。
ObjectMapper objectMapper = new ObjectMapper();
//line - это наша JSON-строка
mainNode = objectMapper.readTree(line).get("main");
String seaLevel = mainNode.get("sea_level");
Jackson を使用すると、データをすぐに数値形式で表すことができます。
double seaLevel = mainNode.get("sea_level").asDouble();
これで、予測から任意のデータを抽出できるようになりました。あとは、必要に応じてデータを結合し、Telegram でユーザーに送信するだけです。完全なソース コードは私のgithubにありますが、リンクを使用するか、Telegram 検索で @denifoBot を見つけてボットを実際に試してみることができます。都市の名前は、「Kyiv」や「Moscow」のようにラテン語の音訳で書く必要があります。最後まで読んでいただいてありがとうございます。私は、地元の飢えた才能と競争するために GitHub で単純なプロジェクトを学習して開発しているだけなので、当然の批判は受け入れます :) 皆さん、さようなら! PS ここにはタイプミスがあるかもしれないので、すべてをプライベートメッセージで送信することも、本当に怒っている場合はコメントで送信することもできます:)
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION