dealfront_enrichment.py aktualisiert
This commit is contained in:
@@ -25,7 +25,7 @@ logging.getLogger("selenium.webdriver.remote").setLevel(logging.WARNING)
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
os.makedirs(Config.OUTPUT_DIR, exist_ok=True)
|
os.makedirs(Config.OUTPUT_DIR, exist_ok=True)
|
||||||
log_filepath = os.path.join(Config.OUTPUT_DIR, f"dealfront_run_{time.strftime('%Y%m%d-%H%M%S')}.log")
|
log_filepath = os.path.join(Config.OUTPUT_DIR, f"dealfront_run_{time.strftime('%Y%m%d-%H%M%S')}.txt")
|
||||||
file_handler = logging.FileHandler(log_filepath, mode='w', encoding='utf-8')
|
file_handler = logging.FileHandler(log_filepath, mode='w', encoding='utf-8')
|
||||||
file_handler.setFormatter(logging.Formatter(LOG_FORMAT))
|
file_handler.setFormatter(logging.Formatter(LOG_FORMAT))
|
||||||
logging.getLogger().addHandler(file_handler)
|
logging.getLogger().addHandler(file_handler)
|
||||||
@@ -131,68 +131,58 @@ class DealfrontScraper:
|
|||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
def scrape_all_pages(self, max_pages=6):
|
def scrape_all_pages(self, max_pages=10):
|
||||||
"""
|
"""
|
||||||
Iteriert durch alle Ergebnisseiten, scrollt auf jeder Seite nach unten,
|
Iteriert durch alle Ergebnisseiten, scrollt auf jeder Seite vollständig,
|
||||||
um alle Daten zu laden, und extrahiert sie dann. Verhindert Duplikate.
|
extrahiert die Daten und klickt auf den korrekten "Weiter"-Button.
|
||||||
"""
|
"""
|
||||||
all_companies = {} # Verwende ein Dictionary, um Duplikate zu vermeiden
|
all_companies = []
|
||||||
|
|
||||||
for page_number in range(1, max_pages + 1):
|
for page_number in range(1, max_pages + 1):
|
||||||
logger.info(f"--- Verarbeite Seite {page_number} ---")
|
logger.info(f"--- Verarbeite Seite {page_number} ---")
|
||||||
|
|
||||||
# Warten, bis die Tabelle grundsätzlich geladen ist
|
# Warten, bis die Tabelle grundsätzlich geladen ist
|
||||||
table_selector = (By.CSS_SELECTOR, "table#t-result-table")
|
self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "table#t-result-table")))
|
||||||
self.wait.until(EC.visibility_of_element_located(table_selector))
|
|
||||||
|
# --- ROBUSTES SCROLLEN ---
|
||||||
|
logger.info("Scrolle Seite nach unten, um alle Zeilen zu laden...")
|
||||||
|
scroll_container = self.driver.find_element(By.CSS_SELECTOR, ".scroll-viewport")
|
||||||
|
last_height = self.driver.execute_script("return arguments[0].scrollHeight", scroll_container)
|
||||||
|
|
||||||
# --- NEU: Intelligente Scroll-Schleife ---
|
|
||||||
logger.info("Scrolle Seite nach unten, um alle Firmen zu laden...")
|
|
||||||
last_height = self.driver.execute_script("return document.querySelector('.scroll-viewport').scrollHeight")
|
|
||||||
while True:
|
while True:
|
||||||
self.driver.execute_script("document.querySelector('.scroll-viewport').scrollTo(0, document.querySelector('.scroll-viewport').scrollHeight);")
|
self.driver.execute_script("arguments[0].scrollTo(0, arguments[0].scrollHeight);", scroll_container)
|
||||||
time.sleep(2) # Wartezeit für das Nachladen der Inhalte
|
time.sleep(2.5) # Wichtige Pause, damit neue Inhalte nachladen können
|
||||||
new_height = self.driver.execute_script("return document.querySelector('.scroll-viewport').scrollHeight")
|
new_height = self.driver.execute_script("return arguments[0].scrollHeight", scroll_container)
|
||||||
if new_height == last_height:
|
if new_height == last_height:
|
||||||
break
|
break
|
||||||
last_height = new_height
|
last_height = new_height
|
||||||
logger.info("Seitenende erreicht, alle Zeilen sollten geladen sein.")
|
logger.info("Seitenende erreicht, alle Zeilen sollten geladen sein.")
|
||||||
|
|
||||||
# Extrahiere die Daten von der komplett geladenen Seite
|
|
||||||
page_results = self.extract_current_page_results()
|
page_results = self.extract_current_page_results()
|
||||||
if not page_results:
|
all_companies.extend(page_results)
|
||||||
logger.warning("Konnte auf dieser Seite keine Ergebnisse extrahieren, obwohl gescrollt wurde.")
|
logger.info(f"Seite {page_number}: {len(page_results)} Firmen gefunden. Gesamt: {len(all_companies)}")
|
||||||
|
|
||||||
for company in page_results:
|
|
||||||
unique_key = (company.get('name'), company.get('website'))
|
|
||||||
if unique_key not in all_companies:
|
|
||||||
all_companies[unique_key] = company
|
|
||||||
|
|
||||||
logger.info(f"Seite {page_number}: {len(page_results)} Firmen gefunden. Gesamt einzigartig: {len(all_companies)}")
|
|
||||||
|
|
||||||
# --- Paginierungs-Logik ---
|
# --- FINALE PAGINIERUNGS-LOGIK ---
|
||||||
try:
|
try:
|
||||||
# Wir merken uns die ID der LETZTEN Zeile, um den Wechsel zu verifizieren
|
# Eindeutiger XPath für den "Weiter"-Pfeil-Button, der nicht deaktiviert ist
|
||||||
last_row_id = self.driver.find_element(By.XPATH, "(//table[@id='t-result-table']/tbody/tr[@id])[last()]").get_attribute("id")
|
next_button_selector = (By.XPATH, "//a[contains(@class, 'eb-pagination-button') and not(contains(@class, 'disabled')) and .//path[starts-with(@d, 'M8.293')]]")
|
||||||
|
|
||||||
next_button_selector = (By.XPATH, "//nav[contains(@class, 'eb-pagination')]//a[not(contains(@class, 'disabled'))][last()]")
|
|
||||||
next_button = self.driver.find_element(*next_button_selector)
|
next_button = self.driver.find_element(*next_button_selector)
|
||||||
|
|
||||||
if "fa-angle-right" not in next_button.get_attribute('innerHTML'):
|
# Den Button in den sichtbaren Bereich scrollen, falls er verdeckt ist
|
||||||
logger.info("Letzte Seite erreicht (kein 'Weiter'-Pfeil im letzten Button).")
|
self.driver.execute_script("arguments[0].scrollIntoView(true);", next_button)
|
||||||
break
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
next_button.click()
|
||||||
|
logger.info(f"Auf Seite {page_number + 1} geblättert...")
|
||||||
|
|
||||||
|
# Warten auf das Neuladen der Tabelle
|
||||||
|
self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "table#t-result-table")))
|
||||||
|
|
||||||
self.driver.execute_script("arguments[0].click();", next_button)
|
except NoSuchElementException:
|
||||||
logger.info(f"Klicke auf 'Weiter' zu Seite {page_number + 1}...")
|
logger.info("Kein 'Weiter'-Button mehr gefunden. Paginierung abgeschlossen.")
|
||||||
|
|
||||||
# Warte darauf, dass die letzte Zeile der alten Seite verschwindet
|
|
||||||
self.wait.until(EC.staleness_of(self.driver.find_element(By.ID, last_row_id)))
|
|
||||||
logger.info("Seitenwechsel erfolgreich verifiziert.")
|
|
||||||
|
|
||||||
except (NoSuchElementException, TimeoutException):
|
|
||||||
logger.info("Kein klickbarer 'Weiter'-Button mehr gefunden. Paginierung abgeschlossen.")
|
|
||||||
break
|
break
|
||||||
|
|
||||||
return list(all_companies.values())
|
return all_companies
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
if self.driver:
|
if self.driver:
|
||||||
|
|||||||
Reference in New Issue
Block a user