From c0f9f2631c1ebf1399f35a058408df25302a31cc Mon Sep 17 00:00:00 2001 From: Floke Date: Wed, 16 Jul 2025 14:56:31 +0000 Subject: [PATCH] scrape_fotograf.py aktualisiert --- scrape_fotograf.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/scrape_fotograf.py b/scrape_fotograf.py index b69cb97d..44c2b841 100644 --- a/scrape_fotograf.py +++ b/scrape_fotograf.py @@ -17,15 +17,18 @@ OUTPUT_FILE = os.path.join(OUTPUT_DIR, 'nutzer_ohne_logins.csv') LOGIN_URL = 'https://app.fotograf.de/login/login' # --- Selektoren --- +# FINALE, KORREKTE VERSION mit präzisem Album-Row-Selector SELECTORS = { "cookie_accept_button": "#CybotCookiebotDialogBodyLevelButtonLevelOptinAllowAll", "login_user": "#login-email", "login_pass": "#login-password", "login_button": "#login-submit", "job_name": "h1", - "album_rows": "div:has(a[href*='/config_jobs_photos/gallery/'])", + # NEU: Findet die Tabellen-Kopfzeile und wählt dann alle folgenden Zeilen als Geschwister aus. + "album_rows": "div:has(> div:contains('Fotos insgesamt')) ~ div", "album_link": "a[href*='/config_jobs_photos/gallery/']", - "login_count": "div:nth-child(7)", + # Dieser Selector sollte jetzt im korrekten Zeilen-Kontext funktionieren. + "login_count": "div:nth-child(7)", "buyer_link": "a.block:has(span:contains('Käufer'))", "buyer_email": "div.flex:nth-of-type(4) span" } @@ -117,8 +120,12 @@ def process_job(driver, job_url): albums_to_process = [] try: - album_rows = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, SELECTORS["album_rows"]))) - print(f"{len(album_rows)} Alben gefunden. Prüfe auf Logins...") + # Warten, bis die Kopfzeile da ist, um sicherzustellen, dass die Tabelle geladen ist + wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "div:contains('Fotos insgesamt')"))) + time.sleep(1) # Kurze extra Wartezeit, falls die Zeilen nach der Kopfzeile nachladen + + album_rows = driver.find_elements(By.CSS_SELECTOR, SELECTORS["album_rows"]) + print(f"{len(album_rows)} Album-Zeilen gefunden. Prüfe auf Logins...") for i, row in enumerate(album_rows): print(f"\n--- Analysiere Zeile {i+1} ---") @@ -148,16 +155,12 @@ def process_job(driver, job_url): print(f" --> FEHLER: Konnte Zeile nicht verarbeiten. Grund: {e}") except TimeoutException: - print("Keine Alben auf der Seite gefunden oder Timeout beim Warten.") + print("Die Album-Tabelle wurde nicht gefunden.") take_error_screenshot(driver, "album_list_timeout") return [] results = [] print(f"\nVerarbeite {len(albums_to_process)} Alben mit 0 Logins im Detail...") - if not albums_to_process: - # Hier geben wir die Funktion nur zurück, wenn keine Alben zu verarbeiten sind - pass # Placeholder - for album in albums_to_process: try: print(f" Rufe Detailseite für '{album['child_name']}' auf...") @@ -215,7 +218,6 @@ def get_profile_choice(): def main(): print("--- Fotograf.de Scraper für Nutzer ohne Logins ---") - # KORRIGIERTE ZEILE credentials = get_profile_choice() if not credentials: return job_url = input("Bitte gib die URL des zu bearbeitenden Fotoauftrags ein: ")