Выглядит это примерно следующим образом:
Проблема усугубляется тем, что данные о недостоверности могут появиться как по заявлению заинтересованного лица так и “сами по себе”, в результате действий налогового органа. Чтобы обезопасить себя от внезапного вылета из ЕГРЮЛ выписки требуется получать регулярно. Как это делать быстро и безболезненно при наличии в холдинге большого количества компаний, мы разобрали в предыдущем посте.
В этот раз разберем как искать сведения о недостоверности в выписках ЕГРЮЛ.
Будем считать, что у нас имеется 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)
402d
14.06.2019 10:35Внутрь PDFок смотрели?
Может у Вас один из частных случаев, когда текст можно относительно
легко извлечь?
а) он лежит как plain
б) декодируется до plain с первого прохода.
так как исходные pdf — это отчеты из системы, там не может быть извращений, которые
встречаются после того как word сконвертировали в PDF через печать в файл.
zoldaten Автор
14.06.2019 10:52а зачем конвертировать? на мой взгляд, самый быстрый способ тот, что в посте.
на счет plain не уверен, но вот, можете проверить — пример выписки.402d
14.06.2019 11:27признаю ошибку. кол-во документов, которое нужно анализировать.
затраты на автоматизацию. тут идеально.
Я сейчас пробежался по гиту. Такого чтобы легко распарсело pdf нет.
Есть платные либы. Стартуют от 200 баксов.
Так что или тут неделя своего времени(если с форматом совсем не знакомы) или деньги, чтобы сделать лучше.zoldaten Автор
14.06.2019 11:41у меня есть реализация такого плана. все выписки перегоняются из pdf в csv сторонней программой, потом они сравниваются построчно с самими собой месячной давности (либо более ранними). такая типа ретроспектива изменений в егрюл. но вряд ли это интересно.
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)
Вы же понимаете, что при достаточном количестве выписок, Вы просто выжрете всю память, более того — поиск по огромному документу — процесс длительный.zoldaten Автор
14.06.2019 14:52Спасибо про «Велосипед...», я читал статью ранее. Она про извлечение данных из pdf. Здесь мы склеиваем pdfы и ищем по ним. Все просто. Не всегда надо собирать велосипед, чтобы поехать.
Про использование памяти я вас не совсем понимаю. Если программу заряжать по всем выпискам из ЕГРЮЛ, возможно она и подвесит комп. Но я обрабатываю порядка 300-400 выписок, все выполняется за секунды.
p.s. про законы действительно обидно прозвучало. напишите свой первый иск, а я потренируюсь в иронии.
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, а то перепишет последний файл :)
pantlmn
18.06.2019 00:28Я бы сделал это в OS X парой команд:
ls -1 *.pdf | while read line; do pdftotext -layout "$line" "$line.txt"; done rg -t txt "недостоверн"
alexsibtone
Да, сшивание отдельных PDF в один не всегда тривиальная задача. Размер исходного файла может оказаться больше суммы отдельных PDF-ок. Меня выручил GhostScript:
p.s. Интересно, дальше вы с помощью inkscape перегоните PDF в SVG и в нем как в текстовом файле ищете слово “недост”?
zoldaten Автор
мне стыдно это признать, но дальше я ищу в общем файле pdf через CTRL+F. перегон с помощью Python из pdf в csv ничего толком не дает, т.к. даже если слово «недост» есть, нельзя понять к какому обществу это относится (понять можно на самом деле, но адреса полей в csv разные каждый раз). Кроме того, «недост» присутствуют в выписках после исправлений сведений о недостоверности в налоговой (так называемая история исправлений), что так же путает.
402d
смотрите. Упрощение справедливо для pdf, которые программисты генерируют в виде
отчетов.
PDF — стопка картинок (листов)
лист — картинка в формате PostScript
PostScript — черепашья графика.
Программисты ленивы.
Значит будет общая шапка
Цикл из повторяющихся команд на каждую строку.
В строке 2 команды выведи текст.
первая — заголовок. 2- значение.
Берете к питону либу для работы с пдф.
Получаете дерево или список. Ближайший аналог Dom в html.
находите нужные пары.
Возможно они кодированные. Не страшно.
А в общем случае проблема в том, что вхождение текстовых элементов возможно
в любом порядке. строчка из подвала например стоит до шапки (у нее просто координаты другие).
homecreate
Ещё есть pdfunite (http://manpages.ubuntu.com/manpages/bionic/man1/pdfunite.1.html).