Запросы при помощи urllib.request и json. Практика запросов при помощи открытых API

Постановка задачи

Инструменты

Пример: космонавты

Результат запроса:

{
  "people":
  [
    {
      "craft": "ISS", "name": "Andrew Morgan"
    },
    {
      "craft": "ISS", "name": "Oleg Skripochka"
    },
    {
      "craft": "ISS", "name": "Jessica Meir"
    }
  ],
  "message": "success",
  "number": 3
}

Упаковка данных

Данные надо упаковывать в структуры. Это как почтовая посылка: в картонную коробку мы кладем несколько вещей, каждая в полиэтиленовом пакете.

Как упакованы данные на языке стандартных типов Python:

«Прочитаем» данные:

  1. сообщение успешно (success) передано,
  2. в космосе 3 космонавта,
  3. люди (people) в космосе – это: Andrew Morgan, Олег Скрипочка и Jessica Meir, все на МКС (ISS).

Программа для получения информации и ее печати на экране:

import json
import urllib.request


URL = 'http://api.open-notify.org/astros.json'
astros_json_bin = urllib.request.urlopen(URL)
astros = json.load(astros_json_bin)
ASTROS = astros.get('people')
print('на орбите', astros.get('number'), 'космонавта:')
for astr in ASTROS:
    print(astr.get('name'))

Использовано:

Задание: время пролетов МКС (почти) над Москвой

Результат запроса:

{
  "message": "success",
  "request": {
    "altitude": 100,
    "datetime": 1585145742,
    "latitude": 55.751244,
    "longitude": 37.618423,
    "passes": 5
  },
  "response": [
    {
      "duration": 530,
      "risetime": 1585148072
    },
    {
      "duration": 625,
      "risetime": 1585153788
    },
    {
      "duration": 640,
      "risetime": 1585159565
    },
    {
      "duration": 615,
      "risetime": 1585165359
    },
    {
      "duration": 481,
      "risetime": 1585171182
    }
  ]
}

Задача: получить данные о времени пролетов МКС на небе Москвы. Напечатать на экране:

  1. Сколько пролетов МКС содержится в ответе (response) на запрос (request)
  2. Для каждого пролета МКС: время восхода (risetime), длительность (duration), время захода в человекочитаемом виде.

Для перевода unix time в понятные человеку день, месяц, год и часы, минуты, секунды используют библиотеку time, функцию ctime:

>>> time.ctime(1585153788)
'Wed Mar 25 19:29:48 2020'
Начало программы, которую требуется дописать:
import json
import urllib.request
import time

URL = 'http://api.open-notify.org/iss-pass.json?lat=55.751244&lon=37.618423'
iss_pass_json_bin = urllib.request.urlopen(URL)
iss_pass = json.load(iss_pass_json_bin)

Решение



МКС на вечернем небе – самое яркое тело на небе после Солнца и Луны:

Точное время

Ссылка на данные (Яндекс.Время).
Результат запроса:

{
  "time": 1585172540959,
  "clocks": {
    "213": {
      "id": 213,
      "name": "Москва",
      "offset": 10800000,
      "offsetString": "UTC+3:00",
      "showSunriseSunset": true,
      "sunrise": "06:15",
      "sunset": "18:55",
      "isNight": true,
      "skyColor": "#00050f",
      "weather": {
        "temp": 4,
        "icon": "skc-n",
        "link": "https://yandex.ru/pogoda/moscow"
      },
      "parents": [
        {
          "id": 225,
          "name": "Россия"
        }
      ]
    }
  }
}

Задача: получить точное время и сравнить его с временем компьютера, на котором запускается программа.
Напечатать на экране:

  1. точную дату и время,
  2. разницу в минутах и секундах с временем компьютера.
  3. «На пятерку»: напечатать время рассвета и заката.

Точное время доступно по ключу "time" и представляет собой unix time, но в миллисекундах.
То есть, для получения результата в функцию time.ctime() надо передать значение, поделенное на 1000.

Для получения времени компьютера надо выполнить time.time() без параметров

Для получения времени рассвета и заката надо извлекать вложенные данные подобно матрешке: сначала обратиться к данным по ключу "clocks", потом по ключу "213" (код Москвы), потом у результата этой операции обратиться по ключам "sunrise" и "sunset".

А еще это напоминает сказку про Кощея бессмертного:

>>> сказка = {"дуб": {"сундук": {"заяц": {"утка": {"яйцо": "игла, смерть Кощея"}}}}}
# Сказка сказывается
>>> сказка.get("дуб")
{'сундук': {'заяц': {'утка': {'яйцо': 'игла, смерть Кощея'}}}}
# Дело делается
>>> сказка.get("дуб").get("сундук")
{'заяц': {'утка': {'яйцо': 'игла, смерть Кощея'}}}
Начало программы, которую требуется дописать:
import json
import urllib.request
import time

URL = 'https://yandex.com/time/sync.json?geo=213'
time_json_bin = urllib.request.urlopen(URL)
time_data = json.load(time_json_bin)

Решение



Бонусная задача: курс доллара

Ссылка на данные.

Результат запроса:

{
"base": "USD", "date": "2020-03-25", "time_last_updated": 1585094645,
"rates": {
    "USD":1, "AED":3.67194, "ARS":63.782963, "AUD":1.689614,
    "BGN":1.803148, "BRL":5.100792, "BSD":1, "CAD":1.446787,
    "CHF":0.977568, "CLP":860.840598, "CNY":7.0736, "COP":4100.333333,
    "CZK":25.65441, "DKK":6.895422, "DOP":54.019448, "EGP":15.761852,
    "EUR":0.92466, "FJD":2.357417, "GBP":0.852776, "GTQ":7.674421,
    "HKD":7.754263, "HRK":7.017643, "HUF":324.992634, "IDR":16550.000184,
    "ILS":3.64491, "INR":76.090264, "ISK":139.995445, "JPY":110.89439,
    "KRW":1245.64532, "KZT":446.150259, "MXN":24.873806, "MYR":4.434908,
    "NOK":11.084183, "NZD":1.724957, "PAB":1, "PEN":3.526802,
    "PHP":51.135164, "PKR":157.994495, "PLN":4.257353, "PYG":6623.615385,
    "RON":4.470324, "RUB":78.849559, "SAR":3.753237, "SEK":10.19446,
    "SGD":1.449219, "THB":32.782756, "TRY":6.480904, "TWD":30.240127,
    "UAH":27.592197, "UYU":44.568841, "ZAR":17.59029
  }
}

Задача: получить усредненный курсы рубля к доллару, евро и другим валютам.
Напечатать на экране:

Для того, чтобы узнать, сколько рублей стоит валюта, надо вычислить отношение курса рубля к курсу выбранной валюты.

Начало программы, которую требуется дописать:
import json
import urllib.request

URL = 'https://api.exchangerate-api.com/v4/latest/USD'
exchangerate_json_bin = urllib.request.urlopen(URL)
exchangerate = json.load(exchangerate_json_bin)

Решение



Для самостоятельного изучения: справочная информация, примеры открытых API

Решение проблем

Если подключение по сети отсутствует, использовать данные из раздела «Результат запроса». Программа для задачи «Космонавты»:

DATA = {"people":[
  {"craft": "ISS", "name": "Andrew Morgan"},
  {"craft": "ISS", "name": "Oleg Skripochka"},
  {"craft": "ISS", "name": "Jessica Meir"}],
"message": "success", "number": 3}
print(DATA)
print("Число космонавтов на орбите:", DATA.get("number"))
print("Первый космонавт:", DATA.get("people")[0].get("name"))
PEOPLE = DATA.get("people")
print("Второй космонавт:", PEOPLE[1].get("name"))
for person in PEOPLE:
    print(person.get("name"))