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:
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user