diff --git a/dealfront_enrichment.py b/dealfront_enrichment.py index 4c536df2..5ebc6b5d 100644 --- a/dealfront_enrichment.py +++ b/dealfront_enrichment.py @@ -133,31 +133,31 @@ class DealfrontScraper: def scrape_all_pages(self, max_pages=10): """ - Iteriert durch alle Ergebnisseiten, indem auf den 'Weiter'-Button geklickt wird. - Verwendet einen präzisen XPath für den Paginierungs-Button. + Iteriert durch alle Ergebnisseiten, indem auf den letzten klickbaren + Button in der Paginierung geklickt wird. """ all_companies = {} for page_number in range(1, max_pages + 1): logger.info(f"--- Verarbeite Seite {page_number} ---") - # Warten, bis die Tabelle sichtbar ist - table_selector = (By.CSS_SELECTOR, "table#t-result-table") - self.wait.until(EC.visibility_of_element_located(table_selector)) - time.sleep(2) # Kurze Pause für das JS-Rendering + self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "table#t-result-table"))) try: first_row_element = self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "table#t-result-table tbody tr[id]"))) first_row_id = first_row_element.get_attribute("id") - logger.debug(f"Erste Zeile auf Seite {page_number} hat die ID: {first_row_id}") except TimeoutException: logger.warning("Konnte keine Datenzeilen mehr finden. Beende Paginierung.") break - page_results = self.extract_current_page_results() - if not page_results: - break + # Scrollen, um alle Elemente zu laden + self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") + time.sleep(2) + page_results = self.extract_current_page_results() + if not page_results and page_number > 1: + break + for company in page_results: unique_key = (company.get('name'), company.get('website')) if unique_key not in all_companies: @@ -165,31 +165,27 @@ class DealfrontScraper: logger.info(f"Seite {page_number}: {len(page_results)} Firmen gefunden. Gesamt einzigartig: {len(all_companies)}") - # --- Detailliertes Paginierungs-Debugging mit dem korrekten Selektor --- try: - # Dieser XPath sucht nach einem -Tag mit der Klasse 'eb-pagination-button', - # das NICHT die Klasse 'disabled' hat und ein SVG-Element enthält, - # dessen -Daten mit "M8.293 5.293" beginnen (der Pfeil nach rechts). - next_button_xpath = ( - "//a[contains(@class, 'eb-pagination-button') and not(contains(@class, 'disabled'))]" - "//svg[.//path[starts-with(@d, 'M8.293')]]" - ) + # === FINALER, EINFACHER SELEKTOR === + # Finde den LETZTEN 'a'-Tag, der NICHT die Klasse 'disabled' hat. + next_button_selector = (By.XPATH, "(//nav[contains(@class, 'eb-pagination')]//a[not(contains(@class, 'disabled'))])[last()]") + next_button = self.wait.until(EC.element_to_be_clickable(next_button_selector)) - logger.debug(f"Versuche, den 'Weiter'-Button mit XPath zu finden: {next_button_xpath}") - next_button = self.driver.find_element(By.XPATH, next_button_xpath) - - logger.info("Klickbarer 'Weiter'-Button gefunden. Klicke darauf.") + # Sicherheitscheck: Wenn der Button keine Pfeil-Grafik enthält, sind wir am Ende. + if "fa-angle-right" not in next_button.get_attribute('innerHTML'): + logger.info("Letzte Seite erreicht (letzter Button ist eine Zahl).") + break + + logger.info("Klicke auf 'Weiter'...") self.driver.execute_script("arguments[0].click();", next_button) - # Warten, bis die alte erste Zeile verschwunden ist - logger.debug(f"Warte auf das Verschwinden der alten Zeile (ID: {first_row_id})...") - old_first_row = self.driver.find_element(By.ID, first_row_id) - self.wait.until(EC.staleness_of(old_first_row)) - logger.info("Seitenwechsel erfolgreich verifiziert!") - + # Warten auf das Verschwinden der alten Zeile + old_first_row_element = self.driver.find_element(By.ID, first_row_id) + self.wait.until(EC.staleness_of(old_first_row_element)) + logger.info("Seitenwechsel erfolgreich verifiziert.") + except (NoSuchElementException, TimeoutException): logger.info("Kein klickbarer 'Weiter'-Button mehr gefunden. Paginierung abgeschlossen.") - self._save_debug_artifacts(f"pagination_end_p{page_number}") break return list(all_companies.values())