JavaRush /Java Blogu /Random-AZ /Bir neçə axşam Telegram üçün sadə hava botu yaradırıq
Philip J.
Səviyyə
Днепр

Bir neçə axşam Telegram üçün sadə hava botu yaradırıq

Qrupda dərc edilmişdir
Hamıya salam! Teleqramlar üçün botların yaradılması mövzusu bir qədər sındırılıb və bir çox bələdçi yazılıb (məsələn, bu ) . Buna görə də, bəzi üçüncü tərəf API ilə işləməyə daha yaxından nəzər salmaq daha yaxşıdır, çünki bu, hər hansı bir veb tərtibatçı üçün kritik bir bacarıqdır. Dərhal deyim ki, proqram ən funksional və faydalı proqnozu təmin etmək məqsədi daşımamışdır; hava saytları ilə rəqabət aparmağın mənası yoxdur; Java istifadə edərək uzaq bağlantılarla və məlumat təhlili ilə necə işləməyi öyrənmək vacib idi. Beləliklə, əvvəlcə bizə nə lazım olduğunu öyrənək. Tətbiqimiz əsasən üç məntiqi hissədən ibarətdir:
  • istifadəçidən mesaj qəbul edin
  • mesajı emal edin və əgər bu düzgün əmrdirsə, cavab üçün məlumat hazırlayın. Bizim vəziyyətimizdə, istifadəçi düzgün şəhərə giribsə, hava proqnozu hazırlayın
  • chatda istifadəçiyə hazır məlumat göndərin
Birinci və üçüncü məqamlar olduqca sadədir və yalnız Telegram API ilə işləməyə aiddir; maraqlananlar yuxarıda qalan linki öyrənə bilərlər. İkinci məqama diqqət yetirəcəyik. API-lər bəzi tərtibatçılar öz məlumatlarına digər tərtibatçılara girişi təmin etmək istədikdə istifadə olunur. Məsələn, VKontakte-i götürək. Hər kəsin dostlarının siyahısı var, o, VK serverlərində verilənlər bazasında bir yerdə saxlanılır. Tutaq ki, hansısa proqramçı dostları ilə dama oyunu yaratmağa qərar verdi. Onun tətbiqinin düzgün işləməsi üçün proqram istənilən oyunçunun dostlarının siyahısını əldə edə bilməlidir. Bunu etmək üçün proqramçı VK API üçün sənədləri tapır və bu siyahını əldə etmək üçün hansı sorğunun edilməsi lazım olduğuna baxır. Bu sorğu HTTP sorğusu adlanır. Və ən çox yayılmış iki HTTP sorğusu GET və POST-dur. İnternetdə onlar haqqında kifayət qədər məlumat var, sizə mane olmayacağam. Məqsədlərimiz üçün, yəni hava proqnozu məlumatlarını əldə etmək üçün sadə bir GET sorğusu kifayət edəcəkdir. Əgər biz adi veb serverə GET sorğusu etsək, o, tez-tez html kodunu qaytarır, brauzer onu istifadəçi dostu səhifəyə çevirir, üslubları, skriptləri və s. tətbiq edir. API serverinə belə bir sorğu göndərsək, cavab adətən yalnız xam data üslublar və skriptlər olmadan qaytarılır. Brauzer pəncərəsində bu belə görünür: Bir neçə axşam Telegram üçün sadə hava botu yaradırıq - 1Bu məlumatlar insanlar üçün deyil, digər proqramlar üçün nəzərdə tutulub, ona görə də belə səhifələrdə məlumatın özündən başqa əlavə heç nə yoxdur. Xam məlumatlar ən çox iki standartdan biri ilə göndərilir: JSON və ya XML. Hər birinin müsbət və mənfi tərəfləri var, lakin hər ikisini başa düşmək vacibdir. Yuxarıdakı skrinşotda siz artıq JSON-u görmüsünüz və XML belə görünür: Bir neçə axşam Telegram üçün sadə hava botu yaradırıq - 2Qısa axtarışdan sonra dəqiqədə 50-dən çox sorğu verməsəniz, məlumatları pulsuz təqdim edən İngilis dilində Açıq Hava Xəritəsi layihəsi tapıldı. Bu, bizim üçün kifayətdir, qeydiyyatdan keçirik, unikal bir işarə (kod) alırıq ki, server bizim saxtakar deyil, layiqli gələcək tərtibatçı olduğumuzu bilsin. API sənədləri ilə səhifəyə gedirik ( tyts ) və hər hansı bir şəhər üçün 5 günlük proqnozu forma sorğusu göndərməklə əldə etmək olar.
https://api.openweathermap.org/data/2.5/forecast?q=(город)&APPID=(уникальный токен, полученный при регистрации)
Belə bir sorğuya cavabın brauzerdə necə göründüyünü görə bilərsiniz.Biz artıq müəyyən etdik ki, əslində, sadəcə olaraq düzgün linki izləmək lazımdır və server lazımi məlumatları təqdim edəcəkdir. Yalnız Java istifadə edərək bunu necə edəcəyinizi öyrənməkdir. Java-da sadə GET sorğusu belə görünür:
//создаём строку со ссылкой на нужную 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();
Əgər sorğu düzgün olsaydı və server mövcud olsaydı, biz faydalı məlumatın indi lazım olmayan məlumatlarla qarışdığı məlumat vərəqini alacağıq. JSON və XML-dən lazımi məlumatları rahat şəkildə çıxarmaq üçün Java üçün hər zövqə uyğun tonlarla kitabxanalar yazılmışdır. JSON-a üstünlük verdiyim üçün onu emal etmək üçün Jackson adlı çox məşhur bir kitabxana seçdim. Yeri gəlmişkən, JavaRush-da bəzi yüksək səviyyədə bir az öyrənilir. Böyük həcmdə JSON məlumatlarını emal etmək üçün sənədin strukturunu başa düşmək vacibdir. Bu kimi faydalı saytlar köməyə gəlir . Solda orijinal JSON, sağda - strukturlaşdırılmışdır: Bir neçə axşam Telegram üçün sadə hava botu yaradırıq - 3 Görünür ki, cavab 5 yüksək səviyyəli JSON obyektindən ibarətdir, onlardan 2-si mürəkkəbdir və aşağıdakı filiallar üçün qovşaqdır. Bizi maraqlandıran məlumatlar siyahı qovşağında saxlanılır . Daxili siyahı hər biri müəyyən vaxtda havanı təsvir edən 38 JSON xəttindən ibarətdir. Yəni bir növ ağaca bənzər quruluşdur, burada kök, budaqlar, budaqlar və hətta yarpaqlar var :) Və düyünlərdə budaqlanma baş verir. Xoşbəxtlikdən, Cekson istənilən etibarlı JSON-u ağac kimi təmsil edə bilər. Beləliklə, bizə lazım olan atributun adını (məsələn, havanın temperaturu) və ağacın hansı səviyyəsində yerləşdiyini bilmək, onu əldə etmək çox problem olmayacaq. Əvvəlcə "list" massivindən bütün sətirləri çıxardım və onları ayrıca siyahıya əlavə etdim. Kobud desək, məlumatların olduğu vərəqi parçalara ayırdım, hər biri ayrıca proqnozdur. Kiçik hissələri yadda saxlamaq və onlarla işləmək daha asandır.
//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());
            }
      }
}
Beləliklə, hər bir sətir müəyyən bir zamanda JSON hava hesabatını əks etdirən sətirlərin siyahısını əldə etdik. Qalan şey istədiyinizi çıxarmaq və formatlaşdırmaqdır. Əgər belə bir xəttimiz varsa:
"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}
onda bu "əsas" adlı bir qovşaqdır. Ondan istənilən məlumatı, məsələn, dəniz səviyyəsini əldə etmək üçün aşağıdakı kod kifayətdir:
ObjectMapper objectMapper = new ObjectMapper();
//line - это наша JSON-строка
mainNode = objectMapper.readTree(line).get("main");
String seaLevel = mainNode.get("sea_level");
Jackson məlumatları dərhal rəqəmsal formatda təqdim etməyə imkan verir:
double seaLevel = mainNode.get("sea_level").asDouble();
İndi biz proqnozdan istənilən məlumatı çıxara bilərik və qalan yalnız onu istədiyiniz kimi yapışdırıb Telegram-da istifadəçiyə göndərməkdir. Tam mənbə kodu mənim githubumdadır , lakin siz linkdən istifadə edərək və ya Telegram axtarışında @denifoBot taparaq botu işlədə sınaya bilərsiniz . Şəhərin adı latın transliterasiyası ilə yazılmalıdır, məsələn, "Kiyev" və ya "Moskva". Təşəkkür edirəm, əgər bunu sona çatdırsanız, məntiqli tənqidi qəbul edirəm, çünki mən şəhərimdən ac istedadlarla rəqabət aparmaq üçün GitHub-da sadə layihələr öyrənirəm və inkişaf etdirirəm :) Hamıya əlvida! P.S. İnanıram ki, burada hərf səhvləri ola bilər, ona görə də hər şeyi şəxsi mesajda və ya həqiqətən qəzəblisinizsə şərhdə göndərə bilərsiniz :)
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION