Initiales Setup für Dealfront-Automatisierung

- Erstellt neues Hauptskript dealfront_enrichment.py
- Integriert Selenium und webdriver-manager als neue Abhängigkeiten
- Implementiert sichere Speicherung der Dealfront-Credentials in separater .json-Datei
- Fügt dealfront_credentials.json zur .gitignore hinzu
- Implementiert eine robuste Login-Klasse DealfrontScraper mit Verifizierung
This commit is contained in:
2025-07-02 05:14:39 +00:00
parent 0b83b0484a
commit c1418c7283

169
dealfront_enrichment.py Normal file
View File

@@ -0,0 +1,169 @@
import os
import json
import time
import logging
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.chrome.options import Options as ChromeOptions
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException
from config import Config, DEALFRONT_LOGIN_URL, DEALFRONT_CREDENTIALS_FILE
from helpers import setup_logging
# Logging aus dem helpers-Modul initialisieren
setup_logging(log_level=logging.DEBUG if Config.DEBUG else logging.INFO)
# Spezifischen Logger für dieses Modul erstellen
logger = logging.getLogger(__name__)
class DealfrontScraper:
"""
Kapselt alle Interaktionen mit der Dealfront-Plattform mittels Selenium.
"""
def __init__(self):
"""
Initialisiert den WebDriver und den WebDriverWait.
"""
logger.info("Initialisiere den DealfrontScraper und den Chrome WebDriver.")
chrome_options = ChromeOptions()
# Optional: Führen Sie den Browser im "headless" Modus aus (ohne sichtbares Fenster)
# chrome_options.add_argument("--headless")
chrome_options.add_argument("--window-size=1920,1080")
chrome_options.add_argument("--disable-blink-features=AutomationControlled")
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
chrome_options.add_experimental_option('useAutomationExtension', False)
# Stellt sicher, dass der korrekte ChromeDriver automatisch heruntergeladen und verwendet wird
try:
service = ChromeService(ChromeDriverManager().install())
self.driver = webdriver.Chrome(service=service, options=chrome_options)
# Wichtig, um als "echter" Browser zu erscheinen
self.driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
except Exception as e:
logger.critical(f"WebDriver konnte nicht initialisiert werden. Stellen Sie sicher, dass Chrome installiert ist. Fehler: {e}")
self.driver = None
raise
# Zentraler WebDriverWait mit einem Timeout von 20 Sekunden
self.wait = WebDriverWait(self.driver, 20)
logger.info("WebDriver erfolgreich initialisiert.")
def _load_credentials(self):
"""Lädt Dealfront-Zugangsdaten sicher aus der JSON-Datei."""
try:
with open(DEALFRONT_CREDENTIALS_FILE, 'r') as f:
creds = json.load(f)
username = creds.get("username")
password = creds.get("password")
if not username or "DEIN_DEALFRONT_BENUTZERNAME" in username or not password or "DEIN_DEALFRONT_PASSWORT" in password:
logger.error(f"Zugangsdaten in '{DEALFRONT_CREDENTIALS_FILE}' sind ungültig oder Platzhalter.")
return None, None
return username, password
except FileNotFoundError:
logger.error(f"Credentials-Datei nicht gefunden: '{DEALFRONT_CREDENTIALS_FILE}'")
return None, None
except json.JSONDecodeError:
logger.error(f"Fehler beim Parsen der Credentials-Datei: '{DEALFRONT_CREDENTIALS_FILE}'")
return None, None
def login(self):
"""
Führt den Login-Prozess auf der Dealfront-Plattform durch.
"""
if not self.driver:
logger.error("Login nicht möglich, da der WebDriver nicht initialisiert wurde.")
return False
username, password = self._load_credentials()
if not username or not password:
return False
try:
logger.info(f"Navigiere zur Login-Seite: {DEALFRONT_LOGIN_URL}")
self.driver.get(DEALFRONT_LOGIN_URL)
# 1. Cookie-Banner behandeln (falls vorhanden)
try:
logger.debug("Suche nach Cookie-Banner...")
# Expliziter Wait für den Button, der durch die ID identifiziert wird
cookie_button_id = "CybotCookiebotDialogBodyLevelButtonLevelOptinAllowAll"
cookie_button = self.wait.until(EC.element_to_be_clickable((By.ID, cookie_button_id)))
cookie_button.click()
logger.info("Cookie-Banner akzeptiert.")
# Kurze Pause nach dem Klick, damit sich die Seite anpassen kann
time.sleep(1)
except TimeoutException:
logger.warning("Cookie-Banner wurde nicht gefunden oder war nicht klickbar. Fahre fort.")
# 2. Anmeldedaten ausfüllen
logger.info("Fülle Anmeldeformular aus...")
username_field = self.wait.until(EC.visibility_of_element_located((By.ID, "username")))
password_field = self.driver.find_element(By.ID, "password")
username_field.send_keys(username)
password_field.send_keys(password)
logger.info("Benutzername und Passwort eingetragen.")
# 3. Login-Button klicken
login_button = self.driver.find_element(By.CSS_SELECTOR, "button[type='submit']")
login_button.click()
logger.info("Login-Button geklickt. Warte auf die Verifizierung...")
# 4. Login-Erfolg verifizieren
# Wir warten auf ein Element, das nur nach erfolgreichem Login existiert,
# z.B. das Haupt-Suchfeld auf dem Dashboard.
verification_element_xpath = "//input[@data-cy='header-search-input']"
self.wait.until(EC.visibility_of_element_located((By.XPATH, verification_element_xpath)))
logger.info("Login erfolgreich! Dashboard-Element gefunden.")
return True
except TimeoutException as e:
logger.error(f"Login fehlgeschlagen. Timeout beim Warten auf ein Element.")
self.driver.save_screenshot("login_error_screenshot.png")
logger.error("Screenshot 'login_error_screenshot.png' wurde für die Analyse gespeichert.")
return False
except NoSuchElementException as e:
logger.error(f"Login fehlgeschlagen. Ein Element konnte nicht gefunden werden.")
self.driver.save_screenshot("login_error_screenshot.png")
return False
except Exception as e:
logger.critical(f"Ein unerwarteter Fehler ist während des Logins aufgetreten: {e}", exc_info=True)
self.driver.save_screenshot("login_error_screenshot.png")
return False
def close(self):
"""
Schließt den WebDriver und beendet die Browser-Session.
"""
if self.driver:
logger.info("Schließe den WebDriver.")
self.driver.quit()
if __name__ == "__main__":
logger.info("Starte Dealfront Automatisierung - Phase 1: Login-Test")
scraper = None
try:
scraper = DealfrontScraper()
if scraper.driver: # Nur wenn der Driver erfolgreich gestartet wurde
if scraper.login():
logger.info("Login-Prozess erfolgreich abgeschlossen. Der Bot ist nun eingeloggt.")
# Hier würde in Zukunft die weitere Logik (Suche, Extraktion) folgen.
# Für den Test warten wir 5 Sekunden, damit man das Ergebnis sehen kann.
time.sleep(5)
else:
logger.error("Login-Prozess ist fehlgeschlagen. Bitte Log-Meldungen und Screenshot prüfen.")
except Exception as e:
logger.critical(f"Ein kritischer Fehler ist im Hauptprozess aufgetreten: {e}", exc_info=True)
finally:
# Stellt sicher, dass der Browser immer geschlossen wird, auch bei einem Fehler.
if scraper:
scraper.close()
logger.info("Login-Test beendet.")