v1.6.7: Behebt strukturelle/Syntax-Fehler; passt Filter für Wiki-Suche via SerpAPI an
- Inkrementiere Versionsnummer auf v1.6.7. - Behebe kritischen AttributeError: Korrigiere die Einrückung für mehrere Verarbeitungsmethoden (_process_single_row, process_reevaluation_rows, process_serp_website_lookup_for_empty, process_website_details_for_marked_rows, prepare_data_for_modeling, process_rows_sequentially, process_find_wiki_with_serp), sodass diese korrekt als Methoden innerhalb der Klasse DataProcessor definiert sind. - Behebe SyntaxError: Löse das Problem mit komplexen f-Strings in _process_single_row und potenziell anderen Stellen, indem die String-Konstruktion von Ausdrücken innerhalb der f-String-Syntax getrennt wird. - Passe Filterlogik für Modus 'find_wiki_serp' an: Die SerpAPI-Suche nach fehlenden Wiki-URLs (M=k.A./leer) wird nun ausgelöst, wenn (CRM Umsatz (J) > 200 Mio ODER CRM Anzahl Mitarbeiter (K) > 500). Implementiere robuste numerische Extraktion für J und K innerhalb der Filterlogik. - Stelle sicher, dass SerpAPI Wiki Search Timestamp (AY) immer nach einem Suchversuch im Modus 'find_wiki_serp' gesetzt wird, unabhängig vom Ergebnis. - Diverse Logging-Anpassungen für Klarheit und Debugging (z.B. im Wiki-Verarbeitungsschritt).
This commit is contained in:
@@ -1,22 +1,14 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
v1.6.6: Füge SerpAPI-Suche für fehlende Wiki-URLs großer Firmen hinzu
|
||||
v1.6.7: Behebt strukturelle/Syntax-Fehler; passt Filter für Wiki-Suche via SerpAPI an
|
||||
|
||||
Git-Änderungsbeschreibung:
|
||||
- Füge neuen Betriebsmodus `--mode find_wiki_serp` hinzu.
|
||||
- Implementiere neue Funktion `serp_wikipedia_lookup`, die SerpAPI nutzt, um gezielt nach Wikipedia-Artikeln für einen Firmennamen zu suchen.
|
||||
- Implementiere neue Funktion `process_find_wiki_with_serp`:
|
||||
- Lädt aktuelle Sheet-Daten.
|
||||
- Filtert Zeilen, bei denen Spalte M (Wiki URL) leer/'k.A.' ist UND Spalte K (CRM Mitarbeiter) einen Schwellenwert (Standard: 500) überschreitet.
|
||||
- Ruft `serp_wikipedia_lookup` für gefilterte Zeilen auf.
|
||||
- Bei erfolgreicher URL-Findung:
|
||||
- Schreibt die gefundene URL in Spalte M.
|
||||
- Setzt Flag 'x' in Spalte A (ReEval Flag).
|
||||
- Löscht Timestamps in Spalten AN (Wikipedia Timestamp) und AO (Timestamp letzte Prüfung).
|
||||
- Führt gebündelte Sheet-Updates am Ende durch.
|
||||
- Integriere den neuen Modus `find_wiki_serp` in die Argumentenverarbeitung und Ausführungslogik der `main`-Funktion.
|
||||
- Füge notwendige Imports hinzu und stelle sicher, dass die neuen Funktionen Logging verwenden.
|
||||
- Aktualisiere Versionsnummer in `Config.VERSION` auf v1.6.6.
|
||||
- Inkrementiere Versionsnummer auf v1.6.7.
|
||||
- Behebe kritischen AttributeError: Korrigiere die Einrückung für mehrere Verarbeitungsmethoden (_process_single_row, process_reevaluation_rows, process_serp_website_lookup_for_empty, process_website_details_for_marked_rows, prepare_data_for_modeling, process_rows_sequentially, process_find_wiki_with_serp), sodass diese korrekt als Methoden innerhalb der Klasse DataProcessor definiert sind.
|
||||
- Behebe SyntaxError: Löse das Problem mit komplexen f-Strings in _process_single_row und potenziell anderen Stellen, indem die String-Konstruktion von Ausdrücken innerhalb der f-String-Syntax getrennt wird.
|
||||
- Passe Filterlogik für Modus 'find_wiki_serp' an: Die SerpAPI-Suche nach fehlenden Wiki-URLs (M=k.A./leer) wird nun ausgelöst, wenn (CRM Umsatz (J) > 200 Mio ODER CRM Anzahl Mitarbeiter (K) > 500). Implementiere robuste numerische Extraktion für J und K innerhalb der Filterlogik.
|
||||
- Stelle sicher, dass SerpAPI Wiki Search Timestamp (AY) immer nach einem Suchversuch im Modus 'find_wiki_serp' gesetzt wird, unabhängig vom Ergebnis.
|
||||
- Diverse Logging-Anpassungen für Klarheit und Debugging (z.B. im Wiki-Verarbeitungsschritt).
|
||||
"""
|
||||
|
||||
import os
|
||||
@@ -73,7 +65,7 @@ PATTERNS_FILE_JSON = "technician_patterns.json" # Optional
|
||||
# ==================== KONFIGURATION ====================
|
||||
class Config:
|
||||
# ... (Alle deine bisherigen Config-Einstellungen) ...
|
||||
VERSION = "v1.6.6" # Versionsnummer erhöhen
|
||||
VERSION = "v1.6.7" # Versionsnummer erhöhen
|
||||
LANG = "de"
|
||||
SHEET_URL = "https://docs.google.com/spreadsheets/d/1u_gHr9JUfmV1-iviRzbSe3575QEp7KLhK5jFV_gJcgo"
|
||||
MAX_RETRIES = 3
|
||||
@@ -368,9 +360,17 @@ def serp_wikipedia_lookup(company_name, website=None, min_score=0.4):
|
||||
return None # Bei unerwarteten Fehlern None zurückgeben
|
||||
|
||||
# Kann als eigenständige Funktion oder Methode in DataProcessor implementiert werden
|
||||
def process_find_wiki_with_serp(sheet_handler, row_limit=None, min_employees=500):
|
||||
# Annahme: COLUMN_MAP ist global definiert und enthält mindestens:
|
||||
# "CRM Name" (B), "CRM Anzahl Mitarbeiter" (K), "CRM Umsatz" (J),
|
||||
# "Wiki URL" (M), "ReEval Flag" (A), "Wiki Absatz" (N), ..., "Wiki Verif. Timestamp" (AX), "SerpAPI Wiki Search Timestamp" (AY)
|
||||
# Annahme: serp_wikipedia_lookup und simple_normalize_url sind definiert und nutzen logging/retry
|
||||
# Annahme: clean_text und normalize_company_name sind definiert
|
||||
# Annahme: get_valid_numeric (oder ähnliche Logik zur numerischen Extraktion) ist verfügbar/implementiert.
|
||||
|
||||
def process_find_wiki_with_serp(sheet_handler, row_limit=None, min_employees=500, min_umsatz=200):
|
||||
"""
|
||||
Sucht fehlende Wikipedia-URLs (Spalte M = k.A.) für Unternehmen mit > min_employees
|
||||
Sucht fehlende Wikipedia-URLs (Spalte M = k.A.) für Unternehmen mit
|
||||
(Umsatz CRM > min_umsatz ODER Mitarbeiter CRM > min_employees)
|
||||
über SerpAPI und trägt gefundene URLs in Spalte M ein. Setzt ReEval-Flag (A)
|
||||
und löscht abhängige Wiki-Spalten (N-V, AN, AO, AP, AX).
|
||||
Merkt sich in Spalte AY, wann die Suche durchgeführt wurde.
|
||||
@@ -378,149 +378,218 @@ def process_find_wiki_with_serp(sheet_handler, row_limit=None, min_employees=500
|
||||
Args:
|
||||
sheet_handler (GoogleSheetHandler): Initialisierte Instanz.
|
||||
row_limit (int, optional): Maximale Anzahl zu prüfender Zeilen. Defaults to None.
|
||||
min_employees (int, optional): Mindestanzahl Mitarbeiter (Spalte K) als Filter. Defaults to 500.
|
||||
min_employees (int, optional): Mindestanzahl Mitarbeiter (Spalte K) als Teilfilter. Defaults to 500.
|
||||
min_umsatz (int, optional): Mindestumsatz (Spalte J) als Teilfilter. Defaults to 200.
|
||||
"""
|
||||
logging.info(f"Starte Modus 'find_wiki_serp': Suche fehlende Wiki-URLs für Firmen > {min_employees} MA...")
|
||||
logging.info(f"Starte Modus 'find_wiki_serp': Suche fehlende Wiki-URLs für Firmen mit (Umsatz CRM > {min_umsatz} ODER Mitarbeiter CRM > {min_employees})...")
|
||||
|
||||
if not sheet_handler.load_data(): return
|
||||
all_data = sheet_handler.get_all_data_with_headers()
|
||||
if not all_data or len(all_data) <= 5:
|
||||
# Annahme: 5 Header-Zeilen
|
||||
header_rows = 5
|
||||
if not all_data or len(all_data) <= header_rows:
|
||||
logging.warning("Keine oder zu wenige Daten im Sheet für 'find_wiki_serp' gefunden.")
|
||||
return
|
||||
header_rows = 5
|
||||
data_rows = all_data[header_rows:]
|
||||
data_rows = all_data[header_rows:] # Daten ab Zeile 6
|
||||
|
||||
# Benötigte Spaltenindizes holen (inkl. aller zu löschenden Spalten)
|
||||
try:
|
||||
col_indices = {
|
||||
"A": COLUMN_MAP["ReEval Flag"],
|
||||
"K": COLUMN_MAP["CRM Anzahl Mitarbeiter"],
|
||||
"M": COLUMN_MAP["Wiki URL"],
|
||||
"B": COLUMN_MAP["CRM Name"],
|
||||
"N": COLUMN_MAP["Wiki Absatz"], # NEU zum Löschen
|
||||
"O": COLUMN_MAP["Wiki Branche"], # NEU zum Löschen
|
||||
"P": COLUMN_MAP["Wiki Umsatz"], # NEU zum Löschen
|
||||
"Q": COLUMN_MAP["Wiki Mitarbeiter"], # NEU zum Löschen
|
||||
"R": COLUMN_MAP["Wiki Kategorien"], # NEU zum Löschen
|
||||
"S": COLUMN_MAP["Chat Wiki Konsistenzprüfung"], # NEU zum Löschen
|
||||
"T": COLUMN_MAP["Chat Begründung Wiki Inkonsistenz"], # NEU zum Löschen
|
||||
"U": COLUMN_MAP["Chat Vorschlag Wiki Artikel"], # NEU zum Löschen
|
||||
"V": COLUMN_MAP["Begründung bei Abweichung"], # NEU zum Löschen
|
||||
"AN": COLUMN_MAP["Wikipedia Timestamp"],
|
||||
"AO": COLUMN_MAP["Timestamp letzte Prüfung"],
|
||||
"AP": COLUMN_MAP["Version"], # NEU zum Löschen
|
||||
"AX": COLUMN_MAP["Wiki Verif. Timestamp"], # NEU zum Löschen
|
||||
"AY": COLUMN_MAP["SerpAPI Wiki Search Timestamp"]
|
||||
}
|
||||
col_letters = {key: sheet_handler._get_col_letter(idx + 1) for key, idx in col_indices.items()}
|
||||
except KeyError as e:
|
||||
logging.critical(f"FEHLER: Benötigter Spaltenschlüssel '{e}' nicht in COLUMN_MAP gefunden! Modus abgebrochen.")
|
||||
return
|
||||
except Exception as e:
|
||||
logging.critical(f"FEHLER beim Holen der Spaltenbuchstaben: {e}")
|
||||
return
|
||||
# Verwenden Sie hier das COLUMN_MAP robust
|
||||
col_indices = {}
|
||||
required_keys = [
|
||||
"ReEval Flag", "CRM Anzahl Mitarbeiter", "CRM Umsatz", "Wiki URL", "CRM Name",
|
||||
"Wiki Absatz", "Wiki Branche", "Wiki Umsatz", "Wiki Mitarbeiter", "Wiki Kategorien",
|
||||
"Chat Wiki Konsistenzprüfung", "Chat Begründung Wiki Inkonsistenz", "Chat Vorschlag Wiki Artikel",
|
||||
"Begründung bei Abweichung", "Wikipedia Timestamp", "Timestamp letzte Prüfung",
|
||||
"Version", "Wiki Verif. Timestamp", "SerpAPI Wiki Search Timestamp"
|
||||
]
|
||||
all_keys_found = True
|
||||
for key in required_keys:
|
||||
idx = COLUMN_MAP.get(key)
|
||||
col_indices[key] = idx
|
||||
if idx is None:
|
||||
logging.critical(f"FEHLER: Benötigter Spaltenschlüssel '{key}' nicht in COLUMN_MAP gefunden! Modus abgebrochen.")
|
||||
all_keys_found = False
|
||||
|
||||
if not all_keys_found:
|
||||
return # Abbruch, da Spalten fehlen
|
||||
|
||||
# Hilfsfunktion zur Konvertierung Spaltenindex -> Buchstabe
|
||||
col_letters = {key: sheet_handler._get_col_letter(idx + 1) for key, idx in col_indices.items()}
|
||||
|
||||
|
||||
all_sheet_updates = []
|
||||
processed_rows = 0
|
||||
found_urls = 0
|
||||
skipped_timestamp_ay = 0
|
||||
skipped_employee_count = 0
|
||||
processed_rows_count = 0 # Zählt Zeilen, für die SerpAPI versucht wurde
|
||||
found_urls_count = 0 # Zählt Zeilen, wo eine URL gefunden wurde
|
||||
skipped_timestamp_ay_count = 0
|
||||
skipped_size_count = 0
|
||||
skipped_m_filled_count = 0
|
||||
|
||||
now_timestamp_str = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
for idx, row in enumerate(data_rows):
|
||||
row_num_in_sheet = idx + header_rows + 1
|
||||
# --- Hilfsfunktion zur sicheren numerischen Extraktion (adaptiert von prepare_data_for_modeling) ---
|
||||
def safe_numeric_extract(value_str):
|
||||
if value_str is None or pd.isna(value_str) or str(value_str).strip() == '': return 0 # Return 0, nicht NaN, für die Vergleichslogik
|
||||
try:
|
||||
# Annahme: clean_text existiert
|
||||
processed_value = clean_text(str(value_str))
|
||||
if processed_value == "k.A.": return 0
|
||||
|
||||
if row_limit is not None and processed_rows >= row_limit:
|
||||
processed_value = re.sub(r'(?i)^\s*(ca\.?|circa|rund|etwa|über|unter|mehr als|weniger als|bis zu)\s+', '', processed_value)
|
||||
processed_value = re.sub(r'[€$£¥]', '', processed_value).strip()
|
||||
processed_value = re.split(r'\s*(-|–|bis)\s*', processed_value, 1)[0].strip()
|
||||
# Entferne Punkte UND Apostrophe als Tausendertrenner, ersetze Komma durch Punkt
|
||||
processed_value = processed_value.replace('.', '').replace("'", "").replace(',', '.')
|
||||
|
||||
match = re.search(r'([\d.]+)', processed_value)
|
||||
if not match: return 0 # Keine numerischen Zeichen gefunden
|
||||
|
||||
num_str = match.group(1)
|
||||
if not num_str or num_str == '.': return 0
|
||||
|
||||
num = float(num_str)
|
||||
|
||||
# Einheiten-Multiplikatoren (Mrd, Mio, Tsd) - Wichtig für Umsatz
|
||||
multiplier = 1.0
|
||||
original_lower = str(value_str).lower() # Nutze den Originalstring für Einheiten
|
||||
if "mrd" in original_lower or "milliarden" in original_lower or "billion" in original_lower: multiplier = 1000000000.0
|
||||
elif "mio" in original_lower or "millionen" in original_lower or "mill." in original_lower: multiplier = 1000000.0
|
||||
elif "tsd" in original_lower or "tausend" in original_lower: multiplier = 1000.0
|
||||
|
||||
num = num * multiplier
|
||||
|
||||
# Für den Vergleich (Umsatz in Mio, Mitarbeiter int)
|
||||
# Umsatz soll > 200 MIO sein, also num direkt mit 200,000,000 vergleichen
|
||||
# Mitarbeiter > 500, num direkt mit 500 vergleichen
|
||||
# Geben Sie den Rohwert nach Multiplikator zurück
|
||||
return num if num > 0 else 0 # Nur positive Werte zählen
|
||||
|
||||
except Exception as e:
|
||||
logging.debug(f"Fehler in safe_numeric_extract für Wert '{str(value_str)[:50]}...': {e}")
|
||||
return 0
|
||||
# --- Ende Hilfsfunktion ---
|
||||
|
||||
|
||||
# Iteriere durch die Datenzeilen
|
||||
for idx, row in enumerate(data_rows):
|
||||
row_num_in_sheet = idx + header_rows + 1 # 1-basierte Sheet-Zeilennummer
|
||||
|
||||
# Limit-Prüfung
|
||||
if row_limit is not None and processed_rows_count >= row_limit:
|
||||
logging.info(f"Zeilenlimit ({row_limit}) für durchgeführte Suchen erreicht.")
|
||||
break
|
||||
|
||||
# Prüfe AY Timestamp
|
||||
ts_ay_val = row[col_indices["AY"]] if len(row) > col_indices["AY"] else ""
|
||||
# Sicherstellen, dass die Zeile lang genug für alle benötigten Spalten ist
|
||||
max_needed_idx = max(col_indices.values())
|
||||
if len(row) <= max_needed_idx:
|
||||
logging.debug(f"Zeile {row_num_in_sheet}: Übersprungen (Zeile zu kurz für benötigte Spalten, erwartet > {max_needed_idx}, hat {len(row)}).")
|
||||
continue
|
||||
|
||||
|
||||
# Prüfe AY Timestamp: Überspringe, wenn SerpAPI Suche für diese Zeile schon versucht wurde
|
||||
ts_ay_val = row[col_indices["SerpAPI Wiki Search Timestamp"]]
|
||||
if ts_ay_val and ts_ay_val.strip():
|
||||
skipped_timestamp_ay += 1
|
||||
skipped_timestamp_ay_count += 1
|
||||
continue
|
||||
|
||||
try:
|
||||
# Mitarbeiterzahl prüfen
|
||||
ma_val_str = row[col_indices["K"]] if len(row) > col_indices["K"] else "0"
|
||||
try:
|
||||
ma_val_str_cleaned = re.sub(r"[^\d]", "", ma_val_str)
|
||||
ma_val = int(ma_val_str_cleaned) if ma_val_str_cleaned else 0
|
||||
except ValueError: ma_val = 0
|
||||
|
||||
if ma_val <= min_employees:
|
||||
skipped_employee_count += 1
|
||||
continue
|
||||
|
||||
# Wiki URL (M) prüfen
|
||||
m_value = row[col_indices["M"]] if len(row) > col_indices["M"] else ""
|
||||
if m_value and m_value.strip().lower() != "k.a.":
|
||||
skipped_m_filled_count += 1
|
||||
continue
|
||||
|
||||
# Kandidat gefunden
|
||||
company_name = row[col_indices["B"]] if len(row) > col_indices["B"] else ""
|
||||
if not company_name:
|
||||
logging.warning(f"Zeile {row_num_in_sheet}: Übersprungen, kein Firmenname für Suche vorhanden.")
|
||||
continue
|
||||
|
||||
# SerpAPI Suche
|
||||
logging.info(f"Zeile {row_num_in_sheet}: Suche Wiki-URL für '{company_name}' (MA: {ma_val})...")
|
||||
wiki_url_found = serp_wikipedia_lookup(company_name)
|
||||
processed_rows += 1
|
||||
time.sleep(1.5)
|
||||
|
||||
# Updates vorbereiten
|
||||
# Timestamp AY IMMER setzen
|
||||
row_updates = [{'range': f'{col_letters["AY"]}{row_num_in_sheet}', 'values': [[now_timestamp_str]]}]
|
||||
|
||||
if wiki_url_found:
|
||||
logging.info(f" -> URL gefunden: {wiki_url_found}. Bereite Update vor (Setze M, A; Lösche N-V, AN, AO, AP, AX).")
|
||||
found_urls += 1
|
||||
# Zusätzliche Updates für gefundene URL
|
||||
row_updates.extend([
|
||||
{'range': f'{col_letters["M"]}{row_num_in_sheet}', 'values': [[wiki_url_found]]}, # URL setzen
|
||||
{'range': f'{col_letters["A"]}{row_num_in_sheet}', 'values': [['x']]}, # ReEval Flag
|
||||
# --- Spalten leeren ---
|
||||
{'range': f'{col_letters["N"]}{row_num_in_sheet}', 'values': [['']]},
|
||||
{'range': f'{col_letters["O"]}{row_num_in_sheet}', 'values': [['']]},
|
||||
{'range': f'{col_letters["P"]}{row_num_in_sheet}', 'values': [['']]},
|
||||
{'range': f'{col_letters["Q"]}{row_num_in_sheet}', 'values': [['']]},
|
||||
{'range': f'{col_letters["R"]}{row_num_in_sheet}', 'values': [['']]},
|
||||
{'range': f'{col_letters["S"]}{row_num_in_sheet}', 'values': [['']]},
|
||||
{'range': f'{col_letters["T"]}{row_num_in_sheet}', 'values': [['']]},
|
||||
{'range': f'{col_letters["U"]}{row_num_in_sheet}', 'values': [['']]},
|
||||
{'range': f'{col_letters["V"]}{row_num_in_sheet}', 'values': [['']]},
|
||||
{'range': f'{col_letters["AN"]}{row_num_in_sheet}', 'values': [['']]},
|
||||
{'range': f'{col_letters["AO"]}{row_num_in_sheet}', 'values': [['']]},
|
||||
{'range': f'{col_letters["AP"]}{row_num_in_sheet}', 'values': [['']]},
|
||||
{'range': f'{col_letters["AX"]}{row_num_in_sheet}', 'values': [['']]}
|
||||
])
|
||||
else:
|
||||
logging.info(f" -> Keine Wiki-URL für '{company_name}' via SerpAPI gefunden.")
|
||||
# Nur AY Timestamp wird geschrieben
|
||||
|
||||
all_sheet_updates.extend(row_updates)
|
||||
|
||||
except Exception as e:
|
||||
logging.exception(f"Unerwarteter Fehler bei Verarbeitung von Zeile {row_num_in_sheet}: {e}")
|
||||
# Prüfe Wiki URL (M): Überspringe, wenn bereits gefüllt (nicht k.A. oder leer)
|
||||
m_value = row[col_indices["Wiki URL"]]
|
||||
if m_value and str(m_value).strip().lower() != "k.a.": # Jetzt auch 'leer' abfangen? Nein, '' ist schon abgedeckt
|
||||
skipped_m_filled_count += 1
|
||||
continue
|
||||
|
||||
# --- Prüfe Unternehmensgröße (J Umsatz ODER K Mitarbeiter) ---
|
||||
umsatz_val_str = row[col_indices["CRM Umsatz"]]
|
||||
ma_val_str = row[col_indices["CRM Anzahl Mitarbeiter"]]
|
||||
|
||||
umsatz_val_num = safe_numeric_extract(umsatz_val_str)
|
||||
ma_val_num = safe_numeric_extract(ma_val_str)
|
||||
|
||||
# Filterlogik: Umsatz > min_umsatz ODER Mitarbeiter > min_employees
|
||||
# Wenn *nicht* (Umsatz > min_umsatz ODER Mitarbeiter > min_employees), dann überspringe
|
||||
if not (umsatz_val_num > min_umsatz * 1000000 or ma_val_num > min_employees):
|
||||
logging.debug(f"Zeile {row_num_in_sheet}: Übersprungen (Größe nicht ausreichend. Umsatz: {umsatz_val_num:.0f}, MA: {ma_val_num}).")
|
||||
skipped_size_count += 1
|
||||
continue
|
||||
# --- Ende Größenprüfung ---
|
||||
|
||||
|
||||
# Kandidat gefunden: M leer/k.A., AY leer, und Größe passt
|
||||
company_name = row[col_indices["CRM Name"]] if len(row) > col_indices["CRM Name"] else ""
|
||||
if not company_name or str(company_name).strip() == "":
|
||||
logging.warning(f"Zeile {row_num_in_sheet}: Übersprungen, kein Firmenname für Suche vorhanden.")
|
||||
# Setze AY Timestamp, damit wir nicht immer wieder versuchen
|
||||
ay_col_letter = col_letters["SerpAPI Wiki Search Timestamp"]
|
||||
all_sheet_updates.append({'range': f'{ay_col_letter}{row_num_in_sheet}', 'values': [[now_timestamp_str]]})
|
||||
continue
|
||||
|
||||
# SerpAPI Suche
|
||||
logging.info(f"Zeile {row_num_in_sheet}: Suche Wiki-URL für '{company_name}' (Umsatz: {umsatz_val_num:.0f}, MA: {ma_val_num})...")
|
||||
processed_rows_count += 1 # Zähle VOR dem Call, dass ein Versuch gestartet wird
|
||||
|
||||
# Annahme: serp_wikipedia_lookup existiert und nutzt logging/retry
|
||||
# website_url wird nicht direkt im SerpAPI Lookup verwendet, kann aber als Kontext hilfreich sein
|
||||
website_url = row[COLUMN_MAP.get("CRM Website", -1)] if COLUMN_MAP.get("CRM Website", -1) != -1 and len(row) > COLUMN_MAP.get("CRM Website", -1) else None
|
||||
wiki_url_found = serp_wikipedia_lookup(company_name, website=website_url)
|
||||
|
||||
# Updates vorbereiten
|
||||
# Timestamp AY IMMER setzen, nachdem der Versuch gemacht wurde
|
||||
ay_col_letter = col_letters["SerpAPI Wiki Search Timestamp"]
|
||||
all_sheet_updates.append({'range': f'{ay_col_letter}{row_num_in_sheet}', 'values': [[now_timestamp_str]]})
|
||||
|
||||
|
||||
if wiki_url_found and wiki_url_found.strip() and wiki_url_found != "k.A.":
|
||||
logging.info(f" -> URL gefunden: {wiki_url_found}. Bereite Update vor (Setze M, A; Lösche N-V, AN, AO, AP, AX).")
|
||||
found_urls_count += 1
|
||||
|
||||
# Zusätzliche Updates für gefundene URL
|
||||
m_l = col_letters["Wiki URL"]
|
||||
a_l = col_letters["ReEval Flag"]
|
||||
# Spalten N-V leeren
|
||||
n_l = col_letters["Wiki Absatz"]
|
||||
v_l = col_letters["Begründung bei Abweichung"]
|
||||
# Timestamps AN, AO, AX, Version AP leeren
|
||||
an_l = col_letters["Wikipedia Timestamp"]
|
||||
ao_l = col_letters["Timestamp letzte Prüfung"]
|
||||
ap_l = col_letters["Version"]
|
||||
ax_l = col_letters["Wiki Verif. Timestamp"]
|
||||
|
||||
|
||||
all_sheet_updates.extend([
|
||||
{'range': f'{m_l}{row_num_in_sheet}', 'values': [[wiki_url_found]]}, # URL setzen in M
|
||||
{'range': f'{a_l}{row_num_in_sheet}', 'values': [['x']]}, # ReEval Flag setzen in A
|
||||
# --- Spalten leeren, damit sie neu befüllt werden ---
|
||||
# Range N:V leeren
|
||||
{'range': f'{n_l}{row_num_in_sheet}:{v_l}{row_num_in_sheet}', 'values': [[''] * (col_indices["Begründung bei Abweichung"] - col_indices["Wiki Absatz"] + 1)]},
|
||||
{'range': f'{an_l}{row_num_in_sheet}', 'values': [['']]}, # AN leeren
|
||||
{'range': f'{ao_l}{row_num_in_sheet}', 'values': [['']]}, # AO leeren
|
||||
{'range': f'{ap_l}{row_num_in_sheet}', 'values': [['']]}, # AP leeren
|
||||
{'range': f'{ax_l}{row_num_in_sheet}', 'values': [['']]} # AX leeren
|
||||
])
|
||||
else:
|
||||
logging.info(f" -> Keine Wiki-URL für '{company_name}' via SerpAPI gefunden.")
|
||||
# Nur AY Timestamp wird gesetzt, was bereits oben passiert ist.
|
||||
|
||||
# Kleiner Sleep nach jeder SerpAPI-Suche, auch wenn es ein Retry gibt
|
||||
# Der Decorator kümmert sich um Retries mit Backoff, dies ist nur eine globale Rate-Limit-Vorsorge.
|
||||
time.sleep(getattr(Config, 'RETRY_DELAY', 5) * 0.3)
|
||||
|
||||
|
||||
# --- Batch Update am Ende ---
|
||||
if all_sheet_updates:
|
||||
logging.info(f"Sende Batch-Update für {processed_rows} geprüfte Zeilen ({found_urls} URLs gefunden, {len(all_sheet_updates)} Zellen)...")
|
||||
logging.info(f"Sende Batch-Update für {processed_rows_count} geprüfte Zeilen ({found_urls_count} URLs gefunden, {len(all_sheet_updates)} Zellen)...")
|
||||
# Annahme: sheet_handler.batch_update_cells existiert und nutzt logging/retry
|
||||
success = sheet_handler.batch_update_cells(all_sheet_updates)
|
||||
if success:
|
||||
logging.info(f"Sheet-Update für 'find_wiki_serp' erfolgreich.")
|
||||
# Der else-Fall wird von batch_update_cells geloggt
|
||||
else:
|
||||
logging.info("Keine Zeilen gefunden, für die eine SerpAPI Wiki-Suche durchgeführt werden musste/konnte.")
|
||||
|
||||
logging.info(f"Modus 'find_wiki_serp' abgeschlossen.")
|
||||
logging.info(f" Durchgeführte Suchen in diesem Lauf: {processed_rows}")
|
||||
logging.info(f" Gefundene & eingetragene URLs: {found_urls}")
|
||||
logging.info(f" Übersprungen (AY bereits gesetzt): {skipped_timestamp_ay}")
|
||||
logging.info(f" Übersprungen (MA <= {min_employees}): {skipped_employee_count}")
|
||||
logging.info(f" Durchgeführte Suchen in diesem Lauf: {processed_rows_count}")
|
||||
logging.info(f" Gefundene & eingetragene URLs: {found_urls_count}")
|
||||
logging.info(f" Übersprungen (AY bereits gesetzt): {skipped_timestamp_ay_count}")
|
||||
logging.info(f" Übersprungen (Größe nicht ausreichend): {skipped_size_count}")
|
||||
logging.info(f" Übersprungen (M bereits gefüllt): {skipped_m_filled_count}")
|
||||
|
||||
def prepare_data_for_modeling(sheet_handler):
|
||||
|
||||
Reference in New Issue
Block a user