Ergänzung gehe zu Liste
This commit is contained in:
@@ -134,43 +134,88 @@ class DealfrontScraper:
|
|||||||
self._save_debug_artifacts()
|
self._save_debug_artifacts()
|
||||||
return False
|
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:
|
try:
|
||||||
# --- SCHRITT 1: Zum Target-Modul navigieren ---
|
logger.info("Navigiere zum 'Target'-Bereich...")
|
||||||
# Wir verwenden die Basis-URL, da die spezifische URL Session-IDs enthalten könnte.
|
target_button_selector = (By.XPATH, "//a[contains(@class, 'text-base') and .//span[normalize-space()='Target']] | //a[.//div[normalize-space()='Target']]")
|
||||||
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.")
|
|
||||||
|
|
||||||
target_list_element = self.wait.until(EC.element_to_be_clickable(list_selector))
|
# Alternative, falls der obere Selektor nicht klappt:
|
||||||
target_list_element.click()
|
# target_button_selector = (By.CSS_SELECTOR, "a[data-test-product-link-for='Target']")
|
||||||
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.")
|
|
||||||
|
|
||||||
|
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
|
return True
|
||||||
|
|
||||||
except Exception as e:
|
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()
|
self._save_debug_artifacts()
|
||||||
return False
|
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):
|
def close(self):
|
||||||
if self.driver:
|
if self.driver:
|
||||||
logger.info("Schließe den WebDriver.")
|
logger.info("Schließe den WebDriver.")
|
||||||
|
|||||||
Reference in New Issue
Block a user