From 5f5605c1e244c6513db8cacdf0166fa98127d3f3 Mon Sep 17 00:00:00 2001 From: Floke Date: Fri, 4 Jul 2025 04:46:11 +0000 Subject: [PATCH] dealfront_enrichment.py aktualisiert --- dealfront_enrichment.py | 68 ++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 39 deletions(-) diff --git a/dealfront_enrichment.py b/dealfront_enrichment.py index b01d3ce4..301913bd 100644 --- a/dealfront_enrichment.py +++ b/dealfront_enrichment.py @@ -84,47 +84,45 @@ 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 durch, indem menschliches Verhalten simuliert wird: - 1. Seite laden. - 2. Warten bis URL korrekt ist. - 3. Warten bis Formular da ist. - 4. Ausfüllen und klicken. + Führt den Login durch und klickt dann auf dem Dashboard auf den + "Quick Link", um zur Target-Seite zu gelangen. """ if not self.driver: return False username, password = self._load_credentials() if not username or not password: return False try: - # SCHRITT 1: SEITE LADEN + # SCHRITT 1: LOGIN logger.info(f"Navigiere zur Login-Seite: {DEALFRONT_LOGIN_URL}") self.driver.get(DEALFRONT_LOGIN_URL) + + self.wait.until(EC.visibility_of_element_located((By.NAME, "email"))).send_keys(username) + self.driver.find_element(By.CSS_SELECTOR, "input[type='password']").send_keys(password) + self.driver.find_element(By.XPATH, "//button[normalize-space()='Log in']").click() + logger.info("Login-Befehl gesendet.") - # SCHRITT 2: VERIFIZIEREN, DASS DIE SEITE VOLLSTÄNDIG GELADEN IST - # Wir warten darauf, dass die URL in der Adressleiste die Login-URL enthält. - # Das ist ein starkes Indiz, dass die Seite nicht im Ladezustand festhängt. - self.wait.until(EC.url_contains("login")) - logger.info("Login-Seite URL erfolgreich bestätigt. Warte kurz, damit die Seite rendern kann...") - time.sleep(3) # Kurze Atempause für die Seite - - # SCHRITT 3: FORMULAR FINDEN UND AUSFÜLLEN - logger.info("Suche nach dem E-Mail-Eingabefeld...") - email_field = self.wait.until(EC.visibility_of_element_located((By.NAME, "email"))) - logger.info("E-Mail-Feld gefunden. Fülle Formulardaten aus.") - email_field.send_keys(username) + # SCHRITT 2: AUF QUICK-LINK-KACHEL WARTEN UND KLICKEN + logger.info("Warte auf Dashboard und 'Prospects finden'-Link in den Quick Links.") - password_field = self.driver.find_element(By.CSS_SELECTOR, "input[type='password']") - password_field.send_keys(password) + # Dieser XPath ist sehr spezifisch für den Link in der "Quick links"-Kachel + prospects_link_selector = (By.XPATH, "//a[@data-test-target-product-tile]") + prospects_link = self.wait.until(EC.element_to_be_clickable(prospects_link_selector)) - login_button = self.driver.find_element(By.XPATH, "//button[normalize-space()='Log in']") - login_button.click() + logger.info("'Prospects finden'-Link gefunden. Klicke darauf...") + prospects_link.click() - logger.info("Login-Befehl gesendet. Die Seite sollte nun weiterleiten.") + # SCHRITT 3: NAVIGATION VERIFIZIEREN + logger.info("Warte auf die finale Target-Seite...") + 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"Login-Prozess ist fehlgeschlagen: {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 @@ -249,7 +247,7 @@ class DealfrontScraper: self.driver.quit() if __name__ == "__main__": - logger.info("Starte Dealfront Automatisierung - Rekonstruierter Workflow") + logger.info("Starte Dealfront Automatisierung - Finaler Workflow") scraper = None try: @@ -257,19 +255,11 @@ 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.") + # === EINZIGER AUFRUF FÜR LOGIN UND NAVIGATION === + if not scraper.login_and_navigate_to_target(): + raise Exception("Login und Navigation fehlgeschlagen.") - # Kurze Pause, um der Weiterleitung nach dem Login eine Chance zu geben. - # Dies ist der einzige 'sleep', den wir brauchen. - time.sleep(5) - - # Schritt 2: Navigation - if not scraper.navigate_to_target(): - raise Exception("Navigation zur Target-Seite fehlgeschlagen.") - - # ... (Rest der main-Funktion mit Suche und Extraktion bleibt gleich) ... + # Ab hier geht es weiter wie geplant... if not scraper.load_search(Config.TARGET_SEARCH_NAME): raise Exception(f"Laden der Suche '{Config.TARGET_SEARCH_NAME}' fehlgeschlagen.")