dealfront_enrichment.py aktualisiert
This commit is contained in:
@@ -81,11 +81,10 @@ class DealfrontScraper:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Konnte Debug-Artefakte nicht speichern: {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.
|
Führt den Login durch UND navigiert direkt zur Target-Seite.
|
||||||
Diese Version wartet explizit auf jedes Element und verwendet
|
Gibt nur True zurück, wenn BEIDE Schritte erfolgreich sind.
|
||||||
die verifizierten Selektoren aus dem HTML-Dump.
|
|
||||||
"""
|
"""
|
||||||
if not self.driver:
|
if not self.driver:
|
||||||
return False
|
return False
|
||||||
@@ -95,46 +94,49 @@ class DealfrontScraper:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
# --- SCHRITT 1: LOGIN ---
|
||||||
logger.info(f"Navigiere zur Login-Seite: {DEALFRONT_LOGIN_URL}")
|
logger.info(f"Navigiere zur Login-Seite: {DEALFRONT_LOGIN_URL}")
|
||||||
self.driver.get(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']")
|
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 = self.wait.until(EC.visibility_of_element_located(email_selector))
|
||||||
email_field.send_keys(username)
|
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']")
|
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 = self.wait.until(EC.visibility_of_element_located(password_selector))
|
||||||
password_field.send_keys(password)
|
password_field.send_keys(password)
|
||||||
logger.info("Passwort-Feld gefunden und ausgefüllt.")
|
|
||||||
|
login_button_selector = (By.XPATH, "//button[normalize-space()='Log in']")
|
||||||
# --- 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 = self.wait.until(EC.element_to_be_clickable(login_button_selector))
|
login_button = self.wait.until(EC.element_to_be_clickable(login_button_selector))
|
||||||
login_button.click()
|
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
|
return True
|
||||||
|
|
||||||
except Exception as e:
|
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()
|
self._save_debug_artifacts()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def navigate_to_target(self):
|
def navigate_to_target(self):
|
||||||
"""
|
"""
|
||||||
Navigiert zum 'Target'-Bereich und verifiziert den Erfolg in drei Schritten.
|
Navigiert zum 'Target'-Bereich und verifiziert den Erfolg in drei Schritten.
|
||||||
@@ -232,7 +234,7 @@ class DealfrontScraper:
|
|||||||
self.driver.quit()
|
self.driver.quit()
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
logger.info("Starte Dealfront Automatisierung - MAXIMALER DEBUG-MODUS")
|
logger.info("Starte Dealfront Automatisierung - Phase 2a: Suche und Extraktion")
|
||||||
|
|
||||||
scraper = None
|
scraper = None
|
||||||
try:
|
try:
|
||||||
@@ -240,46 +242,32 @@ if __name__ == "__main__":
|
|||||||
if not scraper.driver:
|
if not scraper.driver:
|
||||||
raise Exception("WebDriver konnte nicht initialisiert werden.")
|
raise Exception("WebDriver konnte nicht initialisiert werden.")
|
||||||
|
|
||||||
# --- SCHRITT 1: LOGIN ---
|
# Führe den kombinierten Login- und Navigationsschritt aus
|
||||||
if not scraper.login():
|
if not scraper.login_and_navigate_to_target():
|
||||||
raise Exception("Login fehlgeschlagen.")
|
raise Exception("Login und Navigation 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)
|
|
||||||
|
|
||||||
logger.info(f"URL nach Navigationsversuch: {scraper.driver.current_url}")
|
# Suche laden
|
||||||
logger.info("Speichere Debug-Artefakte NACH dem Navigationsversuch...")
|
if not scraper.load_search(Config.TARGET_SEARCH_NAME):
|
||||||
scraper._save_debug_artifacts() # Wir erzwingen hier einen Dump, um den Zustand zu sehen
|
raise Exception(f"Laden der Suche '{Config.TARGET_SEARCH_NAME}' fehlgeschlagen.")
|
||||||
|
|
||||||
# --- SCHRITT 3: VERIFIZIERUNG VERSUCHEN ---
|
|
||||||
logger.info("Versuche jetzt, die Target-Seite zu verifizieren...")
|
|
||||||
|
|
||||||
# Warten, bis die URL sich tatsächlich ändert.
|
# Ergebnisse extrahieren
|
||||||
url_part_to_wait_for = "/t/prospector/"
|
companies = scraper.extract_current_page_results()
|
||||||
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}")
|
|
||||||
|
|
||||||
# Warten auf sichtbares Element auf der neuen Seite.
|
if companies:
|
||||||
verification_selector = (By.XPATH, "//button[normalize-space()='+ Neue Suche']")
|
logger.info("===== Extrahierte Firmen (erste Seite) =====")
|
||||||
logger.info(f"Warte auf Sichtbarkeit des Verifizierungs-Elements: {verification_selector}")
|
for company in companies:
|
||||||
scraper.wait.until(EC.visibility_of_element_located(verification_selector))
|
logger.info(f" - Name: {company['name']}, Webseite: {company['website']}")
|
||||||
logger.info("Verifizierung der Target-Seite ERFOLGREICH!")
|
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:
|
except Exception as e:
|
||||||
logger.critical(f"Ein kritischer Fehler ist im Hauptprozess aufgetreten: {type(e).__name__} - {e}", exc_info=True)
|
logger.critical(f"Ein kritischer Fehler ist im Hauptprozess aufgetreten: {e}", exc_info=False)
|
||||||
# Der Screenshot wird schon in der Methode oder im try-Block gespeichert.
|
|
||||||
finally:
|
finally:
|
||||||
if scraper:
|
if scraper:
|
||||||
logger.info("Warte 10 Sekunden vor dem Schließen des Browsers...")
|
|
||||||
time.sleep(10)
|
|
||||||
scraper.close()
|
scraper.close()
|
||||||
|
|
||||||
logger.info("Dealfront Debugging-Lauf beendet.")
|
logger.info("Dealfront Automatisierung beendet.")
|
||||||
Reference in New Issue
Block a user