dfg
This commit is contained in:
64
probe_coords.py
Normal file
64
probe_coords.py
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
#!/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()
|
||||||
|
# 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}")
|
||||||
Reference in New Issue
Block a user