Camelot извлекает таблицы из PDF в структуры pandas, помогает выбрать подходящий анализатор для таблиц с линиями и без них, показывает качество распознавания и сохраняет результат в CSV, Excel, JSON, HTML, Markdown или SQLite.
Работа строится вокруг вызова camelot.read_pdf(): вы задаёте входной документ, страницы и метод поиска таблиц, а затем получаете коллекцию TableList. В ней каждая найденная область представлена объектом Table с готовым DataFrame, номером страницы, порядком на странице и показателями качества. Для проверки результата предусмотрены диагностические графики текста, линий, узлов сетки, контуров и областей, которые алгоритм считает таблицами.
Главная практическая задача — не просто получить набор ячеек, а подобрать режим под структуру конкретного PDF. Таблицы с явными границами обычно разбирают через lattice, колонки, разделённые пробелами, — через stream, выравнивания текста без полной сетки — через network, а смешанную разметку — через hybrid. Для сложных страниц и сканов можно подключить модельный анализ и OCR, после чего отфильтровать слабые результаты по точности, доле пустых ячеек и интегральной уверенности.
Скачать Camelot
- Редактирование PDF
- Русский интерфейс
- Просто новичкам
- Нужны навыки Python
- OCR требует доппакетов
- Нет ручного GUI
Как устроен рабочий процесс
Типовой сценарий начинается с проверки того, содержит ли PDF текстовый слой. Если текст выделяется и копируется, сначала имеет смысл попробовать обычные анализаторы: они быстрее модельного режима и сохраняют символы непосредственно из документа. Если страница состоит из изображения, нужен режим ml с OCR. Смешанные файлы, где часть страниц цифровая, а часть отсканирована, лучше обрабатывать диапазонами: это позволяет не запускать распознавание там, где текст уже доступен.
Вызов без параметра pages анализирует первую страницу. Это безопасное поведение для пробы, но частая причина неполного результата при пакетной обработке. Для всего документа указывают pages="all", для отдельных страниц — строку с номерами и диапазонами, например "1,3-6,10". Такой синтаксис удобно строить автоматически после предварительного просмотра оглавления или после проверки страниц, на которых реально встречаются таблицы.
import camelot
tables = camelot.read_pdf(
"report.pdf",
pages="1,3-6",
flavor="auto",
)
print(tables)
for table in tables:
print(table.page, table.order, table.shape)
print(table.parsing_report)
Режим auto сначала оценивает устройство таблиц на первой выбранной странице и выбирает между анализом линий и анализом текстовых выравниваний. Это удобно для однородных отчётов, но не заменяет ручной выбор при смешанной верстке. Если на первой странице есть строгая сетка, а дальше идут таблицы без границ, один автоматически выбранный метод может пропустить часть данных. В таких документах диапазоны следует запускать отдельно и затем объединять результаты.
Что возвращает read_pdf
read_pdf() возвращает TableList, который ведёт себя как последовательность: поддерживает длину, индексацию, срезы и перебор. Это упрощает интеграцию с обычным кодом Python, потому что найденные таблицы можно сортировать, фильтровать и передавать в функции без промежуточного сохранения. Внутри списка таблицы идут в порядке страниц и расположения на странице, а атрибут order помогает отличать несколько областей на одном листе.
Главное содержимое объекта Table находится в свойстве df. Это pandas.DataFrame, поэтому к нему применимы переименование столбцов, приведение типов, удаление пустых строк, объединение по ключам, контроль пропусков и экспорт средствами pandas. Дополнительно доступны размеры таблицы, координаты найденной области, матрица ячеек и служебная информация, полезная при отладке неверного деления строк или колонок.
parsing_report содержит точность и долю пустого пространства. Точность показывает, насколько уверенно текстовые фрагменты распределены по ячейкам, а whitespace отражает процент пустых ячеек. Высокая точность не гарантирует правильную семантику заголовков: алгоритм может аккуратно разложить данные по сетке, но оставить много пустых столбцов или принять примечание за отдельную строку. Поэтому метрики нужно сочетать с проверками структуры.
table = tables[0]
df = table.df
assert table.accuracy >= 90
assert table.whitespace <= 35
assert df.shape[1] == 7
assert df.iloc[:, 0].str.strip().ne("").mean() > 0.9
В дополнение к двум базовым показателям объект предоставляет confidence. Значение рассчитывается из точности и доли пустых ячеек, поэтому быстрее отделяет аккуратно заполненные таблицы от областей, где алгоритм нашёл много геометрии, но мало полезных данных. Порог около 0,8 подходит как отправная точка, однако для форм с намеренно пустыми полями его следует снижать, иначе корректные шаблоны будут ошибочно отброшены.
Фильтрация результатов
Метод TableList.filter() создаёт новый список без изменения исходного. Можно задать минимальное число строк и столбцов, нижний предел точности и верхний предел пустых ячеек. Такая фильтрация полезна после обработки длинного отчёта, где рядом с таблицами встречаются колонтитулы, маленькие легенды и рамки из одной строки. Геометрически они похожи на таблицу, но не проходят структурный порог.
clean = tables.filter(
min_rows=3,
min_columns=2,
min_accuracy=88,
max_whitespace=45,
)
for table in clean:
if table.confidence < 0.75:
continue
process(table.df)
Пороговые значения стоит подбирать на нескольких типичных документах, а не на одном удачном файле. Для отчётности с плотными цифровыми таблицами допустимо требовать высокую точность и малую пустоту. Для расписаний, анкет и форм с объединёнными ячейками доля пустого пространства закономерно выше. Практичный подход — сохранять метрики рядом с выгрузкой и отдельно просматривать случаи, которые находятся в пограничной зоне.
Выбор анализатора
Все методы решают одну задачу, но опираются на разные признаки. Ошибка выбора обычно проявляется раньше, чем тонкая ошибка параметров: таблица вообще не находится, несколько колонок склеиваются или, наоборот, каждое слово превращается в отдельную ячейку. Поэтому сначала определяют визуальный тип таблицы, затем выбирают анализатор и только после этого настраивают допуски.
latticeищет горизонтальные и вертикальные линии, их пересечения и замкнутые контуры. Он подходит для бланков, ведомостей и отчётов с нарисованной сеткой.streamстроит строки из близких текстовых фрагментов и выводит границы колонок из повторяющихся промежутков. Он полезен для таблиц без линий.networkиспользует выравнивания текста по координатам, формирует сеть связей и расширяет найденную область по устойчивым горизонтальным и вертикальным совпадениям.hybridсовмещает преимущества анализа линий и текстовой сети, когда часть границ нарисована, а часть выражена только выравниванием.mlприменяет модель определения структуры и при необходимости OCR, поэтому способен работать со сканами и сложной визуальной разметкой.autoвыбирает базовый метод для однородного набора страниц и сокращает число пробных запусков.
Проверка должна опираться не только на внешний вид страницы. Тонкие линии иногда представлены не векторными объектами, а растровым фоном; наоборот, визуально цельная рамка может состоять из множества коротких сегментов. Диагностические графики показывают, какие элементы действительно увидел алгоритм, и помогают понять, менять ли метод, движок рендеринга или геометрические допуски.
Таблицы с явной сеткой: lattice
lattice преобразует страницу в изображение, выделяет линии морфологическими операциями, находит их пересечения и переносит координаты обратно в систему PDF. После этого текстовые фрагменты распределяются по построенным ячейкам. Метод устойчив к большим пробелам внутри текста и к разной ширине колонок, если границы ячеек действительно видимы.
Ключевой параметр line_scale управляет минимальной длиной линий, которые считаются элементами сетки. Увеличение значения позволяет обнаружить короткие сегменты, но чрезмерное увеличение опасно: штрихи букв, подчёркивания и тонкие элементы шрифта начинают восприниматься как линии. Если таблица разбивается на множество ложных ячеек, line_scale следует уменьшить или ограничить область поиска.
Параметры line_tol и joint_tol отвечают за объединение близких отрезков и допустимое отклонение пересечений. Первый помогает, когда линия разорвана на небольшие части или имеет микроскопические промежутки. Второй влияет на то, будут ли горизонтальный и вертикальный сегменты признаны узлом сетки. Слишком большие допуски объединяют соседние границы и могут создавать ячейки, которых нет в документе.
Для линий, нарисованных светлым цветом или находящихся под текстом, полезен process_background=True. Без него анализ ориентируется прежде всего на основные объекты переднего плана. После включения фоновой обработки следует сравнить число найденных таблиц и график узлов: декоративные рамки, подложки и полосы могут добавить ложную геометрию.
Пороговая обработка регулируется параметрами threshold_blocksize и threshold_constant. Они влияют на локальную бинаризацию страницы перед поиском линий. Их меняют, когда скан или экспорт из графического редактора имеет неравномерный фон, серые границы или сглаживание. Слишком агрессивный порог стирает тонкие линии, а слишком мягкий превращает шум и текст в множество объектов.
Движок обработки страницы
Параметр engine позволяет выбрать, какие представления PDF использовать для поиска сетки. Значение combined сочетает векторные сведения и растровый анализ, поэтому подходит как универсальная отправная точка. vector предпочитает геометрические объекты PDF и особенно полезен для чистых цифровых документов. raster опирается на изображение страницы и пригоден там, где линии визуально есть, но векторной структуры нет.
Если vector не находит таблицу, это не означает, что сетка отсутствует: она может быть частью фонового изображения. В таком случае сравнивают combined и raster, а затем настраивают разрешение и пороговую обработку. Обратная ситуация встречается в сложных чертежах: растровый режим захватывает слишком много визуальных деталей, тогда как векторный точнее отделяет реальные линии таблицы.
Параметр resolution задаёт разрешение рендеринга. Повышение помогает на тонких линиях и мелком тексте, но увеличивает память и время обработки. Понижение ускоряет пакетный запуск, однако короткие границы могут исчезнуть. Для длинных документов лучше сначала проверить несколько страниц в стандартном разрешении, а повышенное применять только к проблемным диапазонам.
Диагностика линий и узлов
График joint показывает пересечения, из которых строится сетка. Если на изображении видны линии, но узлов почти нет, проблема обычно связана с разрывами, допуском пересечений или слабой бинаризацией. Если узлов слишком много и они проходят по буквам, значение line_scale завышено либо область поиска включает посторонние элементы.
График line полезен для оценки направления и длины сегментов, grid показывает итоговую сетку, а contour — области, которые могут быть приняты за таблицы. Эти режимы не изменяют результат сами по себе: они дают визуальную обратную связь для настройки. После каждого изменения параметров лучше сравнивать один и тот же фрагмент страницы, иначе улучшение на новой области можно ошибочно принять за эффект настройки.
Таблицы без границ: stream
stream группирует слова в строки по вертикальным координатам, строит текстовые края и определяет устойчивые промежутки между колонками. Метод особенно эффективен в отчётах, где числа выровнены по разрядам, а заголовки расположены над группами столбцов. Для него важны реальные координаты текста: скан без OCR не содержит нужных символов и положений.
row_tol определяет, насколько близко по вертикали должны находиться текстовые фрагменты, чтобы попасть в одну строку. Если индекс, обозначение единицы или перенос строки создаёт две строки вместо одной, допуск можно увеличить. Если соседние строки сливаются, его уменьшают. Параметр особенно чувствителен к документам с плотным межстрочным интервалом.
column_tol помогает объединять или разделять фрагменты по горизонтали. При слишком малом значении число и знак процента могут оказаться в разных колонках; при слишком большом — соседние числовые столбцы объединятся. Лучше менять параметр небольшими шагами и контролировать не только число колонок, но и содержимое первых нескольких строк.
edge_tol влияет на длину текстовых краёв, используемых для поиска таблиц. Увеличение помогает обнаруживать таблицы с большими вертикальными промежутками между строками. Однако слишком большой допуск может объединить основную таблицу с подписью или примечанием ниже. В таких случаях вместе с настройкой края применяют table_regions или точные table_areas.
Ограничение области поиска
table_regions задаёт крупные зоны страницы, внутри которых Camelot должен искать таблицы. Это полезно, когда положение таблицы примерно известно, но её фактические границы меняются от страницы к странице. Например, можно исключить шапку отчёта и нижний колонтитул, оставив широкую центральную область.
table_areas задаёт точные прямоугольники. Координаты передаются строками в порядке x1,y1,x2,y2, где первая точка относится к левому верхнему углу области, а вторая — к правому нижнему. При этом система координат PDF отсчитывает начало от нижнего левого угла страницы. Ошибка в ориентации оси Y — одна из наиболее частых причин пустого результата.
tables = camelot.read_pdf(
"report.pdf",
pages="2-8",
flavor="stream",
table_areas=["45,720,555,120"],
columns=["110,205,310,405,485"],
)
Параметр columns фиксирует разделители столбцов и помогает там, где промежутки между текстом неоднозначны. Количество строк в списке columns должно соответствовать числу областей в table_areas. Если областей несколько, для каждой передают собственную строку координат. Жёсткие разделители надёжны для однотипных форм, но плохо переносятся на документы с меняющейся шириной страницы или масштабом.
header_text и footer_text позволяют использовать повторяющиеся текстовые ориентиры для границ области. Это удобнее абсолютных координат в сериях документов, где таблица немного сдвигается, но над ней и под ней сохраняются одинаковые подписи. Ориентиры должны быть достаточно уникальными, иначе совпадение с похожей фразой в основном тексте приведёт к неверному прямоугольнику.
Network и Hybrid
network ищет текстовые элементы, которые устойчиво выровнены по горизонтали или вертикали. Из совпадений строится сеть, затем удаляются связи, не поддерживающие табличную структуру, выбирается начальная ячейка и область расширяется к соседним элементам. Такой подход полезен для таблиц без полного набора линий, особенно когда колонки задаются повторяющимися левыми, правыми или центральными выравниваниями.
На смешанной странице сеть может захватывать абзацы, маркированные списки или подписи, если они образуют регулярные выравнивания. Ограничение области и фильтрация по размеру помогают убрать такие совпадения. Если заголовок таблицы шире данных, его иногда разумнее исключить из зоны поиска и добавить после извлечения программно.
hybrid объединяет сведения о линиях и текстовых выравниваниях. Он полезен для форм, где рамка и часть разделителей нарисованы, а внутренние колонки существуют только за счёт положения текста. Однако гибридный анализ не гарантирует правильного результата при любой верстке: конфликтующие признаки могут создавать лишние границы. Диагностика сетки и текста остаётся обязательной.
При выборе между stream, network и hybrid стоит сравнить не только число найденных таблиц, но и стабильность схемы на нескольких страницах. Метод, который выдаёт одинаковое число колонок и предсказуемые заголовки на всём диапазоне, обычно предпочтительнее метода с немного более высокой точностью на одной странице.
Модельный режим и OCR
ml использует модель определения таблиц и их структуры. Он нужен для страниц, где геометрические правила дают нестабильный результат: сложная визуальная верстка, вложенные заголовки, частично разрушенные границы или растровое изображение. Для цифрового PDF текст может быть взят из самой страницы, а для скана подключается OCR.
Модельные зависимости устанавливаются отдельно, потому что включают крупные библиотеки и веса. Для распознавания изображения нужен дополнительный набор OCR-зависимостей. Это влияет на размер окружения, время установки и требования к памяти. В производственном процессе разумно держать базовый и модельный контуры отдельно: обычные отчёты обрабатывать лёгкими методами, а сложные страницы отправлять в более дорогой маршрут.
OCR добавляет ошибки, которых нет при чтении текстового слоя: похожие символы, потеря десятичных разделителей, смешение кириллицы и латиницы, неверные минусы и проценты. Поэтому после распознавания обязательны проверки типов, диапазонов и контрольных сумм. Для финансовой таблицы можно сверять итог строки с суммой позиций, а для расписания — допустимые часы и последовательность дат.
Модель определяет структуру, но не заменяет предметную валидацию. Даже визуально правдоподобная таблица может иметь сдвинутый заголовок или объединённую колонку. Полезно сохранять страницу или координаты области вместе с данными, чтобы оператор мог быстро открыть проблемное место и сопоставить его с выгрузкой.
Очистка текста внутри ячеек
split_text=True пытается разнести текст, который пересекает границы нескольких ячеек. Параметр помогает, когда PDF хранит строку одним объектом, хотя визуально она проходит через несколько колонок. После разделения следует проверить слова с пробелами и сложные заголовки: геометрическое деление не всегда совпадает с логическими границами.
flag_size=True отмечает фрагменты с заметно меньшим размером шрифта специальными маркерами. Это позволяет сохранить надстрочные индексы, сноски и обозначения степеней, а затем обработать их отдельно. Вместо потери символа пользователь получает явный признак, который можно преобразовать в Markdown, HTML или отдельный столбец примечаний.
strip_text удаляет заданные символы при формировании ячеек. Он удобен для переводов строк, лишних пробелов и повторяющихся служебных знаков. Важно учитывать тип значения: строка трактуется как набор отдельных символов, а список позволяет задавать целые подстроки. Если нужно удалить конкретное слово или последовательность, безопаснее использовать список, чтобы не стереть отдельные буквы в других данных.
replace_text выполняет замены до окончательной сборки таблицы. Его можно применять для нормализации неразрывных пробелов, вариантов тире, необычных разделителей или повторяющихся обозначений. Замены должны быть узкими и проверяемыми: глобальная подмена запятой на точку испортит текстовые поля и списки, поэтому числовую нормализацию лучше выполнять после извлечения на выбранных колонках.
Текст в объединённых ячейках
В таблицах с ячейками, растянутыми на несколько строк или столбцов, текст может быть назначен не той позиции, которую ожидает пользователь. Параметр shift_text задаёт направления сдвига текста для пустых соседних ячеек, а copy_text копирует содержимое по горизонтали или вертикали. Эти настройки особенно полезны для многоуровневых заголовков.
Копирование не следует применять без последующей проверки. В аналитической таблице повтор заголовка по всем дочерним колонкам удобен, но повтор значения в объединённой ячейке данных может создать ложные дубликаты. Часто безопаснее сохранить исходную матрицу, отдельно построить нормализованный вариант и сравнить количество непустых значений до и после преобразования.
Метод copy_spanning_text() позволяет обработать уже найденную таблицу после извлечения. Это удобно, когда один набор параметров хорошо распознаёт геометрию, но правило заполнения объединённых ячеек зависит от конкретного отчёта. Постобработка оставляет исходный результат доступным для аудита.
Диагностические графики
Функция camelot.plot() визуализирует промежуточные признаки. Доступные виды зависят от анализатора: текстовые точки подходят для любого документа с текстовым слоем, линии и узлы — для lattice, текстовые края — для stream, а поиск сетевой области — для network. График следует строить для конкретного объекта Table, найденного на нужной странице.
Режим text показывает координаты текстовых объектов PDF. Если визуально слово есть, а точки отсутствуют, оно, вероятно, находится в изображении или преобразовано в контуры. В таком случае обычные текстовые методы не получат символы; потребуется OCR либо другой входной файл с доступным текстовым слоем.
textedge показывает края, по которым stream определяет табличные области. Непрерывные длинные края вдоль колонок подтверждают правильность метода. Если края обрываются из-за больших вертикальных интервалов, можно увеличить edge_tol. Если один край связывает таблицу с подписью ниже, область поиска следует сузить.
Для воспроизводимой проверки графики лучше сохранять в файлы, а не только открывать интерактивно. Имя изображения можно формировать из номера документа, страницы, порядка таблицы и набора параметров. Тогда при изменении настроек легко сравнить диагностику до и после, не перепутав страницы.
Командная строка
Команда camelot позволяет запускать извлечение без написания отдельного скрипта. Она полезна для разовых задач, проверки параметров и пакетных сценариев оболочки. Подкоманды соответствуют анализаторам, а общие опции задают страницы, пароль, формат выгрузки, каталог результата и параллельную обработку.
Перед массовым запуском стоит выполнить команду на одной странице и сохранить CSV без сжатия. Так проще увидеть имя файла, разделители и качество данных. После проверки можно включить обработку диапазона и упаковку результатов. Если документ содержит несколько таблиц на странице, Camelot создаёт отдельные файлы с номером страницы и порядком таблицы в имени.
camelot lattice -p 1-5 -f csv -o result.csv report.pdf
CLI отражает те же ограничения, что и Python API. Неверно выбранный анализатор не исправляется самим фактом запуска из терминала, а точные координаты всё равно требуют понимания системы PDF. Преимущество командной строки — быстрая проверка и простая автоматизация, преимущество API — полноценная валидация, ветвление и объединение данных.
Работа из Python
В коде удобно разделить чтение, контроль качества и нормализацию. Функция извлечения должна возвращать таблицы вместе с метаданными, а бизнес-правила — работать уже с DataFrame. Такое разделение не смешивает геометрические параметры с проверкой предметных значений и упрощает тестирование.
from pathlib import Path
import camelot
import pandas as pd
def extract(path: Path) -> list[tuple[pd.DataFrame, dict]]:
tables = camelot.read_pdf(
path,
pages="all",
flavor="lattice",
engine="combined",
)
result = []
for table in tables.filter(min_rows=2, min_columns=2):
meta = {
"page": table.page,
"order": table.order,
"accuracy": table.accuracy,
"whitespace": table.whitespace,
"confidence": table.confidence,
}
result.append((table.df.copy(), meta))
return result
Копирование DataFrame полезно, если дальнейшие операции изменяют данные. Метаданные следует хранить рядом с итогом, иначе после объединения нескольких таблиц будет трудно восстановить страницу и порядок. Для аудита можно добавить координаты области и хеш входного PDF.
Параметр layout_kwargs передаёт настройки анализатору макета PDF. Его применяют, когда стандартная группировка символов в слова не соответствует документу: слишком широкий интервал между буквами, необычное направление текста или плотные колонки. Эти параметры влияют на фундаментальное представление текста, поэтому их меняют только после графика text и сравнения координат.
Страницы, файлы и защищённые документы
Вход можно передавать как путь, URL, объект с байтами или файловый поток. Работа с памятью удобна в серверных конвейерах, где PDF уже получен из хранилища и не нужно создавать временный файл. При этом размер документа всё равно учитывается: несколько копий большого массива байтов и растровые представления страниц способны заметно увеличить потребление памяти.
Параметр password открывает защищённый PDF, если известен пароль пользователя. Некоторые варианты шифрования могут не поддерживаться библиотеками чтения; тогда документ предварительно расшифровывают подходящим инструментом и повторяют извлечение. Пароль нельзя записывать в журналы или включать в командную строку общего сервера, где аргументы видны другим процессам.
Поворот страниц обнаруживается автоматически, и текстовая ориентация корректируется перед анализом. Однако нестандартный угол, перспективное искажение скана или поворот отдельных фрагментов требуют предварительной обработки изображения. Для цифрового PDF дополнительный разворот обычно не нужен и может ухудшить координаты.
per_page=True помогает сохранить разделение результатов по страницам в сценариях, где это важно для дальнейшей логики. Например, одинаковые формы можно обрабатывать независимо, а затем добавлять номер страницы как служебный столбец. Это безопаснее безусловного объединения, если на отдельных страницах меняется заголовок или структура.
Параллельная обработка и память
Параметр parallel=True распределяет страницы между процессами. Число рабочих процессов задаётся через cpu_count. Ускорение зависит от метода и размера страниц: рендеринг и модельный анализ выигрывают сильнее, а короткие документы могут обрабатываться медленнее из-за запуска процессов и передачи данных.
Не стоит автоматически использовать все ядра. Каждый процесс может держать растровое изображение страницы, объекты макета и промежуточные матрицы. На сервере с ограниченной памятью безопаснее начать с двух или четырёх процессов, измерить пик потребления и только затем увеличивать параллелизм. Для OCR и модельного режима нужно учитывать память самих моделей.
Длинные PDF разумно разбивать на диапазоны страниц. После каждого диапазона данные сохраняют, объекты таблиц освобождают и запускают сборку мусора. Такой подход уменьшает риск исчерпания памяти и облегчает повторный запуск: при ошибке не приходится обрабатывать весь документ заново.
for start in range(1, total_pages + 1, 25):
end = min(start + 24, total_pages)
tables = camelot.read_pdf(
"report.pdf",
pages=f"{start}-{end}",
flavor="stream",
parallel=True,
cpu_count=4,
)
save_batch(tables, start, end)
del tables
При пакетной обработке следует фиксировать параметры рядом с результатом: метод, движок, диапазон страниц, допуски и версию схемы нормализации. Без этого невозможно воспроизвести выгрузку после изменения настроек или определить, почему два документа обработались по-разному.
Экспорт таблиц
TableList.export() сохраняет все найденные таблицы в выбранный формат. Поддерживаются CSV, Excel, HTML, JSON, Markdown и SQLite. Имя, переданное в метод, служит основой: для нескольких таблиц добавляются номера страниц и порядковые номера. Это предотвращает перезапись и сохраняет связь с расположением в PDF.
tables.export("report.csv", f="csv", compress=True)
tables.export("report.xlsx", f="excel")
tables.export("report.json", f="json")
tables.export("report.md", f="markdown")
tables.export("report.sqlite", f="sqlite")
CSV удобен для простого обмена, но требует явного контроля кодировки, разделителя и десятичного знака при последующем открытии. Excel сохраняет несколько таблиц в привычном формате, однако типы ячеек после извлечения часто остаются строковыми. JSON лучше подходит для передачи через API, Markdown — для документации, HTML — для публикации внутри закрытой системы, а SQLite — для накопления большого числа таблиц и SQL-запросов.
Параметр compress=True упаковывает набор файлов в ZIP. Он особенно полезен для CSV, HTML и JSON, когда каждая таблица создаёт отдельный файл. Перед автоматической отправкой архива нужно проверить состав и имена: один PDF может породить десятки небольших таблиц, включая ложные области, если фильтрация не выполнена.
Отдельные объекты Table имеют методы to_csv(), to_excel(), to_html(), to_json(), to_markdown() и to_sqlite(). Они нужны, когда для каждой таблицы выбирается свой формат или имя. В Excel доступен режим добавления, позволяющий записывать таблицы в существующую книгу, но имена листов и конфликты следует контролировать явно.
Объединение таблиц с нескольких страниц
Одна логическая таблица часто продолжается на следующих страницах. Метод stack_contiguous() объединяет последовательные таблицы по выбранному правилу. Режим column_count проверяет одинаковое число колонок, а first_row сопоставляет первую строку. Параметр keep_first_header позволяет сохранить заголовок только из первой части.
Автоматическое объединение нужно применять после фильтрации. Две соседние таблицы могут иметь одинаковое число колонок, но относиться к разным разделам. Дополнительные проверки заголовков, типов данных и ключевых полей снижают риск ложного соединения. Для отчётов с повторяющейся шапкой полезно сначала нормализовать пробелы и переносы строк, а затем сравнивать заголовки.
stacked = tables.stack_contiguous(
match="column_count",
keep_first_header=True,
)
for table in stacked:
validate_schema(table.df)
После объединения статистика пересчитывается: показатели частей усредняются, а уверенность обновляется. Страница и порядок берутся из первой таблицы, поэтому для полного аудита лучше дополнительно хранить список исходных страниц. Если между частями есть разрыв, не следует считать их непрерывными без отдельной проверки.
Контроль качества данных
Геометрические метрики отвечают только на вопрос, насколько согласованно алгоритм распределил текст. Бизнес-контроль должен проверять смысл. Для числовых колонок полезны доля успешно преобразованных значений, допустимые диапазоны, уникальность ключей и арифметические связи. Для дат — формат, порядок и границы периода. Для кодов — длина и набор символов.
Первая строка не всегда является заголовком. В PDF над данными могут находиться название раздела, единицы измерения и многоуровневая шапка. Вместо безусловного df.columns = df.iloc[0] лучше определить структуру по шаблону, объединить несколько строк заголовка и только затем удалить их из данных.
Пустые строки и колонки следует удалять после нормализации пробелов. Ячейка может содержать неразрывный пробел, перевод строки или невидимый символ и считаться непустой. Последовательность обычно такова: привести значения к строкам, заменить служебные пробелы, обрезать края, преобразовать пустые строки в NA, затем удалить полностью пустые оси.
df = table.df.copy()
df = df.apply(lambda col: col.str.replace(" ", " ").str.strip())
df = df.replace("", None)
df = df.dropna(axis=0, how="all").dropna(axis=1, how="all")
Для критичных выгрузок полезен двухступенчатый контроль. Сначала автоматические правила отклоняют явно плохие таблицы, затем оператор просматривает выборку пограничных случаев и все документы с изменившейся схемой. Сохранённые диагностические изображения ускоряют этот просмотр и позволяют понять причину без повторного запуска.
Координаты и масштаб
Координаты в PDF измеряются в пунктах и отсчитываются от нижнего левого угла. В большинстве графических редакторов и изображений начало находится сверху слева, поэтому координату Y приходится преобразовывать. Если высота страницы равна H, точка с экранной координатой y приблизительно соответствует H-y в PDF.
При переводе координат с растрового изображения учитывается масштаб. Страница, отрисованная с повышенным DPI, имеет больше пикселей, чем пунктов PDF. Коэффициенты по X и Y вычисляют как отношение размеров PDF к размерам изображения. Без масштабирования область окажется смещённой или выйдет за границы страницы.
pdf_x = image_x * pdf_width / image_width
pdf_y = pdf_height - image_y * pdf_height / image_height
Для точной настройки проще использовать диагностический график и интерактивное отображение координат, затем перенести значения в table_areas. Координаты следует хранить вместе с размером страницы. Один и тот же прямоугольник нельзя без проверки применять к документам формата A4, Letter и страницам с обрезанными полями.
Практические сценарии
Финансовые отчёты
В отчётах с сеткой сначала применяют lattice и ограничивают страницы диапазоном раздела. Затем объединяют продолжения таблицы, удаляют повторяющиеся заголовки и преобразуют денежные значения. Контроль включает равенство итогов сумме строк, одинаковое число колонок и отсутствие букв в числовых полях, кроме допустимых обозначений.
Научные публикации
В статьях таблицы часто имеют только верхнюю и нижнюю линии, поэтому stream или network может быть устойчивее строгого анализа сетки. Сноски и надстрочные символы сохраняют через flag_size, а подпись таблицы исключают точной областью. Многоуровневые заголовки нормализуют отдельно, не смешивая их с наблюдениями.
Расписания и прейскуранты
Большие вертикальные интервалы требуют настройки edge_tol, а близкие строки — row_tol. Для стабильного шаблона можно закрепить колонки координатами. После извлечения проверяют формат времени, последовательность станций или категорий и отсутствие сдвига цен в соседний столбец.
Сканированные формы
Для скана включают модельный режим и OCR, затем усиливают предметные проверки. Поля с кодами, датами и суммами сверяют по маскам, а сомнительные символы отправляют на ручную проверку. Если форма одинакова, координаты и ожидаемая схема помогают быстрее обнаружить отклонение.
Пакетный ETL
Документы сначала классифицируют по шаблону и наличию текстового слоя. Для каждой группы применяют собственный профиль параметров. Результат сопровождают метаданными, хешем входного файла, статистикой качества и журналом ошибок. Изменение числа колонок или падение уверенности создаёт отдельную задачу на проверку, а не попадает без проверки в хранилище.
Типичные ошибки и способы исправления
У модуля нет read_pdf
Сообщение module 'camelot' has no attribute 'read_pdf' часто означает, что установлен другой пакет с именем camelot либо локальный файл camelot.py перекрывает нужный модуль. Следует вывести camelot.__file__, удалить конфликтующий пакет или переименовать файл, затем установить camelot-py в чистое виртуальное окружение.
import camelot
print(camelot.__file__)
print(hasattr(camelot, "read_pdf"))
Конфликт OpenCV
Одновременная установка opencv-python и opencv-python-headless может привести к конфликту файлов cv2. В серверном окружении без графического интерфейса обычно оставляют headless-вариант, удаляют оба пакета и устанавливают нужный заново. После этого проверяют импорт cv2 и повторяют минимальный пример на одной странице.
Найдено ноль таблиц
Сначала проверяют параметр pages и наличие текстового слоя. Затем меняют анализатор: для рамок пробуют lattice, для пробелов — stream или network, для изображения — ml с OCR. Если таблица занимает небольшую часть страницы, задают table_regions или table_areas. Для тонких линий сравнивают combined, vector и raster.
Колонки склеились
В stream уменьшают column_tol или задают разделители через columns. В lattice проверяют, обнаружены ли вертикальные линии, и настраивают line_scale, line_tol и пороговую обработку. Если текстовый объект пересекает несколько ячеек, включают split_text.
Строки разделились
Для stream постепенно увеличивают row_tol, контролируя, чтобы соседние строки не слились. Переносы внутри ячейки можно нормализовать через strip_text или после извлечения. Если строка состоит из нескольких уровней заголовка, лучше сохранить их отдельно и собрать составное имя столбца.
Линии текста приняты за сетку
Причиной часто становится слишком большое значение line_scale. Его уменьшают, ограничивают область таблицы и сравнивают графики line и joint. Подчёркивания в заголовках можно исключить из области либо перейти к stream, если сетка не является надёжным признаком.
Текст попал в соседнюю ячейку
Для объединённых ячеек настраивают shift_text и copy_text. Для обычных ячеек проверяют координаты линий, допуски пересечений и наличие сдвинутого текстового объекта. Иногда безопаснее исправить назначение после извлечения по известной схеме, чем чрезмерно расширять геометрические допуски.
Извлечение расходует слишком много памяти
Документ делят на небольшие диапазоны, уменьшают число процессов и не сохраняют лишние диагностические изображения. Для цифровых таблиц без сложной графики выбирают текстовый метод вместо рендеринга. В модельном режиме освобождают промежуточные объекты и не загружают отдельную копию модели в каждый процесс без необходимости.
Область задана, но результат пуст
Проверяют порядок координат, начало оси Y, размер страницы и масштаб изображения, по которому снимались точки. Затем строят график текста или контуров и убеждаются, что прямоугольник действительно покрывает таблицу. Для документов с разными размерами страниц координаты рассчитывают отдельно.
График не открывается
В окружении должны быть установлены зависимости для построения графиков. На сервере без дисплея используют неинтерактивный backend и сохраняют изображение в файл. Ошибка графики не означает ошибку извлечения: данные можно получить без визуализации, но настройка сложного документа станет менее удобной.
Установка и совместимость
Для работы нужна среда Python 3.10 или новее. Базовая установка выполняется пакетом camelot-py через pip либо канал conda-forge. Отдельное виртуальное окружение защищает проект от конфликтов OpenCV, pandas, библиотек чтения PDF и модельных зависимостей.
python -m venv .venv
.venv/bin/python -m pip install --upgrade pip
.venv/bin/python -m pip install "camelot-py"
На Windows путь активации виртуального окружения отличается, но установка пакета и проверка импорта остаются теми же. После установки выполняют минимальный вызов на небольшом PDF и проверяют версию Python, путь модуля и наличие команды camelot. Такой тест быстрее выявляет ошибку окружения, чем запуск большого конвейера.
Для стандартного рендеринга используется PDFium, поэтому отдельная установка Ghostscript обычно не нужна. Альтернативный backend можно подключить для совместимости с конкретными документами. Если один движок некорректно отображает тонкие линии или прозрачности, результат сравнивают на одной странице, не меняя одновременно остальные параметры.
Дополнительные наборы зависимостей нужны для графиков, модельного анализа и OCR. Их ставят только в том окружении, где соответствующая функция действительно используется. Это уменьшает размер образа и число возможных конфликтов. Для воспроизводимости версии зависимостей фиксируют в lock-файле или файле требований.
Как подобрать параметры без перебора вслепую
- Откройте одну типичную страницу и определите, есть ли выделяемый текст.
- Проверьте внешний признак: полная сетка, пробелы между колонками, устойчивые выравнивания или изображение.
- Запустите подходящий анализатор со стандартными параметрами.
- Сохраните
parsing_report, формуDataFrameи диагностический график. - Если таблица не найдена, сначала смените анализатор или движок, затем меняйте допуски.
- Если найдена лишняя область, ограничьте поиск координатами или текстовыми ориентирами.
- Если структура близка к правильной, настройте один параметр за раз и сравните один и тот же фрагмент.
- После удачной страницы проверьте начало, середину и конец диапазона.
- Добавьте фильтры качества и проверки схемы до массового запуска.
- Сохраните профиль параметров вместе с идентификатором шаблона документа.
Главный принцип — отделять поиск таблицы от очистки данных. Геометрические настройки должны получать устойчивую сетку и назначение текста, а pandas-код — приводить значения к нужным типам и бизнес-формату. Попытка исправить любой дефект только параметрами Camelot делает профиль хрупким; попытка исправить неверную геометрию только постобработкой создаёт риск скрытых сдвигов.
Сравнение Camelot с аналогами
| Программа | Лучше подходит для | Главное ограничение |
|---|---|---|
| Camelot | Автоматического извлечения таблиц с выбором геометрического, сетевого или модельного метода, метриками качества и выгрузкой в DataFrame | Требует настройки Python и отдельных зависимостей для OCR |
| Tabula | Ручного выделения областей таблиц и быстрой выгрузки CSV из цифровых PDF через графический интерфейс | Нужна Java, а тонкая автоматическая настройка ограниченнее |
| pdfplumber | Низкоуровневой работы с символами, линиями, координатами и собственной логикой разбора страниц | Сложную структуру таблицы часто приходится собирать кодом |
| PyMuPDF | Быстрого рендеринга, извлечения текста и комплексных операций с PDF в одном Python-конвейере | Табличный анализ менее специализирован, лицензирование требует внимания |
| gmft | Модельного обнаружения и распознавания сложных таблиц, где геометрические правила нестабильны | Модели и PyTorch увеличивают размер и ресурсоёмкость окружения |
| PDF Commander | Ручного редактирования, объединения, разделения и преобразования PDF в понятном графическом интерфейсе | Не предназначен для пакетной выгрузки таблиц в DataFrame |
Camelot стоит выбирать, когда таблицы нужно извлекать регулярно, параметры можно закрепить в коде, а результат должен проходить автоматический контроль. Tabula удобнее для разовой ручной работы. pdfplumber и PyMuPDF подходят разработчикам, которым нужен более низкий уровень доступа к странице или широкий набор операций помимо таблиц. gmft оправдан для сложной визуальной структуры и сканов. PDF Commander практичнее, когда задача состоит в ручном изменении самого PDF, а не в построении воспроизводимого потока табличных данных.
Построение надёжного конвейера
Надёжная схема начинается с классификации входа. Для каждого документа определяют шаблон, размер страниц, наличие текстового слоя и диапазоны с таблицами. Затем выбирают профиль Camelot: анализатор, движок, области, допуски и правила очистки. Универсальный набор параметров для всех поставщиков почти всегда уступает нескольким узким профилям.
Перед извлечением вычисляют хеш файла и присваивают идентификатор запуска. На выходе сохраняют таблицы, метрики, страницу, порядок, координаты и профиль настроек. Если тот же файл поступит повторно, конвейер сможет обнаружить дубликат. Если настройки изменятся, станет понятно, какая выгрузка была получена старым правилом.
После извлечения выполняются структурные тесты: ожидаемое число таблиц, диапазон строк и колонок, обязательные заголовки, типы ключевых полей. Затем идут предметные тесты. Ошибки разделяют на технические, структурные и смысловые; это помогает выбрать правильное действие — повторить запуск, изменить профиль или отправить документ на ручную проверку.
Хороший конвейер не скрывает неопределённость. Таблица с пограничной уверенностью должна иметь статус проверки, а не автоматически смешиваться с надёжными данными. В журнал записывают причину: высокая пустота, неожиданное число колонок, ошибка OCR, несовпадение итогов или изменение размера страницы.
Для регрессионного тестирования хранят небольшой набор эталонных PDF и ожидаемых таблиц. После обновления зависимостей запуск сравнивает форму, заголовки, ключевые значения и метрики. Полное побайтовое сравнение CSV слишком строго из-за возможных отличий форматирования, поэтому лучше проверять нормализованные данные и критичные поля.
Ограничения, которые важно учитывать
Camelot не восстанавливает смысл документа автоматически. Он извлекает геометрию и текст, но не знает, является ли строка итогом, заголовком или примечанием. Это определяется правилами конкретного отчёта. Чем сложнее многоуровневая структура, тем важнее отдельная нормализация после распознавания.
Качество цифрового PDF зависит от того, как он создан. Два визуально одинаковых файла могут хранить текст по-разному: отдельными символами, строками, контурами или изображением. Поэтому профиль, идеально работающий на одном генераторе отчётов, может потребовать изменений после смены шаблона или системы экспорта.
Координатные области делают извлечение точным, но привязывают профиль к размеру и верстке страницы. Текстовые ориентиры гибче, однако зависят от стабильности подписей. Модельный режим лучше переносит визуальные изменения, но требует больше ресурсов и усиливает необходимость проверки распознанных символов.
Метрики качества полезны для маршрутизации, но не заменяют сравнение с предметными правилами. Таблица с высокой точностью может быть неполной, если часть области не попала в поиск. Таблица с высокой пустотой может быть правильной формой. Порог всегда должен учитывать назначение данных.
Рекомендованная последовательность для новой формы
Сначала выберите три–пять документов: простой, типичный, сложный и, при наличии, скан. На каждом отметьте ожидаемое число таблиц и ключевые колонки. Запустите стандартные методы и сохраните диагностику. Такой мини-набор показывает, действительно ли профиль устойчив, а не случайно удачен на одной странице.
Затем настройте обнаружение области. Сначала используйте широкую table_region, чтобы исключить колонтитулы, после чего при необходимости переходите к точной table_area. Только когда таблица стабильно находится, регулируйте разделение строк и колонок. Это сокращает число комбинаций и делает причину каждого изменения понятной.
После геометрии определите правила заголовка и типов. Составьте список допустимых колонок, их порядка и преобразований. Добавьте проверку итогов, уникальности и диапазонов. Результат должен считаться успешным только после прохождения этих правил, даже если parsing_report выглядит хорошо.
В конце измерьте скорость и память на реальном объёме. Подберите размер диапазона страниц и число процессов, зафиксируйте зависимости и настройте журналирование. После этого профиль готов для регулярного запуска и контролируемого обновления.
Точная настройка Lattice
У lattice есть несколько этапов, и каждый параметр следует связывать с конкретным дефектом. Сначала страница рендерится, затем бинаризуется, после чего отдельные морфологические операции выделяют горизонтальные и вертикальные линии. Далее близкие сегменты объединяются, пересечения превращаются в узлы, а узлы — в прямоугольные ячейки. Если менять параметры без понимания этапа, можно компенсировать одну ошибку другой и получить нестабильную сетку.
iterations управляет числом итераций расширения линий. Небольшое увеличение помогает соединить едва разорванные сегменты, но одновременно утолщает шум и может связать соседние элементы. erode_iterations выполняет обратную операцию и полезен, когда линии после бинаризации получились слишком толстыми. Эти параметры применяют после проверки line_scale и порога, потому что они изменяют уже выделенную геометрию.
Если вертикальная граница пропущена только в одном месте, лучше увеличить допуск объединения сегментов, чем резко повышать разрешение всей страницы. Если все тонкие линии исчезли, проблема находится раньше — в рендеринге или бинаризации. Если границы видны, но таблица не строится, проверяют узлы и joint_tol. Такая последовательность сокращает число пробных запусков.
use_fallback определяет, разрешено ли переходить к запасному способу обработки, когда выбранный путь не даёт результата. В строгом конвейере иногда полезно отключить скрытый запасной маршрут и явно журналировать неудачу: тогда изменение поведения не маскируется. В интерактивной настройке fallback удобен, потому что быстрее даёт исходный результат для сравнения.
Для цветных отчётов важно проверять контраст линий после преобразования в оттенки серого. Светло-серые или цветные границы могут стать почти неотличимыми от фона. Вместо бесконечного увеличения line_scale полезнее подобрать пороговые параметры либо предварительно подготовить страницу, сохранив при этом исходный PDF для контроля.
Точная настройка Stream
stream сначала объединяет отдельные символы и слова в текстовые строки, затем оценивает число потенциальных колонок по повторяющимся интервалам. Поэтому дефект на этапе группировки текста влияет на все последующие границы. Если одно слово разбито на несколько фрагментов, алгоритм может увидеть ложный промежуток; если два соседних значения объединены в один объект, разделитель колонок может исчезнуть.
Перед изменением row_tol и column_tol следует открыть график текста и посмотреть реальные рамки объектов. Если рамки уже пересекаются, одним допуском проблему не решить; потребуется split_text, явные колонки или другая настройка макета. Если между объектами есть чистый зазор, небольшая корректировка допуска обычно достаточна.
В числовых таблицах выравнивание по правому краю часто надёжнее визуального центра. Значения разной длины формируют стабильную правую границу, тогда как левый край меняется. network способен использовать такие совпадения напрямую, а stream выводит колонку из промежутков. Если stream склеивает близкие числа, сравнение с network может показать, что проблема не в допуске, а в выбранной модели структуры.
Большой заголовок над несколькими колонками способен исказить предполагаемое число столбцов. Его исключают координатами, извлекают отдельно или передают ожидаемые разделители через columns. Заголовок затем можно распределить по дочерним колонкам в pandas. Это надёжнее, чем заставлять один геометрический проход одновременно понимать многоуровневую шапку и плотные данные.
При повторяющихся формах полезно строить профиль относительных координат. Абсолютные разделители переводят в доли ширины страницы, а при чтении нового документа пересчитывают обратно. Такой подход выдерживает небольшое изменение размера листа, но не исправляет перестройку макета; изменение порядка колонок всё равно должно обнаруживаться проверкой схемы.
Настройка Network и Hybrid по диагностике
В сетевом анализе ключевое значение имеют повторяющиеся выравнивания. На диагностике полезно отличать плотную внутреннюю сеть таблицы от случайных линий связи в обычном тексте. Настоящая таблица обычно образует прямоугольную область с множеством пересекающихся горизонтальных и вертикальных отношений, тогда как абзац даёт в основном однотипные выравнивания по левому краю.
Если сеть начинает расширяться в подпись или соседний абзац, ограничивают область поиска и исключают колонтитулы. Если она останавливается раньше последней колонки, проверяют, есть ли у этой колонки общее выравнивание с остальными. Неровные текстовые значения можно предварительно нормализовать только после извлечения; геометрически исправить их нельзя, поэтому иногда лучше задать широкую область и добавить ожидаемую колонку правилом.
В hybrid полезно отдельно посмотреть признаки линий и текста. Если линии дают правильные строки, а сеть — правильные колонки, совмещение оправдано. Если оба метода по-разному делят одну и ту же ось, результат может стать хуже. Тогда выбирают доминирующий метод и недостающие границы задают вручную или исправляют постобработкой.
Сравнение следует проводить на идентичном диапазоне страниц. Разное число найденных таблиц само по себе не показывает победителя: один метод может находить дополнительные легенды и рамки. Более информативны стабильность числа колонок, совпадение обязательных заголовков, доля успешно преобразованных чисел и количество ручных исключений.
Особенности OCR-потока
При OCR страница сначала превращается в изображение, затем определяются области и символы, после чего текст связывается со структурой таблицы. Разрешение должно быть достаточным для мелких знаков, но чрезмерное значение увеличивает время и память. Для документов с мелким шрифтом разумно сравнить несколько страниц на двух разрешениях и выбрать минимальное, при котором сохраняются десятичные точки, минусы и индексы.
Язык распознавания должен соответствовать документу. Смешанные русско-английские таблицы требуют набора языков, иначе названия могут распознаваться хуже чисел. Подключение лишних языков иногда снижает точность похожих символов, поэтому профиль OCR следует делать таким же узким, как геометрический профиль Camelot.
После OCR нельзя полагаться только на типовое преобразование astype(float). Сначала нормализуют варианты пробелов, десятичные разделители, длинные тире и символы, похожие на цифры. Неоднозначные замены выполняют только в колонках с известным типом. Например, букву О можно заменить на ноль в коде фиксированной длины, но не в названии организации.
Для контроля полезно хранить исходную строку и нормализованное значение. Если преобразование не прошло или нарушило проверку диапазона, оператор видит, что именно распознал OCR. Полное удаление исходного текста делает исправление ошибок сложнее и лишает конвейер доказательств.
Сканы с перекосом, тенями и перспективой лучше подготовить до анализа: выровнять страницу, убрать сильный фон и сохранить границы. Однако агрессивная очистка способна стереть тонкие линии и десятичные знаки. Эталонный набор должен включать как исходные, так и подготовленные варианты, чтобы измерить реальный эффект.
Форматы вывода и сохранение типов
Любой формат экспорта отражает содержимое DataFrame, а не исходные типы PDF. Текстовый слой не хранит понятия денежное число или дата в виде табличной схемы, поэтому большинство значений сначала оказываются строками. Приведение типов следует выполнять до финального экспорта, если принимающая система ожидает числа, даты или логические значения.
В CSV особенно важен разделитель. Русские таблицы часто содержат десятичную запятую, поэтому запятая как разделитель полей создаёт неоднозначность для некоторых программ. Можно использовать точку с запятой или явно задавать параметры чтения на стороне получателя. Кодировку лучше фиксировать в документации обмена, даже если современные инструменты корректно работают с UTF-8.
При сохранении в Excel следует решить, нужны ли заголовок и индекс pandas. Таблицы Camelot уже содержат строки шапки внутри данных, поэтому без предварительной нормализации Excel может получить технические номера колонок сверху и ещё одну строку заголовков ниже. Сначала формируют правильные df.columns, затем сохраняют без индекса.
JSON подходит для API, но ориентацию структуры нужно выбирать осознанно. Запись по строкам удобна для передачи объектов, по колонкам — для аналитической обработки, а табличная схема — для сохранения типов. Встроенный экспорт даёт быстрый результат; при строгом контракте лучше использовать возможности pandas и собственную схему метаданных.
SQLite полезен, когда один запуск создаёт много таблиц. Имена таблиц базы должны быть детерминированными и безопасными: номер документа, страницы и порядка лучше хранить в отдельных полях, а не только в имени. Перед добавлением новых данных проверяют схему и транзакцию, чтобы частичный сбой не оставил половину диапазона.
Тестирование профиля извлечения
Тест для Camelot должен проверять не только отсутствие исключения. Минимальный набор утверждений включает количество таблиц, форму каждой таблицы, ключевые заголовки и несколько контрольных значений. Для числовых отчётов добавляют арифметические проверки. Для многостраничных таблиц проверяют, что повторный заголовок удалён ровно один раз.
def test_quarterly_report():
tables = camelot.read_pdf(
"fixtures/quarterly.pdf",
pages="4-6",
flavor="lattice",
)
clean = tables.filter(min_rows=5, min_columns=6)
assert len(clean) == 3
assert all(t.df.shape[1] == 7 for t in clean)
assert clean[0].df.iloc[0, 0].strip() == "Показатель"
Геометрические метрики можно проверять диапазоном, а не точным равенством. Небольшое изменение библиотеки рендеринга способно изменить долю пустых ячеек на доли процента без изменения данных. Жёстко фиксируют критичные значения и структуру, а метрики используют как сигнал значительного ухудшения.
Для изображения диагностики допустимо применять визуальное сравнение с порогом, но оно не должно быть единственным тестом. Изменение сглаживания способно изменить пиксели, сохранив правильную сетку. Сравнение координат ячеек, числа узлов и содержимого даёт более устойчивый контроль.
Новый шаблон добавляют в набор после подтверждённой ошибки или существенного изменения верстки. Так регрессионная база постепенно покрывает реальные сложности: короткие линии, многоуровневые заголовки, сканы, повороты, защищённые файлы и продолжения на нескольких страницах.
Журналирование и разбор неудачных запусков
Для каждого вызова полезно записывать имя профиля, страницы, анализатор, движок, длительность, число таблиц и показатели качества. Исключение должно сопровождаться типом ошибки и этапом: чтение PDF, рендеринг, поиск области, OCR, экспорт или валидация. Такой журнал быстрее показывает системную проблему, чем отдельные сообщения пользователей.
Содержимое таблиц не всегда можно писать в журнал из-за конфиденциальности. Для диагностики достаточно формы, хеша нормализованных заголовков, координат и обезличенных контрольных признаков. Проблемный PDF хранят в защищённом месте с ограниченным доступом, а не прикладывают к общему логу.
Если число таблиц внезапно стало нулевым для целой группы документов, сначала проверяют изменение входного шаблона и окружения. Если ошибка касается одной страницы, вероятнее повреждение, другой размер листа или скан. Разделение по профилям и хешам зависимостей помогает быстро отличить изменение данных от изменения программного окружения.
Для повторного запуска сохраняют диапазоны, которые уже успешно обработаны. Идемпотентная запись не создаёт дубликаты при повторе: ключ включает документ, страницу, порядок таблицы и версию профиля. Ошибочный диапазон можно переработать другим методом, не затрагивая подтверждённые страницы.
Итоговая схема работы
Camelot даёт наиболее предсказуемый результат, когда выбор метода основан на реальном устройстве PDF. Сетка направляет к lattice, текстовые интервалы — к stream, устойчивые выравнивания — к network, смешанные признаки — к hybrid, а изображение или сложная структура — к ml с OCR. Диагностические графики подтверждают, какие признаки увидел анализатор.
После обнаружения таблицы результат оценивают по точности, пустоте, уверенности и ожидаемой форме, затем очищают в pandas и сохраняют в нужный формат. Многостраничные части объединяют только после проверки совместимости, а спорные случаи оставляют с метаданными и координатами для просмотра.
Такой процесс превращает извлечение таблиц из разовой операции в воспроизводимый поток: параметры фиксируются, ошибки классифицируются, качество измеряется, а изменения шаблона обнаруживаются до загрузки неверных данных. Именно сочетание нескольких анализаторов, наглядной диагностики и программной валидации делает Camelot полезным для регулярной работы с отчётами, публикациями, формами и архивами PDF.