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.
- Die Seite wird geparst. Jedes Zeichen wird mit Position, Schrift und Größe gelesen, dazu die gezeichneten Linien und Rechtecke.
- Aus Zeichen werden Wörter und Zeilen. Nahe beieinanderliegende Zeichen auf einer Grundlinie bilden Wörter, Wörter auf gleicher Höhe eine Zeile.
- Tabellenbereiche werden gefunden. Anhand von Linien, die ein Raster bilden, oder anhand von Wortspalten, die durch Leerraum getrennt ausgerichtet sind.
- Zellen werden gebildet. Linienkreuzungen oder Spaltenlücken legen die Zellgrenzen fest, und jedes Wort landet in der Zelle, die es enthält.
- 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
| Methode | Code nötig? | Liest Scans? | Am besten für | Wo es hakt |
|---|---|---|---|---|
| Kopieren und Einfügen | Nein | Nein | Eine kleine Tabelle, einmalig | Spalten fallen in eine Zelle zusammen, mehrseitige Tabellen |
| Excel, Daten abrufen > Aus PDF | Nein | Nein | Wenige Dateien pro Monat, Analyse in Excel | Tabellen ohne Rahmen, viele Dateien mit unterschiedlichem Layout |
| pdfplumber (Python) | Ja | Nein | Text plus Tabellen, Batch-Jobs, feine Steuerung | Braucht Feinabstimmung bei Tabellen ohne Rahmen |
| Camelot (Python) | Ja | Optionales Extra | Tabellen mit Linien, Genauigkeitsbericht pro Tabelle | Freitext rund um die Tabellen |
| tabula-py (Python) | Ja | Nein | Schnelle DataFrames aus tabellenlastigen Dateien | Setzt Java auf dem Rechner voraus |
| Tesseract über pytesseract | Ja | Ja | Gescannte Seiten, Fotos von Dokumenten | Genauigkeit 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:
- Öffnen Sie eine leere Arbeitsmappe und wählen Sie Daten > Daten abrufen > Aus Datei > Aus PDF.
- Wählen Sie das PDF aus und klicken Sie auf Öffnen.
- 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.
- 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).
- 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:
python -m venv .venv
.venv\Scripts\activate # macOS/Linux: source .venv/bin/activate
pip install pdfplumber pandasDie Grundlagen passen in wenige Zeilen:
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:
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.
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:
WARNING price-list-scan.pdf p.1 has no text layer, needs OCR
INFO wrote 78 rows to price_lists.csvutf-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.
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:
pip install pytesseract pypdfium2Das 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:
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:
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
Nonezurü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:
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?
| Bedarf | Empfehlung |
|---|---|
| Eine Tabelle aus einer Datei, einmalig | Kopieren und Einfügen, danach Text in Spalten |
| Wenige Text-PDFs pro Monat, Analyse in Excel | Excel, Daten > Daten abrufen > Aus Datei > Aus PDF |
| Text und Tabellen aus einem Ordner, monatlich wiederholt | pdfplumber-Skript, das CSV schreibt |
| Tabellen mit Linien und Qualitätswert pro Tabelle | Camelot, Modus lattice |
| DataFrames mit minimalem Code, Java vorhanden | tabula-py |
| Gescannte Seiten oder Fotos | pypdfium2 mit 300 DPI rendern + Tesseract, Zahlen von einem Menschen prüfen lassen |
| Hunderte PDFs von einer Website | Zuerst 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.
Ist es legal, Daten aus heruntergeladenen PDFs zu extrahieren?
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.




