"Muszę przeszukać 50 umów pod kątem konkretnej klauzuli."
"Chcę zrobić RAG na dokumentach firmowych, ale najpierw muszę je sparsować."
PDF to jeden z najczęstszych formatów w biznesie — i jeden z najbardziej upierdliwych do przetwarzania programistycznie. Ale w Pythonie mamy narzędzia, które robią to dobrze. I za darmo.
{% youtube "-f80-a-OM_s" %}
Trzy podejścia, trzy biblioteki
| Biblioteka | Najlepsza do | Szybkość | Tabele | Skany |
|---|---|---|---|---|
| pdfplumber | Tekst + tabele | Średnia | Świetne | Nie |
| PyMuPDF (fitz) | Szybka ekstrakcja | Bardzo szybka | Podstawowe | Nie |
| Tesseract OCR | Zeskanowane PDF-y | Wolna | Nie | Tak |
Którą wybrać? Zależy od Twoich PDF-ów. Pokażę każdą.
pdfplumber — król tabel
Jeśli Twoje PDF-y mają tabele (faktury, raporty, zestawienia), pdfplumber jest najlepszym wyborem.
Bash1pip install pdfplumber
Ekstrakcja tekstu
Python1 2 3 4 5 6import pdfplumber with pdfplumber.open("faktura.pdf") as pdf: for page in pdf.pages: text = page.extract_text() print(text)
Ekstrakcja tabel
Python1 2 3 4 5 6 7 8 9import pdfplumber import csv with pdfplumber.open("raport.pdf") as pdf: for page in pdf.pages: tables = page.extract_tables() for table in tables: for row in table: print(row) # lista komórek
pdfplumber rozpoznaje linie tabeli i poprawnie dzieli dane na kolumny. Dla faktur i raportów finansowych to game changer.
Praktyczny przykład: parsowanie faktur
Python1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21import pdfplumber import re def parse_invoice(path): with pdfplumber.open(path) as pdf: text = pdf.pages[0].extract_text() # Wyciągnij kluczowe dane nip = re.search(r"NIP[:\s]*(\d{10})", text) kwota = re.search(r"Do zapłaty[:\s]*([\d\s,]+)\s*(?:zł|PLN)", text) data = re.search(r"Data wystawienia[:\s]*(\d{2}[./-]\d{2}[./-]\d{4})", text) return { "nip": nip.group(1) if nip else None, "kwota": kwota.group(1).strip() if kwota else None, "data": data.group(1) if data else None, } result = parse_invoice("faktura.pdf") print(result) # {'nip': '1234567890', 'kwota': '1 230,00', 'data': '15.03.2026'}
PyMuPDF (fitz) — prędkość i precyzja
PyMuPDF jest 3-5x szybszy niż pdfplumber. Jeśli przetwarzasz tysiące dokumentów, różnica jest ogromna.
Bash1pip install PyMuPDF
Ekstrakcja tekstu
Python1 2 3 4 5 6import fitz # PyMuPDF doc = fitz.open("dokument.pdf") for page in doc: text = page.get_text() print(text)
Ekstrakcja z pozycjonowaniem (bounding boxy)
Python1 2 3 4 5 6 7 8 9 10import fitz doc = fitz.open("dokument.pdf") page = doc[0] # Tekst z pozycjami — przydatne gdy układ strony jest ważny blocks = page.get_text("blocks") for block in blocks: x0, y0, x1, y1, text, block_no, block_type = block print(f"[{x0:.0f},{y0:.0f}] {text[:60]}")
To jest przydatne gdy musisz wiedzieć gdzie na stronie jest tekst — np. lewy górny róg to nadawca, prawy to odbiorca.
Benchmark
| Operacja | pdfplumber | PyMuPDF |
|---|---|---|
| 10 stron | 0.8s | 0.15s |
| 100 stron | 7.2s | 1.1s |
| 1000 stron | 68s | 9s |
Dla batch processingu różnica jest znacząca.
Tesseract OCR — dla skanów
Gdy PDF jest zeskanowanym obrazem (nie ma warstwy tekstowej), potrzebujesz OCR.
Bash1 2pip install pytesseract pdf2image Pillow # + zainstaluj Tesseract: sudo apt install tesseract-ocr tesseract-ocr-pol
Python1 2 3 4 5 6 7 8 9 10 11from pdf2image import convert_from_path import pytesseract # Konwertuj PDF na obrazy images = convert_from_path("skan.pdf", dpi=300) for i, img in enumerate(images): # OCR z polskim językiem text = pytesseract.image_to_string(img, lang="pol") print(f"--- Strona {i+1} ---") print(text)
OCR nie jest idealny — jakość zależy od:
- DPI skanu — 300 DPI minimum
- Jakość oryginału — przekrzywione, rozmazane = słabe wyniki
- Język — Tesseract ma model dla polskiego (
pol), ale nie jest perfekcyjny
Tip: sprawdź czy PDF potrzebuje OCR
Python1 2 3 4 5 6 7 8 9 10 11import fitz def needs_ocr(pdf_path): doc = fitz.open(pdf_path) text = doc[0].get_text().strip() return len(text) < 50 # Jeśli mniej niż 50 znaków → prawdopodobnie skan if needs_ocr("dokument.pdf"): print("Ten PDF to skan — użyj OCR") else: print("Tekst dostępny — użyj pdfplumber/PyMuPDF")
Bonus: PDF + LLM = automatyczna analiza
Po wyciągnięciu tekstu możesz go podać do LLM i poprosić o analizę:
Python1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18import fitz import anthropic # 1. Ekstrakcja tekstu doc = fitz.open("umowa.pdf") text = "\n".join(page.get_text() for page in doc) # 2. Analiza przez Claude client = anthropic.Anthropic() msg = client.messages.create( model="claude-haiku-4-5-20251001", max_tokens=1024, messages=[{ "role": "user", "content": f"Przeanalizuj tę umowę. Wyciągnij: strony, przedmiot, kwotę, terminy, kary.\n\n{text[:3000]}" }] ) print(msg.content[0].text)
To jest fundament systemów RAG, automatycznej analizy dokumentów i chatbotów firmowych.
Które podejście wybrać?
- Faktury, raporty z tabelami → pdfplumber
- Duże ilości dokumentów tekstowych → PyMuPDF
- Skany, zdjęcia dokumentów → Tesseract OCR
- Mix → PyMuPDF do szybkiego sprawdzenia + fallback na OCR
Podsumowanie
- Python ma 3 świetne biblioteki do PDF: pdfplumber (tabele), PyMuPDF (szybkość), Tesseract (skany)
- Nie potrzebujesz płatnych API — wszystko działa lokalnie
- pdfplumber najlepszy do faktur i raportów tabelarycznych
- PyMuPDF 3-5x szybszy, idealny do batch processingu
- Tesseract OCR jako fallback dla zeskanowanych dokumentów
- Połącz z LLM (Claude/GPT) do automatycznej analizy dokumentów
Ten temat — ekstrakcja danych z dokumentów — jest fundamentem automatyzacji w firmie. Jeśli chcesz pójść dalej i zbudować pełny pipeline (PDF → analiza → akcja), sprawdź mój kurs n8n.



