v1.4.6 Neue Website-Funktionen: SERP Lookup & Detail-Scraper integriert

- Modus 22: Neue Funktion 'serp_website_lookup' ermittelt per SERPAPI die Website, wenn CRM-Daten fehlen.
- Neue Funktion 'scrape_website_details' extrahiert Seitentitel, Meta-Description und h1/h2/h3-Überschriften.
- Beide Funktionen werden als Testmodule bereitgestellt und können in das Gesamtworkflow integriert werden.
- Main und Betriebsmodus-Menü wurden um die neuen Modi ergänzt.
- Alignment-Demo um neue Spalten erweitert
This commit is contained in:
2025-04-08 18:24:46 +00:00
parent 1d6c0c4b5a
commit 824f521dc0

View File

@@ -241,6 +241,48 @@ def summarize_website_content(raw_text):
debug_print(f"Fehler beim Erstellen der Website-Zusammenfassung: {e}")
return "k.A."
# ==================== NEUE FUNKTION: Website-Suche bei fehlender Website ====================
def serp_website_lookup(company_name):
"""
Ermittelt über SERPAPI (Google-Suche) die Website zum Unternehmen.
- Verwendet als Query den Firmennamen.
- Filtert Ergebnisse anhand einer Blacklist (z.B. bloomberg.com, northdata.de).
Returns:
Die gefundene Website-URL oder "k.A.", falls kein passendes Ergebnis gefunden wurde.
"""
# Blacklist von Domains, die wir nicht verwenden wollen
blacklist = ["bloomberg.com", "northdata.de", "finanzen.net", "handelsblatt.com"]
try:
with open("serpApiKey.txt", "r") as f:
serp_key = f.read().strip()
except Exception as e:
debug_print(f"Fehler beim Lesen des SerpAPI-Schlüssels: {e}")
return "k.A."
query = f"{company_name} Website"
params = {
"engine": "google",
"q": query,
"api_key": serp_key,
"hl": "de"
}
try:
response = requests.get("https://serpapi.com/search", params=params, timeout=10)
data = response.json()
if "organic_results" in data:
for result in data["organic_results"]:
# Extrahiere URL und prüfe, ob sie in der Blacklist enthalten ist
url = result.get("link", "")
if url and not any(black_item in url for black_item in blacklist):
debug_print(f"SERP-Website Lookup: Gefundene Website '{url}' für {company_name}")
return url
return "k.A."
except Exception as e:
debug_print(f"Fehler beim SERP-API Website Lookup für {company_name}: {e}")
return "k.A."
# ==================== NEUE FUNKTION: process_verification_only ====================
def process_verification_only():
debug_print("Starte Verifizierungsmodus (Modus 51) im Batch-Prozess...")
@@ -347,6 +389,52 @@ def process_verification_only():
time.sleep(Config.RETRY_DELAY)
debug_print("Verifizierungs-Batch abgeschlossen.")
# ==================== List Metatitel, Description und Überschriften aus Websiten aus ====================
def scrape_website_details(url):
"""
Ruft die Website ab und extrahiert:
- den Seitentitel (aus <title> im Kopfbereich),
- die Meta-Description (<meta name="description">),
- alle Überschriften h1, h2, h3 als zusammengefassten Text.
Returns:
Ein Dictionary mit den Schlüsseln "title", "description" und "headers".
Falls ein Element nicht gefunden wird, wird "k.A." zurückgegeben.
"""
# Falls URL kein Schema besitzt, ergänze "https://"
if not url.lower().startswith("http"):
url = "https://" + url
try:
response = requests.get(url, timeout=10)
soup = BeautifulSoup(response.text, Config.HTML_PARSER)
# Seitentitel
title_tag = soup.find("title")
title = title_tag.get_text().strip() if title_tag else "k.A."
# Meta-Description
meta_desc = soup.find("meta", attrs={"name": "description"})
description = meta_desc["content"].strip() if meta_desc and meta_desc.get("content") else "k.A."
# Überschriften h1, h2, h3
headers = []
for tag in ['h1', 'h2', 'h3']:
for header in soup.find_all(tag):
header_text = header.get_text().strip()
if header_text:
headers.append(f"{tag.upper()}: {header_text}")
headers_text = "\n".join(headers) if headers else "k.A."
# Rückgabe als Dictionary
return {
"title": title,
"description": description,
"headers": headers_text
}
except Exception as e:
debug_print(f"Fehler beim Scrapen der Website {url}: {e}")
return {"title": "k.A.", "description": "k.A.", "headers": "k.A."}
# ==================== ALIGNMENT DEMO (Hauptblatt) ====================
def alignment_demo(sheet):
new_headers = [
@@ -454,7 +542,7 @@ def alignment_demo(sheet):
"Schätzung Anzahl Mitarbeiter via ChatGPT (nur falls Wiki-Daten fehlen).",
"Vergleich CRM vs. Wiki vs. ChatGPT Mitarbeiterzahl (OK/X).",
"Begründung bei Mitarbeiterabweichung (Prozentdifferenz).",
"Schätzung Servicetechniker via ChatGPT (in Kategorien, z.B. <50, >100 etc.).",
"Schätzung Servicetechniker via ChatGPT (in Kategorien, z.B. <50, >100, >200, >500).",
"Begründung bei Abweichung der Technikerzahl.",
"Schätzung Umsatz via ChatGPT.",
"Begründung bei Umsatzabweichung.",
@@ -520,6 +608,7 @@ def alignment_demo(sheet):
sheet.update(values=new_headers, range_name=header_range)
print("Alignment-Demo abgeschlossen: Neues Spaltenschema in Zeilen A1 bis AS5 geschrieben.")
# ==================== WIKIPEDIA SCRAPER ====================
class WikipediaScraper:
def __init__(self):