Wyodrębnianie tekstu z PDFów za pomocą PDFMinera w Pythonie
Zdobyj wiedzę na temat ekstrakcji tekstu z plików PDF w Pythonie
PDFMiner.six to potężna biblioteka Pythona do ekstrakcji tekstu, metadanych i informacji o układzie z dokumentów PDF.
W przeciwieństwie do prostych czytników PDF, oferuje głęboką analizę struktury PDF i skutecznie obsługuje złożone układy.

Co to jest PDFMiner i dlaczego warto go używać?
PDFMiner to biblioteka napisana w czystym Pythonie, zaprojektowana do ekstrakcji i analizy tekstu z dokumentów PDF. Wersja .six to aktywnie utrzymywana wersja rozgałęzienia, która obsługuje Python 3.x, podczas gdy oryginalny projekt PDFMiner nie jest już aktualizowany.
Główne funkcje:
- Implementacja w czystym Pythonie (brak zależności zewnętrznych)
- Szczegółowa analiza układu i pozycjonowanie tekstu
- Wykrywanie kodowania czcionek i znaków
- Obsługa zaszyfrowanych PDF
- Wbudowane narzędzia wiersza poleceń
- Rozszerzalna architektura do niestandardowej obróbki
PDFMiner jest szczególnie przydatny, gdy potrzebujesz precyzyjnego kontroli nad ekstrakcją tekstu, musisz zachować informacje o układzie lub pracujesz z złożonymi dokumentami wielokolumnowymi. Choć może być wolniejszy niż niektóre alternatywy, jego dokładność i możliwości analizy sprawiają, że jest preferowanym wyborem w potokach przetwarzania dokumentów. Dla odwrotnej procedury, możesz również zainteresować się generowaniem PDF w Pythonie.
Instalacja i konfiguracja
Zainstaluj PDFMiner.six za pomocą pip:
pip install pdfminer.six
Dla środowisk wirtualnych (zalecane):
python -m venv venv
source venv/bin/activate # Na Windows: venv\Scripts\activate
pip install pdfminer.six
Jeśli jesteś nowy w zarządzaniu pakietami Pythona, sprawdź nasz szczególnik Pythona dla więcej informacji na temat pip i środowisk wirtualnych.
Weryfikacja instalacji:
pdf2txt.py --version
Biblioteka zawiera kilka narzędzi wiersza poleceń:
pdf2txt.py- Ekstrakcja tekstu z PDFdumppdf.py- Wyświetlanie wewnętrznej struktury PDFlatin2ascii.py- Konwersja znaków łacińskich na ASCII
Te narzędzia uzupełniają inne narzędzia do manipulacji PDF, takie jak Poppler, które oferują dodatkowe funkcje, takie jak ekstrakcja stron i konwersja formatów.
Podstawowa ekstrakcja tekstu
Prosta ekstrakcja tekstu
Najprostszy sposób na ekstrakcję tekstu z PDF:
from pdfminer.high_level import extract_text
# Ekstrakcja wszystkiego tekstu z PDF
text = extract_text('document.pdf')
print(text)
Ten wyższy poziom API obsługuje większość typowych przypadków użycia i zwraca cały dokument jako pojedynczy ciąg znaków.
Ekstrakcja tekstu z konkretnych stron
Aby wyodrębnić tekst z konkretnych stron:
from pdfminer.high_level import extract_text
# Ekstrakcja tekstu ze stron 2-5 (indeksowane od 0)
text = extract_text('document.pdf', page_numbers=[1, 2, 3, 4])
print(text)
To szczególnie przydatne w przypadku dużych dokumentów, gdzie potrzebujesz tylko niektórych sekcji, znacząco poprawiając wydajność.
Ekstrakcja tekstu z iteracji stron
Dla przetwarzania stron indywidualnie:
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())
Ten podejście daje większą kontrolę nad tym, jak każda strona jest przetwarzana, przydatne przy pracy z dokumentami, gdzie struktura stron się różni.
Zaawansowana analiza układu
Zrozumienie LAParams
LAParams (Parametry analizy układu) kontrolują, jak PDFMiner interpretuje układ dokumentu. Zrozumienie różnicy między PDFMiner a prostszymi bibliotekami jest tutaj kluczowe - PDFMiner analizuje faktyczne relacje przestrzenne między elementami tekstu.
from pdfminer.high_level import extract_text
from pdfminer.layout import LAParams
# Utwórz niestandardowe LAParams
laparams = LAParams(
line_overlap=0.5, # Minimalny nakładanie się linii tekstu
char_margin=2.0, # Margines znaku
line_margin=0.5, # Margines linii
word_margin=0.1, # Przestrzeń między słowami
boxes_flow=0.5, # Próg przepływu pudełek
detect_vertical=True, # Wykrywanie tekstu pionowego
all_texts=False # Ekstrakcja tylko tekstu w pudełkach
)
text = extract_text('document.pdf', laparams=laparams)
Wyjaśnienie parametrów:
line_overlap: Jaka musi być minimalna ilość nakładania się linii, by były uznane za tę samą linię (0.0-1.0)char_margin: Maksymalna odległość między znakami w tym samym słowie (jako wielokrotność szerokości znaku)line_margin: Maksymalna odległość między liniami w tym samym akapicieword_margin: Próg odległości do oddzielania słówboxes_flow: Próg kierunku przepływu pudełek tekstudetect_vertical: Włączenie wykrywania tekstu pionowego (często występującego w językach azjatyckich)
Ekstrakcja informacji o układzie
Pobierz szczegółowe informacje o pozycji i czcionce:
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):
# Pobierz współrzędne pudełka
x0, y0, x1, y1 = element.bbox
print(f"Tekst w ({x0}, {y0}): {element.get_text()}")
# Iteruj przez linie
for text_line in element:
if isinstance(text_line, LTTextLine):
# Pobierz szczegółowe informacje o znakach
for char in text_line:
if isinstance(char, LTChar):
print(f"Znak: {char.get_text()}, "
f"Czcionka: {char.fontname}, "
f"Rozmiar: {char.height}")
Taki poziom szczegółowości jest nieoceniony przy analizie dokumentów, ekstrakcji formularzy lub gdy potrzebujesz zrozumienia struktury dokumentu programistycznie.
Obsługa różnych typów PDF
Zaszyfrowane PDF
PDFMiner potrafi obsługiwać PDF z hasłem:
from pdfminer.high_level import extract_text
# Ekstrakcja z zaszyfrowanego PDF
text = extract_text('encrypted.pdf', password='your_password')
Uwaga: PDFMiner może ekstrahować tylko tekst z PDF - nie potrafi obejść ograniczeń bezpieczeństwa, które uniemożliwiają ekstrakcję tekstu na poziomie PDF.
Dokumenty wielokolumnowe
Dla dokumentów z wieloma kolumnami, dostosuj LAParams:
from pdfminer.high_level import extract_text
from pdfminer.layout import LAParams
# Optymalizacja dla układów wielokolumnowych
laparams = LAParams(
detect_vertical=False,
line_margin=0.3,
word_margin=0.1,
boxes_flow=0.3 # Niższa wartość dla lepszej detekcji kolumn
)
text = extract_text('multi_column.pdf', laparams=laparams)
Parametr boxes_flow jest szczególnie ważny dla dokumentów wielokolumnowych - niższe wartości pomagają PDFMinerowi rozróżniać między oddzielnymi kolumnami.
Tekst nieangielski i Unicode
PDFMiner dobrze obsługuje Unicode, ale upewnij się, że kodowanie jest poprawne:
from pdfminer.high_level import extract_text
# Ekstrakcja tekstu z obsługą Unicode
text = extract_text('multilingual.pdf', codec='utf-8')
# Zapisz do pliku z kodowaniem UTF-8
with open('output.txt', 'w', encoding='utf-8') as f:
f.write(text)
Praca z zeskanowanymi PDF
PDFMiner nie może bezpośrednio ekstrahować tekstu z zeskanowanych PDF (obrazów). Te wymagają OCR (Optyczne rozpoznawanie znaków). Jednak możesz połączyć PDFMiner z narzędziami OCR.
Oto jak wykryć, czy PDF jest zeskanowany i wymaga 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):
"""Sprawdzenie, czy PDF wydaje się być zeskanowany (przeważnie obrazy)"""
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
# Jeśli przeważnie obrazy i mało tekstu, prawdopodobnie zeskanowany
return image_count > text_count * 2
if is_scanned_pdf('document.pdf'):
print("Ten PDF wydaje się być zeskanowany - użyj OCR")
else:
text = extract_text('document.pdf')
print(text)
Dla zeskanowanych PDF rozważ połączenie z Tesseract OCR lub użycie narzędzi do ekstrakcji obrazów z PDF wcześniej, a następnie zastosowanie OCR do tych obrazów.
Użycie wiersza poleceń
PDFMiner zawiera potężne narzędzia wiersza poleceń:
Ekstrakcja tekstu za pomocą narzędzi wiersza poleceń
# Ekstrakcja tekstu do stdout
pdf2txt.py document.pdf
# Zapis do pliku
pdf2txt.py -o output.txt document.pdf
# Ekstrakcja konkretnych stron
pdf2txt.py -p 1,2,3 document.pdf
# Ekstrakcja jako HTML
pdf2txt.py -t html -o output.html document.pdf
Zaawansowane opcje
# Niestandardowe parametry układu
pdf2txt.py -L 0.3 -W 0.1 document.pdf
# Ekstrakcja z szczegółową analizą układu (XML)
pdf2txt.py -t xml -o layout.xml document.pdf
# Ustawienie hasła dla zaszyfrowanego PDF
pdf2txt.py -P mypassword encrypted.pdf
Te narzędzia wiersza poleceń są doskonałe do szybkiego testowania, skryptów wiersza poleceń i integracji do automatycznych potoków pracy.
Optymalizacja wydajności
Przetwarzanie dużych PDF
Dla dużych dokumentów, rozważ te strategie optymalizacji:
from pdfminer.high_level import extract_pages
from pdfminer.layout import LAParams
# Przetwarzanie tylko potrzebnych stron
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
# Wyłączenie analizy układu dla prędkości
from pdfminer.high_level import extract_text
text = extract_text('large.pdf', laparams=None) # O wiele szybszy
Przetwarzanie wsadowe
Dla efektywnego przetwarzania wielu PDF:
from multiprocessing import Pool
from pdfminer.high_level import extract_text
import os
def process_pdf(pdf_path):
"""Przetwarzanie pojedynczego pliku 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"Przetworzono: {pdf_path}"
except Exception as e:
return f"Błąd podczas przetwarzania {pdf_path}: {str(e)}"
# Przetwarzanie PDF w równoległych wątkach
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)
# Użycie
batch_process_pdfs('/path/to/pdfs', num_workers=4)
Typowe problemy i rozwiązania
Problem: Nieprawidłowy porządek tekstu
Problem: Ekstrahowany tekst wydaje się zamieszany lub w złej kolejności.
Rozwiązanie: Dostosuj LAParams, szczególnie boxes_flow:
from pdfminer.layout import LAParams
laparams = LAParams(boxes_flow=0.3) # Spróbuj różnych wartości
text = extract_text('document.pdf', laparams=laparams)
Problem: Brak spacji między słowami
Problem: Słowa łączą się bez spacji.
Rozwiązanie: Zwiększ word_margin:
laparams = LAParams(word_margin=0.2) # Zwiększ od domyślnego 0.1
text = extract_text('document.pdf', laparams=laparams)
Problem: Błędy kodowania
Problem: Strzeżne znaki lub błędy kodowania.
Rozwiązanie: Określ kodowanie jawne:
text = extract_text('document.pdf', codec='utf-8')
Problem: Błędy pamięci z dużymi PDF
Problem: Błędy przekroczenia pamięci z dużymi plikami.
Rozwiązanie: Przetwarzaj stronę po stronie:
def extract_text_chunked(pdf_path, chunk_size=10):
"""Ekstrakcja tekstu w fragmentach, aby zmniejszyć zużycie pamięci"""
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
# Przetwarzanie w fragmentach
if page_count % chunk_size == 0:
yield ''.join(all_text)
all_text = []
# Wydaj pozostały tekst
if all_text:
yield ''.join(all_text)
Porównanie PDFMiner z alternatywami
Zrozumienie, kiedy używać PDFMiner w porównaniu do innych bibliotek jest ważne:
PDFMiner vs PyPDF2
PyPDF2 jest prostszy i szybszy, ale mniej dokładny:
- Użyj PyPDF2 do: Prostych PDF, szybkiej ekstrakcji, łączenia i dzielenia PDF
- Użyj PDFMiner do: Złożonych układów, dokładnego pozycjonowania tekstu, szczegółowej analizy
PDFMiner vs pdfplumber
pdfplumber opiera się na PDFMinerze z wyższym poziomem API:
- Użyj pdfplumber do: Ekstrakcji tabel, prostszego API, szybkiego prototypowania
- Użyj PDFMiner do: Maksymalnej kontroli, niestandardowej obróbki, systemów produkcyjnych
PDFMiner vs PyMuPDF (fitz)
PyMuPDF jest znacznie szybszy, ale ma zależności w języku C:
- Użyj PyMuPDF do: Aplikacji krytycznych pod względem wydajności, dużoskalowego przetwarzania
- Użyj PDFMiner do: Wymagań czystego Pythona, szczegółowej analizy układu
Przykładowy przykład: Ekstrakcja i analiza dokumentu
Oto kompletny przykład, który ekstrahuje tekst i dostarcza statystyki dokumentu:
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):
"""Ekstrakcja tekstu i dostarczanie analizy dokumentu"""
# Ekstrakcja pełnego tekstu
full_text = extract_text(pdf_path)
# Statystyki
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
}
# Szczegółowa analiza
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
}
# Użycie
result = analyze_pdf('document.pdf')
print(f"Strony: {result['stats']['pages']}")
print(f"Słowa: {result['stats']['total_words']}")
print(f"Główna czcionka: {result['most_common_font']}")
print(f"Główny rozmiar: {result['most_common_size']}")
Integracja z potokami przetwarzania dokumentów
PDFMiner działa dobrze w większych potokach przetwarzania dokumentów. Na przykład, przy budowaniu systemów RAG (Retrieval-Augmented Generation) lub rozwiązań zarządzania dokumentami, możesz połączyć go z innymi narzędziami Pythona dla kompletnego potoku.
Po wyekstrahowaniu tekstu z PDF, często potrzebujesz konwersji do innych formatów. Możesz przekonwertować zawartość HTML na Markdown za pomocą bibliotek Pythona lub nawet wykorzystać konwersję z wykorzystaniem LLM i Ollama dla inteligentnej transformacji dokumentów. Te techniki są szczególnie przydatne, gdy ekstrakcja z PDF generuje strukturalny tekst podobny do HTML, który wymaga czyszczenia i ponownego formatowania.
Dla kompletnych potoków konwersji dokumentów, możesz również potrzebować obsługi konwersji dokumentów Word do Markdown, tworząc jednolity potok, który przetwarza wiele formatów dokumentów do wspólnego formatu wyjściowego.
Praktyczne wskazówki
-
Zawsze używaj LAParams dla złożonych dokumentów - Ustawienia domyślne działają dla prostych dokumentów, ale dostosowanie LAParams znacząco poprawia wyniki dla złożonych układów.
-
Testuj z próbnych stron - Przed przetwarzaniem dużych partii, przetestuj swoje ustawienia ekstrakcji na reprezentatywnych próbkach.
-
Zachowuj wyjątki w sposób łagodny - Pliki PDF mogą być uszkodzone lub źle sformatowane. Zawsze opakuj kod ekstrakcji w bloki try-except.
-
Kachuj wyekstrahowany tekst - Dla wielokrotnego przetwarzania, kachuj wyekstrahowany tekst, aby uniknąć ponownego przetwarzania.
-
Weryfikuj jakość wyekstrahowanego tekstu - Zaimplementuj sprawdzenia, aby zweryfikować jakość ekstrakcji (np. minimalna długość tekstu, oczekiwane słowa kluczowe).
-
Rozważ alternatywy dla konkretnych przypadków użycia - Choć PDFMiner jest potężny, czasami specjalistyczne narzędzia (np. tabula-py dla tabel) są bardziej odpowiednie.
-
Zawsze aktualizuj PDFMiner - Wersja
.sixjest aktywnie utrzymywana. Aktualizuj ją, aby uzyskać poprawki błędów i poprawki. -
Dokumentuj swój kod odpowiednio - Gdy udostępniasz skrypty ekstrakcji PDF, używaj odpowiednich bloków kodu w Markdown z wyróżnieniem składni dla lepszej czytelności.
Podsumowanie
PDFMiner.six to niezbędne narzędzie dla programistów Pythona pracujących z dokumentami PDF. Jego implementacja w czystym Pythonie, szczegółowa analiza układu i rozszerzalna architektura sprawiają, że jest idealne do systemów przetwarzania dokumentów w produkcji. Choć może mieć steeper learning curve niż prostsze biblioteki, precyzja i kontrola, które oferuje, są nie do przeoczenia dla złożonych zadań ekstrakcji PDF.
Czy jesteś budowaniem systemu zarządzania dokumentami, analizując naukowe artykuły, czy ekstrahując dane do potoków uczenia maszynowego, PDFMiner dostarcza fundamentów dla niezawodnej ekstrakcji tekstu z PDF w Pythonie.
Powiązane zasoby
Powiązane artykuły na tym serwisie
- Narzędzia do manipulacji PDF w Ubuntu - Poppler - Kompletny przewodnik po narzędziach wiersza poleceń do PDF, w tym pdftotext, pdfimages i innych narzędzi poppler, które współpracują z PDFMiner w potokach przetwarzania dokumentów
- Jak ekstrahować obrazy z PDF - Szczególnik - Naucz się, jak ekstrahować osadzone obrazy z PDF za pomocą narzędzi wiersza poleceń poppler, uzupełniając możliwości PDFMiner w ekstrakcji tekstu
- Generowanie PDF w Pythonie - Biblioteki i przykłady - Poznaj biblioteki Pythona do generowania PDF, w tym ReportLab, PyPDF2 i FPDF, aby stworzyć odwrotny potok ekstrakcji tekstu z PDF
- Szczególnik Pythona - Niezwykle ważna referencja do składni Pythona, w tym obsługa plików, operacje na łańcuchach i najlepsze praktyki przy pisaniu czystych skryptów przetwarzania PDF
- Konwersja HTML na Markdown w Pythonie: Kompletny przewodnik - Gdy budujesz potoki konwersji dokumentów, naucz się, jak konwertować HTML (wyekstrahowane z PDF lub z sieci) na format Markdown za pomocą bibliotek Pythona
- Konwersja zawartości HTML na Markdown za pomocą LLM i Ollama - Zaawansowana technika wykorzystująca lokalne LLM do inteligentnej konwersji zawartości HTML na Markdown, przydatna do czyszczenia wyekstrahowanego tekstu z PDF
- Użycie bloków kodu w Markdown - Zdobądź wiedzę na temat składni Markdown do dokumentowania swojego kodu ekstrakcji PDF z odpowiednim formatowaniem i wyróżnieniem składni
- Konwersja dokumentów Word do Markdown: Kompletny przewodnik - Kompletny przewodnik po konwersji dokumentów Word, PDF i innych formatów dla potoków przetwarzania dokumentów wieloplatformowych