Python чтение pdf файлов

Чтение, извлечение и разделение страниц в PDF-файлах Python

Сегодня Portable Document Format (PDF) относится к наиболее часто используемым форматам данных. В 1990 году структура документа PDF была определена компанией Adobe. Идея формата PDF заключается в том, что передаваемые данные и документы выглядят одинаково для обеих сторон, участвующих в процессе коммуникации – создателя, автора или отправителя и получателя. PDF является преемником формата PostScript и стандартизирован как ISO 32000-2: 2017.

Обработка PDF-документов

Для Linux доступны мощные инструменты командной строки, такие как pdftk и pdfgrep. Как разработчик, с огромным энтузиазмом создает собственное программное обеспечение, основанное на Python и использующее библиотеки PDF, которые находятся в свободном доступе.

Эта статья – начало небольшой серии, в которой будут рассмотрены эти полезные библиотеки Python. В ней мы сосредоточимся на работе с существующими PDF-файлами. Вы узнаете, как читать и извлекать содержимое (как текст, так и изображения), вращать отдельные страницы и разбивать документы на отдельные страницы.

Инструменты и библиотеки

  • PyPDF2: библиотека Python для извлечения информации и содержимого документа, разделения документов по страницам, объединения документов, обрезки страниц и добавления водяных знаков. PyPDF2 поддерживает как незашифрованные, так и зашифрованные документы.
  • PDFMiner: полностью написан на Python и хорошо работает с Python 2.4. Для Python 3 используйте клонированный пакет PDFMiner.six. Оба пакета позволяют анализировать и конвертировать PDF-документы. Это включает поддержку PDF 1.7, а также языков CJK (китайский, японский и корейский) и различных типов шрифтов (Type1, TrueType, Type3 и CID).
  • PDFQuery: он описывает себя как «быструю и удобную библиотеку для парсинга PDF», которая реализована как оболочка для PDFMiner, lxml и pyquery. Его цель дизайна – «надежно извлекать данные из наборов PDF-файлов с минимальным количеством кода».
  • tabula-py: это простая оболочка Python для tabula-java, которая может читать таблицы из PDF-файлов и преобразовывать их в Pandas DataFrames. Он также позволяет конвертировать файл PDF в файл CSV/TSV/JSON.
  • pdflib для Python: расширение библиотеки Poppler, которое предлагает для него привязки Python. Он позволяет анализировать и конвертировать PDF-документы. Не путать с его коммерческим кулоном с таким же названием.
  • PyFPDF: библиотека для создания PDF-документов на Python. Портировано из библиотеки FPDF PHP, хорошо известного замены расширения PDFlib с множеством примеров, скриптов и производных.
  • PDFTables: коммерческий сервис, предлагающий извлечение из таблиц в виде PDF-документа. Предлагает API, позволяющий использовать PDFTables, как SAAS.
  • PyX – графический пакет Python: PyX – это пакет Python для создания файлов PostScript, PDF и SVG. Он сочетает в себе абстракцию модели рисования PostScript с интерфейсом TeX или LaTeX. На основе этих примитивов строятся сложные задачи, такие как создание 2D- и 3D-графиков в готовом для публикации качестве.
  • ReportLab: амбициозная промышленная библиотека, в основном ориентированная на точное создание PDF-документов. Доступно бесплатно, как версия с открытым исходным кодом, а также как коммерческая расширенная версия под названием ReportLab PLUS.
  • PyMuPDF (также известный как «fitz»): привязки Python для MuPDF, который представляет собой легкую программу просмотра PDF и XPS. Библиотека может получить доступ к файлам в форматах PDF, XPS, OpenXPS, epub, и она известна своей высочайшей производительностью и высоким качеством рендеринга.
  • pdfrw: синтаксический анализатор PDF на чистом Python для чтения и записи PDF. Он точно воспроизводит векторные форматы без растеризации. В сочетании с ReportLab он помогает повторно использовать части существующих PDF-файлов в новых PDF-файлах, созданных с помощью ReportLab.
Читайте также:  Load html on canvas

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

Извлечение текста с помощью PyPDF2

PyPDF2 можно установить как обычный программный пакет или с помощью pip3 (для Python3). Тесты здесь основаны на пакете для предстоящего выпуска Debian GNU или Linux 10 «Buster». Имя пакета Debian – python3-pypdf2.

В примере 1 сначала импортируется класс PdfFileReader. Затем, используя этот класс, он открывает документ и извлекает информацию о документе с помощью метода getDocumentInfo(), количество страниц с помощью getDocumentInfo() и содержимое первой страницы.

Обратите внимание, что PyPDF2 начинает подсчет страниц с 0, и поэтому вызов pdf.getPage (0) возвращает первую страницу документа. В конце концов, извлеченная информация выводится на стандартный вывод.

#!/usr/bin/python from PyPDF2 import PdfFileReader pdf_document = "example.pdf" with open(pdf_document, "rb") as filehandle: pdf = PdfFileReader(filehandle) info = pdf.getDocumentInfo() pages = pdf.getNumPages() print (info) print ("number of pages: %i" % pages) page1 = pdf.getPage(0) print(page1) print(page1.extractText())

Извлечение информации и содержимого документа

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

С помощью PyMuPDF

PyMuPDF доступен на веб-сайте PyPi, и вы устанавливаете пакет с помощью следующей команды в терминале:

Отображение информации о документе, печать количества страниц и извлечение текста из PDF-документа выполняется аналогично PyPDF2 (см. пример 2). Импортируемый модуль называется fitz и восходит к предыдущему имени PyMuPDF.

#!/usr/bin/python import fitz pdf_document = "example.pdf" doc = fitz.open(pdf_document): print ("number of pages: %i" % doc.pageCount) print(doc.metadata) page1 = doc.loadPage(0) page1text = page1.getText("text") print(page1text)

Преимущество PyMuPDF заключается в том, что он сохраняет неизменной исходную структуру документа – целые абзацы с разрывами строк сохраняются, как и в документе PDF .

Извлеченные текстовые данные

С помощью PyMuPDF

PyMuPDF упрощает извлечение изображений из документов PDF с помощью метода getPageImageList(). Пример 3 основан на примере вики-страницы PyMuPDF и извлекает и сохраняет все изображения из PDF-файла в виде файлов PNG на постраничной основе. Если изображение имеет цветовое пространство CMYK, оно сначала будет преобразовано в RGB.

#!/usr/bin/python import fitz pdf_document = fitz.open("file.pdf") for current_page in range(len(pdf_document)): for image in pdf_document.getPageImageList(current_page): xref = image[0] pix = fitz.Pixmap(pdf_document, xref) if pix.n < 5: # this is GRAY or RGB pix.writePNG("page%s-%s.png" % (current_page, xref)) else: # CMYK: convert to RGB first pix1 = fitz.Pixmap(fitz.csRGB, pix) pix1.writePNG("page%s-%s.png" % (current_page, xref)) pix1 = None pix = None

Запустив этот скрипт Python на 400-страничном PDF-файле, он извлек 117 изображений менее чем за 3 секунды, что удивительно. Отдельные изображения хранятся в формате PNG. Чтобы сохранить исходный формат и размер изображения, вместо преобразования в PNG ознакомьтесь с расширенными версиями скриптов в вики PyMuPDF.

Извлеченные изображения

Разделение PDF-файлов на страницы с помощью PyPDF2

В этом примере сначала необходимо импортировать классы PdfFileReader и PdfFileWriter. Затем мы открываем PDF-файл, создаем объект-читатель и просматриваем все страницы в цикле, используя метод getNumPages объекта-читателя.

Внутри цикла for мы создаем новый экземпляр PdfFileWriter, который пока не содержит никаких страниц. Затем мы добавляем текущую страницу к нашему объекту записи, используя метод pdfWriter.addPage(). Этот метод принимает объект страницы, который мы получаем с помощью метода PdfFileReader.getPage().

Следующим шагом является создание уникального имени файла, что мы делаем, используя исходное имя файла плюс слово «страница» плюс номер страницы. Мы добавляем 1 к текущему номеру страницы, потому что PyPDF2 считает номера страниц, начиная с нуля.

Наконец, мы открываем новое имя файла в режиме «двоичной записи» (режим wb) и используем метод write() класса pdfWriter для сохранения извлеченной страницы на диск.

#!/usr/bin/python from PyPDF2 import PdfFileReader, PdfFileWriter pdf_document = "example.pdf" pdf = PdfFileReader(pdf_document) for page in range(pdf.getNumPages()): pdf_writer = PdfFileWriter current_page = pdf.getPage(page) pdf_writer.addPage(current_page) outputFilename = "example-page-<>.pdf".format(page + 1) with open(outputFilename, "wb") as out: pdf_writer.write(out) print("created", outputFilename)

Разбиение PDF-файла

Найти все страницы, содержащие текст

Этот вариант использования весьма практичен и работает аналогично pdfgrep. Используя PyMuPDF, скрипт возвращает все номера страниц, которые содержат заданную строку поиска. Страницы загружаются одна за другой, и с помощью метода searchFor() обнаруживаются все вхождения строки поиска. В случае совпадения соответствующее сообщение выводится на стандартный вывод.

#!/usr/bin/python import fitz filename = "example.pdf" search_term = "invoice" pdf_document = fitz.open(filename): for current_page in range(len(pdf_document)): page = pdf_document.loadPage(current_page) if page.searchFor(search_term): print("%s found on page %i" % (search_term, current_page))

На рисунке 5 ниже показан результат поиска по запросу «Debian GNU или Linux» в 400-страничной книге.

 Разбиение PDF-файла

Заключение

Показанные здесь методы довольно мощные. Благодаря сравнительно небольшому количеству строк кода легко получить результат.

Источник

Оцените статью