Парсинг PDF-документов на Python: как извлечь таблицы и текст

    📝 Кратко: PDF-документы — это хранилище неструктурированных данных, которое требует специального подхода к парсингу. Это руководство научит вас использовать **парсинг PDF Python** для извлечения обычного текста с помощью PyPDF2 и сложных таблиц с помощью мощной библиотеки Camelot.
Парсинг PDF-документов на Python

Если вы работаете с данными, то рано или поздно столкнетесь с тем, что нужная информация содержится не на сайте, а в виде отчета, счета или государственного документа в формате PDF. Проблема в том, что PDF — это формат, созданный для печати и визуального представления, а не для программной обработки. Для Python-разработчика PDF — это черная коробка.

Я сам потратил немало времени, пытаясь «вытащить» данные из PDF-отчетов, и знаю, как фрустрирует, когда простое копирование-вставка превращается в рутину на часы.

В этой статье мы разберем два ключевых сценария и выберем для каждого из них лучшие инструменты, чтобы полностью освоить парсинг PDF Python:

  1. Извлечение простого текста: Когда вам нужен весь контент страницы. Мы используем легкую и быструю библиотеку PyPDF2.
  2. Извлечение структурированных данных (таблиц): Когда вам нужно превратить данные в таблице PDF в готовый DataFrame Pandas или CSV. Мы используем специализированный инструмент Camelot.

Давайте перестанем вручную копировать отчеты и начнем автоматизировать!

📖 Сценарий №1: Извлечение обычного текста (PyPDF2)

Если ваша задача — просто получить весь текст со страницы PDF, без сложной структуры, то PyPDF2 — это самый быстрый и надежный инструмент. Он позволяет легко читать метаданные, извлекать текст и манипулировать страницами.

Установка и чтение текста по страницам

PyPDF2 — это чистая Python-библиотека, которая не требует внешних зависимостей.

Установка:

Вы можете установить библиотеку, используя pip. (Кстати, если вы хотите ускорить процесс управления пакетами в 10 раз, рассмотрите uvсамый быстрый пакетный менеджер на Python).

pip install pypdf2

Пример кода для извлечения текста: Предположим, у нас есть файл report.pdf.

import PyPDF2

FILE_PATH = "report.pdf"

def extract_text_from_pdf(file_path):
    all_text = ""
    try:
        # Используем контекстный менеджер 'with' для безопасного открытия файла
        with open(file_path, 'rb') as file:
            reader = PyPDF2.PdfReader(file)

            # Получаем общее количество страниц
            num_pages = len(reader.pages)
            print(f"&#x1f4c3 Обнаружено страниц: {num_pages}")

            # Цикл по всем страницам
            for i in range(num_pages):
                page = reader.pages[i]
                text = page.extract_text()

                if text:
                    # Добавляем текст страницы и разделитель
                    all_text += f"\n--- PAGE {i+1} ---\n"
                    all_text += text
                    print(f"   Извлечено {len(text)} символов со страницы {i+1}")
                else:
                     print(f"   Предупреждение: страница {i+1} пуста или содержит только изображения.")

    except FileNotFoundError:
        print(f"Ошибка: Файл не найден по пути {file_path}")
    except Exception as e:
        print(f"Произошла ошибка при чтении PDF: {e}")

    return all_text

# Запускаем извлечение
extracted_content = extract_text_from_pdf(FILE_PATH)

# Сохраняем результат в текстовый файл для проверки
with open("extracted_text.txt", "w", encoding="utf-8") as f:
    f.write(extracted_content)

print("\n&#x2705 Текст успешно сохранен в extracted_text.txt")

Объяснение кода:

  • with open(file_path, 'rb') as file:: Открываем файл в бинарном режиме ('rb'), что необходимо для работы с PDF.
  • reader = PyPDF2.PdfReader(file): Создаем объект ридера.
  • reader.pages[i].extract_text(): Ключевой метод, который пытается извлечь текстовый слой со страницы. Важно: Если PDF создан как скан изображения, этот метод вернет пустую строку, так как текстового слоя нет.

📚 Документация: PyPDF2

📊 Сценарий №2: Извлечение таблиц (Camelot)

Для парсинга PDF в Python самая сложная задача — это извлечение табличных данных. В отличие от текста, который просто «читается», таблицы нужно идентифицировать, распознать границы ячеек и отделить заголовок от данных. PyPDF2 с этой задачей не справляется.

Для этого мы используем Camelot. Это продвинутая библиотека, которая специализируется на извлечении таблиц.

Установка и системные требования Camelot

Camelot требует, чтобы в системе был установлен Ghostscript (для работы с PDF) и библиотека Tkinter (для графического режима). Кроме того, она зависит от OpenCV и NumPy.

Системные зависимости:

Установите Ghostscript (обязательно).

Убедитесь, что у вас есть библиотеки для работы с изображениями, часто это Tkinter (на Linux).

Установка Python-пакетов:

Установка Camelot требует дополнительных зависимостей (pandas, opencv), поэтому здесь особенно актуально использовать быстрый менеджер пакетов. (Если вам важна скорость установки, попробуйте uvсамый быстрый пакетный менеджер на Python).

pip install camelot-py[cv] pandas

Пример кода для извлечения таблиц: Предположим, наш файл financial_report.pdf содержит таблицу на странице 2.

import camelot
import pandas as pd

TABLE_PDF_PATH = "financial_report.pdf"

def extract_tables_with_camelot(file_path, page_number):
    print(f"&#x1f52d Загружаем файл и ищем таблицы на странице {page_number}...")

    try:
        # 1. Загрузка таблиц
        # 'pages' указывает, на какой странице искать. 'lattice' - метод для таблиц с четкими линиями
        tables = camelot.read_pdf(
            file_path, 
            pages=str(page_number), 
            flavor='lattice' # Используем метод распознавания по линиям
        )

        num_tables = tables.n
        print(f"   Обнаружено таблиц: {num_tables}")

        if num_tables == 0:
            print("   Предупреждение: Таблицы не найдены. Попробуйте flavor='stream'.")
            return None

        # 2. Обработка первой найденной таблицы (чаще всего это нужная)
        table = tables[0]

        # 3. Конвертация в DataFrame Pandas
        df = table.df 
        print(f"   Таблица успешно преобразована в DataFrame размером {df.shape}")

        # 4. Сохранение в CSV
        # Сохраняем сразу в файл
        df.to_csv("extracted_table.csv", index=False, encoding='utf-8')

        print("&#x2705 Таблица сохранена в extracted_table.csv")
        return df

    except FileNotFoundError:
        print(f"Ошибка: Файл не найден по пути {file_path}")
        return None
    except Exception as e:
         # Это может быть ошибка Ghostscript или другой зависимости
        print(f"Непредвиденная ошибка Camelot. Проверьте Ghostscript и зависимости: {e}")
        return None

# Запускаем извлечение таблицы со страницы 2
df_result = extract_tables_with_camelot(TABLE_PDF_PATH, 2)

# Выводим первые строки для демонстрации
if df_result is not None:
    print("\nПервые 5 строк извлеченной таблицы:")
    print(df_result.head())

Объяснение кода:

  • camelot.read_pdf(...): Главная функция, которая ищет таблицы.
  • flavor='lattice': Этот параметр указывает Camelot искать таблицы, у которых есть четкие линии (сетка), разделяющие ячейки. Для таблиц, разделенных только пробелами, используйте flavor='stream'.
  • tables[0].df: Camelot возвращает объект TableList. Мы берем первую таблицу (tables[0]) и конвертируем ее в удобный объект DataFrame библиотеки Pandas.
  • df.to_csv(...): Сохраняем результат в стандартный CSV-файл, готовый к дальнейшей обработке.

📚 Документация: Camelot Python

🛑 Частые проблемы и обходные пути при парсинге PDF

Даже лучшие библиотеки для парсинга PDF не дают 100% гарантии успеха, поскольку PDF-файлы могут быть очень разнообразными.

Решение проблем с форматированием и сканами

Сканированные PDF (Изображения): Если файл является сканом (только изображение, без текстового слоя), ни PyPDF2, ни Camelot не смогут извлечь текст или таблицы.

  • Решение: Вам понадобится OCR (Optical Character Recognition), например, библиотека Tesseract с Python-оберткой pytesseract. Сначала OCR преобразует изображение страницы в текст, а затем вы можете обрабатывать этот текст.

Неправильное распознавание границ таблиц: Если Camelot плохо распознает таблицу:

  • Смена «flavor»: Если lattice не сработал, попробуйте stream (для таблиц с минимальными границами, разделенными пробелами).
  • Указание области (area): Вы можете вручную указать координаты прямоугольной области на странице, где находится нужная таблица, используя параметр table_areas=['x1,y1,x2,y2'].

Кодировка текста: При извлечении текста могут появиться «кракозябры».

  • Решение: Убедитесь, что при сохранении или обработке текста вы всегда используете правильную кодировку, предпочтительно UTF-8, как показано в примере PyPDF2.

✅ Заключение

Парсинг PDF — это задача, которая требует правильного выбора инструмента в зависимости от цели.

  • Для быстрого извлечения текста — используйте легкий PyPDF2.
  • Для извлечения сложных таблиц и структурированных данных — используйте мощный Camelot.

Освоив эти две библиотеки, вы сможете автоматизировать сбор практически любых данных, запертых в PDF-документах, и легко интегрировать их в свои Python-проекты, переводя неструктурированный хаос в чистый и готовый к анализу DataFrame.

🔁 Если вам полезны советы по парсингу и обработке данных, посмотрите также:
Python-скрипт: автоматическая сортировка файлов — ещё один пример автоматизации рутины с файловой системой
Как писать чистый и читаемый код на Python — улучшите обработку данных в ваших парсерах
Как ускорить Python в 10 раз с помощью асинхронности — если вам нужно обрабатывать сотни PDF-файлов одновременно
💬 Остались вопросы? Пишите в комментариях — с радостью уточню, дополню или помогу с вашим кодом.
📢 Подписывайтесь на Telegram-канал PythonAuto, чтобы не пропустить новые гайды по автоматизации, парсингу и Python.
👉 Ваш интерес — лучшая мотивация для новых статей!

Оставьте комментарий