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

Есть интересная статья о том, как Энтузиасты делают погоду.

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

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

d5b62da07ddf4848b3ef2ea1f267d08c.jpg

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

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

appid = "".join(random.choice("abcdef0123456789") for x in range(29))

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


Сначала попытаемся найти интересующий нас город в их базе. Строка запроса должна быть примерно такая:
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

Поскольку нужно будет несколько раз формировать строку запроса, решил сделать для этого функцию form_url_string:
appid = "6d8e495ca73d5bbc1d6bf8ebd52c4"
def form_url_string(s_request):
    global appid
    s_appid = "&APPID=" + appid
    s_template = "http://api.openweathermap.org/data/2.5/" + s_request + s_appid
    return s_template

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


План такой. В ответ на сформированный запрос получаем пакет в формате JSON. Разбираем пакет и получаем нужные значения по названиям полей.
import requests
s_city = "Petersburg"
s_country = "RU"
s_request = "find?q={},{}&type=like".format(s_city, s_country)
s_search_url = form_url_string(s_request)
print(s_search_url)
try:
    res = requests.get(s_search_url)
    data = res.json()
    cities = ["{} ({})".format(d['name'], d['sys']['country'])
          for d in data['list']]
    print( "city:", cities )
except Exception as e:
    print("Exception (find):", e)
    pass

В ответе может оказаться несколько городов, соответствующих нашему запросу. Кстати, если в запросе указать «Moscow» и убрать страну из строки приведенного в примере запроса, то гарантированно получим несколько строк в списке cities:
city: ['Moscow (RU)', 'Moscow (US)', 'Moscow (US)']

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


Осталось только получить искомую информацию о погоде. Если нас не интересуют имперские единицы измерения, то в запросе указываем, что желаем получить метрические единицы: «units=metric»
s_request = "weather?q={},{}&units=metric".format(s_city, s_country)
s_search_url = form_url_string(s_request)
try:
    res = requests.get(s_search_url)
    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: light snow
temp: -5.25
temp_min: -6
temp_max: -5

Как и обещал — всё очень просто.

На сайте OpenWeatherMap есть ещё масса интересного — прогноз, архив погоды, информация со станций погоды. Описание всех доступных сервисов можно посмотреть здесь openweathermap.org/api

Комментарии (14)

  • 15 ноября 2016 в 01:44

    0

    Я делал такое же, только погоду с прогнозом у меня запрашивал stm32 и выводил результат на небольшой дисплей
    • 15 ноября 2016 в 08:29

      –1

      А сервис погоды был этот же — openweathermap.org?
  • 15 ноября 2016 в 02:24

    +4

    Планирует ли автор выложить полный исходный код приложения на гитхаб? Будут ли рассматриваться пулл-рекввесты сообщества? Готовы ли юнит-тесты для полноценной интеграции?
    Нужные десктопные уведомления, где интерефейс доступа? Или это бэкенд? А какие базы данных поддерживаются? Очень нужна %database_name%!1


    Как и обещал — всё очень просто.

    Рассматривает ли автор возможность миграции на более производительную платформу разработки?
    Есть готовые наработки для bash:-P


     #!/bin/bash
    
    set -euf -o pipefail
    
    API_KEY="mew"
    LOCATION="Petersburg,RU"
    
    exec 99<> /dev/tcp/api.openweathermap.org/80
    
    echo -e "GET /data/2.5/find?q=${LOCATION}&type=like&APPID=${API_KEY} HTTP/1.1\r\nhost: api.openweathermap.org\r\nConnection: close\r\n\r\n" >&99
    
    HTTP_ANSWER_WITH_HEADERS=`cat <&99`
    
    JSON_OUTPUT=${HTTP_ANSWER_WITH_HEADERS#*POST}
    
    WEATHER_DESC=`echo $JSON_OUTPUT | jq '.list[0].weather[0].description'`
    
    notify-send "It's ${WEATHER_DESC} at ${LOCATION}"
    • 15 ноября 2016 в 09:34

      +1

      Проверил — Ваш скрипт работает. Пришлось, правда, поставить утилитку jq, которой у меня не оказалось. И заработало. Спасибо за вклад в дело получения метео. Только я не вполне понял Ваши вопросы насчёт юнит-тестов, бэкэнда и пр. Я то зашёл в эту тему из python’а. Узнал, что есть такой сервис OpenWeatherMap, удалось получить текущую температуру, которая на удивление соответствовала окружающей меня действительности. В python’е нашлась хорошая библиотека requests, которая позволила не только запрос сделать, а ещё и распарсить JSON-формат. Подумал, что кому-нибудь ещё может быть интересно, что 1) существует такой общественный сервис, в который каждый желающий может выложить собственную метео-информацию о погоде (идея сама по себе интересная); 2) сервисом OpenWeatherMap можно воспользоваться для получения разного вида информации (в том числе на bash’е), и это достаточно просто делается; 3) примитивный, но работающий код на python’е. И ещё подумал, что, может, кому-нить это может быть интересно, поэтому этим всем я решил поделиться. Где-то есть прокол в моих соображениях?
      • 15 ноября 2016 в 12:37

        0

        Я думаю romangoward сарказмирует. А причина сарказма, это банальная статья из разряда практически hello world. Получение прогноза погоды, это наверное то, что делал почти каждый, изучая программирование (раньше в вебе информер прогноза погоды висел почти на всех сайтах).
  • 15 ноября 2016 в 04:50

    +1

    Библиотечка есть
    • 15 ноября 2016 в 09:35 (комментарий был изменён)

      –1

      Спасибо! Интересно будет попробовать.
      • 15 ноября 2016 в 11:16

        –1

        Ура! Карма вернулась! Теперь смог плюсик Вам поставить за библиотеку pyowm:)
  • 15 ноября 2016 в 09:00

    +4

    curl wttr.in
    • 15 ноября 2016 в 11:28

      0

      Прикольная штука. Спасибо! В Linux’е в командной строке нужно исполнить
      $curl wttr.in
      И в терминалке появится красивая картинка, показывающая погоду в Питере. Вот такого вида.
  • 15 ноября 2016 в 09:36

    +1

    http://trytoguide.me/post/12 — тот же openweather, только по координатам
    • 15 ноября 2016 в 11:40

      –1

      Вот спасибо! По ссылке есть код на python’е! Используются две библиотеки urllib и json. И я тоже сначала этот вариант использовал. Но потом нашел более симпатичную альтернативу — библиотеку requests. И ещё подробно описан процесс регистрации. Ну, и недостаток моего кода решён — сделан перевод на русский текстов с описанием погоды. Хотя, думаю, красивее было бы использовать не if’ы, а dictionary для этой цели. Спасибо за полезный вклад!
  • 15 ноября 2016 в 10:48

    +1

    На онлайн-курсах teamtreehouse.com есть интересный — и достаточно компактный — учебный проект под Андроид, там прогноз погоды на основе API к сайту forecast.io
    Там прогноз на неделю, и по часам на ближайшие сутки с половиной.
    Я его делал в немного расширенном виде — прикрутил еще геолокацию, чтобы показывать погоду в текущей точке. На своем телефоне сам пользовался. А вот чего не знаю — это какой источник данных точнее. Forecast.io — скажем так, на четверку с минусом. А как насчет openweathermap.org?
    • 15 ноября 2016 в 11:11

      –1

      Интересно будет посмотреть Вашу реализацию с forecast.io. Спасибо! Насчёт точности openweathermap — не знаю. Судя по статье от 2012 года, на российской территории станций маловато, поэтому и с точностью должны быть проблемы. Вряд ли за 4 года ситуация кардинальным образом изменилась. А вот западнее — насчёт Европы — точность должна быть лучше. Там с метео-станциями всё очень неплохо.

© Habrahabr.ru