Извлечение таблиц из pdf с помощью camelot
На сайте Newtechaudit.ru описывались различные способы извлечения таблиц с данными из pdf-файлов в excel. В частности, с помощью python-библиотеки camelot (как здесь).
Рассмотрим расширенные возможности camelot, позволяющие распознать большую таблицу со сложной структурой. А также покажем, как использовать библиотеку PyMuPDF в качестве бэкэнда для конвертации pdf в png.
Следует учесть, что сamelot может распознавать только так называемые text-based pdf файлы. То есть те, внутри которых можно выделять текст. Если pdf является сканом, то camelot не сработает.
Установка библиотек на примере pip:
pip install PyMuPDF
pip install "camelot-py[base]"
Файл-пример, который будем использовать, содержит одну таблицу, умещенную на двух страницах. Она содержит данные с kaggle о продажах в кофейне:
Не стоит искать какой-то смысл в содержании данной таблицы, это просто пример. Важно лишь то, что в ней много объединенных ячеек, и она занимает почти всю площадь страницы. Приступим к ее извлечению.
Импорт библиотек
import pandas as pd
import camelot
# Так импортируется PyMuPDF
import sys, fitz
Конвертация pdf в картинку
Camelot определяет границы и структуру таблицы с помощью распознавания линий. Для этого используется бэкенд, конвертирующий pdf в картинку. В качестве бэкенда можно использовать ghostscript или poppler. Но они требуют установки дополнительных зависимостей и ПО, что не очень удобно. Можно обойтись еще одним вариантом бэкенда – написать свой собственный, используя PyMuPDF. Для этого напишем специальный класс:
class ConversionBackend(object):
def convert(self, pdf_path, png_path):
# Открываем документ
doc = fitz.open(pdf_path)
for page in doc.pages():
# Переводим страницу в картинку
pix = page.get_pixmap()
# Сохраняем
pix.save(png_path)
Извлечение таблицы из файла
Вся основная работа производится в функции read_pdf(). В ней присутствует множество параметров, которые указываются в зависимости от исходных данных и требуемого результата. В нашем случае установим следующие параметры (далее будет описано, почему именно такие):
file = 'TableExampleCoffeshop.pdf'
tables = camelot.read_pdf(file,
backend=ConversionBackend(),
strip_text='\n',
line_scale=40,
pages='all',
copy_text=['h'],)
Распознанные таблицы получили в виде списка объектов camelot.core.Table. В списке две таблицы по количеству страниц.
Посмотрим первую таблицу в формате датафрейма:
tables[0].df
У camelot также есть полезная функция визуализации распознанных элементов на разных уровнях. Это позволяет понять, какие параметры лучше подкорректировать в случае ошибок. Убедимся, что линии таблицы и области с текстом были определены верно:
camelot.plot(tables[0], kind=’grid’).show()
camelot.plot(tables[0], kind=’text’).show()
Получим итоговую таблицу и сохраним ее в excel файл:
whole_table = pd.concat([tables[0].df, tables[1].df])
whole_table.to_excel('ResultTableCoffee.xlsx', index=False, header=False)
Взглянем на результат:
Все данные успешно перенесены в excel.
Параметры функции read_pdf
Итак, что же там с параметрами? С файлом и бэкендом понятно, но что означают все остальные?
• strip_text
Удаляет лишние символы из распознанного текста. Если бы мы не указали ‘\n’, то текст бы выглядел так:
• line_scale
Позволяет определять более короткие линии таблицы. Чем больше данный коэффициент, тем меньше размер наименьшей обнаруживаемой линии. Если бы оставили значение по умолчанию, то в третьем столбце с конца Coffee слилось бы с Tea:
• pages
Страницы, с которых нужно считать информацию. Если нужно извлечь конкретные страницы, пишем их через запятую. Например, ‘1, 3’.
• copy_text=['h']
Позволяет копировать текст в объединенных ячейках. Символы h и v обозначают копирование в горизонтальном и вертикальном направлениях соответственно. В нашем случае заголовок Criteria скопировался на все три объединенные ячейки благодаря этому параметру. Остальные пустые клетки заполнять не стали, чтобы наглядно видеть соответствие полученного excel файла исходному pdf.
• shift_text
Указывает, где расположить текст в объединенных ячейках. Значение по умолчанию — [‘l’, ‘t’], то есть в левой верхней части. Если бы поставили значение [»], то есть оставили текст там, где он был в оригинале, то заголовки определились бы как отдельные строки. К тому же, было бы сложно определить, к каким строчкам относятся значения столбцов Criteria, так как они бы «висели в воздухе», как на примере ниже:
Итоги
Нам удалось корректно извлечь таблицу из pdf в excel с помощью camelot и PyMuPDF. Мы использовали собственный легкий бэкенд для функции read_pdf(), рассмотрели основные настраиваемые параметры, а также функцию для визуализации результата распознавания таблицы.
В данном материале рассмотрен только один из способов использования библиотеки camelot. Другие ее возможности можно посмотреть по ссылке. Спасибо за внимание!
https://t.me/python_job_interview