This commit is contained in:
2025-04-10 10:47:32 +00:00
parent 0e06ab7ee7
commit 41e33cd554

View File

@@ -533,10 +533,13 @@ class DataProcessor:
# ==================== NEUE FUNKTION: process_verification_only ====================
def process_verification_only():
"""
Überarbeiteter BatchProzess (Version 1.5.9, Modus 51):
Überarbeiteter BatchProzess (Version 1.5.10, Modus 51):
- Startet die Verarbeitung ab Zeile 7 und sucht ab dort die erste Zeile, in der Spalte AO (Index 41) leer ist.
- Ab dieser Zeile werden alle Zeilen in Paketen der Größe Config.BATCH_SIZE (z.B. 10 Zeilen) verarbeitet.
- Für jedes Batch wird ein aggregierter Prompt erstellt, an ChatGPT gesendet und die Antwort zeilenweise geparst.
- Falls der Nutzer eine Gesamtzeilenanzahl eingibt, die vor dem Startpunkt liegt,
wird dieser Wert ignoriert und alle Zeilen ab dem Startpunkt verarbeitet.
- Verarbeitet die Zeilen ab diesem Startpunkt in Paketen der Größe Config.BATCH_SIZE (z.B. 10 Zeilen).
- Für jedes Batch wird ein aggregierter Prompt erstellt, an ChatGPT gesendet und die Antwort
zeilenweise geparst.
- Die Ergebnisse werden in den Spalten S bis Y geschrieben:
S: Wiki-Validierung ("OK" oder "X")
T: Alternativer Wiki-Artikel (URL oder "Kein Wikipedia-Eintrag vorhanden.")
@@ -544,20 +547,18 @@ def process_verification_only():
VY: Platzhalter (leer)
- Umfangreiche Log-Ausgaben unterstützen die Fehlerdiagnose.
"""
debug_print("Starte Verifizierungsmodus (Modus 51) im Batch-Prozess (Version 1.5.9)...")
debug_print("Starte Verifizierungsmodus (Modus 51) im Batch-Prozess (Version 1.5.10)...")
# Bestimme ab Zeile 7 die erste Zeile, in der Spalte AO (Index 41) leer ist.
# Ermittlung des Startpunkts: ab Zeile 7 die erste Zeile, in der Spalte AO (Index 41) leer ist.
gc = gspread.authorize(ServiceAccountCredentials.from_json_keyfile_name(
Config.CREDENTIALS_FILE, ["https://www.googleapis.com/auth/spreadsheets"]))
sh = gc.open_by_url(Config.SHEET_URL)
main_sheet = sh.sheet1
data = main_sheet.get_all_values()
# Setze den Startindex: Beginne mindestens bei Zeile 7.
start_row = None
for i in range(7, len(data) + 1):
row = data[i - 1]
# Prüfe, ob die Zeile weniger als 41 Spalten hat oder Spalte AO leer ist.
if len(row) < 41 or row[40].strip() == "":
start_row = i
break
@@ -574,8 +575,12 @@ def process_verification_only():
total_rows = None
available_total = len(data) - 1 # ohne Header
if total_rows is not None:
available_rows = min(total_rows, available_total)
# Wenn der Nutzer einen Wert eingibt, der vor dem Startpunkt liegt, wird dieser ignoriert.
if total_rows is not None and total_rows < start_row - 1:
debug_print("Die angegebene Zeilenanzahl liegt vor dem Startpunkt. Es werden alle Zeilen ab dem Startpunkt verarbeitet.")
available_rows = available_total
elif total_rows is not None:
available_rows = total_rows
else:
available_rows = available_total
@@ -586,11 +591,9 @@ def process_verification_only():
batch_size = Config.BATCH_SIZE # z. B. 10
batches = []
row_numbers = []
# Verarbeitung ab start_row bis available_rows
for i in range(start_row, available_rows + 2): # +1 wegen 1-basierter Index, +1 um bis available_rows einzubeziehen
for i in range(start_row, available_rows + 2): # +1 für Einbeziehung, +1 wegen 1-basierter Index
row = data[i - 1]
# Da wir ab start_row starten, gehen wir davon aus, dass bisher keine Zeitstempel in AO vorhanden sind.
entry_text = (
f"Eintrag {i}:\n"
f"Firmenname: {row[1] if len(row) > 1 else ''}\n"
@@ -686,8 +689,164 @@ def _process_batch(main_sheet, batches, row_numbers):
except Exception as e:
debug_print(f"Fehler beim Updaten der Zeile {current_row}: {e}")
time.sleep(Config.RETRY_DELAY)
def process_verification_only():
"""
Überarbeiteter BatchProzess (Version 1.5.10, Modus 51):
- Startet die Verarbeitung ab Zeile 7 und sucht ab dort die erste Zeile, in der Spalte AO (Index 41) leer ist.
- Falls der Nutzer eine Gesamtzeilenanzahl eingibt, die vor dem Startpunkt liegt,
wird dieser Wert ignoriert und alle Zeilen ab dem Startpunkt verarbeitet.
- Verarbeitet die Zeilen ab diesem Startpunkt in Paketen der Größe Config.BATCH_SIZE (z.B. 10 Zeilen).
- Für jedes Batch wird ein aggregierter Prompt erstellt, an ChatGPT gesendet und die Antwort
zeilenweise geparst.
- Die Ergebnisse werden in den Spalten S bis Y geschrieben:
S: Wiki-Validierung ("OK" oder "X")
T: Alternativer Wiki-Artikel (URL oder "Kein Wikipedia-Eintrag vorhanden.")
U: Wiki-Erklärung / Begründung
VY: Platzhalter (leer)
- Umfangreiche Log-Ausgaben unterstützen die Fehlerdiagnose.
"""
debug_print("Starte Verifizierungsmodus (Modus 51) im Batch-Prozess (Version 1.5.10)...")
# Ermittlung des Startpunkts: ab Zeile 7 die erste Zeile, in der Spalte AO (Index 41) leer ist.
gc = gspread.authorize(ServiceAccountCredentials.from_json_keyfile_name(
Config.CREDENTIALS_FILE, ["https://www.googleapis.com/auth/spreadsheets"]))
sh = gc.open_by_url(Config.SHEET_URL)
main_sheet = sh.sheet1
data = main_sheet.get_all_values()
start_row = None
for i in range(7, len(data) + 1):
row = data[i - 1]
if len(row) < 41 or row[40].strip() == "":
start_row = i
break
if start_row is None:
debug_print("Keine Zeile ohne Zeitstempel in Spalte AO gefunden. Es wird nichts verarbeitet.")
return
debug_print(f"Verarbeitung startet ab Zeile {start_row} (erste Zeile ohne Zeitstempel in Spalte AO).")
# Abfrage: Wie viele Zeilen sollen insgesamt verarbeitet werden?
try:
total_rows = int(input("Wie viele Zeilen sollen insgesamt bearbeitet werden? "))
except Exception as e:
debug_print(f"Fehler bei der Eingabe der Zeilenanzahl: {e}. Es werden alle verfügbaren Zeilen verarbeitet.")
total_rows = None
available_total = len(data) - 1 # ohne Header
# Wenn der Nutzer einen Wert eingibt, der vor dem Startpunkt liegt, wird dieser ignoriert.
if total_rows is not None and total_rows < start_row - 1:
debug_print("Die angegebene Zeilenanzahl liegt vor dem Startpunkt. Es werden alle Zeilen ab dem Startpunkt verarbeitet.")
available_rows = available_total
elif total_rows is not None:
available_rows = total_rows
else:
available_rows = available_total
if start_row > available_rows + 1:
debug_print("Es gibt keine Zeilen ohne Zeitstempel ab dem Startpunkt. Es wird nichts verarbeitet.")
return
batch_size = Config.BATCH_SIZE # z. B. 10
batches = []
row_numbers = []
for i in range(start_row, available_rows + 2): # +1 für Einbeziehung, +1 wegen 1-basierter Index
row = data[i - 1]
entry_text = (
f"Eintrag {i}:\n"
f"Firmenname: {row[1] if len(row) > 1 else ''}\n"
f"CRM-Beschreibung: {row[7] if len(row) > 7 else ''}\n"
f"Wikipedia-URL: {row[11] if len(row) > 11 and row[11].strip() not in ['', 'k.A.'] else 'k.A.'}\n"
f"Wiki-Absatz: {row[12] if len(row) > 12 else 'k.A.'}\n"
f"Wiki-Kategorien: {row[16] if len(row) > 16 else 'k.A.'}\n"
"-----\n"
)
batches.append(entry_text)
row_numbers.append(i)
if len(batches) == batch_size:
_process_batch(main_sheet, batches, row_numbers)
batches = []
row_numbers = []
if batches:
_process_batch(main_sheet, batches, row_numbers)
debug_print("Verifizierungs-Batch abgeschlossen.")
def _process_batch(main_sheet, batches, row_numbers):
"""
Hilfsfunktion: Bearbeitet einen Batch, indem ein aggregierter Prompt erstellt und
die aggregierte Antwort zeilenweise den entsprechenden Zeilennummern zugeordnet wird.
Die Ergebnisse werden in Spalten S bis Y geschrieben.
"""
aggregated_prompt = (
"Du bist ein Experte in der Verifizierung von Wikipedia-Artikeln für Unternehmen. "
"Für jeden der folgenden Einträge prüfe, ob der vorhandene Wikipedia-Artikel (URL, Absatz, Kategorien) plausibel passt. "
"Gib das Ergebnis für jeden Eintrag im Format aus:\n"
"Eintrag <Zeilennummer>: <Antwort>\n"
"Regeln:\n"
"- Bei Übereinstimmung: 'OK'\n"
"- Bei Nichtübereinstimmung: 'Alternativer Wikipedia-Artikel vorgeschlagen: <URL> | X | <Begründung>'\n"
"- Falls kein Artikel gefunden wurde: 'Kein Wikipedia-Eintrag vorhanden.'\n\n"
)
aggregated_prompt += "\n".join(batches)
debug_print(f"Verarbeite Batch für Zeilen {row_numbers[0]} bis {row_numbers[-1]}.")
if tiktoken:
try:
enc = tiktoken.encoding_for_model(Config.TOKEN_MODEL)
debug_print(f"Token-Zahl für aktuellen Batch: {len(enc.encode(aggregated_prompt))}")
except Exception as e:
debug_print(f"Fehler beim Token-Counting: {e}")
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 für Verifizierung: {e}")
return
openai.api_key = api_key
try:
response = openai.ChatCompletion.create(
model=Config.TOKEN_MODEL,
messages=[{"role": "user", "content": aggregated_prompt}],
temperature=0.0
)
result = response.choices[0].message.content.strip()
debug_print(f"Aggregierte Antwort für Batch {row_numbers[0]}-{row_numbers[-1]}: {result}")
except Exception as e:
debug_print(f"Fehler bei der ChatGPT-Anfrage für Batch {row_numbers[0]}-{row_numbers[-1]}: {e}")
result = ""
answers = result.split("\n")
for current_row in row_numbers:
answer = "k.A."
for line in answers:
if line.strip().startswith(f"Eintrag {current_row}:"):
answer = line.split(":", 1)[1].strip()
break
if answer.upper() == "OK":
wiki_confirm = "OK"
alt_article = ""
wiki_explanation = ""
elif answer.upper() == "KEIN WIKIPEDIA-EINTRAG VORHANDEN.":
wiki_confirm = ""
alt_article = "Kein Wikipedia-Eintrag vorhanden."
wiki_explanation = ""
elif answer.startswith("Alternativer Wikipedia-Artikel vorgeschlagen:"):
parts = answer.split(":", 1)[1].split("|")
alt_article = parts[0].strip() if len(parts) > 0 else "k.A."
wiki_explanation = parts[2].strip() if len(parts) > 2 else ""
wiki_confirm = "X"
else:
wiki_confirm = ""
alt_article = answer
wiki_explanation = answer
try:
main_sheet.update(values=[[wiki_confirm]], range_name=f"S{current_row}")
main_sheet.update(values=[[alt_article]], range_name=f"T{current_row}")
main_sheet.update(values=[[wiki_explanation]], range_name=f"U{current_row}")
main_sheet.update(values=[["", "", "", ""]], range_name=f"V{current_row}:Y{current_row}")
debug_print(f"Zeile {current_row} verifiziert: Antwort: {answer}")
except Exception as e:
debug_print(f"Fehler beim Updaten der Zeile {current_row}: {e}")
time.sleep(Config.RETRY_DELAY)
# ==================== List Metatitel, Description und Überschriften aus Websiten aus ====================