JavaRush /وبلاگ جاوا /Random-FA /چند شب دیگر یک ربات ساده هواشناسی برای تلگرام ایجاد می کن...
Philip J.
مرحله
Днепр

چند شب دیگر یک ربات ساده هواشناسی برای تلگرام ایجاد می کنیم

در گروه منتشر شد
سلام به همه! موضوع ایجاد ربات برای تلگرام تا حدودی هک شده است و راهنماهای زیادی نوشته شده است (مثلا این یکی ). بنابراین، بهتر است نگاهی دقیق‌تر به کار با برخی از API های شخص ثالث داشته باشیم، زیرا این یک مهارت حیاتی برای هر توسعه دهنده وب است. فوراً می گویم که برنامه برای ارائه کاربردی ترین و مفیدترین پیش بینی تنظیم نشده است؛ رقابت با سایت های آب و هوا فایده ای ندارد؛ یادگیری نحوه کار با اتصالات از راه دور و تجزیه داده ها با استفاده از جاوا مهم بود. بنابراین، بیایید ابتدا دریابیم که به چه چیزی نیاز داریم. برنامه ما اساسا از سه بخش منطقی تشکیل شده است:
  • پذیرفتن پیام کاربر
  • پیام را پردازش کنید، و اگر یک دستور معتبر است، داده ها را برای پاسخ آماده کنید. در مورد ما، در صورتی که کاربر شهر صحیح را وارد کرده باشد، پیش بینی آب و هوا تهیه کنید
  • ارسال اطلاعات آماده به کاربر در چت
نکته اول و سوم کاملا ساده است و فقط مربوط به کار با API تلگرام است؛ علاقه مندان می توانند لینک بالا را مطالعه کنند. ما روی نکته دوم تمرکز خواهیم کرد. API ها زمانی استفاده می شوند که برخی از توسعه دهندگان بخواهند دسترسی به داده های خود را برای توسعه دهندگان دیگر فراهم کنند. برای مثال VKontakte را در نظر بگیرید. هر کس لیستی از دوستان دارد، در جایی در یک پایگاه داده در سرورهای VK ذخیره می شود. بیایید بگوییم که یک برنامه نویس تصمیم گرفت یک بازی چکرز با دوستان خود ایجاد کند. برای اینکه برنامه او به درستی کار کند، برنامه باید بتواند لیست دوستان هر بازیکن را به دست آورد. برای انجام این کار، برنامه نویس مستندات VK API را پیدا می کند و به دنبال این است که چه درخواستی برای دریافت این لیست باید ارائه شود. این درخواست درخواست HTTP نامیده می شود. و دو درخواست رایج HTTP عبارتند از GET و POST. همچنین به اندازه کافی در مورد آنها در اینترنت وجود دارد، من شما را متوقف نمی کنم. برای اهداف ما، یعنی به دست آوردن داده های پیش بینی آب و هوا، یک درخواست ساده GET کافی خواهد بود. اگر ما یک درخواست GET را به یک وب سرور معمولی ارسال کنیم، اغلب کد html را برمی گرداند، که مرورگر آن را به یک صفحه کاربرپسند تبدیل می کند، سبک ها، اسکریپت ها و غیره را اعمال می کند. اگر چنین درخواستی را به سرور API ارائه دهیم، پاسخ معمولاً فقط داده های خام بدون استایل و اسکریپت برگردانده می شوند. در پنجره مرورگر چیزی شبیه این به نظر می رسد: ما یک ربات ساده هواشناسی را در چند شب برای تلگرام ایجاد می کنیم - 1این داده ها برای افراد در نظر گرفته نشده است، بلکه برای برنامه های دیگر در نظر گرفته شده است، بنابراین هیچ چیز اضافی در چنین صفحاتی به جز خود اطلاعات وجود ندارد. داده های خام اغلب با استفاده از یکی از دو استاندارد ارسال می شوند: JSON یا XML. هر کدام مزایا و معایب خود را دارند، با این حال، درک هر دو مهم است. شما قبلا JSON را در اسکرین شات بالا دیده اید و XML به این صورت است: ما یک ربات ساده هواشناسی برای تلگرام در چند شب ایجاد می کنیم - 2پس از یک جستجوی کوتاه، پروژه Open Weather Map به زبان انگلیسی پیدا شد که اگر بیش از 50 درخواست در دقیقه انجام ندهید، داده ها را به صورت رایگان ارائه می دهد. این برای ما کاملاً کافی است، ما ثبت نام می کنیم، یک رمز (کد) منحصر به فرد دریافت می کنیم که با آن سرور متوجه می شود که ما فریبکار نیستیم، بلکه توسعه دهندگان شایسته آینده هستیم. ما به صفحه دارای اسناد API ( tyts ) می رویم و متوجه می شویم که با ارسال درخواست فرم می توان پیش بینی 5 روزه برای هر شهر را بدست آورد.
https://api.openweathermap.org/data/2.5/forecast?q=(город)&APPID=(уникальный токен, полученный при регистрации)
شما می توانید ببینید که چگونه پاسخ به چنین درخواستی در مرورگر به نظر می رسد. ما قبلاً متوجه شده ایم که در واقع فقط باید پیوند صحیح را دنبال کنید و سرور داده های لازم را ارائه می دهد. تنها چیزی که باقی می ماند این است که یاد بگیرید چگونه این کار را با استفاده از جاوا انجام دهید. یک درخواست 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، هزاران کتابخانه برای جاوا نوشته شده است تا با هر سلیقه ای مطابقت داشته باشد. از آنجایی که من JSON را ترجیح می دادم، یک کتابخانه بسیار محبوب به نام جکسون را برای پردازش آن انتخاب کردم. ضمناً در JavaRush در برخی سطوح بالا کمی مطالعه شده است. برای پردازش مقادیر زیادی از داده های JSON، درک ساختار سند مهم است. سایت های مفیدی مانند این به کمک می آیند . در سمت چپ ما JSON اصلی را داریم، در سمت راست - ساختار یافته: ما یک ربات ساده هواشناسی برای تلگرام در چند شب ایجاد می کنیم - 3 می توان دید که پاسخ از 5 شیء سطح بالای JSON تشکیل شده است که 2 تای آنها پیچیده هستند و گره هایی برای شاخه های زیر هستند. داده های مورد علاقه ما در گره لیست ذخیره می شود . فهرست داخلی آرایه ای از 38 خط JSON است که هر کدام آب و هوا را در زمان خاصی توصیف می کنند. یعنی نوعی ساختار درخت مانند است که در آن ریشه، شاخه، شاخه و حتی برگ وجود دارد :) و در گره ها انشعاب صورت می گیرد. خوشبختانه، جکسون می تواند هر 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}
سپس این یک گره به نام "اصلی" است. برای دریافت هر گونه داده از آن، به عنوان مثال سطح دریا، کد زیر کافی است:
ObjectMapper objectMapper = new ObjectMapper();
//line - это наша JSON-строка
mainNode = objectMapper.readTree(line).get("main");
String seaLevel = mainNode.get("sea_level");
جکسون به شما این امکان را می دهد که بلافاصله داده ها را در قالب عددی نشان دهید:
double seaLevel = mainNode.get("sea_level").asDouble();
اکنون می‌توانیم هر داده‌ای را از پیش‌بینی استخراج کنیم و تنها چیزی که باقی می‌ماند این است که آن را به دلخواه به هم بچسبانیم و برای کاربر در تلگرام ارسال کنیم. سورس کد کامل در github من است، اما می‌توانید با استفاده از لینک یا با پیدا کردن @denifoBot در جستجوی تلگرام، ربات را در عمل امتحان کنید . نام شهر باید با حروف لاتین نوشته شود، به عنوان مثال "کیف" یا "مسکو". ممنون، اگر تا انتها پیش رفتید، انتقاد منطقی را می پذیرم، زیرا من به تازگی در حال یادگیری و توسعه پروژه های ساده در GitHub برای رقابت با استعدادهای گرسنه شهرم هستم :) خداحافظ همه! PS من فکر می کنم که ممکن است در اینجا اشتباهات املایی وجود داشته باشد، بنابراین شما می توانید همه چیز را در یک پیام خصوصی یا در یک نظر اگر واقعا عصبانی هستید ارسال کنید :)
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION