diff --git a/brancheneinstufung.py b/brancheneinstufung.py index f89083a8..78140777 100644 --- a/brancheneinstufung.py +++ b/brancheneinstufung.py @@ -4479,201 +4479,13 @@ class DataProcessor: # ====================================================================== # === 2. Wikipedia Handling (Search, Extraction, Status Reset) ========== # ====================================================================== - # Dieser Schritt wird ausgefuehrt, wenn 'wiki' in steps_to_run enthalten ist UND - # (_needs_wiki_processing True ist ODER force_reeval True ist). - # _needs_wiki_processing prueft V (alt AN) und Y="X (URL Copied)" (alt S). - - run_wiki_step = 'wiki' in steps_to_run - # _needs_wiki_processing prüft den Wikipedia Timestamp (Z) und AC="X (URL COPIED)" - wiki_processing_needed_based_on_status = self._needs_wiki_processing(row_data, force_reeval) - - if run_wiki_step and wiki_processing_needed_based_on_status: - any_processing_done = True - # ... (Grund Message für Log erstellen) ... - self.logger.info(f"Zeile {row_num_in_sheet}: Fuehre WIKI Suche/Extraktion aus (Grund: {grund_message})...") - - system_suggested_parent_name = self._get_cell_value_safe(row_data, "System Vorschlag Parent Account").strip() # Spalte O - current_wiki_url_in_sheet_for_daughter = self._get_cell_value_safe(row_data, "Wiki URL").strip() # Spalte R - - url_to_extract_from = None # Die URL, von der WIRKLICH extrahiert wird - # Name, der für die Validierung des Artikels durch _validate_article verwendet wird - name_for_wiki_article_validation = company_name - source_of_wiki_data_origin = "Tochter" # Woher stammen die Wiki-Daten letztendlich? - additional_info_for_af = "" # Für Spalte AF "Begründung bei Abweichung" - - # --- NEUE LOGIK: Parent-Account (O) prüfen --- - if system_suggested_parent_name and system_suggested_parent_name.lower() != "k.a.": - if not current_wiki_url_in_sheet_for_daughter or current_wiki_url_in_sheet_for_daughter.lower() == "k.a.": - # Szenario 1: Parent O gefüllt, Wiki R der Tochter leer/k.A. - self.logger.info(f" Zeile {row_num_in_sheet}: Parent '{system_suggested_parent_name}' (O) vorhanden, Wiki-URL der Tochter (R) leer. Versuche Wiki-Suche für Parent.") - try: - parent_page_object = self.wiki_scraper.search_company_article( - company_name=system_suggested_parent_name, - website=None # Keine spezifische Parent-Website bekannt, suche nur mit Namen - ) - if parent_page_object: - url_to_extract_from = parent_page_object.url - name_for_wiki_article_validation = system_suggested_parent_name # Artikel wird gegen Parent-Namen validiert - source_of_wiki_data_origin = "Parent (O)" - additional_info_for_af = f"INFO: Wiki-Daten von Parent '{system_suggested_parent_name}' übernommen. " - self.logger.info(f" -> Wiki-Artikel für Parent '{system_suggested_parent_name}' gefunden: {url_to_extract_from}") - else: - self.logger.warning(f" -> Kein Wiki-Artikel für Parent '{system_suggested_parent_name}' gefunden. Standard-Tochter-Suche folgt.") - # url_to_extract_from bleibt None, die Standard-Logik unten greift. - except Exception as e_parent_wiki_search: - self.logger.error(f" -> Fehler bei Suche nach Wiki für Parent '{system_suggested_parent_name}': {e_parent_wiki_search}") - # Standard-Tochter-Suche folgt. - else: - # Szenario 2: Parent O gefüllt, UND Wiki R der Tochter auch gefüllt. - self.logger.info(f" Zeile {row_num_in_sheet}: Parent '{system_suggested_parent_name}' (O) vorhanden, aber auch Wiki-URL der Tochter (R) '{current_wiki_url_in_sheet_for_daughter}'. Tochter-Wiki hat Vorrang für Extraktion, falls notwendig.") - # Die Standard-Logik unten wird current_wiki_url_in_sheet_for_daughter verwenden. - # url_to_extract_from wird in der Standard-Logik ggf. mit current_wiki_url_in_sheet_for_daughter initialisiert. - pass # Keine Aktion hier, Standardlogik für Tochter greift. - - # --- Standard-Logik für Wiki-URL der Tochter, wenn nicht schon eine Parent-URL gefunden wurde --- - if url_to_extract_from is None: # Nur wenn noch keine URL vom Parent kam - search_for_daughter_wiki_needed = False - - status_ac_indicates_reparse = self._get_cell_value_safe(row_data, "Chat Wiki Konsistenzpruefung").strip().upper() == "X (URL COPIED)" # Spalte AC - timestamp_z_is_empty = not self._get_cell_value_safe(row_data, "Wikipedia Timestamp").strip() # Spalte Z - - # Hat die Tochter bereits eine valide aussehende URL in Spalte R? - r_url_is_valid_looking = current_wiki_url_in_sheet_for_daughter and \ - "wikipedia.org/wiki/" in current_wiki_url_in_sheet_for_daughter.lower() and \ - current_wiki_url_in_sheet_for_daughter.lower() not in ["k.a.", "kein artikel gefunden", "fehler bei suche"] - - if status_ac_indicates_reparse: - self.logger.info(f" Zeile {row_num_in_sheet}: Status AC ('Chat Wiki Konsistenzpruefung') ist 'X (URL COPIED)'. Starte neue Suche für Tochter '{company_name}'.") - search_for_daughter_wiki_needed = True - elif force_reeval: - if r_url_is_valid_looking: - self.logger.info(f" Zeile {row_num_in_sheet}: Re-Eval Modus. Nutze vorhandene Tochter-URL (R): {current_wiki_url_in_sheet_for_daughter}") - url_to_extract_from = current_wiki_url_in_sheet_for_daughter - else: - self.logger.info(f" Zeile {row_num_in_sheet}: Re-Eval Modus. Tochter-URL (R) leer/ungültig. Starte neue Suche für Tochter '{company_name}'.") - search_for_daughter_wiki_needed = True - elif timestamp_z_is_empty: # Wikipedia Timestamp (Z) fehlt - if r_url_is_valid_looking: - self.logger.info(f" Zeile {row_num_in_sheet}: Wikipedia Timestamp (Z) fehlt. Validiere vorhandene Tochter-URL (R): {current_wiki_url_in_sheet_for_daughter}") - # Hier könnte eine explizite Validierung der Tochter-URL stehen (mit _validate_article), - # aber search_company_article macht das implizit, wenn eine URL direkt übergeben wird. - # Fürs Erste nehmen wir an, die URL wird verwendet und extract_company_data validiert. - url_to_extract_from = current_wiki_url_in_sheet_for_daughter - else: - self.logger.info(f" Zeile {row_num_in_sheet}: Wikipedia Timestamp (Z) fehlt und Tochter-URL (R) leer/ungültig. Starte neue Suche für Tochter '{company_name}'.") - search_for_daughter_wiki_needed = True - elif not r_url_is_valid_looking: # Fallback, wenn Z nicht leer, aber R schlecht ist (z.B. "k.A.") - self.logger.info(f" Zeile {row_num_in_sheet}: Tochter-URL (R) ist ungültig ('{current_wiki_url_in_sheet_for_daughter}'). Starte neue Suche für Tochter '{company_name}'.") - search_for_daughter_wiki_needed = True - else: # R ist vorhanden und Timestamp Z ist gesetzt, kein Re-Eval -> keine Wiki-Aktion für Tochter nötig - self.logger.debug(f" Zeile {row_num_in_sheet}: Wiki-Verarbeitung für Tochter nicht nötig (Timestamp Z gesetzt, R vorhanden, kein Re-Eval/Reparse).") - - - if search_for_daughter_wiki_needed: - self.logger.info(f" -> Suche nach Wikipedia-Artikel für Tochter '{company_name}'...") - daughter_page_object = self.wiki_scraper.search_company_article( - company_name=company_name, # Name der Tochter - website=website_url # Website der Tochter - ) - if daughter_page_object: - url_to_extract_from = daughter_page_object.url - name_for_wiki_article_validation = company_name # Artikel wird gegen Tochter-Namen validiert - source_of_wiki_data_origin = "Tochter (Suche)" - self.logger.info(f" -> Suche für Tochter '{company_name}' erfolgreich, gefundene URL: {url_to_extract_from}") - else: - self.logger.warning(f" -> Kein Wiki-Artikel für Tochter '{company_name}' gefunden.") - url_to_extract_from = "Kein Artikel gefunden" - - # Wenn nach all dem url_to_extract_from immer noch None ist, aber eine URL in R stand, diese nehmen. - if url_to_extract_from is None and r_url_is_valid_looking: - url_to_extract_from = current_wiki_url_in_sheet_for_daughter - name_for_wiki_article_validation = company_name - source_of_wiki_data_origin = "Tochter (aus R)" - - - # --- DATENEXTRAKTION (von der ermittelten URL) --- - # Diese Logik wird nur ausgeführt, wenn eine gültige URL zum Extrahieren gefunden wurde - if url_to_extract_from and isinstance(url_to_extract_from, str) and \ - url_to_extract_from.lower() not in ["k.a.", "kein artikel gefunden"] and \ - not url_to_extract_from.startswith("FEHLER"): - - self.logger.debug(f" -> Extrahiere Wiki-Daten von URL ({source_of_wiki_data_origin}): {url_to_extract_from[:100]}...") - try: - # WICHTIG: Die Validierung innerhalb von extract_company_data muss wissen, ob es sich um einen Parent-Artikel handelt, - # um den korrekten Namen (Parent-Name vs. Tochter-Name) für die Ähnlichkeitsprüfung zu verwenden. - # `extract_company_data` ruft `_validate_article` auf, das `company_name` als Argument bekommt. - # Wir übergeben hier `name_for_wiki_article_validation`. - extracted_data = self.wiki_scraper.extract_company_data( - page_url=url_to_extract_from, - # company_name_for_validation=name_for_wiki_article_validation # Diese Anpassung wäre in extract_company_data nötig - ) - - if extracted_data and isinstance(extracted_data, dict) and extracted_data.get('url') != 'k.A.': - final_wiki_data = extracted_data - wiki_data_updated_in_this_run = True - self.logger.info(f" -> Datenextraktion von {url_to_extract_from[:100]}... ({source_of_wiki_data_origin}) erfolgreich.") - - # Wenn Daten vom Parent stammen, setze den AC-Vermerk - if source_of_wiki_data_origin == "Parent (O)": - ac_wert_fuer_parent_wiki = "INFO_PARENT_WIKI" - self.logger.info(f" -> Setze AC ('Chat Wiki Konsistenzpruefung') auf '{ac_wert_fuer_parent_wiki}', da Wiki-Daten von Parent.") - updates.append({ - 'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Wiki Konsistenzpruefung"] + 1)}{row_num_in_sheet}', - 'values': [[ac_wert_fuer_parent_wiki]] - }) - # Leere auch die abhängigen Chat-Wiki-Spalten AD, AE - updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Begründung Wiki Inkonsistenz"] + 1)}{row_num_in_sheet}', 'values': [['']]}) - updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Vorschlag Wiki Artikel"] + 1)}{row_num_in_sheet}', 'values': [['']]}) - # Und den Wiki Verif. Timestamp (AA) leeren - updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wiki Verif. Timestamp"] + 1)}{row_num_in_sheet}', 'values': [['']]}) - - - else: # Fehler bei Extraktion oder leeres Ergebnis - self.logger.error(f" -> Fehler bei Datenextraktion von {url_to_extract_from[:100]}... oder Extraktion war leer. Setze Daten auf 'k.A.'") - final_wiki_data['url'] = url_to_extract_from - for key_to_clear in ['sitz_stadt', 'sitz_land', 'first_paragraph', 'branche', 'umsatz', 'mitarbeiter', 'categories']: - final_wiki_data[key_to_clear] = 'k.A. (Extraktion fehlgeschlagen)' if key_to_clear == 'first_paragraph' else 'k.A.' - wiki_data_updated_in_this_run = True - - except Exception as e_wiki_extract: - self.logger.error(f"FEHLER bei Wikipedia Datenextraktion von {url_to_extract_from[:100]}...: {e_wiki_extract}") - final_wiki_data['url'] = url_to_extract_from - for key_to_clear in ['sitz_stadt', 'sitz_land', 'first_paragraph', 'branche', 'umsatz', 'mitarbeiter', 'categories']: - final_wiki_data[key_to_clear] = f'k.A. (FEHLER Extraktion)' if key_to_clear == 'first_paragraph' else 'k.A.' - wiki_data_updated_in_this_run = True - - else: # Wenn keine gültige URL zum Extrahieren bestimmt wurde - self.logger.debug(f" -> Keine Wiki-URL zum Extrahieren bestimmt ('{url_to_extract_from}'). Wiki-Daten nicht geändert oder bleiben auf Fehlerstatus.") - if isinstance(url_to_extract_from, str) and (url_to_extract_from.lower() == 'kein artikel gefunden' or url_to_extract_from.startswith("FEHLER")): - # Nur die URL-Spalte (R) mit dem Fehler/Hinweis aktualisieren, Rest auf k.A. - final_wiki_data['url'] = url_to_extract_from - for key_to_clear in ['sitz_stadt', 'sitz_land', 'first_paragraph', 'branche', 'umsatz', 'mitarbeiter', 'categories']: - final_wiki_data[key_to_clear] = 'k.A.' - wiki_data_updated_in_this_run = True # Markiere als Update, damit Timestamps gesetzt werden - - # --- Sheet Updates für Wiki-Daten (R-Y) und Timestamps (Z, AA, AB) --- - updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wiki URL"] + 1)}{row_num_in_sheet}', 'values': [[final_wiki_data.get('url', 'k.A.')]]}) - updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wiki Sitz Stadt"] + 1)}{row_num_in_sheet}', 'values': [[final_wiki_data.get('sitz_stadt', 'k.A.')]]}) - updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wiki Sitz Land"] + 1)}{row_num_in_sheet}', 'values': [[final_wiki_data.get('sitz_land', 'k.A.')]]}) - updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wiki Absatz"] + 1)}{row_num_in_sheet}', 'values': [[final_wiki_data.get('first_paragraph', 'k.A.')]]}) - updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wiki Branche"] + 1)}{row_num_in_sheet}', 'values': [[final_wiki_data.get('branche', 'k.A.')]]}) - updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wiki Umsatz"] + 1)}{row_num_in_sheet}', 'values': [[final_wiki_data.get('umsatz', 'k.A.')]]}) - updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wiki Mitarbeiter"] + 1)}{row_num_in_sheet}', 'values': [[final_wiki_data.get('mitarbeiter', 'k.A.')]]}) - updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wiki Kategorien"] + 1)}{row_num_in_sheet}', 'values': [[final_wiki_data.get('categories', 'k.A.')]]}) - - # Timestamp für Wikipedia-Extraktion (Z) immer setzen, wenn der Wiki-Schritt lief - updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wikipedia Timestamp"] + 1)}{row_num_in_sheet}', 'values': [[now_timestamp]]}) - # Innerhalb von DataProcessor._process_single_row (NEUER Wiki-Block) - - # --- 2. Wikipedia Handling (Search, Extraction, Status Reset) ========== run_wiki_step = 'wiki' in steps_to_run wiki_processing_needed_based_on_status = self._needs_wiki_processing(row_data, force_reeval) if run_wiki_step and wiki_processing_needed_based_on_status: any_processing_done = True - # ---- KORREKTE VARIABLENERSTELLUNG UND VERWENDUNG FÜR LOGGING ---- - grund_message_parts_wiki_list = [] # Eine Liste, um die Gründe zu sammeln + grund_message_parts_wiki_list = [] if force_reeval: grund_message_parts_wiki_list.append('Re-Eval') if not self._get_cell_value_safe(row_data, "Wikipedia Timestamp").strip(): @@ -4681,21 +4493,19 @@ class DataProcessor: if self._get_cell_value_safe(row_data, "Chat Wiki Konsistenzpruefung").strip().upper() == "X (URL COPIED)": grund_message_parts_wiki_list.append("AC (Chat Wiki Konsistenzpruefung)='X (URL COPIED)'") - # Baue die Log-Nachricht zusammen grund_message_wiki_str = ", ".join(filter(None, grund_message_parts_wiki_list)) if not grund_message_wiki_str: - grund_message_wiki_str = "Bedingung für Wiki-Bearbeitung erfüllt (Standard)" # Aussagekräftiger Fallback + grund_message_wiki_str = "Bedingung für Wiki-Bearbeitung erfüllt (Standard)" - # Verwende die korrekte Variable `grund_message_wiki_str` + # ----- KORREKTUR HIER ----- self.logger.info(f"Zeile {row_num_in_sheet}: Fuehre WIKI Schritte aus (Grund: {grund_message_wiki_str})...") - # ---- ENDE KORREKTUR ---- + # ----- ENDE KORREKTUR ----- current_wiki_url_r = self._get_cell_value_safe(row_data, "Wiki URL").strip() system_suggested_parent_o = self._get_cell_value_safe(row_data, "System Vorschlag Parent Account").strip() # parent_account_name_d ist bereits oben in _process_single_row gelesen worden - url_for_extraction = None # Wird die URL sein, von der wir versuchen zu extrahieren - # name_for_validation_for_log = company_name # Für Logging, welcher Name für Validierung genutzt wurde + url_for_extraction = None source_of_wiki_data_origin_log_msg = "Tochter (Initial)" additional_info_for_af_col = "" @@ -4705,7 +4515,7 @@ class DataProcessor: (parent_account_name_d and parent_account_name_d.lower() != 'k.a.'): self.logger.info(f" Zeile {row_num_in_sheet}: R leer, D ('{parent_account_name_d}') gesetzt. Suche Wiki für Parent D via SerpAPI.") try: - potential_url = serp_wikipedia_lookup(parent_account_name_d, website=None) + potential_url = serp_wikipedia_lookup(parent_account_name_d, website=None) # SERP API KEY BENÖTIGT! if potential_url and potential_url.lower() not in ["k.a.", "kein artikel gefunden"] and not potential_url.startswith("FEHLER"): url_for_extraction = potential_url source_of_wiki_data_origin_log_msg = f"Parent D ('{parent_account_name_d}')" @@ -4714,7 +4524,6 @@ class DataProcessor: else: self.logger.warning(f" -> Kein Wiki-Artikel für Parent D '{parent_account_name_d}' gefunden.") additional_info_for_af_col = f"WARN: Kein Wiki für Parent D '{parent_account_name_d}' gefunden. " - # Setze final_wiki_data hier nicht, da die Tochter-Suche noch folgen kann except Exception as e_d_lookup_re: self.logger.error(f"Fehler bei Wiki-Suche für Parent D '{parent_account_name_d}': {e_d_lookup_re}") additional_info_for_af_col = f"ERR: Suche Parent D '{parent_account_name_d}' fehlgeschlagen. " @@ -4722,35 +4531,69 @@ class DataProcessor: # Priorität 2: Systemvorschlag Parent O, wenn R leer UND D nicht erfolgreich war/leer ist if (url_for_extraction is None) and \ (not current_wiki_url_r or current_wiki_url_r.lower() == 'k.a.') and \ - (system_suggested_parent_name_o and system_suggested_parent_name_o.lower() != 'k.a.'): - self.logger.info(f" Zeile {row_num_in_sheet}: R leer, D nicht genutzt/erfolglos. O ('{system_suggested_parent_name_o}') gesetzt. Suche Wiki für Parent O via SerpAPI.") + (system_suggested_parent_o and system_suggested_parent_o.lower() != 'k.a.'): # HIER WAR system_suggested_parent_name_o + self.logger.info(f" Zeile {row_num_in_sheet}: R leer, D nicht genutzt/erfolglos. O ('{system_suggested_parent_o}') gesetzt. Suche Wiki für Parent O via SerpAPI.") try: - potential_url = serp_wikipedia_lookup(system_suggested_parent_name_o, website=None) + potential_url = serp_wikipedia_lookup(system_suggested_parent_o, website=None) # SERP API KEY BENÖTIGT! if potential_url and potential_url.lower() not in ["k.a.", "kein artikel gefunden"] and not potential_url.startswith("FEHLER"): + # Hier keine explizite _validate_article, da serp_wikipedia_lookup schon filtert + # und wir davon ausgehen, dass der Parent-Name in O gut genug ist. url_for_extraction = potential_url - source_of_wiki_data_origin_log_msg = f"Parent O ('{system_suggested_parent_name_o}')" + source_of_wiki_data_origin_log_msg = f"Parent O ('{system_suggested_parent_o}')" updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Wiki Konsistenzpruefung"] + 1)}{row_num_in_sheet}', 'values': [["INFO_PARENT_AUS_O"]]}) - additional_info_for_af_col += f"INFO: Wiki-URL von Parent (aus O): {system_suggested_parent_name_o} via SerpAPI. " + additional_info_for_af_col += f"INFO: Wiki-URL von Parent (aus O): {system_suggested_parent_o} via SerpAPI. " else: - self.logger.warning(f" -> Kein Wiki-Artikel für Parent O '{system_suggested_parent_name_o}' gefunden.") - additional_info_for_af_col += f"WARN: Kein Wiki für Parent O '{system_suggested_parent_name_o}' gefunden. " + self.logger.warning(f" -> Kein Wiki-Artikel für Parent O '{system_suggested_parent_o}' gefunden.") + additional_info_for_af_col += f"WARN: Kein Wiki für Parent O '{system_suggested_parent_o}' gefunden. " except Exception as e_o_lookup_re: - self.logger.error(f"Fehler bei Wiki-Suche für Parent O '{system_suggested_parent_name_o}': {e_o_lookup_re}") - additional_info_for_af_col += f"ERR: Suche Parent O '{system_suggested_parent_name_o}' fehlgeschlagen. " + self.logger.error(f"Fehler bei Wiki-Suche für Parent O '{system_suggested_parent_o}': {e_o_lookup_re}") + additional_info_for_af_col += f"ERR: Suche Parent O '{system_suggested_parent_o}' fehlgeschlagen. " - # Priorität 3: Standard Tochter-Wiki-Logik (wenn keine Parent-URL ermittelt wurde oder R schon gefüllt war) - if url_for_extraction is None or (current_wiki_url_r and current_wiki_url_r.lower() != 'k.a.' and not current_wiki_url_r.startswith("FEHLER")): - # Wenn R schon eine URL hat (und keine Parent-URL gefunden wurde), diese verwenden. - # Oder wenn R leer war und Parent-Suchen fehlschlugen, dann neu für Tochter suchen. - if current_wiki_url_r and current_wiki_url_r.lower() not in ['k.a.'] and not current_wiki_url_r.startswith("FEHLER") and \ - not (force_reeval or self._get_cell_value_safe(row_data, "Chat Wiki Konsistenzpruefung").strip().upper() == "X (URL COPIED)"): - url_for_extraction = current_wiki_url_r - source_of_wiki_data_origin_log_msg = "Tochter (aus R, unverändert)" - self.logger.info(f" Zeile {row_num_in_sheet}: Nutze bestehende Tochter-URL aus R: {url_for_extraction}") - else: # R ist leer oder Re-Eval/Reparse -> Suche für Tochter - self.logger.info(f" Zeile {row_num_in_sheet}: Suche Wiki-Artikel für Tochter '{company_name}'...") + # Priorität 3: Standard Tochter-Wiki-Logik (wenn keine Parent-URL ermittelt wurde oder R schon gefüllt war und reevaluiert wird) + if url_for_extraction is None or \ + (current_wiki_url_r and current_wiki_url_r.lower() != 'k.a.' and not current_wiki_url_r.startswith("FEHLER") and \ + (force_reeval or self._get_cell_value_safe(row_data, "Chat Wiki Konsistenzpruefung").strip().upper() == "X (URL COPIED)")): + + # Bestimme, ob eine neue Suche für die Tochter nötig ist oder die vorhandene URL in R verwendet wird + search_for_daughter_wiki_needed_local = False # Lokale Variable für diesen Block + + status_ac_indicates_reparse_local = self._get_cell_value_safe(row_data, "Chat Wiki Konsistenzpruefung").strip().upper() == "X (URL COPIED)" + timestamp_z_is_empty_local = not self._get_cell_value_safe(row_data, "Wikipedia Timestamp").strip() + + r_url_is_valid_looking_local = current_wiki_url_r and \ + "wikipedia.org/wiki/" in current_wiki_url_r.lower() and \ + current_wiki_url_r.lower() not in ["k.a.", "kein artikel gefunden", "fehler bei suche"] + + if status_ac_indicates_reparse_local: + self.logger.info(f" Zeile {row_num_in_sheet}: Status AC ist 'X (URL COPIED)'. Starte neue Suche für Tochter '{company_name}'.") + search_for_daughter_wiki_needed_local = True + elif force_reeval: + if r_url_is_valid_looking_local and url_for_extraction is None: # Nur wenn keine Parent-URL gefunden wurde + self.logger.info(f" Zeile {row_num_in_sheet}: Re-Eval Modus. Nutze vorhandene Tochter-URL (R): {current_wiki_url_r}") + url_for_extraction = current_wiki_url_r # Setze die URL hier + source_of_wiki_data_origin_log_msg = "Tochter (aus R, Re-Eval)" + elif url_for_extraction is None: # Keine Parent-URL und R ist schlecht + self.logger.info(f" Zeile {row_num_in_sheet}: Re-Eval Modus. Tochter-URL (R) leer/ungültig. Starte neue Suche für Tochter '{company_name}'.") + search_for_daughter_wiki_needed_local = True + elif timestamp_z_is_empty_local and url_for_extraction is None: + if r_url_is_valid_looking_local: + self.logger.info(f" Zeile {row_num_in_sheet}: Wikipedia Timestamp (Z) fehlt. Nutze vorhandene Tochter-URL (R): {current_wiki_url_r}") + url_for_extraction = current_wiki_url_r + source_of_wiki_data_origin_log_msg = "Tochter (aus R, Z leer)" + else: + self.logger.info(f" Zeile {row_num_in_sheet}: Wikipedia Timestamp (Z) fehlt und Tochter-URL (R) leer/ungültig. Starte neue Suche für Tochter '{company_name}'.") + search_for_daughter_wiki_needed_local = True + elif not r_url_is_valid_looking_local and url_for_extraction is None: + self.logger.info(f" Zeile {row_num_in_sheet}: Tochter-URL (R) ist ungültig ('{current_wiki_url_r}'). Starte neue Suche für Tochter '{company_name}'.") + search_for_daughter_wiki_needed_local = True + elif url_for_extraction is None : # Wenn bisher keine URL gefunden/gesetzt wurde + self.logger.debug(f" Zeile {row_num_in_sheet}: Wiki-Verarbeitung für Tochter nicht nötig (Z gesetzt, R gültig, kein Re-Eval/Reparse, kein Parent-Fall).") + + + if search_for_daughter_wiki_needed_local: + self.logger.info(f" -> Suche nach Wikipedia-Artikel für Tochter '{company_name}'...") try: - page_obj_tochter = self.wiki_scraper.search_company_article(company_name, website_url) + page_obj_tochter = self.wiki_scraper.search_company_article(company_name, website_url) # SERP API KEY BENÖTIGT! if page_obj_tochter: url_for_extraction = page_obj_tochter.url source_of_wiki_data_origin_log_msg = "Tochter (Suche erfolgreich)" @@ -4762,15 +4605,22 @@ class DataProcessor: self.logger.error(f"Fehler bei Wiki-Suche für Tochter '{company_name}': {e_tochter_suche_psr}") url_for_extraction = f"Fehler Suche Tochter: {str(e_tochter_suche_psr)[:50]}" + # Fallback, falls immer noch keine URL da ist, aber R eine hatte (und nicht reevaluiert wurde) + if url_for_extraction is None and current_wiki_url_r and \ + current_wiki_url_r.lower() not in ['k.a.'] and not current_wiki_url_r.startswith("FEHLER") and \ + not (force_reeval or self._get_cell_value_safe(row_data, "Chat Wiki Konsistenzpruefung").strip().upper() == "X (URL COPIED)"): + url_for_extraction = current_wiki_url_r + source_of_wiki_data_origin_log_msg = "Tochter (aus R, Fallback)" + self.logger.debug(f" Zeile {row_num_in_sheet}: Fallback auf bestehende Tochter-URL aus R: {url_for_extraction}") + + # --- DATENEXTRAKTION --- if url_for_extraction and isinstance(url_for_extraction, str) and \ url_for_extraction.lower() not in ["k.a.", "kein artikel gefunden"] and \ not url_for_extraction.startswith("FEHLER"): + self.logger.info(f" -> Extrahiere Wiki-Daten von URL ({source_of_wiki_data_origin_log_msg}): {url_for_extraction[:100]}...") try: - # Für Parent-Artikel machen wir keine weitere explizite Validierung hier, - # wir vertrauen dem serp_wikipedia_lookup. - # Für Tochter-Artikel hat search_company_article bereits validiert. extracted_data = self.wiki_scraper.extract_company_data(url_for_extraction) if extracted_data and isinstance(extracted_data, dict) and extracted_data.get('url') != 'k.A.': @@ -4778,12 +4628,18 @@ class DataProcessor: wiki_data_updated_in_this_run = True self.logger.info(f" -> Datenextraktion von {url_for_extraction[:100]}... erfolgreich.") - # AC und abhängige Spalten zurücksetzen, wenn es sich um eine Tochter-URL handelt - # und diese neu ist oder reevaluiert wurde. - # Wenn es eine Parent-URL war, wurde AC schon oben gesetzt. + # AC und abhängige Spalten zurücksetzen/anpassen current_ac_val = self._get_cell_value_safe(row_data, "Chat Wiki Konsistenzpruefung").strip() - if not source_of_wiki_data_origin_log_msg.startswith("Parent") and \ - (force_reeval or current_wiki_url_r != url_for_extraction or current_ac_val.upper() == "X (URL COPIED)"): + + if source_of_wiki_data_origin_log_msg.startswith("Parent"): + # AC wurde schon auf INFO_PARENT_AUS_D/O gesetzt + # Hier sicherstellen, dass abhängige Spalten geleert werden, falls AC neu ist + if current_ac_val not in ["INFO_PARENT_AUS_D", "INFO_PARENT_AUS_O"]: + updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wiki Verif. Timestamp"] + 1)}{row_num_in_sheet}', 'values': [['']]}) + updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Begründung Wiki Inkonsistenz"] + 1)}{row_num_in_sheet}', 'values': [['']]}) + updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Vorschlag Wiki Artikel"] + 1)}{row_num_in_sheet}', 'values': [['']]}) + elif force_reeval or current_wiki_url_r != url_for_extraction or current_ac_val.upper() == "X (URL COPIED)": + # Tochter-URL wurde neu gefunden oder reevaluiert -> AC auf '?' setzen für ChatGPT Verif. self.logger.info(f" -> Setze AC auf '?' und leere AA, AD, AE für Tochter-Wiki-Update.") updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Chat Wiki Konsistenzpruefung"] + 1)}{row_num_in_sheet}', 'values': [['?']]}) updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wiki Verif. Timestamp"] + 1)}{row_num_in_sheet}', 'values': [['']]}) @@ -4797,19 +4653,19 @@ class DataProcessor: wiki_data_updated_in_this_run = True except Exception as e_wiki_extract_final_psr: self.logger.error(f"FEHLER bei Wikipedia Datenextraktion von {url_for_extraction[:100]}...: {e_wiki_extract_final_psr}") - final_wiki_data['url'] = url_for_extraction # Zumindest die (ggf. fehlerhafte) URL speichern + self.logger.debug(traceback.format_exc()) + final_wiki_data['url'] = url_for_extraction for key_to_clear in ['sitz_stadt', 'sitz_land', 'first_paragraph', 'branche', 'umsatz', 'mitarbeiter', 'categories']: final_wiki_data[key_to_clear] = f'k.A. (FEHLER Extr.)' wiki_data_updated_in_this_run = True - elif url_for_extraction: # War "Kein Artikel..." oder "Fehler..." + elif url_for_extraction: self.logger.info(f" -> Keine valide Wiki-URL zur Extraktion vorhanden: '{url_for_extraction}'. Setze Wiki-Felder auf k.A.") final_wiki_data['url'] = url_for_extraction for key_to_clear in ['sitz_stadt', 'sitz_land', 'first_paragraph', 'branche', 'umsatz', 'mitarbeiter', 'categories']: final_wiki_data[key_to_clear] = 'k.A.' - wiki_data_updated_in_this_run = True # Es gab einen Versuch/Änderung + wiki_data_updated_in_this_run = True - # Updates für R-Y und Z (immer ausführen, wenn wiki_data_updated_in_this_run) if wiki_data_updated_in_this_run: updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wiki URL"] + 1)}{row_num_in_sheet}', 'values': [[final_wiki_data.get('url', 'k.A.')]]}) updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wiki Sitz Stadt"] + 1)}{row_num_in_sheet}', 'values': [[final_wiki_data.get('sitz_stadt', 'k.A.')]]}) @@ -4820,18 +4676,18 @@ class DataProcessor: updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wiki Mitarbeiter"] + 1)}{row_num_in_sheet}', 'values': [[final_wiki_data.get('mitarbeiter', 'k.A.')]]}) updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wiki Kategorien"] + 1)}{row_num_in_sheet}', 'values': [[final_wiki_data.get('categories', 'k.A.')]]}) - updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wikipedia Timestamp"] + 1)}{row_num_in_sheet}', 'values': [[now_timestamp]]}) # Z + updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Wikipedia Timestamp"] + 1)}{row_num_in_sheet}', 'values': [[now_timestamp]]}) if additional_info_for_af_col: current_af_val = self._get_cell_value_safe(row_data, "Begründung bei Abweichung").strip() new_af_val = (current_af_val + "; " + additional_info_for_af_col if current_af_val else additional_info_for_af_col).strip() updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["Begründung bei Abweichung"] + 1)}{row_num_in_sheet}', 'values': [[new_af_val]]}) - # SerpAPI Timestamp (AB) setzen, wenn eine SerpAPI-Suche für Parent D oder O durchgeführt wurde if source_of_wiki_data_origin_log_msg.startswith("Parent D") or source_of_wiki_data_origin_log_msg.startswith("Parent O"): updates.append({'range': f'{self.sheet_handler._get_col_letter(COLUMN_MAP["SerpAPI Wiki Search Timestamp"] + 1)}{row_num_in_sheet}', 'values': [[now_timestamp]]}) + # --- Ende des Wikipedia-Blocks --- # Der nächste Block wäre ChatGPT-Evaluationen