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:
@@ -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? "))
|
||||
|
||||
Reference in New Issue
Block a user