v1.4.9: Verbesserte Wikipedia-Konsistenzprüfung und erweiterte Log-Ausgaben für Website-Scraping
- Implementiert die Funktion is_valid_company_article(), die Wikipedia-Kategorien auf das Stichwort "unternehmen" (und Synonyme) überprüft. - In evaluate_branche_chatgpt() wird nun geprüft, ob Wiki-Kategorien "unternehmen" enthalten; falls nicht, wird die Website-Zusammenfassung als Fallback genutzt. - Debug-Ausgaben im Website-Scraping-Bereich (_process_single_row) wurden erweitert, um den extrahierten Rohtext (erste 100 Zeichen) aus Spalte AR und die Zusammenfassung in AS zu protokollieren. - Dies soll helfen, falsche Wikipedia-Artikel zu erkennen und den Fallback-Mechanismus zu verbessern.
This commit is contained in:
@@ -1,17 +1,19 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""
|
"""
|
||||||
Version: v1.4.8
|
Version: v1.4.9
|
||||||
Datum: {aktuelles Datum}
|
Datum: {aktuelles Datum}
|
||||||
Git-Überschrift (max. 100 Zeichen):
|
Git-Überschrift (max. 100 Zeichen):
|
||||||
v1.4.8 Verbesserter Website-Scraper: User-Agent gesetzt und SSL-Verifikation optional
|
v1.4.9: Verbesserte Wikipedia-Konsistenzprüfung und erweiterte Log-Ausgaben für Website-Scraping
|
||||||
|
|
||||||
|
|
||||||
Git-Änderungsbeschreibung:
|
Git-Änderungsbeschreibung:
|
||||||
- In get_website_raw() wurde ein User-Agent-Header hinzugefügt, um Blockaden zu vermeiden.
|
- Implementiert die Funktion is_valid_company_article(), die Wikipedia-Kategorien auf
|
||||||
- SSL-Zertifikatüberprüfung kann jetzt optional durch den Parameter verify_cert deaktiviert werden (Standard: False).
|
das Stichwort "unternehmen" (und Synonyme) überprüft.
|
||||||
- Zusätzliche Debug-Ausgaben protokollieren den Statuscode und erste 100 Zeichen des extrahierten Textes.
|
- In evaluate_branche_chatgpt() wird nun geprüft, ob Wiki-Kategorien "unternehmen" enthalten;
|
||||||
- Damit wird sichergestellt, dass beim Fehlen eines Wikipedia-Eintrags der Website-Fallback besser analysiert werden kann.
|
falls nicht, wird die Website-Zusammenfassung als Fallback genutzt.
|
||||||
|
- Debug-Ausgaben im Website-Scraping-Bereich (_process_single_row) wurden erweitert,
|
||||||
|
um den extrahierten Rohtext (erste 100 Zeichen) aus Spalte AR und die Zusammenfassung in AS zu protokollieren.
|
||||||
|
- Dies soll helfen, falsche Wikipedia-Artikel zu erkennen und den Fallback-Mechanismus zu verbessern.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -37,7 +39,7 @@ except ImportError:
|
|||||||
|
|
||||||
# ==================== KONFIGURATION ====================
|
# ==================== KONFIGURATION ====================
|
||||||
class Config:
|
class Config:
|
||||||
VERSION = "v1.4.8"
|
VERSION = "v1.4.9"
|
||||||
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"
|
||||||
@@ -98,6 +100,27 @@ def simple_normalize_url(url):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return "k.A."
|
return "k.A."
|
||||||
|
|
||||||
|
def is_valid_company_article(wiki_categories):
|
||||||
|
"""
|
||||||
|
Prüft, ob in den Wikipedia-Kategorien ein Hinweis auf einen Unternehmensartikel enthalten ist.
|
||||||
|
Wir suchen nach den Stichwörtern 'unternehmen', 'firma', 'betrieb' und 'konzern'.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
wiki_categories (str): Die Liste oder der String der Wikipedia-Kategorien.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True, wenn eines der Keywords gefunden wird, sonst False.
|
||||||
|
"""
|
||||||
|
if wiki_categories == "k.A.":
|
||||||
|
return False
|
||||||
|
keywords = ["unternehmen", "firma", "betrieb", "konzern"]
|
||||||
|
wiki_cats_lower = wiki_categories.lower()
|
||||||
|
for word in keywords:
|
||||||
|
if word in wiki_cats_lower:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def serp_website_lookup(company_name):
|
def serp_website_lookup(company_name):
|
||||||
"""
|
"""
|
||||||
Ermittelt über SERPAPI (Google-Suche) die Website zum Unternehmen.
|
Ermittelt über SERPAPI (Google-Suche) die Website zum Unternehmen.
|
||||||
@@ -971,6 +994,22 @@ class WikipediaScraper:
|
|||||||
|
|
||||||
# ==================== NEUE FUNKTION: Angepasste evaluate_branche_chatgpt ====================
|
# ==================== NEUE FUNKTION: Angepasste evaluate_branche_chatgpt ====================
|
||||||
def evaluate_branche_chatgpt(crm_branche, beschreibung, wiki_branche, wiki_kategorien, website_summary):
|
def evaluate_branche_chatgpt(crm_branche, beschreibung, wiki_branche, wiki_kategorien, website_summary):
|
||||||
|
"""
|
||||||
|
Ordnet basierend auf den angegebenen Daten das Unternehmen exakt einer Branche aus dem Ziel-Branchenschema zu.
|
||||||
|
Falls kein passender Wikipedia-Artikel vorliegt bzw. die Kategorien nicht aussagekräftig sind
|
||||||
|
(d.h. das Stichwort 'unternehmen' fehlt), wird die Website-Zusammenfassung als Fallback genutzt.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
crm_branche (str): Branche aus CRM-Daten (Spalte F).
|
||||||
|
beschreibung (str): Externe oder CRM-Beschreibung (Spalte G).
|
||||||
|
wiki_branche (str): Wikipedia-Branche (Spalte N).
|
||||||
|
wiki_kategorien (str): Wikipedia-Kategorien (Spalte Q).
|
||||||
|
website_summary (str): Zusammenfassung des Website-Contents als Fallback.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: {"branch": <vorgeschlagene Branche>, "consistency": <"ok" oder "X">, "justification": <Begründung>}
|
||||||
|
"""
|
||||||
|
# Hilfsfunktion zum Laden des Ziel-Branchenschemas
|
||||||
def load_target_branches():
|
def load_target_branches():
|
||||||
try:
|
try:
|
||||||
with open("ziel_Branchenschema.csv", "r", encoding="utf-8") as csvfile:
|
with open("ziel_Branchenschema.csv", "r", encoding="utf-8") as csvfile:
|
||||||
@@ -980,6 +1019,7 @@ def evaluate_branche_chatgpt(crm_branche, beschreibung, wiki_branche, wiki_kateg
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
debug_print(f"Fehler beim Laden des Ziel-Branchenschemas: {e}")
|
debug_print(f"Fehler beim Laden des Ziel-Branchenschemas: {e}")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
target_branches = load_target_branches()
|
target_branches = load_target_branches()
|
||||||
target_branches_str = "\n".join(target_branches)
|
target_branches_str = "\n".join(target_branches)
|
||||||
focus_branches = [
|
focus_branches = [
|
||||||
@@ -1000,17 +1040,10 @@ def evaluate_branche_chatgpt(crm_branche, beschreibung, wiki_branche, wiki_kateg
|
|||||||
"Versorger > Telekommunikation"
|
"Versorger > Telekommunikation"
|
||||||
]
|
]
|
||||||
focus_branches_str = "\n".join(focus_branches)
|
focus_branches_str = "\n".join(focus_branches)
|
||||||
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 (Branche): {e}")
|
|
||||||
return {"branch": "k.A.", "consistency": "k.A.", "justification": "k.A."}
|
|
||||||
openai.api_key = api_key
|
|
||||||
|
|
||||||
# Angepasst: Sobald kein Wikipedia-Artikel (Wiki-Branche) vorhanden ist, wird die Website-Zusammenfassung als Fallback genutzt.
|
# Wenn kein Wikipedia-Artikel vorhanden oder die Kategorien nicht aussagekräftig sind, fallback auf die Website-Zusammenfassung.
|
||||||
if wiki_branche.strip().lower() == "k.a.":
|
if wiki_branche.strip().lower() == "k.a." or not is_valid_company_article(wiki_kategorien):
|
||||||
debug_print("Kein Wikipedia-Artikel vorhanden – verwende Website-Zusammenfassung als Branchenbeschreibung-Fallback.")
|
debug_print("Keine aussagekräftigen Wikipedia-Kategorien – verwende Website-Zusammenfassung als Fallback.")
|
||||||
used_description = website_summary
|
used_description = website_summary
|
||||||
else:
|
else:
|
||||||
used_description = beschreibung
|
used_description = beschreibung
|
||||||
@@ -1038,7 +1071,7 @@ def evaluate_branche_chatgpt(crm_branche, beschreibung, wiki_branche, wiki_kateg
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
response = openai.ChatCompletion.create(
|
response = openai.ChatCompletion.create(
|
||||||
model="gpt-3.5-turbo",
|
model=Config.TOKEN_MODEL,
|
||||||
messages=[{"role": "system", "content": system_prompt}],
|
messages=[{"role": "system", "content": system_prompt}],
|
||||||
temperature=0.0
|
temperature=0.0
|
||||||
)
|
)
|
||||||
@@ -1068,6 +1101,7 @@ def evaluate_branche_chatgpt(crm_branche, beschreibung, wiki_branche, wiki_kateg
|
|||||||
return {"branch": "k.A.", "consistency": "k.A.", "justification": "k.A."}
|
return {"branch": "k.A.", "consistency": "k.A.", "justification": "k.A."}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def evaluate_servicetechnicians_estimate(company_name, company_data):
|
def evaluate_servicetechnicians_estimate(company_name, company_data):
|
||||||
try:
|
try:
|
||||||
with open("serpApiKey.txt", "r") as f:
|
with open("serpApiKey.txt", "r") as f:
|
||||||
@@ -1219,25 +1253,23 @@ def _process_single_row(self, row_num, row_data, process_wiki=True, process_chat
|
|||||||
website_raw = "k.A."
|
website_raw = "k.A."
|
||||||
website_summary = "k.A."
|
website_summary = "k.A."
|
||||||
if website_url.strip() != "" and website_url.strip().lower() != "k.a.":
|
if website_url.strip() != "" and website_url.strip().lower() != "k.a.":
|
||||||
# Extrahiere den Rohtext der Website
|
|
||||||
website_raw = get_website_raw(website_url)
|
website_raw = get_website_raw(website_url)
|
||||||
# Erstelle eine Zusammenfassung des Website-Contents
|
|
||||||
website_summary = summarize_website_content(website_raw)
|
website_summary = summarize_website_content(website_raw)
|
||||||
try:
|
try:
|
||||||
self.sheet_handler.sheet.update(values=[[website_raw]], range_name=f"AR{row_num}")
|
self.sheet_handler.sheet.update(values=[[website_raw]], range_name=f"AR{row_num}")
|
||||||
debug_print(f"Zeile {row_num}: Spalte AR Update erfolgreich.")
|
debug_print(f"Zeile {row_num}: Spalte AR Update erfolgreich – Auszug: {website_raw[:100]}...")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
debug_print(f"Zeile {row_num}: Fehler beim Update von Spalte AR: {e}")
|
debug_print(f"Zeile {row_num}: Fehler beim Update von Spalte AR: {e}")
|
||||||
try:
|
try:
|
||||||
self.sheet_handler.sheet.update(values=[[website_summary]], range_name=f"AS{row_num}")
|
self.sheet_handler.sheet.update(values=[[website_summary]], range_name=f"AS{row_num}")
|
||||||
debug_print(f"Zeile {row_num}: Spalte AS Update erfolgreich.")
|
debug_print(f"Zeile {row_num}: Spalte AS Update erfolgreich – Zusammenfassung: {website_summary}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
debug_print(f"Zeile {row_num}: Fehler beim Update von Spalte AS: {e}")
|
debug_print(f"Zeile {row_num}: Fehler beim Update von Spalte AS: {e}")
|
||||||
debug_print(f"Zeile {row_num}: Website-Daten gescrapt. Rohtext (Länge {len(website_raw)}): {website_raw[:100]}..., Zusammenfassung: {website_summary}")
|
debug_print(f"Zeile {row_num}: Website-Daten gescrapt. Rohtext Länge: {len(website_raw)}, Zusammenfassung: {website_summary}")
|
||||||
else:
|
else:
|
||||||
debug_print(f"Zeile {row_num}: Kein gültiger Website-URL vorhanden, Website-Scraping wird übersprungen.")
|
debug_print(f"Zeile {row_num}: Kein gültiger Website-URL vorhanden, Website-Scraping wird übersprungen.")
|
||||||
|
|
||||||
# Weiterer Verarbeitungsteil: Wikipedia-Verarbeitung (falls process_wiki True)
|
# Wikipedia-Verarbeitung (falls process_wiki True)
|
||||||
wiki_update_range = f"L{row_num}:R{row_num}"
|
wiki_update_range = f"L{row_num}:R{row_num}"
|
||||||
dt_wiki_range = f"AN{row_num}"
|
dt_wiki_range = f"AN{row_num}"
|
||||||
company_data = {}
|
company_data = {}
|
||||||
@@ -1308,14 +1340,13 @@ def _process_single_row(self, row_num, row_data, process_wiki=True, process_chat
|
|||||||
self.sheet_handler.sheet.update(values=[[emp_consistency]], range_name=f"AC{row_num}")
|
self.sheet_handler.sheet.update(values=[[emp_consistency]], range_name=f"AC{row_num}")
|
||||||
revenue_result = evaluate_umsatz_chatgpt(company_name, company_data.get('umsatz', 'k.A.'))
|
revenue_result = evaluate_umsatz_chatgpt(company_name, company_data.get('umsatz', 'k.A.'))
|
||||||
self.sheet_handler.sheet.update(values=[[revenue_result]], range_name=f"AG{row_num}")
|
self.sheet_handler.sheet.update(values=[[revenue_result]], range_name=f"AG{row_num}")
|
||||||
# Hier NICHT mehr neu einlesen! Verwende die bereits extrahierten Website-Daten.
|
|
||||||
total_tokens = f"Wiki: {token_count(str(company_data.get('first_paragraph', '')))}, Chat: {token_count(crm_data + wiki_data_str)}, Emp: {token_count(str(emp_estimate))}"
|
total_tokens = f"Wiki: {token_count(str(company_data.get('first_paragraph', '')))}, Chat: {token_count(crm_data + wiki_data_str)}, Emp: {token_count(str(emp_estimate))}"
|
||||||
self.sheet_handler.sheet.update(values=[[total_tokens]], range_name=f"AQ{row_num}")
|
self.sheet_handler.sheet.update(values=[[total_tokens]], range_name=f"AQ{row_num}")
|
||||||
self.sheet_handler.sheet.update(values=[[datetime.now().strftime('%Y-%m-%d %H:%M:%S')]], range_name=dt_chat_range)
|
self.sheet_handler.sheet.update(values=[[datetime.now().strftime('%Y-%m-%d %H:%M:%S')]], range_name=dt_chat_range)
|
||||||
else:
|
else:
|
||||||
debug_print(f"Zeile {row_num}: ChatGPT-Timestamp bereits gesetzt – überspringe ChatGPT-Auswertung.")
|
debug_print(f"Zeile {row_num}: ChatGPT-Timestamp bereits gesetzt – überspringe ChatGPT-Auswertung.")
|
||||||
|
|
||||||
# Aktualisiere den Timestamp für die letzte Prüfung und die Version
|
# Aktualisiere Timestamp und Version
|
||||||
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=ver_range)
|
self.sheet_handler.sheet.update(values=[[current_dt]], range_name=ver_range)
|
||||||
self.sheet_handler.sheet.update(values=[[Config.VERSION]], range_name=ver_range)
|
self.sheet_handler.sheet.update(values=[[Config.VERSION]], range_name=ver_range)
|
||||||
@@ -1328,6 +1359,7 @@ def _process_single_row(self, row_num, row_data, process_wiki=True, process_chat
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ==================== ALIGNMENT DEMO FÜR HAUPTBLATT UND CONTACTS ====================
|
# ==================== ALIGNMENT DEMO FÜR HAUPTBLATT UND CONTACTS ====================
|
||||||
def alignment_demo_full():
|
def alignment_demo_full():
|
||||||
alignment_demo(GoogleSheetHandler().sheet)
|
alignment_demo(GoogleSheetHandler().sheet)
|
||||||
|
|||||||
Reference in New Issue
Block a user