ParseJet

Jak przekonwertować PDF na Markdown w Pythonie

Konwersja PDF-ów na Markdown stała się standardowym krokiem przygotowania danych dla potoków RAG i przepływów LLM — Markdown zachowuje nagłówki i tabele, dzięki którym modele rozumieją strukturę, przy ułamku liczby tokenów. Python ma kilka dobrych opcji, każdą z realnymi kompromisami. Oto cztery, które się liczą, z działającym kodem dla każdej.

Dlaczego Markdown i dlaczego to trudniejsze, niż się wydaje

LLM-y wyjątkowo dobrze radzą sobie z Markdownem: nagłówki wyznaczają granice sekcji, tabele z pionowymi kreskami trzymają dane tabelaryczne w ryzach, a listy pozostają listami. Podanie modelowi surowego tekstu wyciągniętego z PDF-a traci to wszystko — a podanie binarnego PDF-a w większości potoków w ogóle nie wchodzi w grę. Dlatego niemal każdy poważny stack RAG konwertuje dokumenty na Markdown przed podziałem na fragmenty i embeddingami.

Trudność polega na tym, że PDF-y nie zawierają struktury — zawierają znaki rozmieszczone na współrzędnych x/y. Konwerter musi odtworzyć, które linie są nagłówkami (po rozmiarze czcionki), które słowa tworzą tabelę (po wyrównaniu) i jaka jest kolejność czytania (z analizy układu). Biblioteki ogromnie się różnią w tym, jak dobrze to robią — i właśnie dlatego wybór ma znaczenie.

Druga komplikacja: zeskanowane PDF-y nie zawierają żadnego tekstu, tylko obrazy stron. Tylko część poniższych opcji radzi sobie z nimi — przez OCR.

Opcja 1: PyMuPDF4LLM — szybko i lekko

PyMuPDF4LLM to cienka warstwa nad PyMuPDF (fitz) zbudowana specjalnie pod potoki LLM: pip install pymupdf4llm, a potem md = pymupdf4llm.to_markdown("doc.pdf") — jedna linijka, i to bardzo szybka: większość dokumentów przetwarza znacznie poniżej sekundy.

Wykrywa nagłówki po rozmiarach czcionek, renderuje tabele jako tabele z pionowymi kreskami i potrafi emitować fragmenty stron z metadanymi do bezpośredniego zasilenia LlamaIndex lub LangChain. Dla PDF-ów urodzonych cyfrowo, o prostych układach — raporty, dokumentacja, artykuły bez egzotycznego formatowania — to znakomity domyślny wybór.

Ograniczenia: brak OCR, więc zeskanowane strony wracają puste. Skomplikowane układy wielokolumnowe i zawiłe tabele mogą wyjść pomieszane, bo heurystyki pod spodem stawiają na szybkość, a nie na głęboką analizę układu. Uwaga licencyjna: PyMuPDF jest na AGPL — w porządku dla narzędzi wewnętrznych, ale przed wbudowaniem go w produkt komercyjny skonsultuj się z działem prawnym.

Opcja 2: Marker — najwyższa jakość, wymaga GPU

Marker używa potoku modeli głębokiego uczenia do wykrywania układu, kolejności czytania i struktury tabel i produkuje najwierniejszy Markdown ze wszystkich opcji open source — radzi sobie z wielokolumnowymi artykułami naukowymi, złożonymi tabelami, a nawet równaniami.

Ceną jest infrastruktura: wagi modeli liczące kilka gigabajtów, GPU dla rozsądnej szybkości (CPU działa, ale wolno — często dziesiątki sekund na dokument) oraz ciężkie drzewo zależności, którego wdrożenie na produkcji lub w środowiskach serverless wymaga realnego wysiłku.

Wybierz Marker, gdy jakość wyniku na trudnych dokumentach jest najwyższym priorytetem i masz sprzęt — masowa konwersja korpusu naukowego na maszynie z GPU to jego żywioł. Dla lekkiej usługi albo funkcji serverless ciężar operacyjny zwykle go dyskwalifikuje.

Opcja 3: MarkItDown — konwerter wszystkich formatów od Microsoftu

MarkItDown to open-source'owa biblioteka Microsoftu typu wszystko-na-Markdown: pip install markitdown, a potem MarkItDown().convert("doc.pdf").text_content. Jej siłą jest szerokość — to samo API konwertuje PDF, DOCX, PPTX, XLSX, HTML i więcej, dzięki czemu zrobiła furorę w przygotowywaniu danych dla LLM.

Konkretnie dla PDF-ów jej ekstrakcja jest prostsza niż w opcjach wyspecjalizowanych: opiera się na podstawowym wyciąganiu tekstu, więc wykrywanie nagłówków i wierność tabel ustępują PyMuPDF4LLM i Markerowi, a zeskanowane PDF-y wymagają dodatkowej konfiguracji OCR.

Wybierz MarkItDown, gdy potrzebujesz jednej zależności obsługującej wiele typów plików w umiarkowanej jakości — wewnętrzny skrypt ingestii, który musi przyjąć „cokolwiek ludzie prześlą” — a nie najlepszego możliwego wyniku z PDF-ów.

Opcja 4: hostowane API — zero zależności

Czwarta opcja to nie uruchamiać konwersji lokalnie: wyślij PDF metodą POST do API parsującego i odbierz Markdown. Z ParseJet: resp = httpx.post("https://api.parsejet.com/v1/parse/auto/file", headers={"Authorization": "Bearer KEY"}, files={"file": open("doc.pdf", "rb")}) — pole "text" odpowiedzi JSON to właśnie Markdown.

Ta droga ma wbudowany OCR dla zeskanowanych stron, żadnych wag modeli ani bibliotek natywnych do instalowania i działa identycznie w funkcji serverless, kontenerze czy notatniku. Omija też całkowicie kwestię AGPL. Kompromisem jest podróż przez sieć i koszt per dokument po wyczerpaniu darmowej puli (300 kredytów/miesiąc za darmo; PDF kosztuje 3 kredyty).

Wybierz API, gdy potok ma działać jeszcze dziś, gdy wśród Twoich PDF-ów są skany albo gdy wdrażasz się tam, gdzie ciężkie zależności bolą — Lambda, Cloud Run, Vercel.

Którą opcję wybrać?

PDF-y urodzone cyfrowo, układy proste do umiarkowanych, liczy się szybkość: PyMuPDF4LLM. Najlepszy stosunek efektu do wysiłku w czystym Pythonie.

Trudne dokumenty (wielokolumnowe artykuły, złożone tabele) i masz GPU: Marker. Nic w open source nie bije jakości jego wyników.

Wiele różnych typów plików przez jedną bibliotekę, umiarkowana jakość wystarcza: MarkItDown.

Skany w miksie, wdrożenie serverless albo zero ochoty na zarządzanie zależnościami: hostowane API. Jedno wywołanie HTTP, OCR w zestawie, ten sam schemat wyniku dla każdego dokumentu.

Kompletny przykład: folder PDF-ów na pliki Markdown

Którąkolwiek drogę wybierzesz, kształt potoku jest ten sam — iteruj, konwertuj, zapisuj. Oto wersja z API (zamień wewnętrzne wywołanie na pymupdf4llm.to_markdown(), aby uruchomić lokalnie):

import httpx; from pathlib import Path — a potem dla każdego pdf w Path("pdfs/").glob("*.pdf"): resp = httpx.post("https://api.parsejet.com/v1/parse/auto/file", headers={"Authorization": "Bearer KEY"}, files={"file": pdf.read_bytes()}); Path("md/", pdf.stem + ".md").write_text(resp.json()["text"], encoding="utf-8").

Przy ingestii do RAG dziel Markdown po nagłówkach, a nie po stałej liczbie znaków — fragmenty świadome nagłówków zachowują całe sekcje i wyszukują się dramatycznie lepiej. Ta wierność strukturalna to dokładnie powód, dla którego warto było zadbać o krok konwersji.

Wypróbuj konwersję bez pisania kodu

Prześlij PDF i zobacz Markdown, jaki produkuje to API — z nagłówkami, tabelami i OCR dla zeskanowanych stron.

Przekonwertuj PDF na Markdown za darmo

Często zadawane pytania

Jaka jest najlepsza biblioteka Pythona do konwersji PDF na Markdown?

Dla PDF-ów urodzonych cyfrowo PyMuPDF4LLM oferuje najlepszy stosunek szybkości do jakości. Dla trudnych układów, gdy masz GPU, najwyższą jakość daje Marker. Dla skanów lub wdrożeń bez zależności hostowane API takie jak ParseJet obsługuje OCR i strukturę w jednym wywołaniu HTTP.

Jak przekonwertować zeskanowany PDF na Markdown w Pythonie?

Zeskanowane strony nie zawierają tekstu, więc potrzebujesz OCR. Lokalnie oznacza to samodzielne podpięcie silnika OCR; prostszą drogą jest API z wbudowanym OCR — ParseJet wykrywa strony-obrazy i automatycznie je rozpoznaje w tym samym żądaniu.

Czy MarkItDown nadaje się do konwersji PDF na Markdown?

Siłą MarkItDown jest konwersja wielu formatów (PDF, DOCX, PPTX, XLSX) przez jedną bibliotekę. Konkretnie dla PDF-ów jego wykrywanie struktury jest prostsze niż w PyMuPDF4LLM czy Markerze — wystarcza przy umiarkowanych wymaganiach, ale nie jest najlepszym wyborem dla wiernej ekstrakcji nagłówków i tabel.

Dlaczego konwertować PDF-y na Markdown dla RAG zamiast na czysty tekst?

Markdown zachowuje nagłówki, listy i tabele, które czysty tekst spłaszcza. Dzielenie na fragmenty świadome nagłówków wyszukuje się lepiej, a LLM-y wykorzystują strukturę do rozumienia kontekstu — przy mniej więcej tym samym koszcie tokenów co czysty tekst.

Czy mogę przekonwertować PDF na Markdown w Pythonie bez instalowania czegokolwiek?

Tak — wywołaj API parsujące przez HTTP z httpx lub requests. Wyślij plik metodą POST na /v1/parse/auto/file ParseJet, a pole "text" odpowiedzi to Markdown. Darmowe klucze API obejmują 300 kredytów miesięcznie.

Zacznij bezpłatnie wyodrębniać tekst

Bez rejestracji. Przeanalizuj swój pierwszy plik w kilka sekund.

Zobacz cennik