Papero PDF Text Extractor: Een snelle, open-source API voor PDF-tekstextractie

De tool werkt uitsluitend op de CPU en maakt geen gebruik van ML-modellen. Het kan worden uitgevoerd in de browser, in Python of als een API.

Waarom Papero?

Het extraheren van tekst uit een PDF is eenvoudig, maar het herstellen van de structuur — zoals bepalen welke kolom eerst komt, welke regels een tabel vormen en waar een formule staat — is essentieel om de output bruikbaar te maken voor RAG (Retrieval-Augmented Generation), zoekfuncties en LLM's. Papero bereikt dit via eenvoudige geometrie, waardoor het snel blijft draaien op een laptop-CPU.

Belangrijkste kenmerken

  • Leesvolgorde: Documenten met twee of drie kolommen worden kolom voor kolom gelezen. Headers, footers, paginanummers en herhaalde logo's worden apart gezet.
  • Echte tabellen: Tabellen met lijnen, zonder randen en LaTeX booktabs-tabellen worden omgezet naar rijen en kolommen, inclusief cellen met meerdere regels. Export naar CSV of Excel is mogelijk.
  • Formules: Bovenschriften, onderschriften en wiskundige symbolen worden omgezet naar LaTeX (bijv. $E = mc^{2}$), aangevuld met een uitgesneden afbeelding van de formule.
  • Positie van alle elementen: Elk blok heeft een bounding box. Hierdoor kun je in een RAG-antwoord naar de exacte plek verwijzen, over de pagina tekenen of delen uitknippen.
  • Figuren & grafieken: Afbeeldingen en vectorgrafieken worden uitgesneden als PNG, waarbij het bijschrift, de aslabels en de legenda behouden blijven.
  • Terug naar Word: Uitlijning, inspringingen, regelafstand, vetgedrukte teksten en lettertypen worden behouden, zodat een .docx-export lijkt op de originele pagina.

Aanvullende functionaliteiten:

  • Accenttekens die in LaTeX-PDF's als aparte tekens zijn getekend (bijv. Computa¸ca˜o → Computação) worden gecorrigeerd.
  • Onzichtbare witte tekst (vaak gebruikt door formuliergeneratoren) wordt verwijderd.
  • Gescannde pagina's worden verwerkt via OCR.
  • DOCX, PPTX, XLSX, EPUB en HTML worden gelezen via Apache Tika.

Snel aan de slag

Installatie

pip install papero-extract

Basisgebruik in Python

from pdf_text_api import extract

doc = extract("paper.pdf")
print(doc.to_markdown())

Alternatief: Gebruik de browser-app om een PDF te uploaden en te exporteren naar het gewenste formaat zonder installatie.

Geavanceerd Python-gebruik (tabellen, formules, posities, afbeeldingen)

from pdf_text_api import extract, extract_text

doc = extract("paper.pdf", images=True)

# Toegang tot tabelgegevens
doc.tables[0].rows  # [["Model", "Accuracy"], ["Base", "0.81"], ...]

# Toegang tot LaTeX-formules
doc.formulas[0].latex  # "E = mc^{2}"

# Toegang tot afbeeldingen (PNG bytes)
doc.figures[0].image.data

# Doorloop blokken per pagina (leesvolgorde inclusief posities)
for block in doc.pages[0].blocks:
    print(block.type, block.bbox, block.text[:60])

# Exporteer naar verschillende formaten
doc.to_html()   # behoudt uitlijning en inspringingen
doc.to_dict()   # volledige JSON-output
extract("slides.pptx").to_markdown()  # ondersteunt elk formaat dat Apache Tika leest
extract_text("contract.pdf").text     # snelste methode: alleen schone tekst

Opties

OptieStandaardwaardeBeschrijving
pagesallBijv. "1-3,5,10-"
imagesFalseSnij figuren, tabellen en formules uit naar PNG
tables / formulasTrueDetectie aan/uit
ocr"auto""auto" (alleen gescannde pagina's), "force", "off"
ocr_language"por+eng"Tesseract talen
tikaTrueFalse voert alleen de layout-engine uit (geen Java nodig)
workers1Processen voor lange documenten

Command Line Interface (CLI)

# Markdown + afbeeldingen map
pdf-text-api extract paper.pdf -o paper.md --images

# Export in het formaat van de extensie
pdf-text-api extract paper.pdf -o paper.json

# Alleen tabellen naar CSV
pdf-text-api extract paper.pdf -f csv -o tables.csv

# Specifieke pagina's naar HTML
pdf-text-api extract paper.pdf -p 1-5 -f html

# Alleen schone tekst (snel)
pdf-text-api extract paper.pdf --fast

# Start de API + browser-app op poort 8000
pdf-text-api serve --port 8000

REST API & Docker

Starten met Docker

docker compose up

Dit start de API, Apache Tika, Tesseract en de browser-app op poort 8000.

Voorbeelden van API-aanvragen

# Extractie naar Markdown
curl -F "file=@paper.pdf" "localhost:8000/v1/extract?format=markdown"

# Extractie naar ZIP inclusief afbeeldingen
curl -F "file=@paper.pdf" "localhost:8000/v1/extract?format=zip&images=true" -o paper.zip

# Extractie met blokken en posities per pagina
curl -F "file=@paper.pdf" "localhost:8000/v1/extract?per_page=true"

Endpoint: POST /v1/extract. Interactieve documentatie is beschikbaar op /docs.

API Parameters

ParameterStandaardBeschrijving
modestructuredstructured (layout + Tika) of fast (alleen tekst)
formatjsonjson, markdown, text, html, csv, zip
pagesallBijv. 1-3,5,10-
per_pagefalseVoeg pagina's, blokken en posities toe aan de JSON
imagesfalseSnij figuren, tabellen en formules uit
ocrautoauto, force, off

Configuratie is mogelijk via omgevingsvariabelen (zie .env.example).

Output-specificaties

Elk blok bevat informatie over het type en de positie:

{
  "type": "table",
  "bbox": [56.7, 294.8, 481.9, 374.2],
  "rows": [["Model", "Accuracy"], ["Base", "0.81"]],
  "caption": "Table 1: Comparison between models."
}

Ondersteunde Output-formaten

FormaatPython · CLI · APIBrowser App
Markdown, platte tekst, JSON✓✓
HTML (behoudt uitlijning/inspringing)✓✓
CSV van tabellen, ZIP met afbeeldingen✓✓
Word .docx (behoudt uiterlijk pagina)—✓
Excel .xlsx (één blad per tabel)—✓

JSON Schema en Bloktypes

Het volledige JSON-schema bevat metadata en een lijst van pagina's. Binnen elke pagina bevinden zich blokken.

Bloktypes:

  • heading (met niveau)
  • paragraph
  • list_item (met marker)
  • table (met rijen)
  • figure
  • formula (met LaTeX)
  • caption
  • code
  • Apart gehouden van de hoofdtekst: header, footer, page_number.

De bounding boxes worden weergegeven als [x0, y0, x1, y1] in punten, met de oorsprong linksboven op de pagina.

Benchmarks

Getest op dichte arXiv-papers (multi-kolom, formules, tabellen, figuren) op een laptop-CPU zonder GPU.

  • Snelheid: Gemiddeld 39 ms per pagina.
  • Betrouwbaarheid: 0 fouten op 54 papers.

Vergelijking met andere tools

KenmerkpaperoPyMuPDFpdfplumberpypdfDoclingMarker
LicentieMITAGPLMITBSDMITGPL
ML modellen nodigNeeNeeNeeNeeJaJa
Multi-kolom leesvolgorde✓Gedeeltelijk——✓✓
Gestructureerde tabellen✓✓✓—✓✓
FormulesLaTeX + beeld———✓✓
Bounding boxes✓✓✓—✓✓
DOCX/PPTX/XLSX/EPUB✓Gedeeltelijk——✓Gedeeltelijk
Volledig in browser✓—————

Opmerking: ML-gebaseerde tools presteren nog steeds beter bij zeer onregelmatige layouts en complexe wiskunde (zoals matrices). Papero biedt in dat geval de formule als benaderde LaTeX en als afbeelding, zodat er geen informatie verloren gaat.

Hoe het werkt

Twee engines werken gelijktijdig op hetzelfde bestand:

  1. Layout Engine: Gebaseerd op PDFium. Deze leest elk glief met positie, lettertype en grootte, inclusief lijnen en afbeeldingen. Met een kolom-bewuste XY-cut worden kolommen, tabellen, formules, lijsten en figuren gereconstrueerd.
  2. Apache Tika: Voegt metadata, tagged-PDF koppen, OCR (via Tesseract) en ondersteuning voor niet-PDF formaten toe.

De browser-app gebruikt hetzelfde algoritme, geporteerd naar JavaScript via pdf.js. De CI-tests controleren blok voor blok of beide engines overeenstemmen.

Beperkingen

  • Wiskunde: LaTeX wordt gereconstrueerd uit gliefen. Gestapelde breuken, matrices en grote wortels worden lineair weergegeven (de uitgesneden afbeelding is echter altijd aanwezig).
  • Tabellen: Randloze tabellen met zeer smalle tussenruimtes tussen kolommen kunnen per ongeluk als tekst worden gelezen.
  • OCR: Gescannde PDF's hebben OCR nodig, wat alleen via de server-route werkt (Tesseract zit in de Docker-image).
  • Export: Word/Excel-export is momenteel alleen beschikbaar in de browser-app.

Ontwikkeling

Installatie voor ontwikkelaars

git clone https://github.com/beatrizalmeidaf/papero-pdf-text-extractor.git && cd pdf-text-extractor
pip install -e ".[dev]"

Testen en Controleren

pytest -q                                   # inclusief real-world regressies
ruff check src tests && ruff format --check src tests
npm install --prefix tests/js && python tests/js/expected.py tests/js/out && node tests/js/parity.mjs tests/js/out
python -m http.server -d web                # browser app op http://localhost:8000
  • src/pdftextapi/: De Python engine, API en CLI.
  • web/: De browser-app (GitHub Pages).
  • tests/js/: Controleert of beide engines overeenstemmen.
  • benchmarks/: Downloadt de dataset en tekent de grafieken.

Bijdragen

Heb je een PDF gevonden die Papero niet correct verwerkt? Dit is de meest nuttige manier om bij te dragen: open een issue en voeg het bestand (of een pagina ervan) toe met een beschrijving van de verwachte output. Onderwerpen als leesvolgorde, tabellen, formules, encoding, OCR en verschillen tussen browser/server zijn welkom.

Licentie: MIT © Beatriz Almeida. Gepubliceerd als papero-extract op PyPI.