v1.1.14: Final Umsatz & Mitarbeiter extraction fix (Unicode normalized)

Zusammenfassung der Änderungen (v1.1.13 → v1.1.14)
Unicode Normalisierung:

Die Funktion clean_text nutzt nun unicodedata.normalize("NFKC", ...) um ambigue Unicode-Zeichen zu vereinheitlichen. Dadurch werden unerwartete Zeichen in Infobox-Titeln eliminiert.

Umsatz-Extraktion:

Die Helper-Funktion extract_numeric_value behandelt Zahlenstrings nun robust.

Bei "2,395 Mrd. Euro" wird "2,395" extrahiert, Punkte als Tausendertrennzeichen entfernt und das Komma als Dezimaltrenner genutzt.

"mrd" führt zur Multiplikation mit 1000, was den Wert korrekt in Mio € umrechnet (2395 Mio).

Mitarbeiterextraktion:

Der numerische Teil der Mitarbeiterzahl wird mit derselben Helper-Funktion extrahiert.

Unicode-Normalisierung und ein leicht gelockertes Matching in extract_fields_from_infobox_text („if field.lower() in token.lower()“) sollen sicherstellen, dass auch Zahlen wie "4.175 (2021/22)" erkannt und korrekt zu "4175" verarbeitet werden.

Re-Evaluierungsmodus:

Alle Zeilen mit "x" in Spalte A werden verarbeitet; der vollständige Infobox-Inhalt wird in der Konsole ausgegeben, um die Daten zu überprüfen.
This commit is contained in:
2025-04-01 05:22:33 +00:00
parent 72a69c9e50
commit b5d7add8b5

View File

@@ -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