СоХабр закрыт.

С 13.05.2019 изменения постов больше не отслеживаются, и новые посты не сохраняются.

| сохранено

H Парсер 2GIS в семь строчек кода, или почему важно контролировать лимиты запросов на сервер в черновиках Из песочницы

Наверное любому из тех, кто хоть как-то причастен к области анализа данных хотя-бы раз приходилось сталкиваться с поиском сторонних источников получения этих самых данных. Сегодня я хотел бы поделиться с Вами одним из самых неожиданных для меня мест, где эти данные лежат почти что на поверхности, да еще и в огромных количествах. Знакомьтесь — это 2GIS.


Image


Как ты это сделал?


Итак, первым делом заходим на сайт 2GIS, вводим случайный адрес и открываем режим разработчика, работа с сетью. Нас интересует вкладка XHR(Он же XMLHttpRequest). Данный запрос предоставляет клиенту функциональность для обмена данными между клиентом и сервером. Более подробна его работа описана здесь.


image


Видим, что есть запросы нескольких типов:


  • get — Запрос на получение информации об объекте по его id;
  • items — Запрос на получение списка объектов по строке поиска;
  • markers — Запрос на получение информации о значках и их расположении на карте;
  • count — Запрос на получение ссылок на фотографии с данного места (могу ошибаться);
  • bss — Запрос на построение отдельных полигонов карты (могу ошибаться);
  • poi — Запрос на получение информации об отдельных полигонах на карте.

Нас интересует первые два запроса, а именно — запрос items, и запрос get. Недолго думая, полностью копируем первый, вставляем его в браузерную строку, и получаем тот самый JSON ответ, в котором хранится вся информация по запросу "офис компании 2gis". Делаем однозначный вывод: Если можно напрямую отправлять запросы на сервер и получать от него ответ, то это действие можно автоматизировать. Но, давайте для начала разберем, из чего состоит сам запрос:


items запрос

Перед нами самый обычный GET запрос. Для удобства я предварительно разделил его на части. Взглянем на него и разберемся в деталях:


  • viewpoint1, viewpoint2 — это непосредственные координаты нашего окна карты;
  • type — тип запроса. Изменяя этот параметр можно осуществлять поиск, к примеру, только только по городам, либо только по "жилым зонам", либо же устроить поиск везде, как в нашем примере.
  • page, page_size — номер страницы и количество отображаемых запросов на странице. Бывает так, что по одному запросу может быть несколько ответов. К примеру, на запрос: "банкоматы". Здесь данный параметр очень пригодится.
  • locale — Выбранная локаль для запроса.
  • q — поле нашего запроса. Как видим, пробелы заменены знаками %20, запятые — на знак %2С. При составлении запроса необходимо будет это учитывать.
  • fields — поля возвращаемых значений. В данном поле, по сути, хранится вся информация, которую мы хотим получить в нашем запросе.
  • stat, key, r — поля идентификации пользователя.

Попробуем скорректировать наш запрос и посмотреть, какие поля имеют значения, а какие — нет. Забегая вперед скажу, что запрос прекрасно будет работать и без viewpoint,page и прочих подобных. А вот если изменить поля идентификации — непременно получим error 400. Значит по этим ключам и id любая информация должна быть нам доступна.


Проверим. Попробуем заменить поле нашего запроса на любой случайный адрес, с замененными пробелами и запятыми. Страница обновилась, в окне появились данные о постройке по вновь введенном адресу. Значит, запрос корректен. Можно автоматизировать!


Напишем наш Python скрипт, который будет получать JSON ответ с информацией об адресе. Для этого импортируем модуль requests, добавим в headers заголовки браузера ноутбука, предобработаем адрес, и просто отправим запрос на сервер.


код Python для получения информации по адресу

Вот и все! 7 строчек кода, и поиск по адресу готов. Введя город, улицу, и дом, наша функция вернет JSON с достаточно неплохой информацией об объекте: его id, широту, долготу, тип, район города, и так далее. И это уже впечатляет!


Больше, больше данных!


Еще больше информации можно получить по запросу get. Правда вместо адреса он использует id постройки, но мы без труда получаем его из предыдущего запроса:


код Python для получения информации по строению

Еще 7 строчек кода, и теперь мы имеем доступ не только к данным о строении, но также и об организациях в этом здании. А именно — время работы, способы оплаты, тип организации, и даже номера телефонов.


А теперь распаралеллить!


Для меня было одновременно и шоком и удивлением то, что все это дело без особых проблем параллелится, а количество запросов на сервер никак не контролируется (намек вспомнить название темы).


код Python для получения информации по адресу, многопоточный

Таким образом 2GIS позволяет получать любые данные о любых организациях достаточно быстро и просто. При этом не нужно регистрироваться, оставлять заявку или же изучать API.


Итог


На мой взгляд, это достаточно странно, ведь в наше время подобная информация стоит больших денег, а здесь ее можно получить практически прямиком, в любом объеме и бесплатно.


Решается это вроде бы тоже не так сложно — необходимо лишь наладить лимит запросов на сервер (наврядли человек с одним уникальным stat user & key сможет отправлять больше чем 10 запросов в секунду) и никакой, даже самый хитрый охотник за данными, не сможет их украсть.


P.S — такие возможности были открыты в конце декабря, после чего я сразу отписался в техподдержку 2GIS (при чем ни один раз). На дворе 15 января, ответа до сих пор не поступило, из чего можно сделать вывод что "Это не баг, а фича!". Надеюсь, так оно и задумано. Спасибо!

+7
~4700

комментарии (9)

+1
0x12ee705 ,   * (был изменён)
если вы про key, то этой «фиче» уже N лет, на хабре даже парочка статей вроде где-то была)))
0
+4 –4
Piskov ,  
На дворе 15 января

На 4-й рабочий день в январе? :-) Стоило подождать, если действительно хотели соблюсти приличия.

0
rzerda ,  

Вы сильно недооцениваете хитрость охотников. Предлагаю (в рамках умственного эксперимента, разумеется) поиграть дальше и за «снаряд», и за «броню», и посмотреть, как можно этот лимит обойти в разных начальных условиях (есть у атакующего ещё компьютеры или нет, какой объём данных надо получить, когда получить). Отдельно прикинуть, как этот лимит вообще можно реализовать на стороне «брони».

+9
+11 –2
vedenin1980 ,   * (был изменён)
Для меня было одновременно и шоком и удивлением то, что все это дело без особых проблем параллелится, а количество запросов на сервер никак не контролируется (намек вспомнить название темы). Таким образом 2GIS позволяет получать любые данные о любых организациях достаточно быстро и просто. При этом не нужно регистрироваться, оставлять заявку или же изучать API.

Это вам так кажется, что лимитов нет, на самом деле очень часто в таких случаях делают незаметную блокировку, когда данные вроде бы возвращаться, но исключительно из кеша и иногда не совсем верные или полные.

Конкурент заливает себе базу, а у него адреса части организаций не там где нужно, часы работу врут и телефоны неправильные, его клиенты плются и уходят. А юристы сервиса сточат иски по воровству данных, так искаженные данные отлично видны.
0
+2 –2
tuxi ,  
Причем это не теория, а вполне себе практика. Мы такой прием используем в продакшене.
+7
nomadmoon ,  
Я уверен, компания 2GIS просто добрая и позволяет брать информацию всем желающим.
+7
jehy ,  
1. То, что вы написали — не парсер. Впрочем, если у вас удивление вызвали странные символы "%20"…
2. Ну и целом хочется поздравить вас с открытием интернета и того, что веб приложения работают через API. Сколько подобных " уязвимостей" вам ещё предстоит открыть…
+3
gecube ,   * (был изменён)
Вообще-то 2ГИС платен.

partner.api.2gis.ru
Чтобы использовать данные 2ГИС в своём проекте, подключите платный API. Первый шаг — анкета. Расскажите о себе и опишите проект. Когда анкета придёт, мы свяжемся и обсудим детали.

и еще law.2gis.ru
Никакой автоматизации не подразумевается.

Можно прикинуться «пользователем» карт, но, во-первых, это противоречит ToS, во-вторых, есть шанс получить невалидные данные. В третьих, оператор данных (2ГИС) легко может понять, что Вы его скрейпите (юзер-агент, ip и пр.) и после какого-то лимита попросту заблокировать доступ.
+3
alekciy ,  
Какой объём данных удалось скачать? Рекомендую попробовать выкачать город милионник, узнаете много интересного.