v1.2.0: Added Alignment-Demo mode (Option 3) for new column header mapping

Zusammenfassung der Änderungen (v1.1.16 → v1.2.0)
Neue Alignment-Demo (Modus 3):

Ein neuer Modus „3“ wurde hinzugefügt, der ausschließlich eine Demo-Zeile (Zeile 11200) mit den neuen Spaltenüberschriften in das Google Sheet schreibt.

Dies ermöglicht die Validierung der neuen Spaltenanordnung anhand einer Übersetzungstabelle.

Spaltenzuordnung:

Die Code-Logik für das Update der Zellen wurde so angepasst, dass bei normalen bzw. Re‑Evaluierungsmodi die korrekten Spaltenadressen genutzt werden.

Sonstiges:

Unicode-Normalisierung und bestehende Umsatz- sowie Mitarbeiterextraktion (v1.1.16) bleiben erhalten.
This commit is contained in:
2025-04-01 08:30:39 +00:00
parent 4a3f290e4c
commit 41819a38a2

View File

@@ -13,7 +13,7 @@ import csv
# ==================== KONFIGURATION ====================
class Config:
VERSION = "v1.1.16" # v1.1.16: Umsatz in Mio € & Mitarbeiterzahl extrahiert; Fallback-Debug bei fehlender Umwandlung
VERSION = "v1.2.0" # v1.2.0: Neue Spaltenanordnung, Alignment-Demo-Modus (Option 3)
LANG = "de"
CREDENTIALS_FILE = "service_account.json"
SHEET_URL = "https://docs.google.com/spreadsheets/d/1u_gHr9JUfmV1-iviRzbSe3575QEp7KLhK5jFV_gJcgo"
@@ -45,7 +45,6 @@ def clean_text(text):
"""Normalisiert Unicode, entfernt Referenzen und extra Whitespace."""
if not text:
return "k.A."
# Unicode-Normalisierung (NFKC vereinheitlicht ambigue Zeichen)
text = unicodedata.normalize("NFKC", str(text))
text = re.sub(r'\[\d+\]', '', text)
text = re.sub(r'\s+', ' ', text).strip()
@@ -76,14 +75,13 @@ def extract_numeric_value(raw_value, is_umsatz=False):
"""
Extrahiert den numerischen Wert aus raw_value.
- Nutzt Komma als Dezimaltrenner und entfernt Punkte als Tausendertrennzeichen.
- Für Umsatz: Falls "mrd" vorkommt, wird mit 1000 multipliziert; enthält der Text keine Einheit, so wird durch 1e6 geteilt.
- Für Umsatz: Falls "mrd" vorkommt, wird der Wert mit 1000 multipliziert; enthält der Text keine Einheit, so wird durch 1e6 geteilt.
- Für Mitarbeiter: Gibt den ganzzahligen Wert zurück.
- Falls die Umwandlung fehlschlägt, wird der Original-Rohtext im Debug-Log ausgegeben.
- Bei Fehlern wird der Original-Rohtext im Debug-Log ausgegeben.
"""
raw_value = raw_value.strip()
if not raw_value:
return "k.A."
# Ersetze nichtbrechende Leerzeichen durch normale Leerzeichen
raw = raw_value.lower().replace("\xa0", " ")
match = re.search(r'([\d.,]+)', raw, flags=re.UNICODE)
if not match or not match.group(1).strip():
@@ -96,14 +94,14 @@ def extract_numeric_value(raw_value, is_umsatz=False):
num = float(num_str)
except Exception as e:
debug_print(f"Fehler bei der Umwandlung von '{num_str}' (Rohtext: '{raw_value}'): {e}")
return raw_value # Rückgabe des Rohtexts als Fallback
return raw_value # Fallback: Originaltext
else:
num_str = num_str.replace(' ', '').replace('.', '')
try:
num = float(num_str)
except Exception as e:
debug_print(f"Fehler bei der Umwandlung von '{num_str}' (Rohtext: '{raw_value}'): {e}")
return raw_value # Rückgabe des Rohtexts als Fallback
return raw_value # Fallback: Originaltext
if is_umsatz:
if "mrd" in raw or "milliarden" in raw:
num *= 1000
@@ -235,7 +233,6 @@ 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:
# Verwende "in", um Varianten und ambigue Unicode-Zeichen abzufangen.
if field.lower() in token.lower():
j = i + 1
while j < len(tokens) and not tokens[j]:
@@ -269,7 +266,6 @@ class WikipediaScraper:
debug_print(f"Extraktionsfehler: {str(e)}")
return {'url': 'k.A.', 'first_paragraph': 'k.A.', 'branche': 'k.A.',
'umsatz': 'k.A.', 'mitarbeiter': 'k.A.', 'full_infobox': 'k.A.'}
@retry_on_failure
def search_company_article(self, company_name, website):
search_terms = self._generate_search_terms(company_name, website)
@@ -290,6 +286,31 @@ class WikipediaScraper:
continue
return None
# ==================== ALIGNMENT DEMO (Modus 3) ====================
def alignment_demo(sheet):
"""
Dieser Modus schreibt eine Demo-Zeile (z.B. in Zeile 11200) mit den neuen Spaltenüberschriften.
Passe die Liste new_headers an das gewünschte neue Schema an.
"""
# Beispiel für neue Spaltenüberschriften (bitte anpassen, falls das Schema anders lautet):
new_headers = [
"Re-Eval Flag", # z. B. Spalte A
"Firmenname", # Spalte B
"Website", # Spalte C
"Branche (Datenbank)",# Neue Spalte (grün)
"Branche Wikipedia", # Bestand
"Umsatz Wikipedia (Mio €)", # Bestand
"Mitarbeiter Wikipedia", # Bestand
"Erster Absatz Wikipedia", # Neu verschoben
"Wikipedia URL", # Bestand
"Datum der Extraktion", # Neu
"Version" # Neu
]
# Schreibe die neuen Header in Zeile 11200 (A11200 bis K11200)
header_range = "A11200:K11200"
sheet.update(values=[new_headers], range_name=header_range)
print("Alignment-Demo abgeschlossen: Neue Spaltenüberschriften in Zeile 11200 geschrieben.")
# ==================== DATA PROCESSOR ====================
class DataProcessor:
def __init__(self):
@@ -298,6 +319,10 @@ class DataProcessor:
def process_rows(self, num_rows=None):
if MODE == "2":
print("Re-Evaluierungsmodus: Verarbeitung aller Zeilen mit 'x' in Spalte A.")
elif MODE == "3":
print("Alignment-Demo-Modus: Schreibe Spaltenüberschriften in Zeile 11200.")
alignment_demo(self.sheet_handler.sheet)
return
else:
start_index = self.sheet_handler.get_start_index()
print(f"Starte bei Zeile {start_index+1}")
@@ -347,8 +372,13 @@ class DataProcessor:
# ==================== MAIN ====================
if __name__ == "__main__":
mode_input = input("Wählen Sie den Modus: 1 für normalen Modus, 2 für Re-Evaluierungsmodus: ").strip()
MODE = "2" if mode_input == "2" else "1"
mode_input = input("Wählen Sie den Modus: 1 für normalen Modus, 2 für Re-Evaluierungsmodus, 3 für Alignment-Demo: ").strip()
if mode_input == "2":
MODE = "2"
elif mode_input == "3":
MODE = "3"
else:
MODE = "1"
if MODE == "1":
try:
num_rows = int(input("Wieviele Zeilen sollen überprüft werden? "))