Ergänzung gehe zu Liste
This commit is contained in:
@@ -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.")
|
||||
|
||||
Reference in New Issue
Block a user