Как я спарсил WebGL карту с Федерального сайта

—

от автора

Пишу статью для тех, у кого появилась похожая задача, но они не знают как ее решать. Не уверен что мой способ работает везде (недостаточно опытен), но считаю, что если бы я увидел эту статью, загуглив «как парсить webgl» или что-то типо такого, я бы потратил на несколько часов жизни меньше на поиск решения.

Задача (и как у меня НЕ получилось ее решить)

Мне пришел заказ от знакомого: он мне отправляет QR код, я парсю ссылку с куарки, и при переходе по этой ссылке в конце страницы будет карта. На ней нарисован маршрут.

Мне надо спарсить этот маршрут так, чтобы заказчик его мог использовать при составлении идентичного маршрута в своем специальном приложении-навигаторе (или что-то такое).

Парсинг QR-ки был реализован очень легко:

def qrParser(pathToImage):     decoded = decode(Image.open(pathToImage))     url = (decoded[0].data).decode("utf-8")     return url

А дальше пошла жара.

Я сначала вообще представить не мог как это сделать. Так как это WebGL приложение, в полном подгруженном HTML-JS коде ничего не было. Там это выглядит просто как обьект типа холст (canvas), в который никаких ссылок, яваскриптов не передается. Даже проштудировав многие parent элементы, а также поискав по ключевым классам, ничего путного найдено не было.

В подгружаемых js скриптах тоже ничего понятного обнаружено не было

Сидел я так часа 2-3.

Решение (которое сработало в моем случае)

Далее я решил поискать в network. Это та вкладочка, где показываются по идее все get запросы.

Перезагрузил страницу, долистал до карты. Сбросил историю всех завершенных запросов. И начал отдалять и водить картой туда-сюда. Появились новые запросы, которые должны были подгружать данные карты. Я посмотрел что там: и да, о чудо! В пришедших json’ах были переданы всякие объекты по типу water, grass, road и тд. Я понял, что иду в правильном направлении.

Поизучав все приходящие с самого начала загрузки страницы запросы, я нашел один выделяющийся:

Исходная ссылка: "https://urm.safe-route.ru/check?uuid=ID_HERE"
Исходная ссылка: «https://urm.safe-route.ru/check?uuid=ID_HERE»

Он в аргументах содержал абсолютно точный id, который передавался в исходной ссылке, а также имел ключевое слово api, которое также меня зацепило и я решил посмотреть что же интересного мне возвращает этот запрос. БИНГО. Он возвращал json, в глубинах которого передавались точные координаты (вида Долгота/Широта) всех начальных и конечных точек всех линий, из которых строился графически маршрут, что нам и нужно было.

Вот и все, задача сводится к отправке запроса по ссылке «https://urm.safe-route.ru/api/claim/resolution/check?uuid=ID_HERE». Мы получаем json, в котором передается много всяких параметров, но мы выцепляем нужный нам раздел [«geom»][«features»][номеркоординаты][«geometry»][«coordinates»] и забираем из него списки списков координат, переворачиваем координаты, так как они передаются в виде Долгота/Широта, а правильно будет Широта/Долгота и дампим в json

Вот и все, задача сводится к отправке запроса по ссылке «https://urm.safe-route.ru/api/claim/resolution/check?uuid=ID_HERE». Мы получаем json, в котором передается много всяких параметров, но мы выцепляем нужный нам раздел [«geom»][«features»][номеркоординаты][«geometry»][«coordinates»] и забираем из него списки списков координат, переворачиваем координаты, так как они передаются в виде Долгота/Широта, а правильно будет Широта/Долгота и дампим в json.

Исходный response, который нам приходит (там сверху еще много параметров, нам не нужных)
Исходный response, который нам приходит (там сверху еще много параметров, нам не нужных)
Преобразованный json, в котором каждый элемент это координата точки маршрута (с превеликой точностью в пару метров)
Преобразованный json, в котором каждый элемент это координата точки маршрута (с превеликой точностью в пару метров)
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:94.0) Gecko/20100101 Firefox/94.0"} response = requests.get(url, headers=headers, verify=False)  #url мы здесь передаем уже вида "https://urm.safe-route.ru/api/claim/resolution/check?uuid=ID_HERE" #ведь именно он возвращает нам json с координатами count = 0 answer = {}  for i in range(len(response.json()["geom"]["features"]) - 1, 0, -1):   geometries = (response.json()["geom"]["features"][i]["geometry"]["coordinates"])   for j in geometries:      j = j[::-1]     answer.setdefault(count, j)     count += 1  json_object = json.dumps(answer, indent=4) with open("coords.json", "w+") as file:   file.write(json_object)

verify=False при get запросе был обязателен, без этого сайт не пропускал по причине отсутствия SSL сертификата у python-инициатора запроса.

Надеюсь, кому-то это сэкономило часы жизни.

P.S. Любые замечания и вопросы приветствуются и будут просмотрены автором.


ссылка на оригинал статьи https://habr.com/ru/articles/591229/


Комментарии

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

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