Jak wyodrębnić tekst z pliku PDF w Pythonie (Porównanie 3 bibliotek)
Wyodrębnianie tekstu z pliku PDF wydaje się proste, ale każdy programista, który próbował, wie, że to pole usiane wyjątkami, zepsutymi układami i upartymi dokumentami opartymi na obrazach. Ten przewodnik przebija się przez ten szum. Zaczniemy od bezpośredniego porównania najlepszych bibliotek Pythona do tego zadania, dzięki czemu od razu wybierzesz odpowiednie narzędzie do swojego projektu.

Następnie przejdziemy przez przykłady kodu dla trzech najskuteczniejszych bibliotek — PyPDF2, pdfplumber i PyMuPDF (Fitz) — obejmując wszystko, od podstawowego skrobania tekstu po nawigację po złożonych tabelach. Zajmiemy się również najtrudniejszym wyzwaniem: zeskanowanymi plikami PDF, które wymagają optycznego rozpoznawania znaków (OCR), i pokażemy pragmatyczny sposób ich obsługi bez skomplikowanych lokalnych konfiguracji. Na koniec będziesz mieć kod i strategię do niezawodnego automatyzowania przepływów pracy związanych z przetwarzaniem plików PDF.
Szybki werdykt: Najlepsze biblioteki Pythona do ekstrakcji tekstu z PDF
Zanim zagłębimy się w kod, oto ogólny przegląd najlepszych kandydatów. Twój wybór będzie zależał wyłącznie od tego, czy potrzebujesz szybkości, prostoty, czy precyzyjnej analizy układu.
| Biblioteka | Najlepsze dla | Obsługa układu/tabel | Wydajność | Łatwość użycia (1-5) |
|---|---|---|---|---|
| PyPDF2 | Proste dokumenty tylko tekstowe; podstawowa manipulacja PDF (łączenie/dzielenie) | Słaba (wyodrębnia strumień tekstu, brak danych pozycyjnych) | Umiarkowana | 5 |
| pdfplumber | Wyodrębnianie danych z tabel; dokumenty o ustrukturyzowanych układach | Doskonała (dostarcza współrzędne dla tekstu, linii i prostokątów) | Wolniejsza | 4 |
| PyMuPDF (Fitz) | Szybkie przetwarzanie wsadowe; obsługa obrazów i adnotacji | Dobra (może wyodrębniać tekst z podstawowymi informacjami o pozycji) | Doskonała (najszybsza) | 4 |
Podsumowanie: Zacznij od PyPDF2 w najprostszych przypadkach. Przejdź do pdfplumber w momencie, gdy zobaczysz tabelę. Wybierz PyMuPDF, gdy wydajność jest Twoim głównym zmartwieniem.
Zanim zaczniesz: Konfiguracja środowiska Pythona
Aby zachować czystość zależności projektu i uniknąć konfliktów, zawsze pracuj w środowisku wirtualnym. Jest to bezwzględnie najlepsza praktyka dla każdego poważnego projektu w Pythonie.
Oto jak skonfigurować środowisko w terminalu:
-
Utwórz środowisko wirtualne:
# On macOS/Linux python3 -m venv pdf_env # On Windows python -m venv pdf_env -
Aktywuj je:
# On macOS/Linux source pdf_env/bin/activate # On Windows .\pdf_env\Scripts\activateW wierszu poleceń terminala powinno teraz pojawić się
(pdf_env). -
Zainstaluj biblioteki: Zainstalujemy wszystkie trzy porównywane biblioteki, abyś mógł łatwo eksperymentować.
pip install pypdf2 pdfplumber pymupdfDzięki temu Twoje środowisko jest gotowe na poniższe przykłady kodu.
Metoda 1: Podstawowa ekstrakcja tekstu za pomocą PyPDF2
PyPDF2 to podstawowa biblioteka do fundamentalnych operacji na plikach PDF. Jest prosta, istnieje od dawna i doskonale nadaje się do „natywnych” plików PDF, gdzie tekst jest możliwy do zaznaczenia i nie jest częścią obrazu. Jeśli Twoje dokumenty to proste raporty, artykuły lub eksporty tekstowe, PyPDF2 wykona zadanie przy minimalnej ilości kodu.
Główne ograniczenie? Odczytuje wewnętrzny strumień tekstu pliku PDF, który nie zawsze odpowiada wizualnej kolejności czytania, zwłaszcza w układach wielokolumnowych. Nie ma również pojęcia o tabelach; po prostu połączy cały tekst komórek w jedną całość.
Oto prosty skrypt do ekstrakcji całego tekstu z pliku PDF:
# requirements: pip install pypdf2
import PyPDF2
def extract_text_with_pypdf2(pdf_path):
"""
Extracts text from a PDF file using the PyPDF2 library.
Args:
pdf_path (str): The file path to the PDF.
Returns:
str: The extracted text content, or an error message.
"""
try:
with open(pdf_path, 'rb') as file:
reader = PyPDF2.PdfReader(file)
num_pages = len(reader.pages)
print(f"Total pages: {num_pages}")
full_text = ""
for page_num in range(num_pages):
page = reader.pages[page_num]
full_text += page.extract_text() + "\n"
return full_text
except FileNotFoundError:
return f"Error: The file at {pdf_path} was not found."
except Exception as e:
return f"An unexpected error occurred: {e}"
# --- Usage Example ---
pdf_file = 'path/to/your/document.pdf'
extracted_text = extract_text_with_pypdf2(pdf_file)
if "Error" not in extracted_text:
print("--- Extracted Text ---")
print(extracted_text)
else:
print(extracted_text)
Ten skrypt działa pięknie dla prostego, jednokolumnowego tekstu. Ale co się dzieje, gdy podasz mu sprawozdanie finansowe z uporządkowanymi tabelami? Otrzymasz pomieszany tekst i liczby bez struktury. Właśnie tutaj nasza następna biblioteka błyszczy.
Metoda 2: Obsługa tabel i układów za pomocą pdfplumber
Gdy Twoje zadanie obejmuje ekstrakcję danych strukturalnych, pdfplumber jest właściwym narzędziem. Zbudowany na bazie pdfminer.six, został zaprojektowany, aby zapewnić szczegółowy dostęp do geometrii strony PDF. „Widzi” znaki, linie i prostokąty, a także posiada fantastyczną wbudowaną metodę do wykrywania i ekstrakcji tabel.
To zmienia zasady gry w dziedzinie nauki o danych i automatyzacji biznesu. Wyobraź sobie próbę wyciągnięcia kwartalnych zarobków z raportu PDF firmy. Z PyPDF2 to koszmar parsowania ciągów znaków. Z pdfplumber możesz pobrać dane jako czystą listę list, gotową do użycia w Pandas DataFrame.
Głównym powodem, dla którego pdfplumber przewyższa PyPDF2 w przypadku danych strukturalnych, jest jego zdolność do interpretowania układu wizualnego, a nie tylko surowego strumienia tekstu. Rozumie, że pewne elementy tekstowe są wyrównane w wierszach i kolumnach, oddzielone liniami.
Oto jak wyodrębnić tabele ze strony PDF:
# requirements: pip install pdfplumber
import pdfplumber
import pandas as pd
def extract_tables_with_pdfplumber(pdf_path, page_number=0):
"""
Extracts all tables from a specific page of a PDF using pdfplumber.
Args:
pdf_path (str): The file path to the PDF.
page_number (int): The page number to extract tables from (0-indexed).
Returns:
list of pandas.DataFrame: A list where each element is a DataFrame
representing a table found on the page.
"""
tables = []
try:
with pdfplumber.open(pdf_path) as pdf:
if page_number >= len(pdf.pages):
print(f"Error: Page {page_number} is out of range. The PDF has {len(pdf.pages)} pages.")
return tables
page = pdf.pages[page_number]
# .extract_tables() is the key method here
extracted_tables = page.extract_tables()
for table_data in extracted_tables:
# Convert the list of lists into a pandas DataFrame
df = pd.DataFrame(table_data[1:], columns=table_data[0])
tables.append(df)
return tables
except FileNotFoundError:
print(f"Error: The file at {pdf_path} was not found.")
return tables
except Exception as e:
print(f"An unexpected error occurred: {e}")
return tables
# --- Usage Example ---
# You'll need pandas for this example: pip install pandas
pdf_file_with_table = 'path/to/your/report.pdf'
all_tables = extract_tables_with_pdfplumber(pdf_file_with_table, page_number=0)
if all_tables:
print(f"Found {len(all_tables)} table(s) on page 0.")
for i, table_df in enumerate(all_tables):
print(f"\n--- Table {i+1} ---")
print(table_df)
else:
print("No tables found on the specified page.")
Kompromisem dla tej precyzji jest szybkość. pdfplumber wykonuje więcej pracy analizując stronę, więc jest z natury wolniejszy niż biblioteki, które po prostu zrzucają tekst.
Metoda 3: Wysokowydajna ekstrakcja za pomocą PyMuPDF (Fitz)
Gdy musisz szybko przetwarzać setki lub tysiące plików PDF, wydajność staje się decydującym czynnikiem. W tym miejscu PyMuPDF, który importujesz jako fitz, dominuje. Jest to wiązanie Pythona dla MuPDF, lekkiej biblioteki C, co czyni go wyjątkowo szybkim.
Miałem kiedyś projekt, który wymagał przetworzenia kilku tysięcy wielostronicowych dokumentów prawnych. Mój początkowy skrypt pdfplumber miał zająć godziny. Przejście na PyMuPDF skróciło czas wykonania do mniej niż 30 minut. Różnica w szybkości jest tak dramatyczna.
Poza szybkością, PyMuPDF to potęga funkcji. Może renderować strony jako obrazy (kluczowe dla przepływów pracy OCR), wyodrębniać osadzone obrazy i obsługiwać adnotacje. Chociaż jego ekstrakcja tabel nie jest tak gotowa do użycia jak w pdfplumber, jego szybkość ekstrakcji surowego tekstu jest niezrównana.
Oto odpowiednik PyMuPDF do szybkiej ekstrakcji tekstu:
# requirements: pip install PyMuPDF
import fitz # The PyMuPDF library
def extract_text_with_pymupdf(pdf_path):
"""
Extracts text from a PDF file using the high-performance PyMuPDF (Fitz) library.
Args:
pdf_path (str): The file path to the PDF.
Returns:
str: The extracted text content, or an error message.
"""
try:
doc = fitz.open(pdf_path)
full_text = ""
for page in doc:
# .get_text() is the core function
full_text += page.get_text() + "\n"
doc.close()
return full_text
except FileNotFoundError:
return f"Error: The file at {pdf_path} was not found."
except Exception as e:
# PyMuPDF can raise specific errors, e.g., fitz.fitz.FitzError
return f"An error occurred with PyMuPDF: {e}"
# --- Usage Example ---
pdf_file = 'path/to/your/document.pdf'
fast_extracted_text = extract_text_with_pymupdf(pdf_file)
if "Error" not in fast_extracted_text:
print("--- Extracted Text (Fast Method) ---")
print(fast_extracted_text)
else:
print(fast_extracted_text)
Dla czystej przepustowości w przypadku plików PDF opartych na tekście, PyMuPDF jest niekwestionowanym mistrzem.
Przypadek specjalny: Obsługa zeskanowanych plików PDF za pomocą OCR
Możesz się zastanawiać: co się dzieje, gdy żadna z tych metod nie działa? Jeśli uruchomisz powyższy kod na zeskanowanym dokumencie — takim jak zdjęcie umowy lub zeskanowana strona książki — otrzymasz pusty ciąg znaków.
Dzieje się tak, ponieważ nie ma warstwy tekstowej. Plik PDF zawiera obraz, a nie znaki. Aby to rozwiązać, potrzebujesz optycznego rozpoznawania znaków (OCR), aby „przeczytać” obraz i przekształcić go w tekst czytelny maszynowo.
Standardowym rozwiązaniem w Pythonie jest pytesseract, wrapper dla silnika OCR Tesseract firmy Google. Chociaż jest potężny, wiąże się z dużym problemem: musisz zainstalować Tesseract oddzielnie w swoim systemie (np. za pomocą brew na Macu lub instalatora w systemie Windows) i upewnić się, że Python może znaleźć plik wykonywalny. Ta konfiguracja może być krucha, zwłaszcza podczas wdrażania kodu na serwerze lub udostępniania go współpracownikom.
Alternatywa: Wstępne przetwarzanie złożonych plików PDF za pomocą narzędzia bez kodu
Gdy masz mało czasu lub po prostu nie chcesz kłopotać się zarządzaniem zależnościami OCR, praktyczną alternatywą jest najpierw przekazanie ekstrakcji tekstu dedykowanemu narzędziu. Oddziela to złożony problem OCR od Twojej podstawowej logiki Pythona.
Narzędzie oparte na sztucznej inteligencji, takie jak ekstraktor tekstu PDF Lynote AI, może działać jako potężny preprocesor. Możesz przesłać swój trudny zeskanowany plik PDF, a narzędzie zajmie się OCR w tle, dostarczając czysty tekst, który następnie możesz wprowadzić do swojego skryptu. Jest to szczególnie przydatne w przypadku jednorazowych zadań lub gdy masz do czynienia z małą partią problematycznych plików.
Oto jak prosty jest ten przepływ pracy:
- Prześlij swój plik PDF. Przejdź do obszaru roboczego Lynote. W zakładce „Prześlij plik” możesz przeciągnąć i upuścić plik PDF lub przeglądać komputer, aby go wybrać. Działa to zarówno dla plików PDF opartych na tekście, jak i zeskanowanych plików PDF opartych na obrazach.
- Wyodrębnij tekst z pliku PDF. Po przesłaniu pliku kliknij przycisk „Utwórz notatkę”. Silnik AI Lynote przetwarza dokument, automatycznie stosując OCR, jeśli wykryje plik oparty na obrazie, i generuje czystą, przeszukiwalną wersję tekstową.
- Skopiuj wyodrębniony tekst. Gdy tekst pojawi się w edytorze, możesz go przejrzeć, wprowadzić drobne poprawki, a następnie użyć przycisku kopiowania, aby pobrać całą zawartość. Jest teraz w Twoim schowku, gotowy do wklejenia do skryptu Pythona jako zmienna typu string.


To podejście pozwala skupić się na części kodu dotyczącej analizy danych, a nie na infrastrukturze i obsłudze błędów lokalnej konfiguracji OCR.
Typowe pułapki i zaawansowane wskazówki
Ekstrakcja tekstu z plików PDF rzadko jest idealnym procesem. Oto kilka typowych problemów, na które prawdopodobnie natrafisz:
- Kodowanie znaków: Możesz napotkać
UnicodeDecodeError. Często zdarza się to w przypadku starszych plików PDF lub tych wygenerowanych przez nieznane oprogramowanie. Większość nowoczesnych bibliotek dobrze radzi sobie zUTF-8, ale określenie kodowania może czasami pomóc, jeśli biblioteka na to pozwala. - Pliki PDF chronione hasłem: Jeśli plik PDF wymaga hasła do otwarcia, wszystkie te biblioteki zawiodą. Musisz podać hasło podczas procesu otwierania. Na przykład,
PyPDF2.PdfReader(file, password='your_password'). - Utrata formatowania: Pamiętaj, że ekstrakcja tekstu prawie zawsze powoduje utratę formatowania, takiego jak pogrubienie, kursywa, rozmiar czcionki i kolor. Otrzymujesz surową zawartość tekstową, a nie wizualną reprezentację.
- Pomieszany tekst z kolumn: Jak wspomniano w przypadku PyPDF2, układy wielokolumnowe (jak w artykułach naukowych) mogą skutkować tekstem, który miesza linie z różnych kolumn.
pdfplumberznacznie lepiej radzi sobie z ich rozdzielaniem, ponieważ rozumie geometrię strony.
Wskazówka eksperta: Zawsze testuj swój skrypt na reprezentatywnej próbce dokumentów. Rozwiązanie, które działa idealnie na jednym pliku PDF, może całkowicie zawieść na innym, pochodzącym z innego źródła.
Często zadawane pytania
Dlaczego wyodrębniony tekst z mojej tabeli zamienił się w jeden długi, nieuporządkowany ciąg znaków?
Jest to klasyczny tryb awarii bibliotek takich jak PyPDF2, które nie analizują układu strony. Odczytują one surowy strumień tekstu w kolejności, w jakiej jest przechowywany w pliku, co często nie odpowiada wizualnej strukturze wierszy i kolumn. Aby to naprawić, musisz użyć biblioteki świadomej układu, takiej jak **pdfplumber**, która jest specjalnie zaprojektowana do rozpoznawania danych tabelarycznych.
Czy Python może wyodrębnić tekst z określonego obszaru strony PDF?
Tak, ale potrzebujesz biblioteki, która dostarcza informacje o współrzędnych. pdfplumber i PyMuPDF są do tego doskonałe. Z pdfplumber możesz użyć metody .crop((x0, top, x1, bottom)) do utworzenia ramki ograniczającej, a następnie uruchomić .extract_text() lub .extract_tables() tylko w tym przyciętym obszarze.
Dlaczego wyodrębniony tekst z mojego zeskanowanego pliku PDF jest pusty?
Twój plik PDF zawiera obraz tekstu, a nie rzeczywiste dane tekstowe. Standardowe biblioteki nie potrafią „czytać” obrazów. Musisz użyć procesu optycznego rozpoznawania znaków (OCR). Możesz albo skonfigurować lokalny silnik OCR za pomocą pytesseract, albo użyć narzędzia do wstępnego przetwarzania, takiego jak Lynote, aby najpierw przekonwertować plik PDF oparty na obrazie na czysty tekst.
Jak radzić sobie z plikami PDF zawierającymi wiele języków?
Nowoczesne biblioteki, takie jak PyMuPDF i pdfplumber, zazwyczaj dobrze radzą sobie z Unicode (który obsługuje większość języków). Główne wyzwanie pojawia się podczas OCR. Tesseract, na przykład, wymaga pobrania i określenia pakietów językowych, których chcesz użyć (np. -l eng+fra dla angielskiego i francuskiego).
Podsumowanie: Wybór odpowiedniego narzędzia Pythona do PDF
Nie ma jednej „najlepszej” biblioteki do ekstrakcji tekstu z plików PDF w Pythonie. Właściwy wybór zawsze zależy od charakteru Twoich dokumentów i celów projektu.
Sprowadźmy to do prostego drzewa decyzyjnego:
- Jeśli Twoje pliki PDF to proste dokumenty tekstowe i potrzebujesz tylko surowej zawartości, PyPDF2 jest najłatwiejsze i najszybsze do zaimplementowania.
- Jeśli Twoje pliki PDF zawierają tabele lub ustrukturyzowane układy, które musisz przetworzyć na dane (np. do załadowania do bazy danych lub Pandas DataFrame), pdfplumber jest wyraźnym zwycięzcą.
- Jeśli przetwarzasz dużą liczbę dokumentów, a surowa szybkość jest Twoim priorytetem, PyMuPDF (Fitz) jest najpotężniejszą i najbardziej wydajną opcją.
- Jeśli masz do czynienia ze zeskanowanymi plikami PDF opartymi na obrazach, musisz użyć OCR. Aby uzyskać szybkie i niezawodne rozwiązanie bez problemów z lokalną konfiguracją, wstępne przetwarzanie pliku za pomocą zewnętrznego narzędzia jest często najbardziej pragmatyczną drogą, zanim wprowadzisz czysty tekst do środowiska Pythona.


