Пишу статью для тех, у кого появилась похожая задача, но они не знают как ее решать. Не уверен что мой способ работает везде (недостаточно опытен), но считаю, что если бы я увидел эту статью, загуглив "как парсить webgl" или что-то типо такого, я бы потратил на несколько часов жизни меньше на поиск решения.
Мне надо спарсить этот маршрут так, чтобы заказчик его мог использовать при составлении идентичного маршрута в своем специальном приложении-навигаторе (или что-то такое).
Парсинг 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.
Перезагрузил страницу, долистал до карты. Сбросил историю всех завершенных запросов. И начал отдалять и водить картой туда-сюда. Появились новые запросы, которые должны были подгружать данные карты. Я посмотрел что там: и да, о чудо! В пришедших json'ах были переданы всякие объекты по типу water, grass, road и тд. Я понял, что иду в правильном направлении.
Поизучав все приходящие с самого начала загрузки страницы запросы, я нашел один выделяющийся:
Исходная ссылка: "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, который нам приходит (там сверху еще много параметров, нам не нужных)
Преобразованный 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"]["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-инициатора запроса.
Надеюсь, кому-то это сэкономило часы жизни.
Задача (и как у меня НЕ получилось ее решить)
Мне пришел заказ от знакомого: он мне отправляет 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 и тд. Я понял, что иду в правильном направлении.
Поизучав все приходящие с самого начала загрузки страницы запросы, я нашел один выделяющийся:
Он в аргументах содержал абсолютно точный 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 = 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"]["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-инициатора запроса.
Надеюсь, кому-то это сэкономило часы жизни.
Как я спарсил WebGL карту с Федерального сайта
Пишу статью для тех, у кого появилась похожая задача, но они не знают как ее решать. Не уверен что мой способ работает везде (недостаточно опытен), но считаю, что если бы я увидел эту статью, загуглив...
habr.com