Как написать на питоне приложение погоды
Перейти к содержимому

Как написать на питоне приложение погоды

  • автор:

Пишем программу погоды

Итак, давайте напишем консольную программу, которая будет показывать текущую погоду по нашим координатам. Чтоб не по IP-адресу как-то пытаться неточно вычислять местоположение, а именно по текущим реальным GPS-координатам. Чтобы программа показывала температуру за бортом, идёт ли там дождь/снег и время восхода-заката солнца. Для съёмки видео важно понимать, во сколько сегодня восход или закат солнца, чтобы ориентироваться на освещённость за окном.

Итак, в первую очередь, нам надо понять, как получить доступ к текущим координатам, есть ли такая возможность. Решение будет для MacBook, гуглим: python mac get gps coordinates . Первая ссылка говорит о программе whereami, которая печатает текущие координаты в консоль

whereami 

Отлично, теперь мы можем получать наши текущие координаты, отправить их в какой-то сервис погоды через API, получить оттуда погоду и отобразить её.

Команда работает по аналогии с whoami — та показывает, «кто я», а вот команда whereami показывает, «где я»:).

Давайте найдём какой-то сервис погоды. Поисковый запрос API прогноз погоды привёл меня на проект OpenWeather. У них есть бесплатный доступ. Еще есть Яндекс погода в России, Gismeteo, но там, насколько я понял, для получения API-ключа надо куда-то писать на почту, для наших целей это слишком долго. Воспользуемся OpenWeather.

Запрос на получение погоды по примерно моим координатам:

http https://api.openweathermap.org/data/2.5/weather\?lat\=55.7\&lon\=37.5\&appid\=7549b3ff11a7b2f3cd25b56d21c83c6a\&lang\=ru\&units\=metric 

httpie — это удобная утилита работы с веб-сервисами, такая вариация на тему curl , можно установить на Mac OS с помощью brew командой brew install httpie . Она выводит в раскрашенном виде JSON, например, что удобно.

API-ключ, использующийся в запросе, получается сразу после регистрации, но активируется в течение, может быть, минут десяти.

< "base": "stations", "clouds": < "all": 61 >, "cod": 200, "coord": < "lat": 55.7, "lon": 37.5 >, "dt": 1651521003, "id": 529334, "main": < "feels_like": 9.26, "grnd_level": 993, "humidity": 74, "pressure": 1013, "sea_level": 1013, "temp": 10.25, "temp_max": 12.01, "temp_min": 8.55 >, "name": "Moscow", "sys": < "country": "RU", "id": 47754, "sunrise": 1651455877, "sunset": 1651511306, "type": 2 >, "timezone": 10800, "visibility": 10000, "weather": [ < "description": "облачно с прояснениями", "icon": "04n", "id": 803, "main": "Clouds" > ], "wind": < "deg": 180, "gust": 8.08, "speed": 2.69 >> 

Так, отлично, мы умеем находить текущие координаты и умеем по ним получать температуру, состояние погоды — дождь/снег/облака, а также получать время восхода и заката солнца.

Давайте напишем программу для этого! Чтобы запускаешь её и она писала наше местоположение и выводила эти данные — температуру, характеристику погоды (снег/облака/туман) и время восхода заката солнца.

Пишем свой прогноз погоды на Python

У Практикума появился новый бесплатный мини-курс — «Прогноз погоды на Python за час». Мы посмотрели, как он работает, и решили повторить это у себя в статье — как обычно, с комментариями и разбором. При этом на курсе всё удобнее — там в тренажёре можно сразу увидеть результат и получить совет, как исправить ошибки, если они появятся.

Можете сейчас пролистать статью, а потом пойти потренироваться в Практикуме. У них написано, что это приключение на час, но описанная в этой статье часть займёт минут пятнадцать. Вводить данные карты не нужно. Выглядит так:

Пишем свой прогноз погоды на Python

Что делаем

Пишем скрипт, который покажет погоду в выбранном городе. Для этого мы:

  1. Подключаемся к службе погоды OpenWeather.
  2. Выбираем город.
  3. Получаем текущую температуру воздуха в этом городе и то, как она ощущается.
  4. Выводим результаты на экран.

На деле это проще, чем кажется, — за нас всю работу сделает API службы погоды, а мы только получим и обработаем результаты.

Для работы нам понадобится Python. Если будете делать проект без тренажёра Практикума, вам потребуется среда разработки. Прочитайте, как установить Python на компьютер и начать на нём писать.

Если будете делать в тренажёре Практикума, там среда уже настроена, можно просто делать без установки.

Подключаемся к службе погоды

Чтобы скрипт мог отправлять запросы к другим серверам, нам понадобится библиотека requests . Если вы делаете всё в тренажёре Практикума, эта библиотека уже установлена. А для установки её на свой компьютер нужно открыть терминал и выполнить такую команду:

pip install requests

После установки мы сразу можем подключить библиотеку к своему скрипту. Это уже пишем в коде, а не в терминале:

С этого момента наша программа будет знать, как отправлять запросы на сервер и получать в ответ новые данные. Теперь сделаем переменную с городом, погоду в котором нам интересно узнать:

Город в переменной может стоять любой — Москва, Брянск, Тула, Воронеж или что угодно ещё. Главное, чтобы о нём знала служба погоды OpenWeather.

Перед тем как отправить запрос, нам нужно его сформировать: подготовить специальную строку, которую сервер сможет обработать, чтобы вернуть нам данные о погоде. Она будет состоять из трёх частей:

  1. Адреса сервера, к которому мы отправляем запрос → https://api.openweathermap.org/data/2.5/weather
  2. Города, температуру в котором нам интересно узнать → он лежит в переменной city
  3. Служебных параметров: единиц измерения и ключа приложения → &units=metric&lang=ru&appid=79d1ca96933b0328e1c7e3e7a26cb347

Собираем всё вместе и кладём результат в переменную url:

url = 'https://api.openweathermap.org/data/2.5/weather?q='+city+'&units=metric&lang=ru&appid=79d1ca96933b0328e1c7e3e7a26cb347'

Теперь подробнее про службу погоды.

Служба погоды OpenWeather

OpenWeather — это погодный сервис, который собирает данные о погоде в городах со всего мира. У него есть сайт, на который можно зайти, вбить свой город и узнать погоду на сегодня (на английском):

Пишем свой прогноз погоды на Python

Но особенность этого сервиса в том, что он ещё умеет отвечать на внешние запросы — такие же, как мы сформировали в скрипте.

Если мы заменим переменную в адресе на конкретный город, а затем вставим эту строку в браузер и перейдём по этому адресу, то получим полную информацию о погоде и расположении этого города:

Пишем свой прогноз погоды на Python

А вот что нам вернул сервер:

В скрипте мы получим эти же данные, а потом обработаем их, чтобы сразу видеть, как там с погодой, не разбираясь во всех этих числах.

Это JSON. Обратите внимание на строку выше. Это называется JSON — JavaScript Object Notation. Это способ передать структурированные данные от одной программы к другой, используя при этом строку текста. В этой строке зашифрованы объекты, их свойства и значения.

Например, видно, что сначала мы задаём нечто под названием coord (координаты), внутри него лежат две сущности lon и lat — широта и долгота. В каждой из этих сущностей лежат числа. Получается, что мы зашифровали в строке какие-то координаты. Благодаря этой разметке можно вкладывать много сущностей друг в друга и передавать так данные между программами. Читайте подробнее об этом в нашей статье про JSON.

Отправляем запрос и выводим результат

Для отправки запроса в службу погоды используем команду requests.get().json() .

Команда Get() отвечает за сам запрос, а json() разбирает ответ в json-формате на составляющие, с которыми потом будет удобно работать:

После этой команды в переменной weather_data появятся все данные с сервера. Чтобы посмотреть их в удобном виде, используем такие команды:

weather_data_structure = json.dumps(weather_data, indent=2) print(weather_data_structure)

Пишем свой прогноз погоды на Python

Видно, что данные остались теми же, но стали выглядеть структурированно и понятно. Например, можно заметить, что данные о погоде лежат в разделе main в блоке temp . Используем это, чтобы вывести значение температуры в выбранном городе и то, как она ощущается. Сразу округлим значения функцией round() , чтобы воспринимать градусы было удобнее:

# получаем данные о температуре и о том, как она ощущается temperature = round(weather_data['main']['temp']) temperature_feels = round(weather_data['main']['feels_like']) # выводим значения на экран print('Сейчас в городе', city, str(temperature), '°C') print('Ощущается как', str(temperature_feels), '°C')

Пишем свой прогноз погоды на Python

Готовый код

# подключаем библиотеку для работы с запросами import requests # указываем город city = 'Сочи' # формируем запрос url = 'https://api.openweathermap.org/data/2.5/weather?q='+city+'&units=metric&lang=ru&appid=79d1ca96933b0328e1c7e3e7a26cb347' # отправляем запрос на сервер и сразу получаем результат weather_data = requests.get(url).json() # получаем данные о температуре и о том, как она ощущается temperature = round(weather_data['main']['temp']) temperature_feels = round(weather_data['main']['feels_like']) # выводим значения на экран print('Сейчас в городе', city, str(temperature), '°C') print('Ощущается как', str(temperature_feels), '°C')

Что дальше

Теперь, когда вы знаете, как выглядит структура данных с ответом от сервера и как получить к ним доступ, вы сможете вывести:

  • скорость ветра;
  • время рассвета и заката;
  • облачность;
  • координаты города;
  • и много других параметров.

Если хотите разобраться с тем, как работать с такими данными и что ещё можно с ними сделать, — пройдите бесплатный тренажёр «Прогноз погоды на Python за час». Там есть моменты, которые мы не разбирали в статье, — про работу функций и json-форматирование.

Попробуйте бесплатное в «Яндекс Практикуме»

В «Яндекс Практикуме» есть бесплатные курсы, на которых можно получить полезные навыки для работы в ИТ: от Git и Excel до основ Python и облачных технологий.

Попробуйте бесплатное в «Яндекс Практикуме» Попробуйте бесплатное в «Яндекс Практикуме» Попробуйте бесплатное в «Яндекс Практикуме» Попробуйте бесплатное в «Яндекс Практикуме»

Получите ИТ-профессию

В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.

Накидываем структуру приложения

Итак, первое, что надо сделать — подумать, из каких слоёв будет состоять наше приложение. Бросаться писать код сразу не надо. Давайте подумаем, что будет делать наша программа, вот просто перечислим, не думая пока о коде, функциях, классах, о том, как именно мы будем это реализовывать, а просто подумаем, что будет делать программа, из каких функциональных блоков она будет состоять.

Итак, наша программа погоды должна:

  • уметь получать текущие координаты устройства
  • запрашивать по этим координатам где-то погоду, в нашем случае на OpenWeather, но потенциально было бы здорово, если бы была возможность потом подцепить и какой-то другой сервис, если понадобится
  • результаты работы этого погодного сервиса надо распарсить, то есть разобрать, чтобы выдернуть оттуда нужные нам данные
  • и, наконец, наши данные надо отобразить в терминале.

Получается, 4 блока тут есть, причём второй и третий функции мы можем объединить в один верхнеуровневый слой получения погоды из внешнего сервиса. Итого мы имеем следующие слои работы приложения:

  1. Слой, запускающий приложение и связывающий остальные слои
  2. Получение текущих координат
  3. Получение по координатам погоды
  4. Печать погоды

Создаём директорию и накидываем туда слои нашего приложения. Сразу создаём структуру. У нас есть 4 слоя нашего приложения, создадим под них сразу Python-модули, чтобы логика каждого слоя лежала сразу в них.

  • weather — входная точка приложения, сделаем её исполнимым файлом без расширения .py , чтобы можно было запускать её без указания интерпретатора
  • coordinates.py — получение текущих GPS-координат ноутбука
  • weather_api_service.py — работа с внешним сервисом прогноза погоды
  • weather_formatter.py — форматирование погоды, то есть «сборка» строки с данными погоды (например, для последующей печати этой строки в терминале)

Создаём директорию для проекта, в моём случае weather-yt , переходим в неё и создаём в ней пустой файл weather , добавляем этому файлу права на выполнение с помощью chmod , и затем открываем этот файл в редакторе кода, в моём случае в nvim :

mkdir weather-yt && cd $_ true > weather chmod +x weather nvim weather 

Зададим заглушку в файле weather :

#!/usr/bin/env python3.10 print("Hello world") 

Первая строка называется шебанг, при помощи чего будет запускаться текущий файл. В нашем случае файл будет запускаться с помощью интерпретатора python3.10 . Убедитесь, что у вас есть такой интерпретатор в системе, что путь к нему добавлен в переменную окружения PATH , убедитесь, что python3.10 успешно запускается. Мы будем использовать здесь возможности актуальной на сегодня версии Python — 3.10. Проверим работу приложения:

./weather 

Отлично! Точка входа в приложение готова. Теперь сделаем, чтобы она запускалась откуда угодно из системы, прокинув симлинк (ярлык) на этот исполнимый файл в /usr/local/bin/ :

sudo ln -s $(pwd)/weather /usr/local/bin/ 

Отлично, теперь мы можем узнавать погоду (запускать weather ) из любой директории в системе.

Создаём остальные модули приложения:

true > coordinates.py true > weather_api_service.py true > weather_formatter.py ls -l 

Итак, у нас есть структура приложения, начинаем накидывать функционал.

Узнаем текущую погоду и прогноз простеньким скриптом на Python’е

На Хабре есть интересная статья о том, как энтузиасты делают погоду. Энтузиасты делают, а мы воспользуемся плодами их трудов — получим эту самую погоду от OpenWeatherMap.org скриптом на Python’е.

Для получения доступа к сервису погоды придется пройти несложную процедуру регистрации на сайте OpenWeatherMap.org. Сформируем и отправим запрос, разберем ответный пакет в формате JSON, и получим текущую температуру с описанием состояния погоды.

Зарегистрироваться на openweathermap.org совсем несложно, а остальное сделать будет ещё проще.

Регистрация нужна для получения идентифицирующей пользователя строки App Id, состоящей из набора букв и цифр (похоже — только из шестнадцатеричных цифр). Такого вида:
«6d8e495ca73d5bbc1d6bf8ebd52c4». После регистрации нужно зайти в личный кабинет и взять App Id, который там называется «API key».

Формирование строки запроса

Сначала попытаемся найти интересующий нас город в их базе. Строка запроса должна быть примерно такая:

http://api.openweathermap.org/data/2.5/find?q=Petersburg&type=like&APPID=6d8e495ca73d5bbc1d6bf8ebd52c4

В запросе нужно указать нужный город (вместо «Petersburg») и свой App Id (вместо «6d8e495ca73d5bbc1d6bf8ebd52c4». Можно уточнить запрос, указав идентификатор страны после названия города через запятую. Например, так:

http://api.openweathermap.org/data/2.5/find?q=Petersburg,RU&type=like&APPID=6d8e495ca73d5bbc1d6bf8ebd52c4

Собственно запросная строка будет сформирована самой библиотекой requests в функции get, которую используем для отправки запроса:

requests.get("http://api.openweathermap.org/data/2.5/find", params=) 

Проверка наличия в базе информации о нужном населенном пункте

План такой. В ответ на сформированный запрос получаем пакет в формате JSON. Разбираем пакет и получаем нужные значения по названиям полей.

import requests s_city = "Petersburg,RU" city_id = 0 appid = "буквенно-цифровой APPID" try: res = requests.get("http://api.openweathermap.org/data/2.5/find", params=) data = res.json() cities = ["<> (<>)".format(d['name'], d['sys']['country']) for d in data['list']] print("city:", cities) city_id = data['list'][0]['id'] print('city_id=', city_id) except Exception as e: print("Exception (find):", e) pass 

Запомним числовой идентификатор города city_id для последующего запроса, потому что поставщики сервиса рекомендовали делать запрос не по имени, а по идентификатору.
В ответе может оказаться несколько городов, соответствующих нашему запросу. Кстати, если в запросе указать “Moscow” и убрать страну из строки приведенного в примере запроса, то гарантированно получим несколько строк в списке cities:

city: [‘Moscow (RU)’, ‘Moscow (US)’, ‘Moscow (US)’]

Получение информации о текущей погоде

Осталось только получить искомую информацию о погоде. Если нас не интересуют имперские единицы измерения, то в запросе указываем, что желаем получить метрические единицы: «units=metric». Если описание погоды нужно получить на русском, то указываем «lang=ru».

try: res = requests.get("http://api.openweathermap.org/data/2.5/weather", params=) data = res.json() print("conditions:", data['weather'][0]['description']) print("temp:", data['main']['temp']) print("temp_min:", data['main']['temp_min']) print("temp_max:", data['main']['temp_max']) except Exception as e: print("Exception (weather):", e) pass 

Если верить сервису, сейчас (14.11.2016 в 23:20) в Москве:

conditions: небольшой снег
temp: -5.25
temp_min: -6
temp_max: -5

Прогноз на 5 дней

 try: res = requests.get("http://api.openweathermap.org/data/2.5/forecast", params=) data = res.json() for i in data['list']: print( i['dt_txt'], ''.format(i['main']['temp']), i['weather'][0]['description'] ) except Exception as e: print("Exception (forecast):", e) pass 

Получим такой вывод:
2016-11-24 15:00 -1 7 м/с ЮЗ пасмурно
2016-11-24 18:00 +2 7 м/с З легкий дождь
2016-11-24 21:00 +2 7 м/с З легкий дождь
2016-11-25 00:00 -0 7 м/с З ясно
2016-11-25 03:00 +0 7 м/с З небольшой снегопад
2016-11-25 06:00 -0 6 м/с СЗ слегка облачно
.

Скачать owm-request.py. Чтобы этот скрипт заработал, нужно в первой строке ввести Ваш «API key», полученный при регистрации на OpenWeatherMap.org.
Командная строка, например, такая:
$python owm-request.py Moscow,RU

На сайте OpenWeatherMap есть ещё масса интересного — получение информации по географическим координатам, архив погоды, информация с конкретных метеостанций. Описание всех доступных сервисов можно посмотреть здесь http://openweathermap.org/api
Для работы на Python’е с OpenWeatherMap существует специализированная библиотека pyowm.

Помимо OpenWeatherMap есть другие сайты, предоставляющие аналогичную информацию. Например, WorldWeatherOnline. Доступные API можно посмотреть здесь. Регистрация нужна. Есть библиотека на Python’е: pywwo.

Отдельное спасибо JetBrains за PyCharm.

  • Веб-разработка
  • Python
  • Разработка мобильных приложений
  • API

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *