PDFs, E-Mails, Dokumente: Alles wird zugänglich
Jeder Dokumenttyp hat seine Eigenarten. PDFs verstecken Text in komplexen Layern, E-Mails sind in archaischen Formaten strukturiert, Word-Dokumente mischen Content mit Formatierung. Diese Formate zu knacken und den wertvollen Text zu extrahieren ist handwerkliche Arbeit, aber lösbar.
PDF-Extraktion ist oft der schwierigste Teil. Moderne PDFs enthalten echten Text, alte oder gescannte PDFs sind im Grunde Bilder. Dazwischen gibt es alle Arten von Zwischenlösungen mit verschiedenen Encoding-Problemen und Layout-Herausforderungen.
Document Processing ist zu 80% Problemlösung für Edge Cases. Das Standard-Happy-Path-PDF funktioniert einfach, aber korrupte, verschlüsselte oder schlecht formatierte Dokumente erfordern robusten Error-Handling und Fallback-Strategien.
Verschiedene PDF-Libraries haben verschiedene Stärken. PyPDF2 ist einfach aber limitiert, pdfplumber behält Layout-Informationen, pymupdf ist schnell und feature-rich. Für robuste Systeme brauchst Du oft mehrere Tools als Fallbacks.
Multi-Tool-PDF-Extraktion:
def extract_pdf_text(file_path):
# Versuch 1: PyMuPDF (schnell, robust)
try:
import fitz
doc = fitz.open(file_path)
text = ""
for page in doc:
text += page.get_text()
if len(text.strip()) > 100: # Mindest-Content
return text
except:
pass
# Versuch 2: pdfplumber (besseres Layout)
try:
import pdfplumber
with pdfplumber.open(file_path) as pdf:
return '\n'.join([page.extract_text() for page in pdf.pages])
except:
return None
OCR für gescannte PDFs ist ein eigenes Thema. Tesseract ist der Standard für Open-Source-OCR, aber es braucht gute Preprocessing: Kontrast-Anpassung, Noise-Removal, Rotation-Correction. Die Qualität schwankt stark je nach Scan-Qualität.
Vielleicht magst Du OCR als separaten Schritt behandeln. Erst versuchen normalen Text zu extrahieren, nur bei Bedarf OCR anwenden. Das spart Zeit und Ressourcen für die 90% der PDFs, die echten Text enthalten.
E-Mail-Verarbeitung ist komplex wegen der verschiedenen Formate. MBOX-Dateien von Thunderbird, PST-Files von Outlook, EML-Files als Einzelnachrichten – jedes Format braucht einen eigenen Parser. Und dann sind da noch Attachments, HTML vs. Plain-Text, Encoding-Issues.
E-Mail-Extraktion multi-format:
# MBOX-Dateien (Thunderbird, Apple Mail)
import mailbox
for message in mailbox.mbox('inbox.mbox'):
subject = message['Subject']
body = message.get_payload(decode=True)
# EML-Dateien (Einzelnachrichten)
import email
with open('message.eml', 'r') as f:
msg = email.message_from_file(f)
subject = msg['Subject']
body = msg.get_payload()
# PST-Dateien (Outlook) - benötigt libpst
import pypff
pst = pypff.file()
pst.open('outlook.pst')
HTML-Cleanup in E-Mails ist essentiell. E-Mail-HTML ist oft schlecht formatiert und voller Tracking-Pixel und Layout-Code. BeautifulSoup oder html2text extrahieren den reinen Text und entfernen den HTML-Ballast.
E-Mail-Privacy: E-Mails enthalten persönliche und vertrauliche Informationen. Überlege Dir genau, was Du indexierst und wie lange Du es aufbewahrst. Compliance-Regeln können hier relevant sein.
Word-Dokumente sind relativ einfach mit python-docx. Das Library versteht die DOCX-Struktur und extrahiert Text, Tabellen und Metadaten sauber. Alte DOC-Dateien sind schwieriger und brauchen oft LibreOffice als Konverter.
Office-Dokumente verarbeiten:
# DOCX-Dateien
import docx
doc = docx.Document('document.docx')
text = '\n'.join([paragraph.text for paragraph in doc.paragraphs])
# Tabellen extrahieren
for table in doc.tables:
for row in table.rows:
row_data = [cell.text for cell in row.cells]
# PowerPoint (PPTX)
from pptx import Presentation
prs = Presentation('presentation.pptx')
for slide in prs.slides:
for shape in slide.shapes:
if hasattr(shape, "text"):
text += shape.text
Encoding-Probleme sind der Fluch der Dokumenten-Verarbeitung. UTF-8, Latin-1, Windows-1252, und dutzende andere Encodings können in einem einzigen Archiv vorkommen. Chardet hilft bei der automatischen Encoding-Erkennung, aber 100% perfekt ist es nie.
Encoding-Realität: Plane für Encoding-Fehler. Nicht jedes Dokument lässt sich perfekt dekodieren. Graceful Degradation und Fallback zu "ignore" oder "replace" Strategien sind praktischer als perfekte Encoding-Behandlung.
Batch-Processing-Pipeline für große Dokumentenmengen braucht sorgfältige Planung. Memory-Management, parallele Verarbeitung, Progress-Tracking, Error-Recovery – ein robustes System ist deutlich komplexer als ein einfacher Script.
Robuste Batch-Processing-Pipeline:
import multiprocessing as mp
from concurrent.futures import ProcessPoolExecutor
def process_document(file_path):
try:
# Text extrahieren
text = extract_text(file_path)
# Embeddings generieren
embedding = generate_embedding(text)
# In ChromaDB speichern
store_in_chromadb(file_path, text, embedding)
return {"status": "success", "file": file_path}
except Exception as e:
return {"status": "error", "file": file_path, "error": str(e)}
# Parallelverarbeitung
with ProcessPoolExecutor(max_workers=4) as executor:
results = executor.map(process_document, file_list)
Tabellen und strukturierte Daten aus Dokumenten zu extrahieren ist eine Kunst für sich. PDFs mit Tabellen, Excel-Dateien, CSV-Files – jedes Format hat seine Eigenarten. pandas ist oft der beste Freund für strukturierte Datenverarbeitung.
Es ist besser, Tabellendaten separat zu indexieren. Eine Tabelle pro ChromaDB-Eintrag, nicht das gesamte Dokument. Das macht Suchen präziser und Ergebnisse relevanter.
Attachments in E-Mails sind oft die wertvollsten Inhalte. Verträge, Präsentationen, Berichte – aber sie sind schwer zu finden, weil sie in E-Mails versteckt sind. Attachments extrahieren und separat indexieren macht sie durchsuchbar.
E-Mail-Attachment-Extraktion:
def extract_attachments(email_message, output_dir):
attachments = []
for part in email_message.walk():
if part.get_content_disposition() == 'attachment':
filename = part.get_filename()
if filename:
file_path = os.path.join(output_dir, filename)
with open(file_path, 'wb') as f:
f.write(part.get_payload(decode=True))
attachments.append(file_path)
return attachments
Performance-Monitoring hilft beim Identifizieren von Bottlenecks. Welche Dokumenttypen brauchen am längsten? Wo ist RAM-Verbrauch problematisch? Diese Daten helfen bei der Optimierung der Pipeline.
Große Dokumente können Memory-Problems verursachen. 100MB-PDFs oder PST-Files mit Gigabyte-Größe sprengen schnell den verfügbaren RAM. Streaming-Processing oder Dokument-Splitting können helfen.
Metadata-Preservation ist wichtig für späteren Kontext. Wann wurde das Dokument erstellt? Wer hat es geschrieben? In welcher E-Mail war es attached? Diese Informationen machen Suchergebnisse wertvoller.
Umfassendes Metadata-Schema:
{
"source_type": "email_attachment",
"email_subject": "Quarterly Report Q4 2024",
"email_sender": "ceo@company.com",
"email_date": "2024-01-15T10:30:00Z",
"attachment_name": "Q4_Report.pdf",
"document_author": "Finance Team",
"document_created": "2024-01-10T14:20:00Z",
pages": 23,
"file_size": 2048576,
"extraction_method": "pymupdf"
}
Kontinuierliche Verbesserung der Extraction-Quality durch Feedback-Loops. Welche Dokumente wurden nicht gut extrahiert? Wo sind manuell nacharbeiten nötig? Diese Erkenntnisse fließen in bessere Preprocessing-Pipelines.
Document Processing ist wie Archäologie: Du gräbst wertvollen Content aus verschiedensten Formaten und Encodings aus. Geduld und robuste Tools sind wichtiger als perfekte Algorithmen.
Mit systematischer Dokument-Verarbeitung hast Du alle wichtigen Informationsquellen erschlossen. Jetzt können wir die wahre Kraft semantischer Suche entfalten und nach Bedeutung statt nur nach Wörtern suchen.