среда, 8 сентября 2021 г.

Достаём данные с сайта без api: egrul.nalog.ru



В сети существует большое количество сайтов предоставляющих информацию пользователю. Большинство из них дружелюбно и предоставляют эту информацию с помощью API (Application programming interface)
Такие интерфейсы есть почти у каждой уважающей себя системы - VK, Telegram, Yandex, Google  и многие, многие другие. С их помощью можно сделать всё (или почти всё) что можно сделать вручную: отправить сообщение, получить информацию, заполнить таблицу, распечатать документ, вывести карту с метками и многое, многое другое.
 где мы можем
бесплатно получить сведения из ЕГРЮЛ/ЕГРИП о конкретном юридическом лице/индивидуальном предпринимателе в виде выписки из соответствующего реестра/справки об отсутствии запрашиваемой информации в форме электронного документа, подписанного усиленной квалифицированной электронной подписью

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

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

function getCookie(){
let url='https://egrul.nalog.ru/'
return UrlFetchApp.fetch(url).getAllHeaders()['Set-Cookie'].split(';')[0]
}
Получили ключик к сайту. Дальше необходимо с этим ключиком постучаться на сайт и запросить нужную информацию, создать запрос на получение информации, region - номер региона РФ (11-Республика Коми), page - номер страницы, nameEq - точное соответствие искомому слову find, вполне может быть что потребуется решать капчу при блокировании ip адреса, но это выходит за рамки статьи.   
function find(cookie,find){
let body={
vyp3CaptchaToken: '',
page: '',
query: find,
nameEq: 'on',
region:'11',
PreventChromeAutocomplete:'',
}
let params={
headers:{'Cookie':cookie},
method:'post',
payload:body
}
let url='https://egrul.nalog.ru/'
let response=UrlFetchApp.fetch(url,params)
let responseJson=JSON.parse(response.getContentText()).t
return responseJson
}
В ответе получаем часть ссылки по которой опять же нужно сделать запрос для получения первой страницы поиска:
function getInfo(cookie,urlPart){
let params={
method:'get',
headers:{'Cookie':cookie}
}
let time=new Date().getTime()
let response2=UrlFetchApp.fetch('https://egrul.nalog.ru/search-result/'+urlPart+'?r='+time+'&_='+time,params).getContentText()
return JSON.parse(response2)
}
В ответ нам придёт объект который в дальнейшем можно будет разобрать, например по ячейкам таблицы. Весь этот код можно объединить в одну функцию, сделать из него библиотеку и подключать в нужных документах в скрипты.

  function egrulEgrip(searchWord){
  let url = 'https://egrul.nalog.ru/'
  let cookie = UrlFetchApp.fetch(url).getAllHeaders()['Set-Cookie'].split(';')[0]
  let body={
    vyp3CaptchaToken: '',
    page: '',
    query: searchWord,
    nameEq: 'on',
    region:'11', 
    PreventChromeAutocomplete:'', 
  }
  let params={
    headers:{'Cookie':cookie},
    method:'post',
    payload:body
  }
  let response=UrlFetchApp.fetch(url,params)
  let urlPart=JSON.parse(response.getContentText()).t
  params.method='get'
  delete params.payload
  let time=new Date().getTime()
  let response2=UrlFetchApp.fetch('https://egrul.nalog.ru/search-result/'+urlPart+'?r='+time+'&_='+time,params).getContentText()
  return JSON.parse(response2)
}
Передавая последней функции, в качестве параметра Название организации или Фамилию или ИНН или ОГРН, можем получать достаточно большой список данных, который сами сможем отфильтровать, взяв только нужное. То есть это и есть написанное API, довольно сырое, но рабочее.
Будут вопросы - милости прошу писать комментарии.)

Что в итоге:
  • первые 3 функции написаны для того чтобы разобрать ход написания кода. Для решения задачи подойдёт сразу последняя. 
  • для запросов на данный сайт можно обойтись без Cookie, но кто знает когда это прикроют. С помощью cookie мы можем проходить авторизацию на сайтах и получать информацию из различных систем.
  • факт что данный код подходит данному сайту, не факт что он подойдёт для другого.
  • параметры подключения к сайту взяты из консоли браузера, таким же образом можно "подсмотреть" параметры get и post запросов для других систем. 

Особая благодарность каналу телеграм - Google Таблицы и чату Чат | Google Таблицы и скрипты за продвижение технологий google скриптинга и таблицестроительства.

8 комментариев:

  1. Роман, результат супер!

    Интересно, как вы нашли такой подход, что читали, где копали.

    Интересно, возможно ли такой подход применить на других сайтах.

    ОтветитьУдалить
    Ответы
    1. Доброго дня.
      Консоль браузера очень хороший инструмент для анализа исходящих запросов и приходящих ответов, в итогах статьи есть про это.
      Таких сайтов большинство.) В статье рассмотрен пример использования cookie в запросах UrlfetchApp, остальное дело техники.

      Удалить
  2. Роман, благодарю за статью,получилось адаптировать, работает!
    Есть ли опыт получения JSESSIONID ?

    ОтветитьУдалить
    Ответы
    1. Доброго дня.
      Вы же понимаете что JSESSIONID предоставляет не один сайт? Их слишком много чтобы говорить про опыт.)

      Удалить
  3. РОман, добрый день!

    А можно ли этот код использовать как-то для автозаполнения в Эксель.
    Есть задача, по инн получить наименование. Как-то можно использовать ваш код в этом случае?
    Простая вроде задача, но готового решения никак не могу найти((

    ОтветитьУдалить
    Ответы
    1. Доброго вечера.
      Excel - продукт Майкрософт, работает локально на вашем компьютере, поддерживает макросы и скорее всего что-то подобное можно сделать, но не с этим кодом. Языки различаются кардинально. В Excel VBA скрипты, в таблицах google js.
      По работе с инн и наименованиям, вам, скорее всего, нужен другой источник - https://dadata.ru/, например. В блоге есть статья про них.

      Удалить
  4. Добрый день!
    После того как скопировал ваш скрипт и он заработал (спасибо огромное!), захотелось скачать выписку в pdf.

    Через консоль нашёл функцию, которая направляет соответствующий запрос, но вот дальше возникает ошибка и выписки не скачивается.

    Хотя из консоли работает. Соответственно вопрос, что я мог упустить? Cookie?

    ОтветитьУдалить
    Ответы
    1. Доброго дня.
      После получения объекта с результатами поиска нужно раздербанить его и найти параметр t, который представляет собой часть нужной ссылки. Причём этот параметр скорее всего привязан к cookies и динамичен. Для получения необходимо опрашивать ссылку и получить blob. В консоли браузера это можно отследить.

      Удалить