From 5d83a1df5da2584640a76dd12b5a6c9d1ac6a7de Mon Sep 17 00:00:00 2001 From: Floke Date: Thu, 3 Jul 2025 12:10:20 +0000 Subject: [PATCH] dealfront_enrichment.py aktualisiert --- dealfront_enrichment.py | 108 ++++++++++++++++++---------------------- 1 file changed, 48 insertions(+), 60 deletions(-) diff --git a/dealfront_enrichment.py b/dealfront_enrichment.py index 25d18f29..4bb2c777 100644 --- a/dealfront_enrichment.py +++ b/dealfront_enrichment.py @@ -81,11 +81,10 @@ class DealfrontScraper: except Exception as e: logger.error(f"Konnte Debug-Artefakte nicht speichern: {e}") - def login(self): + def login_and_navigate_to_target(self): """ - Führt den Login-Prozess auf der Dealfront-Plattform durch. - Diese Version wartet explizit auf jedes Element und verwendet - die verifizierten Selektoren aus dem HTML-Dump. + Führt den Login durch UND navigiert direkt zur Target-Seite. + Gibt nur True zurück, wenn BEIDE Schritte erfolgreich sind. """ if not self.driver: return False @@ -95,46 +94,49 @@ class DealfrontScraper: return False try: + # --- SCHRITT 1: LOGIN --- logger.info(f"Navigiere zur Login-Seite: {DEALFRONT_LOGIN_URL}") self.driver.get(DEALFRONT_LOGIN_URL) - - # --- SCHRITT 1: Warten auf das E-Mail-Feld und ausfüllen --- + email_selector = (By.CSS_SELECTOR, "input[name='email']") - logger.debug(f"Warte auf die Sichtbarkeit des E-Mail-Feldes: {email_selector}") email_field = self.wait.until(EC.visibility_of_element_located(email_selector)) email_field.send_keys(username) - logger.info("E-Mail-Feld gefunden und ausgefüllt.") - # --- SCHRITT 2: Warten auf das Passwort-Feld und ausfüllen --- - # KORRIGIERT: Wir verwenden den CSS-Selektor für das 'type'-Attribut, - # da kein 'name'-Attribut vorhanden ist. password_selector = (By.CSS_SELECTOR, "input[type='password']") - logger.debug(f"Warte auf die Sichtbarkeit des Passwort-Feldes: {password_selector}") password_field = self.wait.until(EC.visibility_of_element_located(password_selector)) password_field.send_keys(password) - logger.info("Passwort-Feld gefunden und ausgefüllt.") - - # --- SCHRITT 3: Warten auf den Anmelde-Button und klicken --- - login_button_selector = (By.XPATH, "//button[normalize-space()='Log in']") # Englische Version, falls Sprache umschaltet - logger.debug(f"Warte darauf, dass der Anmelde-Button klickbar ist: {login_button_selector}") + + login_button_selector = (By.XPATH, "//button[normalize-space()='Log in']") login_button = self.wait.until(EC.element_to_be_clickable(login_button_selector)) login_button.click() - logger.info("Anmelde-Button geklickt. Warte auf die Verifizierung...") - - # --- SCHRITT 4: Login-Erfolg verifizieren --- - verification_element_selector = (By.XPATH, "//input[@data-cy='header-search-input']") - logger.debug(f"Warte auf das Verifizierungs-Element: {verification_element_selector}") - self.wait.until(EC.visibility_of_element_located(verification_element_selector)) - logger.info("LOGIN ERFOLGREICH! Dashboard-Element gefunden.") + # Login Verifizierung + verification_login_selector = (By.XPATH, "//input[@data-cy='header-search-input']") + self.wait.until(EC.visibility_of_element_located(verification_login_selector)) + logger.info("Login auf Dashboard erfolgreich verifiziert.") + + # --- SCHRITT 2: DIREKTE NAVIGATION ZUR TARGET-SEITE --- + logger.info(f"Navigiere jetzt direkt zur Target-URL: {Config.DEALFRONT_TARGET_URL}") + self.driver.get(Config.DEALFRONT_TARGET_URL) + + # Navigation Verifizierung + url_part_to_wait_for = "/t/prospector/" + self.wait.until(EC.url_contains(url_part_to_wait_for)) + logger.info(f"URL-Wechsel zu Target bestätigt. Aktuelle URL: {self.driver.current_url}") + + verification_target_selector = (By.XPATH, "//button[normalize-space()='+ Neue Suche']") + self.wait.until(EC.visibility_of_element_located(verification_target_selector)) + logger.info("'Target'-Seite erfolgreich und vollständig geladen.") + return True except Exception as e: - logger.critical(f"Ein Fehler ist während des Logins aufgetreten: {type(e).__name__}", exc_info=True) + logger.critical(f"Login- oder Navigationsprozess fehlgeschlagen: {type(e).__name__}", exc_info=True) self._save_debug_artifacts() return False + def navigate_to_target(self): """ Navigiert zum 'Target'-Bereich und verifiziert den Erfolg in drei Schritten. @@ -232,7 +234,7 @@ class DealfrontScraper: self.driver.quit() if __name__ == "__main__": - logger.info("Starte Dealfront Automatisierung - MAXIMALER DEBUG-MODUS") + logger.info("Starte Dealfront Automatisierung - Phase 2a: Suche und Extraktion") scraper = None try: @@ -240,46 +242,32 @@ if __name__ == "__main__": if not scraper.driver: raise Exception("WebDriver konnte nicht initialisiert werden.") - # --- SCHRITT 1: LOGIN --- - if not scraper.login(): - raise Exception("Login fehlgeschlagen.") - logger.info(f"Login erfolgreich abgeschlossen. Aktuelle URL: {scraper.driver.current_url}") - logger.info("Warte 5 Sekunden, um den Dashboard-Zustand zu stabilisieren...") - time.sleep(5) - - # --- SCHRITT 2: NAVIGATION ZUR TARGET URL --- - logger.info(f"Versuche jetzt, zur Target-URL zu navigieren: {Config.DEALFRONT_TARGET_URL}") - scraper.driver.get(Config.DEALFRONT_TARGET_URL) - logger.info("Navigationsbefehl zur Target-URL wurde gesendet.") - logger.info("Warte 5 Sekunden, damit die Navigation wirken kann...") - time.sleep(5) + # Führe den kombinierten Login- und Navigationsschritt aus + if not scraper.login_and_navigate_to_target(): + raise Exception("Login und Navigation fehlgeschlagen.") - logger.info(f"URL nach Navigationsversuch: {scraper.driver.current_url}") - logger.info("Speichere Debug-Artefakte NACH dem Navigationsversuch...") - scraper._save_debug_artifacts() # Wir erzwingen hier einen Dump, um den Zustand zu sehen - - # --- SCHRITT 3: VERIFIZIERUNG VERSUCHEN --- - logger.info("Versuche jetzt, die Target-Seite zu verifizieren...") + # Suche laden + if not scraper.load_search(Config.TARGET_SEARCH_NAME): + raise Exception(f"Laden der Suche '{Config.TARGET_SEARCH_NAME}' fehlgeschlagen.") - # Warten, bis die URL sich tatsächlich ändert. - url_part_to_wait_for = "/t/prospector/" - logger.info(f"Warte explizit, bis die URL '{url_part_to_wait_for}' enthält...") - scraper.wait.until(EC.url_contains(url_part_to_wait_for)) - logger.info(f"URL-Wechsel bestätigt! Aktuelle URL: {scraper.driver.current_url}") + # Ergebnisse extrahieren + companies = scraper.extract_current_page_results() - # Warten auf sichtbares Element auf der neuen Seite. - verification_selector = (By.XPATH, "//button[normalize-space()='+ Neue Suche']") - logger.info(f"Warte auf Sichtbarkeit des Verifizierungs-Elements: {verification_selector}") - scraper.wait.until(EC.visibility_of_element_located(verification_selector)) - logger.info("Verifizierung der Target-Seite ERFOLGREICH!") + if companies: + logger.info("===== Extrahierte Firmen (erste Seite) =====") + for company in companies: + logger.info(f" - Name: {company['name']}, Webseite: {company['website']}") + logger.info("===========================================") + else: + logger.warning("Keine Firmen auf der ersten Seite extrahiert.") + + logger.info("Phase 2a Test erfolgreich abgeschlossen. Warte vor dem Schließen...") + time.sleep(10) except Exception as e: - logger.critical(f"Ein kritischer Fehler ist im Hauptprozess aufgetreten: {type(e).__name__} - {e}", exc_info=True) - # Der Screenshot wird schon in der Methode oder im try-Block gespeichert. + logger.critical(f"Ein kritischer Fehler ist im Hauptprozess aufgetreten: {e}", exc_info=False) finally: if scraper: - logger.info("Warte 10 Sekunden vor dem Schließen des Browsers...") - time.sleep(10) scraper.close() - logger.info("Dealfront Debugging-Lauf beendet.") \ No newline at end of file + logger.info("Dealfront Automatisierung beendet.") \ No newline at end of file