v1.2.8: Verbesserte numerische Parsing-Logik und robustere Umsatz-Vergleichslogik

Robuste numerische Extraktion:
Die Funktion extract_numeric_value wurde erweitert, um führende und umgebende Texte zu entfernen. Kommas werden je nach Kontext als Dezimaltrennzeichen oder Tausendertrennzeichen behandelt.

Verbesserte Vergleichslogik:
Vor dem Vergleich werden die bereinigten Werte geloggt. Falls einer der Werte nicht in einen Float konvertiert werden kann, wird "Daten unvollständig" zurückgegeben.

Erweiterte Debug-Ausgabe:
Log-Ausgaben zeigen jetzt explizit die bereinigten Vergleichswerte für CRM- und Wikipedia-Umsätze.

Pause zur Datensynchronisation:
Eine einsekündige Pause wurde nach dem Schreiben in Google Sheets eingeführt, um
This commit is contained in:
2025-04-02 05:58:22 +00:00
parent ff7d5dd278
commit c5bc203fab

View File

@@ -4,16 +4,17 @@ import re
import gspread import gspread
import wikipedia import wikipedia
import requests import requests
import openai
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from oauth2client.service_account import ServiceAccountCredentials from oauth2client.service_account import ServiceAccountCredentials
from datetime import datetime from datetime import datetime
from difflib import SequenceMatcher from difflib import SequenceMatcher
import unicodedata
import csv import csv
import openai # falls für ChatGPT-API benötigt
# ==================== KONFIGURATION ==================== # ==================== KONFIGURATION ====================
class Config: class Config:
VERSION = "1.2.8" VERSION = "v1.2.8" # v1.2.8: Verbesserte numerische Extraktion für Umsatz und Mitarbeiter; robustere Vergleichslogik
LANG = "de" LANG = "de"
CREDENTIALS_FILE = "service_account.json" CREDENTIALS_FILE = "service_account.json"
SHEET_URL = "https://docs.google.com/spreadsheets/d/1u_gHr9JUfmV1-iviRzbSe3575QEp7KLhK5jFV_gJcgo" SHEET_URL = "https://docs.google.com/spreadsheets/d/1u_gHr9JUfmV1-iviRzbSe3575QEp7KLhK5jFV_gJcgo"
@@ -44,7 +45,7 @@ def debug_print(message):
def clean_text(text): def clean_text(text):
if not text: if not text:
return "k.A." return "k.A."
text = str(text) text = unicodedata.normalize("NFKC", str(text))
text = re.sub(r'\[\d+\]', '', text) text = re.sub(r'\[\d+\]', '', text)
text = re.sub(r'\s+', ' ', text).strip() text = re.sub(r'\s+', ' ', text).strip()
return text if text else "k.A." return text if text else "k.A."
@@ -70,63 +71,88 @@ def normalize_company_name(name):
normalized = re.sub(r'\s+', ' ', normalized).strip() normalized = re.sub(r'\s+', ' ', normalized).strip()
return normalized.lower() return normalized.lower()
def parse_currency_value(text): def extract_numeric_value(raw_value, is_umsatz=False):
""" raw_value = raw_value.strip()
Parst einen Umsatz-Text. Entfernt Tausenderpunkte, ersetzt Komma als Dezimaltrenner. if not raw_value or raw_value.lower() in ["k.a.", "n.a."]:
Ermittelt den Skalierungsfaktor: 'mrd' -> 1000, 'mio' -> 1, sonst Annahme: Euro -> /1e6. return "k.A."
Liefert den Wert in Mio. Euro als float. # Entferne Texte wie "ca.", "circa", etc.
""" raw_value = re.sub(r'\b(ca\.?|circa|etwa|über|rund)\b', '', raw_value, flags=re.IGNORECASE)
raw = text.lower() raw_value = raw_value.replace("\xa0", " ").strip()
# Entferne unnötige Zeichen und Einheiten # Entferne Textteile in Klammern
raw = raw.replace("", "").replace("eur", "") raw_value = re.sub(r'\(.*?\)', '', raw_value).strip()
# Prüfe auf Skalierung # Extrahiere den numerischen Teil
scale = None match = re.search(r'([\d.,]+)', raw_value)
if "mrd" in raw or "milliarden" in raw:
scale = 1000
elif "mio" in raw or "millionen" in raw:
scale = 1
# Extrahiere den numerischen Teil (erlaubt Punkte und Kommas)
match = re.search(r'([\d.,]+)', raw)
if not match: if not match:
return None debug_print(f"Keine numerischen Zeichen gefunden im Rohtext: '{raw_value}'")
num_str = match.group(1).strip() return "k.A."
# Wenn ein Komma vorkommt, nehme an, dass es der Dezimaltrenner ist und entferne Punkte num_str = match.group(1)
if ',' in num_str: # Wenn ein einzelnes Komma als Dezimaltrenner und kein Punkt vorhanden ist
num_str = num_str.replace('.', '') if ',' in num_str and '.' not in num_str and len(num_str.split(',')[1]) <= 2:
num_str = num_str.replace(',', '.') num_str = num_str.replace(',', '.')
else: else:
# sonst entferne alle Punkte (als Tausendertrenner) num_str = num_str.replace(',', '')
num_str = num_str.replace('.', '')
try: try:
value = float(num_str) num = float(num_str)
except Exception as e: except Exception as e:
debug_print(f"Fehler beim Parsen von Umsatz: {num_str} - {e}") debug_print(f"Fehler bei der Umwandlung von '{num_str}' (Rohtext: '{raw_value}'): {e}")
return None return raw_value
if scale is None: if is_umsatz:
# Wenn keine Skalierung angegeben, gehe davon aus, dass der Wert in Euro vorliegt raw_lower = raw_value.lower()
value /= 1e6 if "mrd" in raw_lower or "milliarden" in raw_lower:
num *= 1000
elif "mio" in raw_lower or "millionen" in raw_lower:
pass
else:
num /= 1e6
return str(int(round(num)))
else: else:
value *= scale return str(int(round(num)))
return value
def parse_employee_value(text): def compare_umsatz_values(crm, wiki):
""" debug_print(f"Vergleich CRM Umsatz: '{crm}' mit Wikipedia Umsatz: '{wiki}'")
Parst Mitarbeiterzahlen. Entfernt "ca.", Leerzeichen und Tausenderpunkte.
Liefert den Wert als int.
"""
raw = text.lower()
raw = raw.replace("ca.", "").strip()
# Entferne Klammerinhalt (z. B. (2021/22))
raw = re.sub(r'\(.*?\)', '', raw)
# Entferne Leerzeichen
raw = raw.replace(" ", "")
# Entferne Tausendertrenner (Punkt) und ersetze Komma durch Punkt
raw = raw.replace(".", "").replace(",", ".")
try: try:
return int(float(raw)) crm_val = float(crm)
wiki_val = float(wiki)
except Exception as e: except Exception as e:
debug_print(f"Fehler beim Parsen von Mitarbeiterzahl: {raw} - {e}") debug_print(f"Fehler beim Umwandeln der Werte: CRM='{crm}', Wiki='{wiki}': {e}")
return None return "Daten unvollständig"
if crm_val == 0:
return "CRM Umsatz 0"
diff = abs(crm_val - wiki_val) / crm_val
if diff < 0.1:
return "OK"
else:
diff_mio = abs(crm_val - wiki_val)
return f"Abweichung: {int(round(diff_mio))} Mio €"
def evaluate_umsatz_chatgpt(company_name, wiki_umsatz):
try:
with open("api_key.txt", "r") as f:
api_key = f.read().strip()
except Exception as e:
debug_print(f"Fehler beim Lesen des API-Tokens: {e}")
return "k.A."
openai.api_key = api_key
prompt = (f"Bitte schätze den Umsatz in Mio. Euro für das Unternehmen '{company_name}'. "
f"Die Wikipedia-Daten zeigen: '{wiki_umsatz}'. "
"Antworte nur mit der Zahl.")
try:
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": prompt}],
temperature=0.0
)
result = response.choices[0].message.content.strip()
debug_print(f"ChatGPT Antwort: '{result}'")
try:
value = float(result.replace(',', '.'))
return str(int(round(value)))
except Exception as conv_e:
debug_print(f"Fehler bei der Verarbeitung der ChatGPT-Antwort '{result}': {conv_e}")
return result
except Exception as e:
debug_print(f"Fehler beim Aufruf der ChatGPT API: {e}")
return "k.A."
# ==================== GOOGLE SHEET HANDLER ==================== # ==================== GOOGLE SHEET HANDLER ====================
class GoogleSheetHandler: class GoogleSheetHandler:
@@ -143,6 +169,26 @@ class GoogleSheetHandler:
filled_n = [row[13] if len(row) > 13 else '' for row in self.sheet_values[1:]] filled_n = [row[13] if len(row) > 13 else '' for row in self.sheet_values[1:]]
return next((i + 1 for i, v in enumerate(filled_n, start=1) if not str(v).strip()), len(filled_n) + 1) return next((i + 1 for i, v in enumerate(filled_n, start=1) if not str(v).strip()), len(filled_n) + 1)
# ==================== ALIGNMENT DEMO (Modus 3) ====================
def alignment_demo(sheet):
new_headers = [
"Spalte A (ReEval Flag)", "Spalte B (Firmenname)", "Spalte C (Website)", "Spalte D (Ort)", "Spalte E (Beschreibung)",
"Spalte F (Aktuelle Branche)", "Spalte G (Beschreibung Branche extern)", "Spalte H (Anzahl Techniker CRM)",
"Spalte I (Umsatz CRM)", "Spalte J (Anzahl Mitarbeiter CRM)", "Spalte K (Vorschlag Wiki URL)",
"Spalte L (Wikipedia URL)", "Spalte M (Wikipedia Absatz)", "Spalte N (Wikipedia Branche)",
"Spalte O (Wikipedia Umsatz)", "Spalte P (Wikipedia Mitarbeiter)", "Spalte Q (Wikipedia Kategorien)",
"Spalte R (Konsistenzprüfung)", "Spalte S (Begründung bei Inkonsistenz)", "Spalte T (Vorschlag Wiki Artikel ChatGPT)",
"Spalte U (Begründung bei Abweichung)", "Spalte V (Vorschlag neue Branche)", "Spalte W (Konsistenzprüfung Branche)",
"Spalte X (Begründung Abweichung Branche)", "Spalte Y (FSM Relevanz Ja / Nein)", "Spalte Z (Begründung für FSM Relevanz)",
"Spalte AA (Schätzung Anzahl Mitarbeiter)", "Spalte AB (Konsistenzprüfung Mitarbeiterzahl)",
"Spalte AC (Begründung für Abweichung Mitarbeiterzahl)", "Spalte AD (Einschätzung Anzahl Servicetechniker)",
"Spalte AE (Begründung bei Abweichung Anzahl Servicetechniker)", "Spalte AF (Schätzung Umsatz ChatGPT)",
"Spalte AG (Begründung für Abweichung Umsatz)", "Spalte AH (Timestamp letzte Prüfung)", "Spalte AI (Version)"
]
header_range = "A11200:AI11200"
sheet.update(values=[new_headers], range_name=header_range)
print("Alignment-Demo abgeschlossen: Neue Spaltenüberschriften in Zeile 11200 geschrieben.")
# ==================== WIKIPEDIA SCRAPER ==================== # ==================== WIKIPEDIA SCRAPER ====================
class WikipediaScraper: class WikipediaScraper:
def __init__(self): def __init__(self):
@@ -153,8 +199,7 @@ class WikipediaScraper:
website = website.lower().strip() website = website.lower().strip()
website = re.sub(r'^https?:\/\/', '', website) website = re.sub(r'^https?:\/\/', '', website)
website = re.sub(r'^www\.', '', website) website = re.sub(r'^www\.', '', website)
website = website.split('/')[0] return website.split('/')[0]
return website
def _generate_search_terms(self, company_name, website): def _generate_search_terms(self, company_name, website):
terms = [] terms = []
full_domain = self._get_full_domain(website) full_domain = self._get_full_domain(website)
@@ -213,6 +258,14 @@ class WikipediaScraper:
except Exception as e: except Exception as e:
debug_print(f"Fehler beim Extrahieren des ersten Absatzes: {e}") debug_print(f"Fehler beim Extrahieren des ersten Absatzes: {e}")
return "k.A." return "k.A."
def extract_categories(self, soup):
cat_div = soup.find('div', id="mw-normal-catlinks")
if cat_div:
ul = cat_div.find('ul')
if ul:
cats = [clean_text(li.get_text()) for li in ul.find_all('li')]
return ", ".join(cats)
return "k.A."
def _extract_infobox_value(self, soup, target): def _extract_infobox_value(self, soup, target):
infobox = soup.find('table', class_=lambda c: c and any(kw in c.lower() for kw in ['infobox', 'vcard', 'unternehmen'])) infobox = soup.find('table', class_=lambda c: c and any(kw in c.lower() for kw in ['infobox', 'vcard', 'unternehmen']))
if not infobox: if not infobox:
@@ -220,7 +273,7 @@ class WikipediaScraper:
keywords_map = { keywords_map = {
'branche': ['branche', 'industrie', 'tätigkeit', 'geschäftsfeld', 'sektor', 'produkte', 'leistungen', 'aktivitäten', 'wirtschaftszweig'], 'branche': ['branche', 'industrie', 'tätigkeit', 'geschäftsfeld', 'sektor', 'produkte', 'leistungen', 'aktivitäten', 'wirtschaftszweig'],
'umsatz': ['umsatz', 'jahresumsatz', 'konzernumsatz', 'gesamtumsatz', 'erlöse', 'umsatzerlöse', 'einnahmen', 'ergebnis', 'jahresergebnis'], 'umsatz': ['umsatz', 'jahresumsatz', 'konzernumsatz', 'gesamtumsatz', 'erlöse', 'umsatzerlöse', 'einnahmen', 'ergebnis', 'jahresergebnis'],
'mitarbeiter': ['mitarbeiter', 'beschäftigte', 'personal', 'mitarbeiterzahl'] 'mitarbeiter': ['mitarbeiter', 'beschäftigte', 'personal', 'mitarbeiterzahl', 'angestellte', 'belegschaft', 'personalstärke']
} }
keywords = keywords_map.get(target, []) keywords = keywords_map.get(target, [])
for row in infobox.find_all('tr'): for row in infobox.find_all('tr'):
@@ -235,11 +288,9 @@ class WikipediaScraper:
clean_val = re.sub(r'\[.*?\]|\(.*?\)', '', raw_value) clean_val = re.sub(r'\[.*?\]|\(.*?\)', '', raw_value)
return ' '.join(clean_val.split()).strip() return ' '.join(clean_val.split()).strip()
if target == 'umsatz': if target == 'umsatz':
parsed = parse_currency_value(raw_value) return extract_numeric_value(raw_value, is_umsatz=True)
return str(parsed) if parsed is not None else raw_value.strip()
if target == 'mitarbeiter': if target == 'mitarbeiter':
parsed = parse_employee_value(raw_value) return extract_numeric_value(raw_value, is_umsatz=False)
return str(parsed) if parsed is not None else raw_value.strip()
return "k.A." return "k.A."
def extract_full_infobox(self, soup): def extract_full_infobox(self, soup):
infobox = soup.find('table', class_=lambda c: c and any(kw in c.lower() for kw in ['infobox', 'vcard', 'unternehmen'])) infobox = soup.find('table', class_=lambda c: c and any(kw in c.lower() for kw in ['infobox', 'vcard', 'unternehmen']))
@@ -251,7 +302,7 @@ class WikipediaScraper:
tokens = [token.strip() for token in infobox_text.split("|") if token.strip()] tokens = [token.strip() for token in infobox_text.split("|") if token.strip()]
for i, token in enumerate(tokens): for i, token in enumerate(tokens):
for field in field_names: for field in field_names:
if token.lower() == field.lower(): if field.lower() in token.lower():
j = i + 1 j = i + 1
while j < len(tokens) and not tokens[j]: while j < len(tokens) and not tokens[j]:
j += 1 j += 1
@@ -259,26 +310,33 @@ class WikipediaScraper:
return result return result
def extract_company_data(self, page_url): def extract_company_data(self, page_url):
if not page_url: if not page_url:
return {'url': 'k.A.', 'first_paragraph': 'k.A.', 'branche': 'k.A.', 'umsatz': 'k.A.', 'mitarbeiter': 'k.A.'} return {'url': 'k.A.', 'first_paragraph': 'k.A.', 'branche': 'k.A.',
'umsatz': 'k.A.', 'mitarbeiter': 'k.A.', 'categories': 'k.A.', 'full_infobox': 'k.A.'}
try: try:
response = requests.get(page_url) response = requests.get(page_url)
soup = BeautifulSoup(response.text, Config.HTML_PARSER) soup = BeautifulSoup(response.text, Config.HTML_PARSER)
full_infobox = self.extract_full_infobox(soup) full_infobox = self.extract_full_infobox(soup)
extracted_fields = self.extract_fields_from_infobox_text(full_infobox, ['Branche', 'Umsatz', 'Mitarbeiterzahl']) extracted_fields = self.extract_fields_from_infobox_text(full_infobox, ['Branche', 'Umsatz', 'Mitarbeiter'])
branche_val = extracted_fields.get('Branche', self._extract_infobox_value(soup, 'branche')) raw_branche = extracted_fields.get('Branche', self._extract_infobox_value(soup, 'branche'))
umsatz_val = extracted_fields.get('Umsatz', self._extract_infobox_value(soup, 'umsatz')) raw_umsatz = extracted_fields.get('Umsatz', self._extract_infobox_value(soup, 'umsatz'))
mitarbeiter_val = extracted_fields.get('Mitarbeiterzahl', self._extract_infobox_value(soup, 'mitarbeiter')) raw_mitarbeiter = extracted_fields.get('Mitarbeiter', self._extract_infobox_value(soup, 'mitarbeiter'))
umsatz_val = extract_numeric_value(raw_umsatz, is_umsatz=True)
mitarbeiter_val = extract_numeric_value(raw_mitarbeiter, is_umsatz=False)
categories_val = self.extract_categories(soup)
first_paragraph = self.extract_first_paragraph(page_url) first_paragraph = self.extract_first_paragraph(page_url)
return { return {
'url': page_url, 'url': page_url,
'first_paragraph': first_paragraph, 'first_paragraph': first_paragraph,
'branche': branche_val, 'branche': raw_branche,
'umsatz': umsatz_val, 'umsatz': umsatz_val,
'mitarbeiter': mitarbeiter_val 'mitarbeiter': mitarbeiter_val,
'categories': categories_val,
'full_infobox': full_infobox
} }
except Exception as e: except Exception as e:
debug_print(f"Extraktionsfehler: {str(e)}") debug_print(f"Extraktionsfehler: {str(e)}")
return {'url': 'k.A.', 'first_paragraph': 'k.A.', 'branche': 'k.A.', 'umsatz': 'k.A.', 'mitarbeiter': 'k.A.'} return {'url': 'k.A.', 'first_paragraph': 'k.A.', 'branche': 'k.A.',
'umsatz': 'k.A.', 'mitarbeiter': 'k.A.', 'categories': 'k.A.', 'full_infobox': 'k.A.'}
@retry_on_failure @retry_on_failure
def search_company_article(self, company_name, website): def search_company_article(self, company_name, website):
search_terms = self._generate_search_terms(company_name, website) search_terms = self._generate_search_terms(company_name, website)
@@ -304,55 +362,95 @@ class DataProcessor:
def __init__(self): def __init__(self):
self.sheet_handler = GoogleSheetHandler() self.sheet_handler = GoogleSheetHandler()
self.wiki_scraper = WikipediaScraper() self.wiki_scraper = WikipediaScraper()
def process_rows(self, num_rows): def process_rows(self, num_rows=None):
start_index = self.sheet_handler.get_start_index() if MODE == "2":
print(f"Starte bei Zeile {start_index+1}") print("Re-Evaluierungsmodus: Verarbeitung aller Zeilen mit 'x' in Spalte A.")
for i in range(start_index, min(start_index + num_rows, len(self.sheet_handler.sheet_values))): elif MODE == "3":
row = self.sheet_handler.sheet_values[i] print("Alignment-Demo-Modus: Schreibe neue Spaltenüberschriften in Zeile 11200.")
self._process_single_row(i+1, row) alignment_demo(self.sheet_handler.sheet)
return
else:
start_index = self.sheet_handler.get_start_index()
print(f"Starte bei Zeile {start_index+1}")
for i, row in enumerate(self.sheet_handler.sheet_values[1:], start=2):
if MODE == "2":
if row[0].strip().lower() == "x":
self._process_single_row(i, row)
else:
if i >= self.sheet_handler.get_start_index():
self._process_single_row(i, row)
def _process_single_row(self, row_num, row_data): def _process_single_row(self, row_num, row_data):
company_name = row_data[1] if len(row_data) > 1 else "" company_name = row_data[1] if len(row_data) > 1 else ""
website = row_data[2] if len(row_data) > 2 else "" website = row_data[2] if len(row_data) > 2 else ""
wiki_update_range = f"K{row_num}:Q{row_num}"
chatgpt_range = f"AF{row_num}"
abgleich_range = f"AG{row_num}"
dt_range = f"AH{row_num}"
ver_range = f"AI{row_num}"
print(f"\n[{datetime.now().strftime('%H:%M:%S')}] Verarbeite Zeile {row_num}: {company_name}") print(f"\n[{datetime.now().strftime('%H:%M:%S')}] Verarbeite Zeile {row_num}: {company_name}")
article = self.wiki_scraper.search_company_article(company_name, website) article = self.wiki_scraper.search_company_article(company_name, website)
if article: if article:
company_data = self.wiki_scraper.extract_company_data(article.url) company_data = self.wiki_scraper.extract_company_data(article.url)
else: else:
company_data = {'url': 'k.A.', 'first_paragraph': 'k.A.', 'branche': 'k.A.', 'umsatz': 'k.A.', 'mitarbeiter': 'k.A.'} company_data = {
# Beispiel: Schreibe die Wikipedia-Daten in Spalten J bis N (anpassen an das neue Schema) 'url': 'k.A.',
self.sheet_handler.sheet.update(values=[[ 'first_paragraph': 'k.A.',
'branche': 'k.A.',
'umsatz': 'k.A.',
'mitarbeiter': 'k.A.',
'categories': 'k.A.',
'full_infobox': 'k.A.'
}
wiki_values = [
"k.A.", # Vorschlag Wiki URL
company_data.get('url', 'k.A.'), company_data.get('url', 'k.A.'),
company_data.get('first_paragraph', 'k.A.'), company_data.get('first_paragraph', 'k.A.'),
company_data.get('branche', 'k.A.'), company_data.get('branche', 'k.A.'),
company_data.get('umsatz', 'k.A.'), company_data.get('umsatz', 'k.A.'),
company_data.get('mitarbeiter', 'k.A.') company_data.get('mitarbeiter', 'k.A.'),
]], range_name=f"J{row_num}:N{row_num}") company_data.get('categories', 'k.A.')
# Füge 1 Sekunde Pause ein, damit die Sheets-Daten sicher gespeichert werden ]
time.sleep(1) self.sheet_handler.sheet.update(values=[wiki_values], range_name=wiki_update_range)
# Hier folgt der Umsatzvergleich (CRM vs. Wikipedia) Debug-Ausgabe time.sleep(1) # Sicherstellen, dass Werte synchronisiert werden
crm_umsatz = row_data[?] # Hier anpassen: Spalte mit CRM-Umsatz
wiki_umsatz = company_data.get('umsatz', 'k.A.') wiki_umsatz = company_data.get('umsatz', 'k.A.')
debug_print(f"Vergleich CRM Umsatz: '{crm_umsatz}' mit Wikipedia Umsatz: '{wiki_umsatz}'") if wiki_umsatz != "k.A.":
try: chatgpt_umsatz = evaluate_umsatz_chatgpt(company_name, wiki_umsatz)
crm_value = float(crm_umsatz.replace(',', '.')) else:
wiki_value = float(wiki_umsatz) chatgpt_umsatz = "k.A."
debug_print(f"Vergleich CRM Umsatz: '{crm_value}' mit Wikipedia Umsatz: '{wiki_value}'") self.sheet_handler.sheet.update(values=[[chatgpt_umsatz]], range_name=chatgpt_range)
except Exception as e: crm_umsatz = row_data[8] if len(row_data) > 8 else "k.A."
debug_print(f"Fehler beim Umwandeln der Werte: CRM='{crm_umsatz}', Wiki='{wiki_umsatz}': {e}") debug_print(f"Bereinigte Vergleichswerte vor Umwandlung: CRM Umsatz: '{crm_umsatz}', Wiki Umsatz: '{wiki_umsatz}'")
# Aktualisiere weitere Spalten (Timestamp, Version etc.) abgleich_result = compare_umsatz_values(crm_umsatz, wiki_umsatz)
self.sheet_handler.sheet.update(values=[[abgleich_result]], range_name=abgleich_range)
current_dt = datetime.now().strftime("%Y-%m-%d %H:%M:%S") current_dt = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
self.sheet_handler.sheet.update(values=[[current_dt]], range_name=f"AH{row_num}") self.sheet_handler.sheet.update(values=[[current_dt]], range_name=dt_range)
self.sheet_handler.sheet.update(values=[[Config.VERSION]], range_name=f"AI{row_num}") self.sheet_handler.sheet.update(values=[[Config.VERSION]], range_name=ver_range)
print(f"✅ Aktualisiert: URL: {company_data.get('url', 'k.A.')}, Absatz: {company_data.get('first_paragraph', 'k.A.')[:30]}..., Branche: {company_data.get('branche', 'k.A.')}, Umsatz: {company_data.get('umsatz', 'k.A.')}, Mitarbeiter: {company_data.get('mitarbeiter', 'k.A.')}") print(f"✅ Aktualisiert: URL: {company_data.get('url', 'k.A.')}, Absatz: {company_data.get('first_paragraph', 'k.A.')[:30]}..., "
f"Branche: {company_data.get('branche', 'k.A.')}, Wikipedia Umsatz: {company_data.get('umsatz', 'k.A.')}, "
f"Mitarbeiter: {company_data.get('mitarbeiter', 'k.A.')}, Kategorien: {company_data.get('categories', 'k.A.')}, "
f"ChatGPT Umsatz: {chatgpt_umsatz}, Umsatz-Abgleich: {abgleich_result}")
if MODE == "2":
print("----- Vollständiger Infobox-Inhalt -----")
print(company_data.get("full_infobox", "k.A."))
print("----------------------------------------")
time.sleep(Config.RETRY_DELAY) time.sleep(Config.RETRY_DELAY)
# ==================== MAIN ====================
if __name__ == "__main__": if __name__ == "__main__":
try: mode_input = input("Wählen Sie den Modus: 1 für normalen Modus, 2 für Re-Evaluierungsmodus, 3 für Alignment-Demo: ").strip()
num_rows = int(input("Wieviele Zeilen sollen überprüft werden? ")) if mode_input == "2":
except Exception as e: MODE = "2"
print("Ungültige Eingabe. Bitte eine Zahl eingeben.") elif mode_input == "3":
exit(1) MODE = "3"
else:
MODE = "1"
if MODE == "1":
try:
num_rows = int(input("Wieviele Zeilen sollen überprüft werden? "))
except Exception as e:
print("Ungültige Eingabe. Bitte eine Zahl eingeben.")
exit(1)
else:
num_rows = None
processor = DataProcessor() processor = DataProcessor()
processor.process_rows(num_rows) processor.process_rows(num_rows)
print("\n✅ Wikipedia-Auswertung abgeschlossen") print(f"\n✅ Wikipedia-Auswertung abgeschlossen ({Config.VERSION})")