Skip to main navigation Skip to main content Skip to page footer

Outlook-.msg-Dateien automatisch „schwärzen“ – ein kurzer Leitfaden zum gezeigten Python-Skript

Wer E-Mails weitergeben muss (Tickets, Audits, Schulungen), steht oft vor demselben Problem: personenbezogene Daten sollen drin nicht mehr sichtbar sein. Das hier gezeigte Python-Skript nimmt Outlook-.msg-Dateien aus einem Ordner, maskiert Name und E-Mail-Adresse und speichert eine „geschwärzte“ Kopie – bequem und reproduzierbar.
 

Was das Skript macht – in drei Sätzen

  1. Es liest alle .msg-Dateien aus C:/Temp ein.
  2. Es ersetzt den konkreten Namen Christian Dräger sowie passende E-Mail-Adressen (christian.draeger@…) durch einen Balken (████████████).
  3. Es erstellt über die Outlook-COM-Schnittstelle neue .msg-Dateien mit den bereinigten Betreff- und Textinhalten.

Voraussetzungen

  • Windows mit installiertem Microsoft Outlook (für die COM-Schnittstelle win32com.client).
  • Python-Pakete:
    • extract_msg (liest .msg-Inhalte ohne Outlook)
    • pywin32 (stellt win32com.client bereit)
  • Schreib-/Leserechte im Zielordner (C:/Temp im Beispiel).

Kurzer Code-Walkthrough

Konfiguration

verzeichnis = "C:/Temp"

name_to_mask = "Christian Dräger"

email_to_mask = r"christian\.draeger@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"

balken = "████████████"

Hier legen Sie Ordner, Zielnamen/E-Mail und das Maskierungszeichen fest. Der E-Mail-Regex ist bewusst restriktiv (passt auf Domains wie example.de, .com, .info etc.).

Maskierung

def maskiere_inhalt(text):

    if not text:

        return ""

    text = text.replace(name_to_mask, balken)

    text = re.sub(email_to_mask, balken, text)

    return text

replace arbeitet exakt und groß/kleinschreibungs-sensitiv. „christian dräger“ wird also nicht getroffen.

re.sub maskiert die E-Mail anhand des Regex.

Lesen & Schreiben

outlook = win32com.client.Dispatch("Outlook.Application")

for datei in os.listdir(verzeichnis):

    if datei.lower().endswith(".msg"):

        msg = extract_msg.Message(pfad)

        msg_subject = maskiere_inhalt(msg.subject)

        msg_body = maskiere_inhalt(msg.body)

        mail = outlook.CreateItem(0)  # olMailItem

        mail.Subject = msg_subject

        mail.Body = msg_body

        mail.SaveAs(ziel_pfad)

  • extract_msg liest Betreff/Body.
  • Über Outlook wird ein neues Mail-Objekt erzeugt und als .msg gespeichert.
  • Absender/Empfänger werden nicht übernommen – die Infos müssten ggf. in den Body kopiert oder separat dokumentiert werden.

Wichtige Hinweise & Grenzen

  • Formatierung: mail.Body ist Nur-Text. Wenn die Original-Mail HTML enthält, geht Formatierung verloren.
  • Anhänge: Das Skript überträgt keine Anhänge. Wenn Sie Anhänge brauchen (und ggf. maskieren), muss das ergänzt werden.
  • Groß-/Kleinschreibung & Varianten: replace findet nur exakt „Christian Dräger“. Schreibvarianten, Diakritika, Doppelnamen bleiben unmaskiert.
  • Kompatibilität: win32com setzt Windows + Outlook voraus.
  • Datenschutz/Compliance: Prüfen Sie vorab Ihre internen Richtlinien (Stichwort DSGVO/PII). Automatisches Schwärzen ist hilfreich, aber kein Ersatz für eine inhaltliche Prüfung.

Sinnvolle Verbesserungen (Quick Wins)

  1. Case-insensitive & Wortgrenzen für Namen:
  2. name_pattern = re.compile(r"\bchristian\s+drä(?:ger|eger)\b", re.IGNORECASE)
  3. text = name_pattern.sub(balken, text)
  4. E-Mail allgemeiner fassen (alle E-Mails maskieren, nicht nur eine Person):
  5. email_pattern = re.compile(r"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}")
  6. text = email_pattern.sub(balken, text)
  7. HTML erhalten: Wenn msg.htmlBody vorhanden ist, lieber mail.HTMLBody setzen und darin maskieren (Achtung auf HTML-Entities).
  8. Fehlerbehandlung & Logging: try/except um Datei- und COM-Operationen, Fortschritte loggen.
  9. Sicher speichern: Bestehende Dateien nicht überschreiben, z. B. Suffix mit Zeitstempel.
  10. CLI-Parameter: Ordner, Zielmuster, Regex via Kommandozeile übergeben (argparse).
  11. Dry-Run: Erst nur anzeigen, was maskiert würde – dann erst schreiben.

 

Phyton-Quellcode

import os

import re

import datetime as dt

import extract_msg

import win32com.client

VERZEICHNIS = r"C:/Temp"

BALKEN = "████████████"

# Muster: alle E-Mails + Name (varianten- & case-insensitive)

EMAIL_RE = re.compile(r"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}")

NAME_RE  = re.compile(r"\bchristian\s+drä(?:ger|eger)\b", re.IGNORECASE)

def mask_text(text: str) -> str:

    if not text:

        return ""

    text = EMAIL_RE.sub(BALKEN, text)

    text = NAME_RE.sub(BALKEN, text)

    return text

def safe_name(base: str) -> str:

    ts = dt.datetime.now().strftime("%Y%m%d-%H%M%S")

    return f"{base}_maskiert_{ts}.msg"

def process_msg_file(path: str, outlook) -> str:

    msg = extract_msg.Message(path)

    subject = mask_text(msg.subject)

    # Body: HTML bevorzugen, falls vorhanden

    html = getattr(msg, "htmlBody", None)

    if html:

        body_html = mask_text(html)

    else:

        body_html = None

    body_text = mask_text(msg.body)

    mail = outlook.CreateItem(0)  # olMailItem

    mail.Subject = subject

    if body_html:

        mail.HTMLBody = body_html

    else:

        mail.Body = body_text

    out_dir  = os.path.dirname(path)

    out_name = safe_name(os.path.splitext(os.path.basename(path))[0])

    out_path = os.path.join(out_dir, out_name)

    mail.SaveAs(out_path)

    return out_name

def main():

    outlook = win32com.client.Dispatch("Outlook.Application")

    for fname in os.listdir(VERZEICHNIS):

        if not fname.lower().endswith(".msg"):

            continue

        fpath = os.path.join(VERZEICHNIS, fname)

        try:

            out = process_msg_file(fpath, outlook)

            print(f"[OK] {fname} → {out}")

        except Exception as e:

            print(f"[FEHLER] {fname}: {e}")

if __name__ == "__main__":

    main()

 

Praxis-Tipps

  • Testordner verwenden: Zuerst mit Kopien arbeiten.
  • Regex iterativ schärfen: Namen, Kürzel, Telefonnummern, Kundennummern etc. Schritt für Schritt ergänzen.
  • Review einplanen: Trotz Automatik immer stichprobenartig prüfen.
  • Dokumentieren: Welche Felder werden maskiert? Welche nicht? So bleibt die Weitergabe nachvollziehbar.

 

Viel Spaß beim Testen ;)

 

Zurück
Outlook-.msg-Dateien automatisch „schwärzen“ – ein kurzer Leitfaden zum gezeigten Python-Skript