Jeśli katalog PDF zawiera tekst, zacznij od jego bezpośredniego odczytu w Pythonie. Jeśli strony są obrazami, najpierw potrzebujesz OCR, czyli rozpoznawania tekstu na obrazie. W obu przypadkach wynik trzeba jeszcze podzielić na pola produktów i porównać z oryginałem. Sama możliwość skopiowania tekstu nie oznacza, że powstała poprawna tabela.
Najbezpieczniejszy proces wygląda tak: sprawdzenie stron PDF, ewentualny OCR, wydobycie tekstu, zapis kandydatów do CSV i kontrola przed importem. Poniższy przykład pokazuje ten proces dla prostego, hipotetycznego układu katalogu. Nie jest uniwersalnym narzędziem do każdego PDF-u.
1. Sprawdź, co naprawdę zawiera PDF
Otwórz katalog i spróbuj zaznaczyć oraz skopiować kod i nazwę kilku produktów. Wklej je do zwykłego edytora tekstu. Jeśli dostajesz czytelny tekst, możesz zacząć od bezpośredniego odczytu. Jeśli nie możesz zaznaczyć liter albo po wklejeniu pojawiają się nieczytelne znaki, sprawdź, czy strona nie jest skanem lub obrazem.
Nie ograniczaj testu do okładki i pierwszej strony. Jeden dokument może zawierać zarówno tekst, jak i strony obrazowe. Nawet istniejąca warstwa tekstowa bywa niekompletna lub zawiera błędy wcześniejszego OCR. Porównaj więc skopiowany fragment z tym, co widzisz w PDF-ie.
Biblioteka pypdf odczytuje tekst zapisany w PDF-ie, ale nie rozpoznaje liter na obrazach. Jej dokumentacja zwraca też uwagę na trudności z odtworzeniem kolejności tekstu i struktury tabel. Przykładowo elementy widoczne obok siebie na stronie mogą pojawić się w wyniku w innej kolejności.
| Co widzisz podczas sprawdzania? | Od czego zacząć? | Co skontrolować? |
|---|---|---|
| Tekst da się skopiować i jest czytelny | Odczyt przez pypdf | Kolejność pól, brakujące znaki i strony |
| Strona jest obrazem, bez czytelnego tekstu | OCR, a następnie odczyt tekstu | Zwłaszcza kody, liczby i polskie znaki |
| Dokument ma strony różnego rodzaju | Sprawdzenie każdej strony i dobranie ścieżki | Czy OCR nie pomija stron wymagających rozpoznania |
| Tekst istnieje, ale jest błędny | Ocena jakości warstwy tekstowej i ewentualne ponowne przetworzenie | Wpływ na istniejący tekst i zgodność z obrazem |
2. Ustal, jakie dane mają trafić do arkusza
Zanim napiszesz reguły, wybierz kilka reprezentatywnych stron: z typowymi pozycjami, długimi nazwami, nietypowym układem i gorszą jakością obrazu. Określ, które pola są potrzebne oraz jak rozpoznasz początek i koniec produktu.
Na początek wystarczą kod i nazwa. Jeśli potrzebujesz również jednostki, ceny albo wariantu, dodaj je dopiero po sprawdzeniu, czy da się je jednoznacznie przypisać do produktu. Cena bez informacji o walucie, jednostce czy rodzaju ceny może wprowadzić więcej problemów niż pożytku.
Do każdego wyniku warto dołączyć nazwę pliku i numer strony. Dzięki temu osoba sprawdzająca może szybko odnaleźć pozycję w katalogu. Zachowaj też oryginalne PDF-y oraz wersję po OCR osobno, żeby móc porównać wynik ze źródłem.
3. Gdy potrzebujesz OCR, dodaj warstwę tekstową
Jedną z lokalnych ścieżek jest OCRmyPDF, który wykorzystuje silnik Tesseract. Dokumentacja OCRmyPDF opisuje dodawanie warstwy tekstowej do zeskanowanych dokumentów. Potem Python może próbować odczytać tę warstwę tak jak inny tekst w PDF-ie.
Do rozpoznawania polskich tekstów potrzebujesz silnika Tesseract oraz polskich danych językowych. Instrukcja instalacji Tesseracta opisuje warianty dla różnych systemów, a dokumentacja plików językowych wyjaśnia rolę plików traineddata. Dostępność języka sprawdzisz poleceniem:
tesseract --list-langs
Na liście powinien znaleźć się pol. Po zainstalowaniu OCRmyPDF i jego zależności przykładowe polecenie dla dokumentu po polsku wygląda tak:
ocrmypdf -l pol --skip-text katalog.pdf katalog_ocr.pdf
Opcja --skip-text pozwala pominąć OCR na stronach, które już zawierają tekst. To przydatne w dokumentach mieszanych, ale ma ograniczenie: jeśli strona zawiera niewielką ilość tekstu oraz obraz z produktami, pominięcie OCR może pozostawić te produkty nierozpoznane. Istniejąca błędna warstwa tekstowa również nie zostanie przez to naprawiona. Takie strony wymagają osobnej oceny i dobrania sposobu ponownego przetwarzania. Przed uruchomieniem sprawdź opcje i zależności dla zainstalowanej wersji OCRmyPDF.
Przetwarzanie lokalne nie wymaga wysyłania katalogu do usługi chmurowej ani opłaty za stronę w takim wariancie. Nadal trzeba uwzględnić czas konfiguracji, zasoby komputera i kontrolę danych. Dostęp do firmowych katalogów oraz plików wynikowych powinien być ograniczony do osób, które ich potrzebują.
4. Odczytaj tekst stron w Pythonie
Zainstaluj bibliotekę pypdf w swoim środowisku Pythona:
python -m pip install pypdf
Najpierw obejrzyj surowy wynik. Uruchom poniższy kod w katalogu z plikiem katalog.pdf. Jeśli wcześniej wykonano OCR, podmień nazwę na katalog_ocr.pdf.
from pypdf import PdfReader
reader = PdfReader("katalog.pdf")
for numer, strona in enumerate(reader.pages, start=1):
tekst = strona.extract_text() or ""
print(f"\n--- Strona {numer} ---")
print(tekst[:1500])
Sprawdź wynik co najmniej dla kilku stron, również tych o innym układzie. Czy kod i nazwa występują w tym samym wierszu? Czy nazwa nie została podzielona? Czy tekst z dwóch kolumn nie został połączony? Ograniczenie do pierwszych 1500 znaków służy tu tylko szybkiemu podglądowi, nie analizie całej strony.
Jeśli tekstu jest dużo, nie oznacza to jeszcze, że odczytano wszystkie produkty. Skrypt może na przykład wydobyć nagłówki, a pominąć produkty umieszczone na obrazach. Z kolei pusty wynik nie zawsze dowodzi, że cała strona jest skanem: przyczyną może być sposób zapisania dokumentu.
5. Przykład: kody i nazwy z powtarzalnych wierszy
Załóżmy hipotetyczny katalog, w którym każdy produkt po odczytaniu zajmuje jeden wiersz. Kod ma format ABC-1234, po nim jest spacja i nazwa produktu. Przykładowe dwa wiersze wyglądają tak:
ABC-1234 Uchwyt montażowy
XYZ-5678 Zestaw śrub
Poniższy skrypt zapisuje dopasowane wiersze do CSV. Oznacza brak nazwy i powtórzone kody. Pozostałe niepuste wiersze zapisuje do osobnego pliku do kontroli, ponieważ mogą zawierać nagłówki, opisy albo produkty, których nie udało się dopasować. Dodatkowo zapisuje liczbę dopasowań na każdej stronie.
import csv
import re
from collections import Counter
from pathlib import Path
from pypdf import PdfReader
plik = Path("katalog.pdf") # albo katalog_ocr.pdf
wzorzec = re.compile(r"^([A-Z]{3}-[0-9]{4})(?:\s+(.*))?$")
rekordy = []
pozostale = []
strony = []
reader = PdfReader(str(plik))
for numer, strona in enumerate(reader.pages, start=1):
tekst = strona.extract_text() or ""
liczba = 0
for wiersz in tekst.splitlines():
wiersz = wiersz.strip()
if not wiersz:
continue
wynik = wzorzec.fullmatch(wiersz)
if wynik:
kod = wynik.group(1)
nazwa = (wynik.group(2) or "").strip()
rekordy.append({
"plik": plik.name, "strona": numer,
"kod": kod, "nazwa": nazwa,
"tekst_zrodlowy": wiersz,
})
liczba += 1
else:
pozostale.append({
"plik": plik.name, "strona": numer,
"tekst_zrodlowy": wiersz,
})
strony.append({
"plik": plik.name, "strona": numer,
"liczba_dopasowan": liczba,
"znaki_tekstu": len(tekst),
})
liczniki = Counter(r["kod"] for r in rekordy)
for r in rekordy:
uwagi = []
if not r["nazwa"]:
uwagi.append("brak nazwy")
if liczniki[r["kod"]] > 1:
uwagi.append("powtorzony kod")
r["uwagi"] = "; ".join(uwagi) or "do sprawdzenia"
def zapisz(nazwa, pola, dane):
with open(nazwa, "w", newline="", encoding="utf-8-sig") as plik_csv:
writer = csv.DictWriter(plik_csv, fieldnames=pola)
writer.writeheader()
writer.writerows(dane)
zapisz("kandydaci.csv",
["plik", "strona", "kod", "nazwa", "tekst_zrodlowy", "uwagi"],
rekordy)
zapisz("niedopasowane.csv", ["plik", "strona", "tekst_zrodlowy"], pozostale)
zapisz("strony.csv", ["plik", "strona", "liczba_dopasowan", "znaki_tekstu"], strony)
Zapisz kod na przykład jako katalog.py i uruchom python katalog.py. Powstaną trzy pliki: kandydaci na produkty, pozostałe wiersze i zestawienie stron. Kodowanie utf-8-sig może ułatwić otwarcie polskich znaków w arkuszu. Jeśli program do arkuszy nie rozdzieli kolumn automatycznie, użyj importu tekstu i wybierz przecinek jako separator oraz UTF-8 jako kodowanie.
Co ten przykład potrafi, a czego nie?
Wzorzec jest celowo wąski. Rozpoznaje tylko trzy wielkie litery, myślnik i cztery cyfry. Nie rozpozna innych formatów kodu, nazwy w kolejnym wierszu ani kodu z błędem OCR, który nie pasuje do wzorca. Taki wiersz trafi do niedopasowane.csv, o ile w ogóle został odczytany z PDF-u.
Brak kodu nie jest oznaczany w pliku kandydatów: bez rozpoznanego kodu skrypt nie wie, czy wiersz jest produktem. Dlatego trzeba przejrzeć także niedopasowane wiersze oraz strony z zerową lub podejrzanie małą liczbą dopasowań. Nawet poprawnie wyglądający kod może być błędny, jeśli OCR zamienił jedną cyfrę na inną. Status „do sprawdzenia” nie oznacza poprawności rekordu.
W rzeczywistym katalogu trzeba dopasować reguły do dokumentu. Jeśli kod i nazwa leżą w osobnych kolumnach, opisy zajmują wiele wierszy albo układ zmienia się między stronami, prosty podział na linie może nie wystarczyć. Wtedy warto rozważyć analizę położenia tekstu na stronie lub ręczną kontrolę większej części wyniku.
6. Skontroluj dane przed importem
Plik CSV z ekstrakcji traktuj jako materiał roboczy, nie gotowy plik do sklepu. Zacznij od zestawienia stron: sprawdź każdą stronę bez dopasowań oraz strony, na których liczba znalezionych pozycji wyraźnie odbiega od liczby widocznej w katalogu. Następnie przejrzyj niedopasowane wiersze i ustal, czy nie zawierają pominiętych produktów.
Porównując rekordy z oryginałem, zwróć uwagę na:
- Kody: podobne znaki, takie jak O i 0, oraz brakujące myślniki lub zera na początku.
- Nazwy: ucięte końcówki, tekst z sąsiedniej kolumny i pominięte warianty.
- Duplikaty: powtórzenie kodu może być błędem albo świadomym wystąpieniem tego samego produktu na kilku stronach. Decyzja zależy od zasad katalogu.
- Kompletność: porównaj liczbę pozycji na wybranych stronach, a przy istotnych danych sprawdź wszystkie strony.
- Pola dodatkowe: jednostki, ceny i waluty wymagają odrębnych reguł i kontroli, której pokazany skrypt nie wykonuje.
Po korekcie przygotuj osobny plik zgodny z wymaganiami systemu docelowego. Ustal mapowanie kolumn, sposób obsługi istniejących produktów oraz reguły dla pustych pól. Najpierw wykonaj import próbny w środowisku testowym albo na niewielkim zestawie, jeśli system to umożliwia. Zachowaj kopię danych sprzed importu i sposób wycofania zmian.
Gdy dane są już sprawdzone i zapisane w arkuszach, kolejnym etapem może być ich uporządkowanie. Zobacz poradnik o tym, jak łączyć firmowe pliki CSV i Excel za pomocą Pythona. Z kolei przy przekazywaniu danych między systemami przydaje się zaplanowanie kontroli duplikatów i błędów automatyzacji.
Kiedy pełna automatyzacja może się nie opłacać?
Jeżeli otrzymujesz pojedynczy, krótki katalog, przygotowanie i utrzymywanie reguł może zająć więcej czasu niż ręczne przepisanie danych. Podobnie będzie, gdy każdy dostawca stosuje inny układ albo często go zmienia. Słaby skan także może wymagać niemal pełnej korekty wyniku OCR.
Dobrym pierwszym krokiem jest niewielka próba na kilku różnych stronach, bez automatycznego importu. Zapisz czas przygotowania reguł, liczbę pozycji wymagających poprawy i rodzaje pominięć. Na tej podstawie zdecyduj, czy rozszerzyć rozwiązanie, ograniczyć je do jednego typu katalogu, czy pozostać przy ręcznym opracowaniu danych.




