From 145ef73aeefcc514be789f12704920cc79f931ab Mon Sep 17 00:00:00 2001 From: Floke Date: Wed, 16 Jul 2025 19:14:42 +0000 Subject: [PATCH] =?UTF-8?q?Schaut=20auch=20nach=201-er-=C3=96ffnungen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scrape_fotograf.py | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/scrape_fotograf.py b/scrape_fotograf.py index efef72cb..daaf2824 100644 --- a/scrape_fotograf.py +++ b/scrape_fotograf.py @@ -3,6 +3,7 @@ import os import time import csv import math +import re # NEU: Modul für reguläre Ausdrücke importieren from datetime import datetime from selenium import webdriver from selenium.webdriver.chrome.options import Options @@ -14,7 +15,7 @@ from selenium.common.exceptions import TimeoutException, NoSuchElementException, # --- Konfiguration & Konstanten --- CREDENTIALS_FILE = 'fotograf_credentials.json' OUTPUT_DIR = 'output' -OUTPUT_FILE = os.path.join(OUTPUT_DIR, 'nutzer_mit_wenig_logins.csv') # Dateiname angepasst +OUTPUT_FILE = os.path.join(OUTPUT_DIR, 'nutzer_mit_wenig_logins.csv') LOGIN_URL = 'https://app.fotograf.de/login/login' # --- Selektoren (unverändert) --- @@ -98,13 +99,17 @@ def login(driver, username, password): def process_full_job(driver, job_url): wait = WebDriverWait(driver, 15) - print(f"\nVerarbeite Job-URL: {job_url}") + # Der Job-Name wird von der Einstellungs-Seite geholt, da diese stabil ist. + # Wir konstruieren die URL aus der eingegebenen URL, egal welche es war. try: - driver.get(job_url) - except InvalidArgumentException: - print(f"!!! FEHLER: Die URL '{job_url}' wurde von Selenium als ungültig angesehen.") + job_id = re.search(r'/(\d+)$', job_url).group(1) + settings_url = f"https://app.fotograf.de/config_jobs_settings/index/{job_id}" + except (AttributeError, IndexError): + print(f"!!! FEHLER: Konnte keine Job-ID aus der URL '{job_url}' extrahieren.") return [] + print(f"\nVerarbeite Job-ID: {job_id}") + driver.get(settings_url) try: job_name = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, SELECTORS["job_name"]))).text print(f"Auftragsname: '{job_name}'") @@ -113,7 +118,6 @@ def process_full_job(driver, job_url): take_error_screenshot(driver, "job_name_not_found") return [] - job_id = job_url.split('/')[-1] albums_overview_url = f"https://app.fotograf.de/config_jobs_photos/index/{job_id}" print(f"Navigiere zur Alben-Übersicht: {albums_overview_url}") driver.get(albums_overview_url) @@ -160,7 +164,6 @@ def process_full_job(driver, job_url): login_count_text = person_row.find_element(By.XPATH, SELECTORS["person_logins"]).text - # --- HIER IST DIE GEÄNDERTE LOGIK --- if int(login_count_text) <= 1: vorname = person_row.find_element(By.XPATH, SELECTORS["person_vorname"]).text print(f" --> ERFOLG: '{vorname}' mit {login_count_text} Login(s) gefunden!") @@ -244,12 +247,18 @@ def main(): credentials = get_profile_choice() if not credentials: return - job_url_raw = input("Bitte gib die URL des zu bearbeitenden Fotoauftrags ein (Einstellungs-Seite): ") - job_url_cleaned = job_url_raw.replace("\x1b[200~", "").replace("\x1b[201~", "") - job_url = job_url_cleaned.strip() + job_url_raw = input("Bitte gib eine beliebige URL des zu bearbeitenden Fotoauftrags ein: ") + + # NEU: Robuste URL-Extraktion mit Regex, um Terminal-Steuerzeichen zu entfernen + match = re.search(r'https?://[^\s]+', job_url_raw) + if not match: + print("Keine gültige URL in der Eingabe gefunden.") + return + job_url = match.group(0) - if "fotograf.de/config_jobs_settings/index/" not in job_url: - print("Dies scheint keine gültige URL für die Auftragseinstellungen zu sein.") + # NEU: Flexible Überprüfung, die jede Job-Seite akzeptiert + if "fotograf.de/config_jobs_" not in job_url: + print("Dies scheint keine gültige URL für einen Fotoauftrag zu sein.") return driver = setup_driver()