diff --git a/brancheneinstufung.py b/brancheneinstufung.py index 1fb1f838..4846a290 100644 --- a/brancheneinstufung.py +++ b/brancheneinstufung.py @@ -8,11 +8,12 @@ from bs4 import BeautifulSoup from oauth2client.service_account import ServiceAccountCredentials from datetime import datetime from difflib import SequenceMatcher +import unicodedata import csv # ==================== KONFIGURATION ==================== class Config: - VERSION = "1.1.13" # Neue Version mit finaler Umsatz- und Mitarbeiterextraktion + VERSION = "v1.1.14" # v1.1.14: Umsatz in Mio € korrekt; Mitarbeiterzahl als ganze Zahl (Unicode-Normalisierung) LANG = "de" CREDENTIALS_FILE = "service_account.json" SHEET_URL = "https://docs.google.com/spreadsheets/d/1u_gHr9JUfmV1-iviRzbSe3575QEp7KLhK5jFV_gJcgo" @@ -41,9 +42,11 @@ def debug_print(message): print(f"[DEBUG] {message}") def clean_text(text): + """Normalize Unicode, entferne Referenzen und extra Whitespace.""" if not text: return "k.A." - text = str(text) + # Unicode-Normalisierung (NFKC vereinheitlicht Zeichen) + text = unicodedata.normalize("NFKC", str(text)) text = re.sub(r'\[\d+\]', '', text) text = re.sub(r'\s+', ' ', text).strip() return text if text else "k.A." @@ -72,24 +75,20 @@ def normalize_company_name(name): def extract_numeric_value(raw_value, is_umsatz=False): """ Extrahiert den numerischen Wert aus raw_value. - - Falls raw_value leer ist, wird "k.A." zurückgegeben. - - Wenn ein Komma vorhanden ist, werden Punkte als Tausendertrennzeichen entfernt und das Komma als Dezimaltrenner genutzt. - - Wenn kein Komma vorhanden ist, werden alle Punkte entfernt (als Tausendertrennzeichen). - - Für Umsatz: Falls "mrd" (Milliarden) vorkommt, wird der Wert mit 1000 multipliziert; enthält der Text weder "mio" noch "mrd", so wird angenommen, dass der Wert in Euro ist, und er wird durch 1e6 geteilt. - - Für Mitarbeiter: Der extrahierte Wert wird als ganze Zahl zurückgegeben. + - Nutzt Komma als Dezimaltrenner, entfernt Punkte als Tausendertrennzeichen. + - Für Umsatz: "mrd" multipliziert mit 1000, bei fehlender Einheit wird durch 1e6 geteilt. + - Für Mitarbeiter: Gibt den ganzzahligen Wert zurück. """ raw_value = raw_value.strip() if not raw_value: return "k.A." raw = raw_value.lower() match = re.search(r'([\d.,]+)', raw) - if not match: + if not match or not match.group(1): return "k.A." num_str = match.group(1) - if not num_str: - return "k.A." - # Wenn ein Komma vorhanden ist, behandeln wir es als Dezimaltrenner. if ',' in num_str: + # Entferne Punkte als Tausendertrennzeichen, ersetze Komma durch Punkt num_str = num_str.replace('.', '').replace(',', '.') try: num = float(num_str) @@ -97,6 +96,7 @@ def extract_numeric_value(raw_value, is_umsatz=False): debug_print(f"Fehler bei der Umwandlung von {num_str}: {e}") return "k.A." else: + # Entferne alle Punkte (Tausendertrennzeichen) num_str = num_str.replace(' ', '').replace('.', '') try: num = float(num_str) @@ -212,6 +212,7 @@ class WikipediaScraper: header = row.find('th') if header: header_text = clean_text(header.get_text()).lower() + # Nutze "in" statt "==" um unsichere Unicode-Zeichen zu umgehen if any(kw in header_text for kw in keywords): value = row.find('td') if value: @@ -234,7 +235,8 @@ class WikipediaScraper: tokens = [token.strip() for token in infobox_text.split("|") if token.strip()] for i, token in enumerate(tokens): for field in field_names: - if token.lower() == field.lower(): + # Verwende "in" um etwaige Unicode-Variationen abzufangen + if field.lower() in token.lower(): j = i + 1 while j < len(tokens) and not tokens[j]: j += 1