Ergänzung gehe zu Liste

This commit is contained in:
2025-07-03 11:21:28 +00:00
parent 9196323b61
commit 3d495b9dbd

View File

@@ -134,43 +134,88 @@ class DealfrontScraper:
self._save_debug_artifacts()
return False
def navigate_to_target_list(self, list_name: str):
"""
Navigiert nach dem Login zu einer spezifischen Zielliste im Target-Modul.
:param list_name: Der exakte Name der Zielliste, die angeklickt werden soll.
"""
def navigate_to_target(self):
"""Navigiert zum 'Target'-Bereich der Anwendung."""
try:
# --- SCHRITT 1: Zum Target-Modul navigieren ---
# Wir verwenden die Basis-URL, da die spezifische URL Session-IDs enthalten könnte.
target_url = "https://app.dealfront.com/t"
logger.info(f"Navigiere zum Target-Modul: {target_url}")
self.driver.get(target_url)
# --- SCHRITT 2: Auf die Liste in der Seitenleiste warten und klicken ---
# Wir suchen nach einem Link, dessen Text genau mit dem Listennamen übereinstimmt.
# Dieser XPath ist sehr spezifisch und robust.
list_selector = (By.XPATH, f"//div[contains(@class, 'list-group-item')]//a[normalize-space()='{list_name}']")
logger.debug(f"Warte darauf, dass die Zielliste '{list_name}' klickbar ist.")
logger.info("Navigiere zum 'Target'-Bereich...")
target_button_selector = (By.XPATH, "//a[contains(@class, 'text-base') and .//span[normalize-space()='Target']] | //a[.//div[normalize-space()='Target']]")
target_list_element = self.wait.until(EC.element_to_be_clickable(list_selector))
target_list_element.click()
logger.info(f"Zielliste '{list_name}' erfolgreich angeklickt.")
# --- SCHRITT 3: Warten, bis die Ergebnisseite geladen ist ---
# Wir verifizieren, dass der Header der Tabelle sichtbar ist.
# Ein guter Indikator ist die Spaltenüberschrift "Firma".
results_header_selector = (By.XPATH, "//th[normalize-space()='Firma']")
self.wait.until(EC.visibility_of_element_located(results_header_selector))
logger.info("Ergebnistabelle erfolgreich geladen.")
# Alternative, falls der obere Selektor nicht klappt:
# target_button_selector = (By.CSS_SELECTOR, "a[data-test-product-link-for='Target']")
target_button = self.wait.until(EC.element_to_be_clickable(target_button_selector))
target_button.click()
# Verifizieren, dass die Seite geladen ist, indem wir auf den "+ Neue Suche"-Button warten
new_search_button_selector = (By.XPATH, "//button[normalize-space()='+ Neue Suche']")
self.wait.until(EC.visibility_of_element_located(new_search_button_selector))
logger.info("'Target'-Seite erfolgreich geladen.")
return True
except Exception as e:
logger.critical(f"Fehler beim Navigieren zur Zielliste '{list_name}': {type(e).__name__}", exc_info=True)
logger.critical(f"Navigation zur 'Target'-Seite fehlgeschlagen: {type(e).__name__}", exc_info=True)
self._save_debug_artifacts()
return False
def load_search(self, search_name):
"""Lädt eine vordefinierte Suche anhand ihres Namens."""
try:
logger.info(f"Suche und lade die vordefinierte Suche: '{search_name}'")
# Der XPath sucht nach einem Link, dessen Text den Suchnamen enthält
search_link_selector = (By.XPATH, f"//a[contains(., '{search_name}')] | //div[contains(., '{search_name}') and contains(@class, 'list-item')]")
search_link = self.wait.until(EC.element_to_be_clickable(search_link_selector))
search_link.click()
# Verifizieren, dass die Ergebnisse geladen sind, indem wir auf die Ergebnistabelle warten.
# Ein guter Indikator ist die Tabellenüberschrift "Firma".
results_table_header_selector = (By.XPATH, "//th[normalize-space()='Firma']")
self.wait.until(EC.visibility_of_element_located(results_table_header_selector))
logger.info(f"Suche '{search_name}' erfolgreich geladen und Ergebnisse angezeigt.")
# Eine kleine, feste Wartezeit kann helfen, damit alle Daten nachgeladen sind.
time.sleep(3)
return True
except Exception as e:
logger.critical(f"Laden der Suche '{search_name}' fehlgeschlagen: {type(e).__name__}", exc_info=True)
self._save_debug_artifacts()
return False
def extract_current_page_results(self):
"""Extrahiert die Firmennamen und Webseiten von der aktuellen Ergebnisseite."""
try:
logger.info("Extrahiere Ergebnisse von der aktuellen Seite...")
results = []
# Finde alle Zeilen in der Ergebnistabelle. Wir gehen davon aus, dass es `tr`-Elemente sind.
# Ein stabiler Selektor könnte die `data-test`-Attribute nutzen, falls vorhanden.
rows_selector = (By.XPATH, "//tbody/tr")
rows = self.driver.find_elements(*rows_selector)
if not rows:
logger.warning("Keine Ergebniszeilen auf der Seite gefunden.")
return []
logger.info(f"{len(rows)} Ergebniszeilen gefunden.")
for row in rows:
try:
# Extrahiere Firmenname und Webseite.
# Diese XPaths sind Annahmen und müssen ggf. nach Analyse des HTML angepasst werden.
company_name = row.find_element(By.XPATH, ".//td[2]//a").text.strip()
website = row.find_element(By.XPATH, ".//td[3]//a").text.strip()
if company_name and website:
results.append({'name': company_name, 'website': website})
except NoSuchElementException:
logger.warning("Konnte Name oder Webseite in einer Zeile nicht finden, überspringe Zeile.")
continue
logger.info(f"{len(results)} Firmen erfolgreich extrahiert.")
return results
except Exception as e:
logger.error(f"Fehler bei der Extraktion der Ergebnisse: {type(e).__name__}", exc_info=True)
self._save_debug_artifacts()
return []
def close(self):
if self.driver:
logger.info("Schließe den WebDriver.")