На сайте ФНС по адресу egrul.nalog.ru/index.html есть замечательный сервис проверки контрагентов или своих собственных обществ.

Суть проверки сводится к подаче запроса в ЕГРЮЛ (единый реестр фактов детальности юридических лиц) и получении тут же, онлайн, выписки из реестра.

Работа с сервисом не вызывает каких-либо затруднений: внес в поле ОГРН, нажал кнопку “Найти” и нажал кнопку “Скачать” ниже. Все, выписка получена.

Как здесь может помочь автоматизация? Очень просто.

Если ваш холдинг состоит из n-количества юридических лиц, то даже такая работа как копипастинг ОГРН в строку поиска сервиса может надоесть.

Избавимся от рутины и автоматизируем процесс подачи-скачивания выписок из ЕГРЮЛ!

В нашем случае программа будет “забирать” по одному ОГРН из заранее подготовленной таблицы excel, вносить значение в строку сервиса, нажимать необходимые кнопки.

В идеале работа программы будет выглядеть так:


Приступим.

Для начала подготовим таблицу excel, куда внесем ОГРН, по которым мы будем работать, в столбик:



Количество ОГРН не имеет значения (можно хоть весь ЕГРЮЛ скачать), главное чтобы они все были в столбце А.

Назовем файл выпискиЕГРЮЛ.xlsx и сохраним в рабочей директории python.

Теперь создадим сам файл с программой – egrul.py.

Первые строки программы, как обычно, начинаются с импорта необходимых модулей, далее мы выбираем браузер (в моем случае Chrome) и “заходим” на сайт:



Далее мы запускаем цикл по всем ОГРН в таблице excel:



Здесь надо обратить внимание на значения x вначале цикла:



2- это начальная ячейка с ОГРН (стартовая), которая соответствует A2 в excel таблице. Конечная ячейка будет A9, хотя в цикле указана цифра 10.

Это надо иметь ввиду, чтобы все ОГРН были обработаны и последнее значение не потерялось.
Между подачами запросов в ЕГРЮЛ программа выдерживает паузу в 30 секунд. Это может показаться недопустимо долго и этот период захочется сократить. Это можно сделать, поменяв значение в строке time.sleep(30) на, например, time.sleep(10). Однако в данном случае можно попасть под санкции сервиса ФНС и получить капчу. Данную капчу можно обойти, но это тема отдельного поста. А в этой программе лучше оставить задержку между подачами запросов в 30 секунд и пойти спокойно пить чай, пока программа за вас работает.

Ссылка на программу – здесь.

Ссылка на тестовую таблицу excel – здесь.

Комментарии (11)


  1. saw_tooth
    12.06.2019 11:45
    +2

    ох, реализация «с лазерной пушки, которая вращается на орбите планеты Земля, по воробьям»

    В ответе приходит хеш-строка URI, по которому есть результаты поиска в виде JSON.

    Заголовок спойлера
    В редакторе есть тег code, для выкладок кода.
    Вместо Excel, куда удобнее и проще использовать csv, который нативными модулями парсится


  1. Drakosh
    12.06.2019 13:43

    Не оставляйте, пожалуйста пробелов перед скобками (при вызове функций).
    Всегда оставляйте, пожалуйста пробелы вокруг знака равно.
    Pep8 вам в помощь — habr.com/ru/post/251531
    если бы код был на github то нашлись бы люди, которые это поправили. А как исправить код на картинке или выложенный в частное облако?


  1. stalker1984
    12.06.2019 18:37
    +1

    Воот матёрые програмисты подтянулись. PEP8 и прочее. Ребят, просто порадуйтесь за человека. Хочу сказать что иногда не обязательно быть прям хардкор-программистом чтобы просто радоваться плюсам автоматизации.
    У меня случилась недавно такая история на работе — мы собираем досье на медизделие и в нём соответствующая нормативная документация на сырьё. На всё на это порядка 10 однотипных докуметов. Я за полчаса написал скрипт и сгенерировал более 2500 файлов съэкономив тем самым кучу времени и нервных клеток, себе и коллегам.
    Я не программист (я химик), но иногда мне нравиться поступать разумно (пусть даже и с пушкой по пернатым).
    Автору удачи!!!


    1. Tinkz
      13.06.2019 10:51

      согласен, как раз искал подобное решение, а про webdriver впервые слышу, т.ч. автору спасибо!


  1. phaggi
    12.06.2019 20:18

    Хорошо бы втянуть excel в pandas через df = pandas.read_xls(“ЕГРЮЛ.xlsx”) и там уже при помощи len(df.index) определить длину столбца, а не вписывать руками 30 в начало скрипта.

    Впрочем, если скрипт для разового применения — сойдёт и так. А если для регулярного — лучше от «ручника» уйти.


    1. zoldaten Автор
      14.06.2019 10:57

      да, у меня есть такая реализация. без pandas, все проще. но ручник нужен для ситуации, если полезли капчи либо отошел, либо интернет отвалился. напишу как-нибудь попозже пост как кидаться запросами, в том числе игнорируя капчи.


  1. technic93
    13.06.2019 00:39

    А почему код картинкой? В Хабр можно легко вставить код с подсветкой.


  1. zoldaten Автор
    13.06.2019 09:46

    спасибо за комменты. первый пост, он такой ) тем более, что я юрист, а не программер. порой проще написать «лазерную пушку по воробьям» самому, чем идти в ИТ и объяснять, что это и зачем надо.


    1. redskif
      14.06.2019 11:25

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


      1. zoldaten Автор
        14.06.2019 12:05

        Вот именно, и «еще откуда-нибудь». Все существующие системы Спарк, Правобот и т.п. предоставляют какую-то информацию. Эта информация не особо-то и нужна, иногда не релевантна, а иногда вообще вводит в заблуждение. Кроме того, разрабатывать мелкие сервисы такие программные монстры не будут. Здесь и рождается ниша для IT-юристов.


  1. Xokare228
    15.06.2019 22:41

    import requests, json, os, datetime, traceback; from time import sleep
    inn = 6724005460 #инн из воздуха
    s = requests.Session()
    
    r = s.get("https://egrul.nalog.ru/index.html",
        headers={
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0",
            "Accept-Language": "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3",
            }
        )
    
    req = requests.Request(
        'POST',
        'https://egrul.nalog.ru/',
        data=b'vyp3CaptchaToken=&page=&query='+bytes(inn)+'&region=&PreventChromeAutocomplete=', # хабр почему то заменяет rеg в слове rеgion (буква е заменена на русскую) на знак ®, магия 
        headers = {
        "Host": "egrul.nalog.ru",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0",
        "Accept": "application/json, text/javascript, */*; q=0.01",
        "Accept-Language": "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3",
        "Accept-Encoding": "gzip, deflate, br",
        "Referer": "https://egrul.nalog.ru/index.html",
        "Content-Type": "application/x-www-form-urlencoded",
        "X-Requested-With": "XMLHttpRequest"
        }
        )
    
    r = s.prepare_request(req)
    r = s.send(r)
    #print(r.text)
    t = json.loads(r.text)['t']
    
    sleep(0.5)
    
    r = s.get("https://egrul.nalog.ru/search-result/"+str(t),
        headers={
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0",
            "Accept-Language": "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3",
            "Referer": "https://egrul.nalog.ru/index.html"
            }
        )
    
    #print(r.text)
    jsn = json.loads(r.text)
    
    try:
        while True:
            if jsn['status'] != 'wait': break
            sleep(0.2)
    except Exception:
        pass
    
    try:
        item = (jsn["rows"])[0]
        if str(item['tot']) != '0':
            if len(item['n']) < 50: name = str(item['n'])
            else: name = str(item['i'])
    
            name = name.replace('"',"'").replace('\\','?').replace('/','?').replace('|','¦').replace(':',';').replace('*','?').replace('?','').replace('<','«').replace('>','»')
    
            try:
                os.mkdir(name)
            except Exception:
                pass
                name = name + ' '+str(datetime.datetime.strftime(datetime.datetime.now(datetime.timezone(datetime.timedelta(hours=3))),'%x %X %Z')).replace('/','.').replace(':','-')
                os.mkdir(name)
    
            f = open(name+'\\'+name+'.txt','w+',encoding='utf-8')
            f.write('по состоянию на ' + str(datetime.datetime.strftime(datetime.datetime.now(datetime.timezone(datetime.timedelta(hours=3))),'%x %X %Z')).replace('/','.')+'\n'+str(item))
            f.close()
    
            t = item['t']
    
            r = s.get("https://egrul.nalog.ru/vyp-request/"+str(t),
                headers={
                    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0",
                    "Accept-Language": "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3",
                    "Referer": "https://egrul.nalog.ru/index.html"
                    }
                )
            sleep(0.5)
            while True:
                r = s.get("https://egrul.nalog.ru/vyp-status/"+str(t),
                    headers={
                        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0",
                        "Accept-Language": "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3",
                        "Referer": "https://egrul.nalog.ru/index.html"
                        }
                    )
                st = json.loads(r.text)['status']
                if st == 'ready': break
                sleep(0.5)
    
            r = s.get("https://egrul.nalog.ru/vyp-download/"+str(t),
                    headers={
                        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0",
                        "Accept-Language": "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3",
                        "Referer": "https://egrul.nalog.ru/index.html"
                        }
                    )
    
            #print(r.text)
    
            f = open(name+'\\'+name+' выписка.pdf','wb+')
            f.write(r.content)
            f.close()
    
    except Exception as e:
        print(e)
        traceback.print_exc()
        pass

    Капча, обработка jsona с ответом и всякое такое в сделку не входит, но дописывается просто