#!/usr/bin/env python3 """ probe_coords.py - Zeigt die Y-Koordinaten von Labels und Werten auf der Info-Seite, um koordinatenbasiertes Parsen zu ermoeglichen. Idee (vom Nutzer): Jeder Wert gehoert zu dem Label, UNTER dem er steht und UEBER dem naechsten Label. Types-Werte liegen zwischen 'TYPES OF BUSINESSES' und 'BACKGROUND'; Background-Werte zwischen 'BACKGROUND' und 'TOTAL PURCHASE'. Aufruf: python3 probe_coords.py --pdf ~/data/S/"Schultz, Gunnar 022526.pdf" """ import argparse import pdfplumber ANCHOR_INFO = "BUYER INFORMATION SHEET" # Label-Texte, deren Y-Position wir als Grenzen brauchen LABELS = [ "NAME / COMPANY", "PHONE", "ADDRESS", "EMAIL ADDRESS", "HOW DID YOU HEAR", "ARE YOU INTERESTED", "TYPES OF BUSINESSES", "BACKGROUND", "TOTAL PURCHASE PRICE", "DOWN PAYMENT", "INCOME REQUIREMENTS", "ACCOUNTANT", "ATTORNEY", "BANK", ] ap = argparse.ArgumentParser() ap.add_argument("--pdf", required=True) args = ap.parse_args() with pdfplumber.open(args.pdf) as pdf: info_page = None for page in pdf.pages: if ANCHOR_INFO in (page.extract_text() or ""): info_page = page break if not info_page: print("Keine Info-Seite"); raise SystemExit(1) # Zeilen rekonstruieren: Woerter nach 'top' gruppieren (gleiche Zeile = aehnliches top) words = info_page.extract_words(x_tolerance=5) # nach top sortieren words.sort(key=lambda w: (round(w["top"]), w["x0"])) # Zeilen bilden (Toleranz 3px) lines = [] cur = [] cur_top = None for w in words: if cur_top is None or abs(w["top"] - cur_top) <= 3: cur.append(w); cur_top = w["top"] if cur_top is None else cur_top else: lines.append((cur_top, cur)); cur = [w]; cur_top = w["top"] if cur: lines.append((cur_top, cur)) print(f"{'TOP':>6} | {'X0':>5} | TEXT") print("-"*70) for top, ws in lines: text = " ".join(w["text"] for w in ws) x0 = min(w["x0"] for w in ws) # Markiere Label-Zeilen is_label = any(lbl in text.upper() for lbl in LABELS) mark = " <== LABEL" if is_label else "" print(f"{top:6.0f} | {x0:5.0f} | {text[:60]}{mark}")