erweiterung normalize URL

This commit is contained in:
2025-08-01 11:11:37 +00:00
parent 84e5135130
commit df77fb757a

View File

@@ -207,13 +207,23 @@ def create_log_filename(mode):
# ============================================================================== # ==============================================================================
def simple_normalize_url(url): def simple_normalize_url(url):
"""Normalisiert URL zu domain.tld oder k.A. (ohne www, ohne Pfad).""" """
Bereinigt und normalisiert eine URL auf die reine Domain (z.B. 'example.com').
Entfernt 'www.', Protokolle, Pfade und Query-Parameter.
NEU v2.1: Behandelt unsichtbare Zeichen und internationale Domains (Umlaute) korrekt.
"""
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
if not url or not isinstance(url, str): return "k.A." if not url or not isinstance(url, str):
url = url.strip() return "k.A."
if not url or url.lower() == 'k.a.': return "k.A."
if not url.lower().startswith(("http://", "https://")): # 1. Bereinige unsichtbare Zeichen, die oft Probleme machen
# \u200b = zero-width space, \xad = soft hyphen
url = url.replace('\u200b', '').replace('\xad', '').strip()
if not url or url.lower() == 'k.a.':
return "k.A."
# 2. Füge ein Protokoll hinzu, falls es fehlt, damit urlparse funktioniert
if not re.match(r'^(http|https)://', url):
url = "https://" + url url = "https://" + url
try: try:
@@ -223,34 +233,43 @@ def simple_normalize_url(url):
logger.debug(f"URL '{url[:100]}...' konnte nicht sinnvoll geparst werden (leerer netloc).") logger.debug(f"URL '{url[:100]}...' konnte nicht sinnvoll geparst werden (leerer netloc).")
return "k.A." return "k.A."
# Entferne Port-Informationen
domain_part = domain_part.split(":", 1)[0] domain_part = domain_part.split(":", 1)[0]
# Entferne User-Info (user@domain.com)
if '@' in domain_part: if '@' in domain_part:
domain_part = domain_part.split('@', 1)[1] domain_part = domain_part.split('@', 1)[1]
# 3. KORRIGIERTE LOGIK: Zuerst in IDNA encodieren, dann als ASCII decodieren
try: try:
domain_part = domain_part.encode('ascii').decode('idna') # Das ist der entscheidende Schritt für Umlaute etc.
except UnicodeDecodeError: # 'lübeck.de' -> b'xn--lbeck-5wa.de' (bytes)
pass domain_part_encoded = domain_part.encode('idna')
# b'xn--lbeck-5wa.de' -> 'xn--lbeck-5wa.de' (string)
domain_part = domain_part_encoded.decode('ascii')
except UnicodeError as e:
logger.warning(f"Konnte Domain '{domain_part[:100]}' nicht nach IDNA konvertieren: {e}")
return "k.A. (Unicode-Fehler)"
# 4. Standard-Normalisierung
domain_part = domain_part.lower() domain_part = domain_part.lower()
if domain_part.startswith("www."): if domain_part.startswith("www."):
domain_part = domain_part[4:] domain_part = domain_part[4:]
# 5. Finale Validierung
if domain_part and '.' in domain_part: if domain_part and '.' in domain_part:
parts = domain_part.split('.') parts = domain_part.split('.')
if len(parts) > 1 and parts[-1].isalpha() and len(parts[-1]) >= 2: if len(parts) > 1 and parts[-1].isalpha() and len(parts[-1]) >= 2:
return domain_part return domain_part
else: else:
logger.debug(f"URL '{url[:100]}...' normalisiert zu '{domain_part}', aber TLD-Pruefung schlug fehl.") logger.debug(f"URL '{url[:100]}...' normalisiert zu '{domain_part}', aber TLD-Prüfung schlug fehl.")
return "k.A." return "k.A."
else: else:
logger.debug(f"URL '{url[:100]}...' normalisiert zu '{domain_part}', enthaelt keinen Punkt oder ist leer.") logger.debug(f"URL '{url[:100]}...' normalisiert zu '{domain_part}', enthält keinen Punkt oder ist leer.")
return "k.A." return "k.A."
except Exception as e: except Exception as e:
logger.error(f"Fehler bei URL-Normalisierung fuer '{url[:100]}...': {e}") logger.error(f"Unerwarteter Fehler bei URL-Normalisierung für '{url[:100]}...': {e}")
return "k.A. (Fehler Normalisierung)" return "k.A. (Fehler bei Normalisierung)"
def normalize_string(s): def normalize_string(s):