Daten aus PDF extrahieren: Tabellen, Text und OCR

Veröffentlicht:

14 Min. Lesezeit

Acar Diveroli
Autor: Acar Diveroli
Isometrischer Stapel dunkler Würfel mit PDF-Teilen, oben ein blauer CSV-Würfel, daneben ein gestrichelter Platz: needs OCR

Ein Lieferant schickt seine Preisliste jeden Monat als 40-seitiges PDF. Die Finanzabteilung erhält Kontoauszüge auf dieselbe Weise, und der Marktbericht, den Sie letzte Woche gekauft haben, hat seine wichtigste Tabelle auf Seite 17. Diese Zeilen sollen in eine Tabellenkalkulation. Abtippen oder Kopieren zerlegt die Spalten, verliert Minuszeichen und kostet eine Stunde, die Sie nächsten Monat erneut aufwenden.

Dieser Beitrag beginnt mit der Frage, die über die Methode entscheidet: Hat die Datei eine Textebene? Danach geht es um den PDF-Connector von Excel, um pdfplumber, Camelot und tabula-py, um OCR mit Tesseract für Scans und um ein Batch-Skript, das einen Ordner voller PDFs in eine einzige CSV-Datei überführt. Alle Beispiele haben wir mit Beispiel-PDFs ausgeführt, die wir mit ReportLab erzeugt haben.

Was bedeutet es, Daten aus einem PDF zu extrahieren?

Daten aus einem PDF zu extrahieren heißt, Inhalte, die für den Druck gesetzt wurden, in Zeilen und Felder zu verwandeln, die Sie sortieren und anderswo laden können. Ein PDF speichert keine „Tabelle mit vier Spalten“. Es speichert Anweisungen wie „zeichne 1,007.50 an dieser Position in dieser Schrift“ und „zeichne eine Linie von hier nach dort“. Jedes Extraktionswerkzeug baut die Tabelle aus diesen Koordinaten neu auf. Deshalb kann dieselbe Datei in einem Tool sauber und in einem anderen völlig durcheinander herauskommen.

Die Aufgabe ist dieselbe wie beim Auslesen von Feldern aus einer Webseite (Daten aus einer Website extrahieren), nur mit positionierten Zeichen statt HTML-Tags. PDFs in großer Zahl von Websites zu sammeln, gehört zu einer umfassenderen Data-Scraping-Pipeline.

Text-PDF oder gescanntes PDF: Wie erkennen Sie den Unterschied?

  • Text-PDF (digital). Exportiert aus Word, einem Buchhaltungssystem oder einem Reporting-Tool. Die Zeichen sind als Text gespeichert, die Extraktion liest also exakt die Zahlen in der Datei.
  • Gescanntes PDF (Bild). Jede Seite ist ein Bild von Papier. Text entsteht erst, wenn OCR (optische Zeichenerkennung) die Zeichen aus den Pixeln errät.

Der Schnelltest: Drücken Sie Strg+F und suchen Sie nach einem Wort, das Sie sehen. Wird es gefunden, gibt es eine Textebene. Im Code zeigt eine leere page.chars-Liste in pdfplumber, dass die Seite ein Scan ist. Manche Dateien mischen beides (etwa ein digitaler Bericht mit eingescannter Unterschriftsseite), prüfen Sie daher pro Seite, nicht pro Datei.

Wie funktioniert die Tabellenextraktion aus PDFs?

Ob Excel, pdfplumber oder Camelot: Im Hintergrund laufen dieselben Schritte ab.

  1. Die Seite wird geparst. Jedes Zeichen wird mit Position, Schrift und Größe gelesen, dazu die gezeichneten Linien und Rechtecke.
  2. Aus Zeichen werden Wörter und Zeilen. Nahe beieinanderliegende Zeichen auf einer Grundlinie bilden Wörter, Wörter auf gleicher Höhe eine Zeile.
  3. Tabellenbereiche werden gefunden. Anhand von Linien, die ein Raster bilden, oder anhand von Wortspalten, die durch Leerraum getrennt ausgerichtet sind.
  4. Zellen werden gebildet. Linienkreuzungen oder Spaltenlücken legen die Zellgrenzen fest, und jedes Wort landet in der Zelle, die es enthält.
  5. Zeilen werden zurückgegeben. Eine Liste von Zeilen (oder ein DataFrame), die Sie bereinigen und speichern.

Die meisten Probleme entstehen in Schritt 3. Ein vollständiges Raster ist einfach; bei einer Tabelle ohne Rahmen muss das Tool die Spalten aus dem Leerraum erraten, und ein einziger langer Produktname kann alle Spalten verschieben.

PDF-Extraktionsmethoden im Vergleich

MethodeCode nötig?Liest Scans?Am besten fürWo es hakt
Kopieren und EinfügenNeinNeinEine kleine Tabelle, einmaligSpalten fallen in eine Zelle zusammen, mehrseitige Tabellen
Excel, Daten abrufen > Aus PDFNeinNeinWenige Dateien pro Monat, Analyse in ExcelTabellen ohne Rahmen, viele Dateien mit unterschiedlichem Layout
pdfplumber (Python)JaNeinText plus Tabellen, Batch-Jobs, feine SteuerungBraucht Feinabstimmung bei Tabellen ohne Rahmen
Camelot (Python)JaOptionales ExtraTabellen mit Linien, Genauigkeitsbericht pro TabelleFreitext rund um die Tabellen
tabula-py (Python)JaNeinSchnelle DataFrames aus tabellenlastigen DateienSetzt Java auf dem Rechner voraus
Tesseract über pytesseractJaJaGescannte Seiten, Fotos von DokumentenGenauigkeit hängt von der Scanqualität ab; Tabellen verlieren ihre Struktur

Ohne Code: Kopieren und Excel

Kopieren. Für eine kleine Tabelle markieren Sie sie im Viewer und fügen sie ein. Landet jede Zeile in einer einzigen Zelle, nutzen Sie Daten > Text in Spalten. Das scheitert, sobald ein Produktname Leerzeichen enthält.

Der PDF-Connector von Excel. Excel für Microsoft 365 unter Windows kann PDF-Dateien über Power Query lesen:

  1. Öffnen Sie eine leere Arbeitsmappe und wählen Sie Daten > Daten abrufen > Aus Datei > Aus PDF.
  2. Wählen Sie das PDF aus und klicken Sie auf Öffnen.
  3. Der Navigator listet auf, was Power Query gefunden hat: jede erkannte Tabelle (Table001, Table002 …) und jede ganze Seite (Page001 …). Klicken Sie auf einen Eintrag, um eine Vorschau zu sehen.
  4. Wählen Sie Laden, um die Tabelle auf ein Arbeitsblatt zu übernehmen, oder Daten transformieren, um sie zuerst im Power Query-Editor zu bereinigen (wiederholte Kopfzeilen entfernen, den Typ der Preisspalte auf Zahl ändern).
  5. Im nächsten Monat ersetzen Sie die Datei und klicken auf Daten > Alle aktualisieren; dieselben Schritte laufen erneut.

Die Dokumentation des PDF-Connectors von Microsoft beschreibt die Optionen dahinter: Pdf.Tables akzeptiert StartPage und EndPage für große Dateien sowie die Option MultiPageTables, die eine über mehrere Seiten laufende Tabelle zusammenführt. Der Connector führt kein OCR aus, und Power Query in Excel für Mac bietet PDF nicht als Quelle an. Der Ordner-Connector kombiniert PDFs mit gleichem Layout; sobald die Layouts abweichen, ist ein Skript leichter zu pflegen.

Text und Tabellen mit pdfplumber extrahieren

pdfplumber ist eine Python-Bibliothek auf Basis von pdfminer.six mit eigener Tabellenerkennung. Die aktuelle Version ist 0.11.10 (Juni 2026); laut README funktioniert sie am besten mit maschinell erzeugten PDFs und führt kein OCR aus. Installieren Sie sie in einer virtuellen Umgebung:

bash
python -m venv .venv
.venv\Scripts\activate        # macOS/Linux: source .venv/bin/activate
pip install pdfplumber pandas

Die Grundlagen passen in wenige Zeilen:

python
import pdfplumber

with pdfplumber.open("pdfs/price-list-2026-08.pdf") as pdf:
    page = pdf.pages[0]
    print(page.extract_text())          # gesamter Text, Zeile für Zeile
    table = page.extract_table()        # die größte Tabelle auf der Seite
    print(table[:2])
# [['SKU', 'Product', 'Unit', 'Price'], ['B-001', 'Cable set 1', 'box', '13.40']]

extract_tables() gibt jede Tabelle der Seite als Listen von Zellen-Strings zurück. Standardmäßig sucht pdfplumber nach gezeichneten Linien; bei einer Tabelle ohne Rahmen wechseln Sie zur Text-Strategie:

python
settings = {"vertical_strategy": "text", "horizontal_strategy": "text"}
rows = page.extract_tables(table_settings=settings)

Wählen Sie die Strategie passend zur Tabelle. Bei unserer Preisliste mit Linien teilte die Text-Strategie „Cable set 1“ auf zwei Spalten auf und verschmolz „Unit“ und „Price“, weil sie aus Wortabständen erriet, was die Linien bereits zeigten. Ist nur ein Teil der Seite eine Tabelle, schneiden Sie zuerst mit page.crop((x0, top, x1, bottom)) zu.

Ein vollständiges Skript: ein PDF-Ordner in eine CSV-Datei

Das folgende Skript liest jedes PDF in einem Ordner, entnimmt die Dokumentnummer dem Text der ersten Seite, holt die Tabellenzeilen von jeder Seite, überspringt wiederholte Kopfzeilen, wandelt Preise in Zahlen um und schreibt eine einzige CSV-Datei. Seiten ohne Textebene werden für OCR protokolliert, und eine defekte Datei hält den Batch nicht auf.

python
import csv
import logging
import re
from pathlib import Path

import pdfplumber

logging.basicConfig(level=logging.INFO, format="%(levelname)s %(message)s")

IN_DIR = Path("pdfs")
OUT_CSV = Path("price_lists.csv")
HEADER = ["SKU", "Product", "Unit", "Price"]
DOC_NO = re.compile(r"price list (\S+)", re.IGNORECASE)


def to_number(text):
    """'1,007.50' -> 1007.5; gibt None für leere oder defekte Zellen zurück."""
    if not text:
        return None
    try:
        return float(text.replace(",", "").strip())
    except ValueError:
        return None


def rows_from_pdf(path):
    with pdfplumber.open(path) as pdf:
        first_text = pdf.pages[0].extract_text() or ""
        match = DOC_NO.search(first_text)
        doc_no = match.group(1) if match else path.stem

        for page in pdf.pages:
            if not page.chars:  # keine Textebene: vermutlich ein Scan
                logging.warning("%s p.%d has no text layer, needs OCR", path.name, page.page_number)
                continue
            for table in page.extract_tables():
                for row in table:
                    cells = [(c or "").strip() for c in row]
                    if cells == HEADER:  # Kopfzeile wiederholt sich auf jeder Seite
                        continue
                    if len(cells) != len(HEADER):
                        logging.warning("%s p.%d skipped row %r", path.name, page.page_number, cells)
                        continue
                    sku, product, unit, price = cells
                    yield {
                        "file": path.name,
                        "doc_no": doc_no,
                        "page": page.page_number,
                        "sku": sku,
                        "product": product,
                        "unit": unit,
                        "price": to_number(price),
                    }


def main():
    fields = ["file", "doc_no", "page", "sku", "product", "unit", "price"]
    count = 0
    with OUT_CSV.open("w", newline="", encoding="utf-8-sig") as f:
        writer = csv.DictWriter(f, fieldnames=fields)
        writer.writeheader()
        for path in sorted(IN_DIR.glob("*.pdf")):
            try:
                for row in rows_from_pdf(path):
                    writer.writerow(row)
                    count += 1
            except Exception as exc:  # eine defekte Datei soll den Stapel nicht stoppen
                logging.error("%s failed: %s", path.name, exc)
    logging.info("wrote %d rows to %s", count, OUT_CSV)


if __name__ == "__main__":
    main()

In unserem Testordner (eine Preisliste mit 70 Zeilen über zwei Seiten, eine Preisliste mit 8 Zeilen und eine gescannte Kopie) sah die Ausgabe so aus:

bash
WARNING price-list-scan.pdf p.1 has no text layer, needs OCR
INFO wrote 78 rows to price_lists.csv

utf-8-sig sorgt dafür, dass Excel Namen mit Akzenten wie „Café“ korrekt anzeigt, und file, doc_no und page in jeder Zeile führen jede Zahl auf ihre Seite zurück. Wo Sie die Zeilen danach speichern, zeigt Gescrapte Daten als CSV, JSON und in SQLite speichern; die Bereinigung behandelt Gescrapte Daten mit pandas bereinigen.

Camelot und tabula-py: Wann lohnen sie sich?

Zwei weitere Bibliotheken konzentrieren sich ausschließlich auf Tabellen.

Camelot erreichte im Juni 2026 Version 2.0.0. read_pdf() nutzt standardmäßig den Modus lattice für Tabellen mit Linien; stream und network verarbeiten Tabellen ohne Rahmen, und auto wählt pro Seite. Jede Tabelle hat einen parsing_report mit einem Genauigkeitswert, mit dem Sie problematische Seiten markieren können. Siehe die Camelot-Dokumentation.

tabula-py ist ein Python-Wrapper um tabula-java und setzt daher eine Java-Installation voraus. tabula.read_pdf() liefert direkt eine Liste von pandas-DataFrames.

python
import camelot
import tabula

PDF = "pdfs/price-list-2026-09.pdf"

tables = camelot.read_pdf(PDF, pages="1-end", flavor="lattice")
for t in tables:
    print(t.page, t.shape, t.parsing_report["accuracy"])
tables[0].df.to_csv("camelot_page1.csv", index=False)

dfs = tabula.read_pdf(PDF, pages="all", lattice=True)
print(len(dfs), [df.shape for df in dfs])

Bei unserer zweiseitigen Preisliste fanden beide eine Tabelle pro Seite. Camelot meldete eine Genauigkeit von 100.0 und behielt die Kopfzeile als erste Zeile; tabula verwendete sie als Spaltennamen. Alle drei Bibliotheken lasen die Tabelle mit Linien korrekt. Entscheiden Sie also nach dem Rest der Aufgabe: pdfplumber, wenn auch Freitext gebraucht wird, Camelot für einen Wert pro Tabelle, tabula-py für DataFrames mit dem wenigsten Code, sofern Java installiert ist.

Gescannte PDFs: OCR mit Tesseract

Hat eine Seite keine Textebene, müssen die Zeichen aus dem Bild erkannt werden. Tesseract ist die verbreitete Open-Source-OCR-Engine, pytesseract ihr Python-Wrapper. Der Wrapper enthält die Engine nicht: Installieren Sie zuerst Tesseract selbst (liegt es danach nicht im PATH, setzen Sie tesseract_cmd wie unten gezeigt), dann:

bash
pip install pytesseract pypdfium2

Das Skript rendert jede Seite mit 300 DPI in Graustufen, führt OCR aus und gibt die mittlere Wort-Konfidenz aus. Daran sehen Sie, welche Seiten ein Mensch prüfen sollte:

python
import sys

import pypdfium2 as pdfium
import pytesseract

# Unter Windows pytesseract auf die ausführbare Datei verweisen, falls sie nicht im PATH liegt:
# pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"


def ocr_pdf(path, lang="eng", dpi=300):
    pdf = pdfium.PdfDocument(path)
    pages = []
    for i, page in enumerate(pdf, start=1):
        image = page.render(scale=dpi / 72).to_pil().convert("L")  # Graustufen helfen
        text = pytesseract.image_to_string(image, lang=lang, config="--psm 6")
        pages.append(text)
        # Konfidenz pro Wort: -1 bedeutet „kein Wort“, sonst 0-100.
        data = pytesseract.image_to_data(image, lang=lang, output_type=pytesseract.Output.DICT)
        confs = [float(c) for c in data["conf"] if float(c) >= 0]
        if confs:
            print(f"page {i}: mean confidence {sum(confs) / len(confs):.1f}")
    return pages


if __name__ == "__main__":
    try:
        for text in ocr_pdf(sys.argv[1] if len(sys.argv) > 1 else "scans/price-list-scan.pdf"):
            print(text)
    except pytesseract.TesseractNotFoundError:
        sys.exit("Tesseract is not installed or not on PATH")

Der Wert von 300 DPI stammt aus Tesseracts Leitfaden zur Verbesserung der Qualität. --psm 6 behandelt die Seite als einen einheitlichen Textblock. Derselbe Leitfaden weist darauf hin, dass Tabellen eine eigene Segmentierung brauchen und Scanränder als Zeichen fehlgedeutet werden können.

OCR verwechselt 0 und O, 1 und l sowie Komma und Punkt in einem Preis; blasse oder schiefe Scans verschlimmern das. Prüfen Sie bei wichtigen Zahlen, ob die Einzelposten die Summe ergeben, und lassen Sie Seiten mit niedriger Konfidenz von einer Person durchsehen. OCR liefert Text, keine Tabellenstruktur: Bauen Sie die Spalten pro Zeile mit einem regulären Ausdruck neu auf oder probieren Sie das optionale Extra ocr von Camelot.

Wo die Datenextraktion aus PDFs eingesetzt wird

  • Preislisten von Lieferanten. Monatliche PDFs werden zu einer Preishistorie, die Sie über die Zeit vergleichen können, die Grundlage für Preisüberwachung.
  • Markt- und Branchenberichte. Tabellen aus öffentlichen Berichten fließen in ein Modell für Marktforschung, statt abgetippt zu werden.
  • Rechnungen und Kontoauszüge. Summen, Daten und Referenznummern werden in Buchhaltung oder Abstimmung übernommen, eine häufige Aufgabe in Finanz-Teams.
  • Amtliche Veröffentlichungen und Statistiken. Viele Behörden veröffentlichen Tabellen noch immer nur als PDF; ein Skript macht aus Jahrgängen davon einen Datensatz, ein typischer erster Schritt vor dem Data Mining.
  • ETL-Pipelines. Das Parsen von PDFs ist das „Extract“ in einem größeren Ablauf; Was ist ETL? erklärt, wie Transformation und Laden darum herum angeordnet sind.

Viele PDFs von Websites herunterladen

Die PDFs liegen oft in einem Lieferantenportal oder auf der Veröffentlichungsseite einer Aufsichtsbehörde. Hunderte davon herunterzuladen ist ein Scraping-Job: Nutzen Sie den offiziellen Download oder eine API, falls vorhanden, lesen Sie robots.txt und die Nutzungsbedingungen und takten Sie die Anfragen. Der folgende Downloader überspringt bereits vorhandene Dateien, wiederholt 4xx-Fehler nicht, beachtet Retry-After bei HTTP 429 und prüft, ob die Antwort wirklich ein PDF ist:

python
import os
import time
from pathlib import Path
from urllib.parse import urlparse

import requests

PROXY = os.environ.get("PROXY_URL", "http://user:pass@pr.proxynet.io:8000")
URLS = os.environ.get("PDF_URLS", "https://example.com/reports/price-list.pdf").split()
OUT = Path("pdfs")
OUT.mkdir(exist_ok=True)

session = requests.Session()
session.proxies = {"http": PROXY, "https": PROXY}
session.headers["User-Agent"] = "price-list-archiver/1.0 (contact: data@example.com)"


def download(url, retries=3):
    target = OUT / Path(urlparse(url).path).name
    if target.exists():  # bereits bei einem früheren Lauf geholt
        return target
    for attempt in range(1, retries + 1):
        try:
            r = session.get(url, timeout=30)
            if r.status_code == 429:
                time.sleep(int(r.headers.get("Retry-After", 30)))
                continue
            if 400 <= r.status_code < 500:  # 403, 404 ...: Wiederholen hilft nicht
                print(f"{url} returned {r.status_code}, skipped")
                return None
            r.raise_for_status()
            if not r.content.startswith(b"%PDF"):  # eine HTML-Fehlerseite, kein PDF
                print(f"{url} did not return a PDF, skipped")
                return None
            target.write_bytes(r.content)
            return target
        except requests.RequestException as exc:
            print(f"attempt {attempt} failed: {exc}")
            time.sleep(2 ** attempt)
    return None


for url in URLS:
    print(url, "->", download(url))
    time.sleep(2)  # den Server schonen

Über einen lokalen Test-Proxy mit user:pass wurde ein gültiges PDF gespeichert, eine gefälschte .pdf und ein 404 wurden übersprungen, und ein zweiter Lauf lud nichts erneut herunter. Ein Proxy hilft, wenn eine Quelle je nach Land unterschiedliche Dokumente ausliefert (ein Residential-Proxy mit Zielland) oder wenn ein langer Archiv-Download an Limits pro IP stößt (ein Rotierender Proxy). Langsamer werden hat trotzdem Vorrang, wie HTTP 429 Too Many Requests erklärt.

Häufige Probleme und ihre Lösung

  • Verbundene Zellen kommen als None zurück. pdfplumber füllt nur die erste Zeile einer verbundenen Zelle; ffill() in pandas kopiert den Wert nach unten (Beispiel unten).
  • Die Tabelle geht auf der nächsten Seite weiter. Extrahieren Sie Seite für Seite, entfernen Sie die wiederholten Kopfzeilen (wie im Skript oben) und fügen Sie alles zusammen. In Excel übernimmt das die Option MultiPageTables.
  • Zahlen kommen als Text an. "1,007.50", "(250.00)" für negative Werte, "1.007,50" in einer deutschen Datei. Normalisieren Sie je Format; raten Sie das Dezimaltrennzeichen nie anhand eines einzelnen Werts.
  • Umlaute und Akzente sehen kaputt aus. Meist liegt der Fehler beim Anzeigeprogramm, nicht im Text: eine Windows-Konsole oder Excel, das UTF-8 ohne BOM öffnet (siehe Python-Unicode-Encoding-Fehler). Liefert schon extract_text() seltsame Symbole, hat die Schrift keine Unicode-Zuordnung, und OCR ist der verlässliche Weg.
  • Spalten verrutschen in Tabellen ohne Rahmen. Wechseln Sie zur Text-Strategie, schneiden Sie auf den Tabellenbereich zu oder geben Sie die Spaltenpositionen explizit mit "vertical_strategy": "explicit" und "explicit_vertical_lines" vor.
  • Keine Zeilen, kein Fehler. Die Seite ist ein Scan, die Tabelle ist ein Bild oder die Datei ist passwortgeschützt (pdfplumber.open(path, password="...") für Dateien, die Sie öffnen dürfen).

Hier die Lösung für verbundene Zellen im Ganzen, getestet an einer Tabelle, in der „North“ zwei Zeilen überspannt:

python
import pandas as pd
import pdfplumber

with pdfplumber.open("merged.pdf") as pdf:
    rows = pdf.pages[0].extract_table()

df = pd.DataFrame(rows[1:], columns=rows[0])
df["Region"] = df["Region"].ffill()  # eine verbundene Zelle kommt unterhalb ihrer ersten Zeile als None zurück
df["Price"] = pd.to_numeric(df["Price"].str.replace(",", ""), errors="coerce")
print(df)

Welche Methode sollten Sie wählen?

BedarfEmpfehlung
Eine Tabelle aus einer Datei, einmaligKopieren und Einfügen, danach Text in Spalten
Wenige Text-PDFs pro Monat, Analyse in ExcelExcel, Daten > Daten abrufen > Aus Datei > Aus PDF
Text und Tabellen aus einem Ordner, monatlich wiederholtpdfplumber-Skript, das CSV schreibt
Tabellen mit Linien und Qualitätswert pro TabelleCamelot, Modus lattice
DataFrames mit minimalem Code, Java vorhandentabula-py
Gescannte Seiten oder Fotospypdfium2 mit 300 DPI rendern + Tesseract, Zahlen von einem Menschen prüfen lassen
Hunderte PDFs von einer WebsiteZuerst offizieller Download oder API; sonst ein getakteter Downloader, mit Proxy, wenn die Quelle regional ist

Häufige Fragen

Kann ich Daten kostenlos aus einem PDF extrahieren?

Ja. pdfplumber, Camelot, tabula-py und Tesseract sind Open Source, und der PDF-Connector gehört zu Excel für Microsoft 365 unter Windows. Kostenpflichtige Tools bieten vor allem Vorlagen-Editoren und besseres OCR bei schlechten Scans.

Wie übertrage ich eine Tabelle aus einem PDF nach Excel?

In Excel für Microsoft 365 unter Windows wählen Sie Daten > Daten abrufen > Aus Datei > Aus PDF, markieren die Tabelle im Navigator und klicken auf Laden. In Python extrahieren Sie die Zeilen mit pdfplumber und schreiben sie mit pandas to_excel() oder als CSV, die Excel öffnet.

Warum liefert meine PDF-Extraktion leeren Text?

Die Seite hat höchstwahrscheinlich keine Textebene. Prüfen Sie page.chars in pdfplumber oder versuchen Sie Strg+F in einem Viewer; wird nichts gefunden, führen Sie OCR aus.

Ist pdfplumber für Tabellen besser als PyPDF?

Für Tabellen ja. pypdf eignet sich gut zum Teilen, Zusammenführen und Lesen von reinem Text, hat aber keine Tabellenerkennung. pdfplumber behält die Position jedes Zeichens und baut Zellen aus Linien oder Ausrichtung neu auf, und genau das braucht die Tabellenextraktion.

Wie genau ist OCR bei gescannten PDFs?

Das hängt vom Scan ab. Saubere, mit 300 DPI gescannte Druckseiten gelingen meist gut; schiefe, blasse oder niedrig aufgelöste Scans, Handschrift und kleine Schriften nicht. Prüfen Sie die Konfidenzwerte und kontrollieren Sie die Summen.

Daten aus Dateien zu extrahieren, die Sie nutzen dürfen (eigene Rechnungen, öffentliche Berichte), ist in der Regel unproblematisch. Der Inhalt kann aber trotzdem urheberrechtlich geschützt sein, und personenbezogene Daten darin unterliegen weiterhin Gesetzen wie der DSGVO. Lesen Sie die Nutzungsbedingungen der Quelle, bevor Sie in großem Umfang herunterladen; unser Beitrag zur Rechtslage beim Data Scraping beschreibt den allgemeinen Rahmen. Dies ist keine Rechtsberatung.

Fazit

Jede PDF-Aufgabe beginnt mit einer Prüfung: Gibt es eine Textebene? Wenn ja, erledigt der PDF-Connector von Excel gelegentliche Tabellen, und ein pdfplumber-Skript macht aus einem Ordner eine CSV-Datei; für reine Tabellenarbeit kommen Camelot oder tabula-py infrage. Wenn nein, rendern Sie mit 300 DPI, führen Tesseract aus und prüfen die Zahlen. Halten Sie Quelldatei und Seite in jeder Zeile fest, und behandeln Sie Massen-Downloads von PDFs wie jeden anderen Scraping-Job. Kommen diese Downloads aus regionalen oder ratenbegrenzten Quellen, liefern unsere Proxy-Tarife der Pipeline die nötigen Adressen.

ChatGPT fragenClaude fragen