- PVSM.RU - https://www.pvsm.ru -
«Где мы, папа», — спросил меня 5-летний сын.
«Мы приземлимся примерно через час», — ответил я.
«Да нет, я имею в виду, где мы? Мы ещё не пролетаем Италию?»
Точно ответить я не мог. Это был недолгий перелёт по низкому тарифу без удобств в виде встроенных в подголовники кресел экранов. Тогда я огляделся по сторонам и заметил наклейку с призывом подключиться к WiFi-сети самолёта. Должно сработать. Думаю, что сайт вроде FlightRadar [1] ответит на вопрос моего сынишки с точностью до нескольких метров.
Но, к его сожалению, я разработчик PySkyWiFi [2] («абсолютно дурацкого WiFI-инструмента для бесплатного доступа в интернет при длительных перелётах»). Не платить за интернет авиакомпании — это моя личная фишка. Здесь же нам потребуется иная, офлайн-стратегия.
Я рассуждал так. Когда ты подключаешься к WiFi-сети самолёта, то обычно попадаешь на страницу оплаты, где покупаешь доступ в интернет. На этой же странице обычно предоставляется та же информация о полёте, что и на экранах подголовников — скорость, направление и расчётное время прибытия (Estimated Arrival Time, ETA). Поначалу я думал, что там будет ещё и карта.
В итоге я достал ноутбук, подключился к сети и загрузил платёжную страницу. На ней действительно показывалась воздушная скорость судна, направление полёта и расчётное время до прибытия. Но карты не было.
(Тогда я не додумался сделать скрин этой страницы, так что вот вам моя художественная интерпретация):
«Возможно, сервер, который отправляет нам эти данные, по факту отправляет и наше местоположение, но веб-страница этого не показывает», — подумал я. Открыв инструменты разработчика Chrome, я увидел, что мой браузер выполняет регулярные запросы к конечной точке /info
.
Я развернул один из этих запросов. Конечная точка /info
действительно отправляла большие объёмы данных, включая поля для ground_speed
, wind_speed
и estimated_arrival_time
.
В нижней части ответа я заметил поля для latitude
и longitude
. Мой пульс участился. Но при внимательном рассмотрении оказалось, что они оба null
. Облом.
Казалось, что на этом всё. Я уже собирался сдаться и сказать сыну, что мы летим где-то севернее Италии… над какой-то частью Европы. Но затем меня осенили две фантастических идеи.
Идея №1: конечная точка /info
не сообщала наши координаты, но предоставляла точную и регулярно обновляемую информацию о скорости и направлении движения. Тогда в течение всего нашего обратного полёта я смогу отслеживать и сохранять эти данные примерно раз в секунду. Используя эту информацию, я буду определять, насколько далеко и в каком направлении мы ежесекундно перемещаемся. То есть смогу динамически вычислять наше местоположение, начав с координат аэропорта и поступательно их корректируя.
Идея №2. Даже если бы я смог найти в ответе /info
координаты нашей широты и долготы, ни мне, ни моему сыну они бы ничего полезного не сообщили. Однако я смог создать веб-приложение, которое выполняется на моём ноутбуке и в реальном времени показывает динамически вычисляемое местонахождение на карте. Это приложение может автоматически обновлять график расчётного времени прибытия, направления ветра, скорости, высоты и так далее. Ах да, ещё в нём есть интерфейс для выполнения произвольных запросов по этим данным и обратные вызовы событий, позволяющие программно активировать код, исходя из информации о полёте («когда ETA составит ровно 2 часа, программа будет блокировать мне доступ к Netflix.com и открывать последний черновик моего незаконченного романа»). Мой сын будет понимать, где он находится, а я проявлю себя как хороший папа.
Я решил назвать приложение PyMyFlySpy, чтобы прослеживалась связь с PySkyWiFi [3]. Мне не терпелось начать. К сожалению, в тот момент я был зажат между двумя детьми, 5-ти и 2-х лет, и мы все очень плохо разбирались в JavaScript. Оставалось с нетерпением ждать.
Наконец, мы приземлились. Я написал PyMyFlySpy за время праздников, посвятив этому поздние вечера и несколько послеобеденных часов, пока остальные члены семьи развлекались какими-то обыденными способами. Я не понимал, окажется ли дурным тоном использование ноутбука в традиционных итальянских кофейнях, и в каких из них есть WiFi, поэтому к своему бесконечному стыду нагуглил «starbucks рядом». Найдя подходящее заведение, я заказал себе моккачино и, усевшись в укромном уголке, принялся печатать.
В итоге я закончил PyMyFlySpy за день до нашего отлёта. Его код доступен на GitHub [4]. Настроить и запустить это приложение несложно. В нём даже есть «холостой» режим, который позволяет симулировать полёт, не находясь в самолёте.
Что же конкретно умеет мой PyMyFlySpy?
PyMyFlySpy показывает карту с пройденным вами на данный момент путём. Он также показывает текущие метрики полёта и тренд их изменения за всё его время. Делает он это для всех данных, доступных с бортового WiFi, даже тех, которые на сайте или экране подголовника не отображаются. С его помощью вы можете точно видеть, где находитесь, и в некоторой степени ощущать себя пилотом.
PyMyFlySpy сохраняет всю регистрируемую информацию в базе данных. В его UI есть страница, которая позволяет писать запросы к данным для определения, например «максимальной скорости за всё время полёта и момента её достижения» или «скорости ветра во время только что пройденной турбулентности».
Я не утверждаю, что это прям очень полезно, но, как минимум, просто круто.
У разных авиакомпаний разные системы WiFi. Регистратор для JetBlue не будет работать на авиалиниях AirFrance. К счастью, PyMyFlySpy позволяет с лёгкостью добавлять и использовать регистраторы для разных систем. Достаточно загрузить стартовую страницу подключения WiFi, открыть инструменты разработчика в браузере и найти способ спарсить данные с этой страницы, как сделал я выше. Затем нужно добавить новый код в конфигурацию PyMyFlySpy и указать на него регистратору. Всё остальное продолжит работать так же.
Система очень проста и состоит из 4 частей:
В ходе разработки я принял одно неординарное решение — использовать для считывания данных полёта расширение Firefox вместо того, чтобы написать скрейпер, который бы напрямую выполнял собственные запросы. Такой скрейпинг информации получился бы более гибким и простым, да и полностью безвредным. Сотни людей и так подключены к WiFi, а базовая страница бортовой WiFi-системы связывается с конечной точкой /info
каждые пару секунд. Добавление дополнительного запроса от скрейпера никак бы не навредило.
Тем не менее авиакомпания вряд ли приветствовала бы вмешательство в свои бортовые сервисы посторонних, даже если совершающие его люди очень осторожны, доброжелательны и благородны. И чтобы их не тревожить, я придумал ещё более рациональный подход.
Вместо скрейпинга конечной точки данных я написал расширение для Firefox. Это расширение ожидает, когда базовая страница WiFi-системы запросит последние данные с /info
. После запроса она просматривает полученные данные и отправляет их на сервер PyMyFlySpy, который записывает эти данные в БД для передачи фронтенду. Подобное использование расширения означает, что PyMyFlySpy никогда не взаимодействует с информацией сервера самолёта напрямую и навредить этому серверу никак не может.
Мне пришлось написать расширение для Firefox, а не Chrome, потому что в Chrome планируют урезать возможность взаимодействия расширений с запросами сайта [5] (вроде тех, которые совершаются к конечной точке /info
). В частности, разработчики этого браузера планируют запретить расширениям считывать ответы на HTTP-запросы сайта, а значит, PyMyFlySky не сможет считывать данные, возвращаемые /info
. Насколько я понимаю, эти ограничения частично вызваны заботой о безопасности, а отчасти служат для усложнения разработки блокировщиков рекламы. Как бы то ни было, но PyMyFlySpy требует Firefox.
PyMyFlySpy даёт нам программный доступ к данным о полёте. И будет здорово использовать их для активации различных событий вроде таких:
Пожалуй, займусь этим в следующие праздники.
Обратный перелёт был вечерним. Мы взобрались на борт и взлетели. Я достал ноутбук, подключился к WiFi, загрузил PyMyFlySpy и повернулся к сыну, чтобы показать, где мы находимся. Я показывал ему прототип программы всю прошлую неделю, и его реакция была где-то между «безразличием» и «лёгким интересом». Но он уже уснул. Тогда я сделал несколько скриншотов, чтобы показать их ему позже.
Следующие несколько часов я провёл за мониторингом и отладкой регистратора, чтобы обеспечить его устойчивую работу. Мой двухлетний сын кричал на протяжении всего полёта, то и дело норовя вывалиться на пол. Я поддерживающим взглядом посматривал на жену, которая сидела с ним через проход от меня, и давал понять, что готов его взять. Но супруга мотала головой — она понимала, что у меня важное дело.
Я просматривал графики. Температура была в норме, воздушная скорость стабильна, и тут внезапно высота упала на пятьдесят футов. Мне пришла мысль сообщить об этом пилотам, но я решил, что у них наверняка всё под контролем. Хотя наблюдение всё же продолжил — мало ли.
Автор: Bright_Translate
Источник [6]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/python/405194
Ссылки в тексте:
[1] FlightRadar: https://www.flightradar24.com/
[2] PySkyWiFi: https://robertheaton.com/pyskywifi/
[3] PySkyWiFi: https://github.com/robert/PySkyWiFi
[4] GitHub: https://github.com/robert/PyMyFlySpy
[5] урезать возможность взаимодействия расширений с запросами сайта: https://brave.com/blog/brave-shields-manifest-v3/#whats-the-issue-with-manifest-v3
[6] Источник: https://habr.com/ru/companies/ruvds/articles/865956/?utm_source=habrahabr&utm_medium=rss&utm_campaign=865956
Нажмите здесь для печати.