From 68726646018c739cb153799a1e6501cb4f6c3839 Mon Sep 17 00:00:00 2001 From: Floke Date: Wed, 9 Apr 2025 17:20:40 +0000 Subject: [PATCH] bugfix --- brancheneinstufung.py | 134 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 127 insertions(+), 7 deletions(-) diff --git a/brancheneinstufung.py b/brancheneinstufung.py index 0242f40e7..ba185c158 100644 --- a/brancheneinstufung.py +++ b/brancheneinstufung.py @@ -1567,6 +1567,123 @@ def count_linkedin_contacts(company_name, website, position_query, crm_kurzform) debug_print(f"Fehler bei der SerpAPI-Suche (Count): {e}") return 0 +def search_linkedin_contact(company_name, website, position_query, crm_kurzform): + """ + Sucht über SERPAPI einen einzelnen LinkedIn-Kontakt basierend auf der Positionsbezeichnung und der CRM-Kurzform des Unternehmens. + Es wird nur ein Treffer zurückgegeben, wenn der Titel auch die CRM-Kurzform (als Teilstring) enthält. + + Args: + company_name (str): Der Firmenname. + website (str): Die Website des Unternehmens. + position_query (str): Die zu suchende Positionsbezeichnung (z. B. "Serviceleiter"). + crm_kurzform (str): Die manuell gepflegte Kurzform des Firmennamens. + + Returns: + dict oder None: Ein Dictionary mit den Kontaktdaten (Vorname, Nachname, Position, LinkedInURL) oder None, falls kein passender Kontakt gefunden wurde. + """ + try: + with open("serpApiKey.txt", "r") as f: + serp_key = f.read().strip() + except Exception as e: + debug_print("Fehler beim Lesen des SerpAPI-Schlüssels: " + str(e)) + return None + + query = f'site:linkedin.com/in "{position_query}" "{company_name}"' + 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 and len(data["organic_results"]) > 0: + # Gehe die Ergebnisse durch und prüfe, ob der Titel den crm_kurzform-String enthält + for result in data["organic_results"]: + title = result.get("title", "") + if crm_kurzform.lower() in title.lower(): + # Aufteilen des Titels in Namens- und Positionsbestandteile + if "–" in title: + parts = title.split("–") + elif "-" in title: + parts = title.split("-") + else: + parts = [title] + if len(parts) >= 2: + name_part = parts[0].strip() + pos_part = parts[1].split("|")[0].strip() + name_parts = name_part.split(" ", 1) + if len(name_parts) == 2: + firstname, lastname = name_parts + else: + firstname = name_part + lastname = "" + linkedin_url = result.get("link", "") # LinkedIn-Profil-Link aus dem Ergebnis + debug_print(f"Gefundener Kontakt: {firstname} {lastname}, Position: {pos_part}") + return { + "Firmenname": company_name, + "Website": website, + "Vorname": firstname, + "Nachname": lastname, + "Position": pos_part, + "LinkedInURL": linkedin_url + } + debug_print("Kein Treffer mit CRM-Kurzform in Titel gefunden.") + return None + else: + debug_print("Keine organic_results für Query gefunden.") + return None + except Exception as e: + debug_print(f"Fehler bei der SerpAPI-Suche: {e}") + return None + +def count_linkedin_contacts(company_name, website, position_query, crm_kurzform): + """ + Zählt über SERPAPI, wieviele LinkedIn-Kontakte für einen bestimmten Positionsbegriff existieren, + wobei als Filter zusätzlich geprüft wird, ob der Titel Teile der CRM-Kurzform enthält. + + Args: + company_name (str): Firmenname. + website (str): Website des Unternehmens. + position_query (str): Gewünschte Position (z. B. "Serviceleiter"). + crm_kurzform (str): Kurzform des Firmennamens. + + Returns: + int: Anzahl der Treffer, die den Filter erfüllen. + """ + try: + with open("serpApiKey.txt", "r") as f: + serp_key = f.read().strip() + except Exception as e: + debug_print("Fehler beim Lesen des SerpAPI-Schlüssels: " + str(e)) + return 0 + + query = f'site:linkedin.com/in "{position_query}" "{company_name}"' + 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() + count = 0 + if "organic_results" in data: + for result in data["organic_results"]: + title = result.get("title", "") + if crm_kurzform.lower() in title.lower(): + count += 1 + debug_print(f"Anzahl Kontakte für Query '{query}' mit CRM-Kurzform-Filter: {count}") + return count + else: + debug_print(f"Keine Ergebnisse für Query: {query}") + return 0 + except Exception as e: + debug_print(f"Fehler bei der SerpAPI-Suche (Count): {e}") + return 0 + def process_contact_research(): """ Sucht mithilfe der SerpAPI Kontakte für bestimmte Positionen für jedes Unternehmen. @@ -1598,14 +1715,15 @@ def process_contact_research(): debug_print("Keine neuen Zeilen zu verarbeiten, da Timestamp in Spalte AM bereits bis zum Ende vorhanden ist.") return - # Versuche, das Kontakte-Tabellenblatt zu öffnen; falls nicht vorhanden, erstelle es + # Versuche, das Kontakte-Blatt zu öffnen; falls nicht vorhanden, erstelle es try: contacts_sheet = sh.worksheet("Contacts") except gspread.exceptions.WorksheetNotFound: contacts_sheet = sh.add_worksheet(title="Contacts", rows="1000", cols="10") - # Header um eine zusätzliche Spalte für Suchbegriffskategorie erweitert - header = ["Firmenname", "CRM Kurzform", "Website", "Vorname", "Nachname", "Position", "Suchbegriffskategorie", "Timestamp"] - contacts_sheet.update(values=[header], range_name="A1:H1") + # Header um eine zusätzliche Spalte für Suchbegriffskategorie, LinkedIn-Link und Timestamp angepasst + header = ["Firmenname", "CRM Kurzform", "Website", "Vorname", "Nachname", "Position", + "Suchbegriffskategorie", "LinkedIn-Link", "Timestamp"] + contacts_sheet.update(values=[header], range_name="A1:I1") debug_print("Neues Blatt 'Contacts' erstellt und Header eingetragen.") # Verarbeite jede Zeile im Hauptblatt ab der festgelegten Startzeile @@ -1627,7 +1745,8 @@ def process_contact_research(): # Suche und speichere den ersten passenden Kontakt contact = search_linkedin_contact(crm_kurzform, website, pos, crm_kurzform) if contact: - # Hänge den Kontakt im Kontakte-Blatt an; hier wird in Spalte G der Suchbegriff und in Spalte H der Timestamp eingetragen + # In Spalte G wird der Suchbegriff (Kategorie) eingetragen, + # in Spalte H der LinkedIn-Link und in Spalte I der Timestamp. timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") contact_row = [ company_name, @@ -1636,8 +1755,9 @@ def process_contact_research(): contact.get("Vorname", ""), contact.get("Nachname", ""), contact.get("Position", ""), - pos, # Suchbegriffskategorie - timestamp # Timestamp + pos, # Suchbegriffskategorie in Spalte G + contact.get("LinkedInURL", ""), # LinkedIn-Link in Spalte H + timestamp # Timestamp in Spalte I ] try: contacts_sheet.append_row(contact_row)