Извлечение текста из PDF-файлов с помощью PDFMiner в Python
Освойте извлечение текста из PDF с помощью Python
PDFMiner.six — это мощная библиотека Python для извлечения текста, метаданных и информации о макете из PDF-документов.
В отличие от простых PDF-ридеров, она предоставляет глубокий анализ структуры PDF и эффективно обрабатывает сложные макеты.

Что такое PDFMiner и зачем его использовать?
PDFMiner — это чистая библиотека Python, предназначенная для извлечения и анализа текста из PDF-документов. Версия .six — это активно поддерживаемая форка, которая поддерживает Python 3.x, в то время как оригинальный проект PDFMiner больше не обновляется.
Основные возможности:
- Чистая реализация на Python (нет внешних зависимостей)
- Детальный анализ макета и позиционирования текста
- Обнаружение шрифтов и кодировки символов
- Поддержка зашифрованных PDF
- Включены инструменты командной строки
- Расширяемая архитектура для пользовательской обработки
PDFMiner особенно полезен, когда вам нужна точная контроль над извлечением текста, необходимо сохранить информацию о макете или работать со сложными многоколонными документами. Хотя он может быть медленнее некоторых альтернатив, его точность и детальные возможности анализа делают его предпочтительным выбором для обработки документов. Для обратного рабочего процесса вам также может быть интересно программное создание PDF в Python.
Установка и настройка
Установите PDFMiner.six с помощью pip:
pip install pdfminer.six
Для виртуальных сред (рекомендуется):
python -m venv venv
source venv/bin/activate # На Windows: venv\Scripts\activate
pip install pdfminer.six
Если вы новичок в управлении пакетами Python, ознакомьтесь с нашим Python Cheatsheet для получения дополнительной информации о pip и виртуальных средах.
Проверьте установку:
pdf2txt.py --version
Библиотека включает несколько инструментов командной строки:
pdf2txt.py— извлечение текста из PDFdumppdf.py— дамп внутренней структуры PDFlatin2ascii.py— преобразование латинских символов в ASCII
Эти инструменты дополняют другие утилиты для работы с PDF, такие как Poppler, которые предоставляют дополнительные функции, такие как извлечение страниц и преобразование форматов.
Базовое извлечение текста
Простое извлечение текста
Самый простой способ извлечь текст из PDF:
from pdfminer.high_level import extract_text
# Извлечение всего текста из PDF
text = extract_text('document.pdf')
print(text)
Этот высокоуровневый API обрабатывает большинство распространенных случаев использования и возвращает весь документ в виде одной строки.
Извлечение текста с определенных страниц
Для извлечения текста с определенных страниц:
from pdfminer.high_level import extract_text
# Извлечение текста со страниц 2-5 (с нулевым индексом)
text = extract_text('document.pdf', page_numbers=[1, 2, 3, 4])
print(text)
Это особенно полезно для больших документов, где вам нужны только определенные разделы, значительно улучшая производительность.
Извлечение текста с итерацией по страницам
Для индивидуальной обработки страниц:
from pdfminer.high_level import extract_pages
from pdfminer.layout import LTTextContainer
for page_layout in extract_pages('document.pdf'):
for element in page_layout:
if isinstance(element, LTTextContainer):
print(element.get_text())
Этот подход дает вам больше контроля над тем, как каждая страница обрабатывается, что полезно при работе с документами, где структура страниц различается.
Продвинутый анализ макета
Понимание LAParams
Параметры LAParams (Layout Analysis Parameters) управляют тем, как PDFMiner интерпретирует макет документа. Понимание различий между PDFMiner и более простыми библиотеками здесь критически важно — PDFMiner фактически анализирует пространственные отношения между текстовыми элементами.
from pdfminer.high_level import extract_text
from pdfminer.layout import LAParams
# Создание пользовательских LAParams
laparams = LAParams(
line_overlap=0.5, # Минимальное перекрытие для текстовых строк
char_margin=2.0, # Отступ символа
line_margin=0.5, # Отступ строки
word_margin=0.1, # Отступ слова
boxes_flow=0.5, # Порог направления потока блоков
detect_vertical=True, # Обнаружение вертикального текста
all_texts=False # Извлечение только текста в блоках
)
text = extract_text('document.pdf', laparams=laparams)
Объяснение параметров:
line_overlap: Насколько строки должны перекрываться вертикально, чтобы считаться одной строкой (0.0-1.0)char_margin: Максимальное расстояние между символами в одном слове (как кратное ширине символа)line_margin: Максимальное расстояние между строками в одном абзацеword_margin: Пороговое значение расстояния для разделения словboxes_flow: Порог направления потока текстовых блоковdetect_vertical: Включение обнаружения вертикального текста (часто встречается в азиатских языках)
Извлечение информации о макете
Получение детальной информации о позиции и шрифте:
from pdfminer.high_level import extract_pages
from pdfminer.layout import LTTextBox, LTTextLine, LTChar
for page_layout in extract_pages('document.pdf'):
for element in page_layout:
if isinstance(element, LTTextBox):
# Получение координат ограничивающего прямоугольника
x0, y0, x1, y1 = element.bbox
print(f"Текст в ({x0}, {y0}): {element.get_text()}")
# Итерация по строкам
for text_line in element:
if isinstance(text_line, LTTextLine):
# Получение деталей на уровне символов
for char in text_line:
if isinstance(char, LTChar):
print(f"Символ: {char.get_text()}, "
f"Шрифт: {char.fontname}, "
f"Размер: {char.height}")
Этот уровень детализации бесценен для анализа документов, извлечения форм или когда вам нужно программно понять структуру документа.
Работа с различными типами PDF
Зашифрованные PDF
PDFMiner может обрабатывать защищенные паролем PDF:
from pdfminer.high_level import extract_text
# Извлечение из защищенного паролем PDF
text = extract_text('encrypted.pdf', password='your_password')
Обратите внимание, что PDFMiner может извлекать только текст из PDF — он не может обходить ограничения безопасности, которые предотвращают извлечение текста на уровне PDF.
Документы с несколькими колонками
Для документов с несколькими колонками настройте LAParams:
from pdfminer.high_level import extract_text
from pdfminer.layout import LAParams
# Оптимизация для макетов с несколькими колонками
laparams = LAParams(
detect_vertical=False,
line_margin=0.3,
word_margin=0.1,
boxes_flow=0.3 # Меньшее значение для лучшего обнаружения колонок
)
text = extract_text('multi_column.pdf', laparams=laparams)
Параметр boxes_flow особенно важен для документов с несколькими колонками — меньшие значения помогают PDFMiner различать отдельные колонки.
Нена английский и Unicode текст
PDFMiner хорошо обрабатывает Unicode, но убедитесь в правильной кодировке:
from pdfminer.high_level import extract_text
# Извлечение текста с поддержкой Unicode
text = extract_text('multilingual.pdf', codec='utf-8')
# Сохранение в файл с кодировкой UTF-8
with open('output.txt', 'w', encoding='utf-8') as f:
f.write(text)
Работа со сканированными PDF
PDFMiner не может извлекать текст из сканированных PDF (изображений) напрямую. Для этого требуется OCR (оптическое распознавание символов). Однако вы можете интегрировать PDFMiner с инструментами OCR.
Вот как определить, является ли PDF сканированным и требует ли OCR:
from pdfminer.high_level import extract_text
from pdfminer.high_level import extract_pages
from pdfminer.layout import LTFigure, LTImage
def is_scanned_pdf(pdf_path):
"""Проверка, является ли PDF сканированным (в основном изображениями)"""
text_count = 0
image_count = 0
for page_layout in extract_pages(pdf_path):
for element in page_layout:
if isinstance(element, (LTFigure, LTImage)):
image_count += 1
elif hasattr(element, 'get_text'):
if element.get_text().strip():
text_count += 1
# Если в основном изображения и мало текста, вероятно, это сканированный PDF
return image_count > text_count * 2
if is_scanned_pdf('document.pdf'):
print("Этот PDF, похоже, сканированный - используйте OCR")
else:
text = extract_text('document.pdf')
print(text)
Для сканированных PDF рассмотрите возможность интеграции с Tesseract OCR или использования инструментов для извлечения изображений из PDF сначала, а затем применения OCR к этим изображениям.
Использование командной строки
PDFMiner включает мощные инструменты командной строки:
Извлечение текста с помощью инструментов командной строки
# Извлечение текста в stdout
pdf2txt.py document.pdf
# Сохранение в файл
pdf2txt.py -o output.txt document.pdf
# Извлечение определенных страниц
pdf2txt.py -p 1,2,3 document.pdf
# Извлечение как HTML
pdf2txt.py -t html -o output.html document.pdf
Продвинутые параметры
# Пользовательские параметры макета
pdf2txt.py -L 0.3 -W 0.1 document.pdf
# Извлечение с детальным макетом (XML)
pdf2txt.py -t xml -o layout.xml document.pdf
# Установка пароля для защищенного PDF
pdf2txt.py -P mypassword encrypted.pdf
Эти инструменты командной строки отлично подходят для быстрого тестирования, скриптов оболочки и интеграции в автоматизированные рабочие процессы.
Оптимизация производительности
Обработка больших PDF-файлов
Для больших документов рассмотрите следующие стратегии оптимизации:
from pdfminer.high_level import extract_pages
from pdfminer.layout import LAParams
# Обрабатывать только нужные страницы
def extract_page_range(pdf_path, start_page, end_page):
text_content = []
for i, page_layout in enumerate(extract_pages(pdf_path)):
if i < start_page:
continue
if i >= end_page:
break
text_content.append(page_layout)
return text_content
# Отключить анализ макета для ускорения
from pdfminer.high_level import extract_text
text = extract_text('large.pdf', laparams=None) # Значительно быстрее
Пакетная обработка
Для эффективной обработки нескольких PDF-файлов:
from multiprocessing import Pool
from pdfminer.high_level import extract_text
import os
def process_pdf(pdf_path):
"""Обработка одного PDF-файла"""
try:
text = extract_text(pdf_path)
output_path = pdf_path.replace('.pdf', '.txt')
with open(output_path, 'w', encoding='utf-8') as f:
f.write(text)
return f"Обработано: {pdf_path}"
except Exception as e:
return f"Ошибка при обработке {pdf_path}: {str(e)}"
# Обработка PDF-файлов параллельно
def batch_process_pdfs(pdf_directory, num_workers=4):
pdf_files = [os.path.join(pdf_directory, f)
for f in os.listdir(pdf_directory)
if f.endswith('.pdf')]
with Pool(num_workers) as pool:
results = pool.map(process_pdf, pdf_files)
for result in results:
print(result)
# Использование
batch_process_pdfs('/path/to/pdfs', num_workers=4)
Распространенные проблемы и решения
Проблема: Некорректный порядок текста
Проблема: Извлеченный текст выглядит беспорядочно или в неправильном порядке.
Решение: Настройте параметры LAParams, особенно boxes_flow:
from pdfminer.layout import LAParams
laparams = LAParams(boxes_flow=0.3) # Попробуйте разные значения
text = extract_text('document.pdf', laparams=laparams)
Проблема: Отсутствие пробелов между словами
Проблема: Слова сливаются без пробелов.
Решение: Увеличьте word_margin:
laparams = LAParams(word_margin=0.2) # Увеличьте от значения по умолчанию 0.1
text = extract_text('document.pdf', laparams=laparams)
Проблема: Ошибки кодировки
Проблема: Странные символы или ошибки кодировки.
Решение: Укажите кодировку явно:
text = extract_text('document.pdf', codec='utf-8')
Проблема: Ошибки памяти при работе с большими PDF-файлами
Проблема: Ошибки нехватки памяти при работе с большими файлами.
Решение: Обрабатывать страницы по одной:
def extract_text_chunked(pdf_path, chunk_size=10):
"""Извлекать текст блоками для уменьшения использования памяти"""
all_text = []
page_count = 0
for page_layout in extract_pages(pdf_path):
page_text = []
for element in page_layout:
if hasattr(element, 'get_text'):
page_text.append(element.get_text())
all_text.append(''.join(page_text))
page_count += 1
# Обработка блоками
if page_count % chunk_size == 0:
yield ''.join(all_text)
all_text = []
# Возврат оставшегося текста
if all_text:
yield ''.join(all_text)
Сравнение PDFMiner с альтернативами
Понимание, когда использовать PDFMiner вместо других библиотек, важно:
PDFMiner vs PyPDF2
PyPDF2 проще и быстрее, но менее точен:
- Используйте PyPDF2 для: Простых PDF-файлов, быстрого извлечения, объединения/разделения PDF-файлов
- Используйте PDFMiner для: Сложных макетов, точного позиционирования текста, детального анализа
PDFMiner vs pdfplumber
pdfplumber строится на основе PDFMiner с более высокоуровневым API:
- Используйте pdfplumber для: Извлечения таблиц, более простого API, быстрого прототипирования
- Используйте PDFMiner для: Максимального контроля, пользовательской обработки, производственных систем
PDFMiner vs PyMuPDF (fitz)
PyMuPDF значительно быстрее, но имеет зависимости от C:
- Используйте PyMuPDF для: Приложений, требующих высокой производительности, массовой обработки
- Используйте PDFMiner для: Требований к чистому Python, детального анализа макета
Практический пример: Извлечение и анализ документа
Вот полный пример, который извлекает текст и предоставляет статистику документа:
from pdfminer.high_level import extract_pages, extract_text
from pdfminer.layout import LTTextBox, LTChar
from collections import Counter
import re
def analyze_pdf(pdf_path):
"""Извлекать текст и предоставлять анализ документа"""
# Извлечение полного текста
full_text = extract_text(pdf_path)
# Статистика
stats = {
'total_chars': len(full_text),
'total_words': len(full_text.split()),
'total_lines': full_text.count('\n'),
'fonts': Counter(),
'font_sizes': Counter(),
'pages': 0
}
# Детальный анализ
for page_layout in extract_pages(pdf_path):
stats['pages'] += 1
for element in page_layout:
if isinstance(element, LTTextBox):
for line in element:
for char in line:
if isinstance(char, LTChar):
stats['fonts'][char.fontname] += 1
stats['font_sizes'][round(char.height, 1)] += 1
return {
'text': full_text,
'stats': stats,
'most_common_font': stats['fonts'].most_common(1)[0] if stats['fonts'] else None,
'most_common_size': stats['font_sizes'].most_common(1)[0] if stats['font_sizes'] else None
}
# Использование
result = analyze_pdf('document.pdf')
print(f"Страницы: {result['stats']['pages']}")
print(f"Слова: {result['stats']['total_words']}")
print(f"Основной шрифт: {result['most_common_font']}")
print(f"Основной размер: {result['most_common_size']}")
Интеграция с конвейерами обработки документов
PDFMiner хорошо работает в более крупных конвейерах обработки документов. Например, при создании систем RAG (Retrieval-Augmented Generation) или решений для управления документами, вы можете комбинировать его с другими инструментами Python для создания полного конвейера.
После извлечения текста из PDF-файлов вам часто нужно преобразовать его в другие форматы. Вы можете преобразовать HTML-контент в Markdown с использованием библиотек Python или даже использовать преобразование с поддержкой LLM с Ollama для интеллектуального преобразования документов. Эти техники особенно полезны, когда извлечение PDF производит HTML-подобный структурированный текст, который требует очистки и переформатирования.
Для комплексных конвейеров преобразования документов вам также может понадобиться обрабатывать преобразование документов Word в Markdown, создавая унифицированный рабочий процесс, который обрабатывает несколько форматов документов в общий выходной формат.
Лучшие практики
-
Всегда используйте LAParams для сложных документов - Настройки по умолчанию работают для простых документов, но настройка LAParams значительно улучшает результаты для сложных макетов.
-
Тестируйте образцы страниц сначала - Перед обработкой больших партий протестируйте настройки извлечения на репрезентативных образцах.
-
Обрабатывайте исключения корректно - PDF-файлы могут быть повреждены или иметь неправильный формат. Всегда оборачивайте код извлечения в блоки try-except.
-
Кэшируйте извлеченный текст - Для повторной обработки кэшируйте извлеченный текст, чтобы избежать повторной обработки.
-
Проверяйте извлеченный текст - Реализуйте проверки для подтверждения качества извлечения (например, минимальная длина текста, ожидаемые ключевые слова).
-
Рассмотрите альтернативы для конкретных случаев использования - Хотя PDFMiner мощный, иногда специализированные инструменты (например, tabula-py для таблиц) более подходящие.
-
Держите PDFMiner в актуальном состоянии - Форк
.sixактивно поддерживается. Обновляйте его для исправления ошибок и улучшений. -
Документируйте свой код должным образом - При распространении скриптов извлечения PDF используйте правильные блоки кода Markdown с подсветкой синтаксиса для лучшей читаемости.
Заключение
PDFMiner.six - это важный инструмент для разработчиков Python, работающих с PDF-документами. Его чистая реализация на Python, детальный анализ макета и расширяемая архитектура делают его идеальным для производственных систем обработки документов. Хотя он может иметь более крутую кривую обучения, чем более простые библиотеки, точность и контроль, которые он предлагает, не имеют себе равных для сложных задач извлечения PDF.
Будь то создание системы управления документами, анализ научных статей или извлечение данных для конвейеров машинного обучения, PDFMiner предоставляет основу для надежного извлечения текста из PDF в Python.
Связанные ресурсы
Связанные статьи на этом сайте
- Инструменты для работы с PDF в Ubuntu - Poppler - Полное руководство по инструментам командной строки для работы с PDF, включая pdftotext, pdfimages и другие утилиты poppler, которые работают вместе с PDFMiner в рабочих процессах обработки документов
- Как извлечь изображения из PDF - Шпаргалка - Узнайте, как извлекать встроенные изображения из PDF с помощью инструментов командной строки poppler, дополняющих возможности извлечения текста PDFMiner
- Генерация PDF в Python - Библиотеки и примеры - Исследуйте Python-библиотеки для генерации PDF, включая ReportLab, PyPDF2 и FPDF, чтобы создать обратный рабочий процесс извлечения текста из PDF
- Шпаргалка по Python - Основные ссылки по синтаксису Python, включая работу с файлами, операции со строками и лучшие практики для написания чистых скриптов обработки PDF
- Конвертация HTML в Markdown с помощью Python: Полное руководство - При создании конвейеров конвертации документов узнайте, как преобразовывать HTML (извлеченный из PDF или веба) в формат Markdown с помощью Python-библиотек
- Конвертация HTML-контента в Markdown с использованием LLM и Ollama - Продвинутая техника использования локальных LLM для интеллектуального преобразования HTML-контента в Markdown, полезная для очистки извлеченного текста PDF
- Использование блоков кода Markdown - Освойте синтаксис Markdown для документирования вашего кода извлечения PDF с правильным форматированием и подсветкой синтаксиса
- Конвертация документов Word в Markdown: Полное руководство - Полное руководство по конвертации документов, включая Word, PDF и другие форматы для кроссплатформенных конвейеров обработки документов