В настоящее время весьма актуальной темой остается возможность налогового органа исключить из ЕГРЮЛ общество всего лишь ”выявив” в отношении компании так называемые недостоверные сведения. Как показывает статистика с сентября 2018 года ФНС исключила из ЕГРЮЛ 90 тысяч организаций с записью о недостоверности сведений о руководителе, учредителе или адресе юрлица. Обнаружить тот факт, что в отношении компании имеются недостоверные сведения можно лишь просмотрев выписку из ЕГРЮЛ.

Выглядит это примерно следующим образом:



Проблема усугубляется тем, что данные о недостоверности могут появиться как по заявлению заинтересованного лица так и “сами по себе”, в результате действий налогового органа. Чтобы обезопасить себя от внезапного вылета из ЕГРЮЛ выписки требуется получать регулярно. Как это делать быстро и безболезненно при наличии в холдинге большого количества компаний, мы разобрали в предыдущем посте.

В этот раз разберем как искать сведения о недостоверности в выписках ЕГРЮЛ.

Будем считать, что у нас имеется n-е количество выписок, которые мы скачали с сайта ФНС. Выписки имеют расширение .pdf и какие-то наименования.

Все, что от нас требуется это осуществить поиск по слову “недост” в каждом pdf файле.

Открывать каждый pdf файл с выпиской и производить поиск не наш метод. Это может занять избыточно много времени. Можно склеить все файлы в Abbyy Finereader, но это тоже займет достаточно времени.

Напишем программу, которая склеит все pdf файлы в один. Python позволяет это сделать за секунды!

В дальнейшем мы сможем открыть созданный файл и провести поиск по требуемому слову сразу по всем выпискам из ЕГРЮЛ.

Начнем.

*Выписки из ЕГРЮЛ у нас находятся в директории С:\1.
В новом файле python импортируем модули для работы с pdf и системой в целом:

import PyPDF2, os

Далее создаем пустой список и перемещаемся в директорию C:\1, в которой будут находиться все наши выписки.

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

pdfFiles = []
os.chdir('C:\\1')
for filename in os.listdir('.'):
    if filename.endswith('.pdf'):
        pdfFiles.append(filename)
pdfFiles.sort()

Следующий блок склеивает выписки между собой, добавляя каждую последующую выписку в конец:

pdfWriter = PyPDF2.PdfFileWriter()
# Loop through all the PDF files.
for filename in pdfFiles:
    pdfFileObj = open(filename, 'rb')
    pdfReader = PyPDF2.PdfFileReader(pdfFileObj)

    # Loop through all the pages and add them.
    for pageNum in range(0, pdfReader.numPages):
        pageObj = pdfReader.getPage(pageNum)
        pdfWriter.addPage(pageObj)

Осталось только сохранить результат:

pdfOutput = open('all.pdf', 'wb')
pdfWriter.write(pdfOutput)
pdfOutput.close()

Итак, после работы программы, мы получили файл all.pdf, по которому уже можно искать требуемую информацию о недостоверности сведений.

Скачать программу для склейки pdf в один – здесь.

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


  1. alexsibtone
    14.06.2019 10:14

    Да, сшивание отдельных PDF в один не всегда тривиальная задача. Размер исходного файла может оказаться больше суммы отдельных PDF-ок. Меня выручил GhostScript:

    gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=out.pdf  *.pdf

    p.s. Интересно, дальше вы с помощью inkscape перегоните PDF в SVG и в нем как в текстовом файле ищете слово “недост”?


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

      мне стыдно это признать, но дальше я ищу в общем файле pdf через CTRL+F. перегон с помощью Python из pdf в csv ничего толком не дает, т.к. даже если слово «недост» есть, нельзя понять к какому обществу это относится (понять можно на самом деле, но адреса полей в csv разные каждый раз). Кроме того, «недост» присутствуют в выписках после исправлений сведений о недостоверности в налоговой (так называемая история исправлений), что так же путает.


      1. 402d
        14.06.2019 10:57

        смотрите. Упрощение справедливо для pdf, которые программисты генерируют в виде
        отчетов.
        PDF — стопка картинок (листов)
        лист — картинка в формате PostScript
        PostScript — черепашья графика.

        Программисты ленивы.

        Значит будет общая шапка
        Цикл из повторяющихся команд на каждую строку.
        В строке 2 команды выведи текст.
        первая — заголовок. 2- значение.

        Берете к питону либу для работы с пдф.
        Получаете дерево или список. Ближайший аналог Dom в html.
        находите нужные пары.
        Возможно они кодированные. Не страшно.

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



  1. 402d
    14.06.2019 10:35

    Внутрь PDFок смотрели?
    Может у Вас один из частных случаев, когда текст можно относительно
    легко извлечь?
    а) он лежит как plain
    б) декодируется до plain с первого прохода.
    так как исходные pdf — это отчеты из системы, там не может быть извращений, которые
    встречаются после того как word сконвертировали в PDF через печать в файл.


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

      а зачем конвертировать? на мой взгляд, самый быстрый способ тот, что в посте.
      на счет plain не уверен, но вот, можете проверить — пример выписки.


      1. 402d
        14.06.2019 11:27

        признаю ошибку. кол-во документов, которое нужно анализировать.
        затраты на автоматизацию. тут идеально.
        Я сейчас пробежался по гиту. Такого чтобы легко распарсело pdf нет.
        Есть платные либы. Стартуют от 200 баксов.
        Так что или тут неделя своего времени(если с форматом совсем не знакомы) или деньги, чтобы сделать лучше.


        1. zoldaten Автор
          14.06.2019 11:41

          у меня есть реализация такого плана. все выписки перегоняются из pdf в csv сторонней программой, потом они сравниваются построчно с самими собой месячной давности (либо более ранними). такая типа ретроспектива изменений в егрюл. но вряд ли это интересно.


          1. saw_tooth
            14.06.2019 13:23

            Опять городите велосипед
            Не хочу показаться оскорбительным, но Вы и законы так используете в работе, не понимая что они делают и где их действительно нужно использовать?
            pdfFileObj = open(filename, 'rb')
            pdfOutput = open('all.pdf', 'wb')

            Так писать ненужно, для работы с файлами есть контекстные менеджеры.
            Loop through all the pages and add them.
            for pageNum in range(0, pdfReader.numPages):
            pageObj = pdfReader.getPage(pageNum)
            pdfWriter.addPage(pageObj)

            Вы же понимаете, что при достаточном количестве выписок, Вы просто выжрете всю память, более того — поиск по огромному документу — процесс длительный.


            1. zoldaten Автор
              14.06.2019 14:52

              Спасибо про «Велосипед...», я читал статью ранее. Она про извлечение данных из pdf. Здесь мы склеиваем pdfы и ищем по ним. Все просто. Не всегда надо собирать велосипед, чтобы поехать.
              Про использование памяти я вас не совсем понимаю. Если программу заряжать по всем выпискам из ЕГРЮЛ, возможно она и подвесит комп. Но я обрабатываю порядка 300-400 выписок, все выполняется за секунды.
              p.s. про законы действительно обидно прозвучало. напишите свой первый иск, а я потренируюсь в иронии.


  1. Nfan
    17.06.2019 09:05

    Как альтернатива:

    gitlab.com/pdfgrep/pdfgrep
    Работает почти как grep, как можно догадаться по названию :)

    pdfgrep -Rin недост

    Найдет все упоминанию фразы во всех pdf, включая в подпапках (-R), игнорируя кейс (-i), и указав номер страницы (-n)

    Для склейки есть pdfunite в составе пакета poppler:
    pdfunite *.pdf all.pdf

    Главное не забыть all.pdf, а то перепишет последний файл :)


    1. zoldaten Автор
      17.06.2019 09:07

      спасибо. но пока не пересесть никак на unix. или есть для windows?


  1. pantlmn
    18.06.2019 00:28

    Я бы сделал это в OS X парой команд:

    ls -1 *.pdf | while read line; do pdftotext -layout "$line" "$line.txt"; done
    rg -t txt "недостоверн"