# social_networks/facebook/facebook_automation.py """ Facebook-Automatisierung - Hauptklasse für Facebook-Automatisierungsfunktionalität Mit Anti-Bot Features wie bei Instagram. """ import logging import time import random from datetime import datetime from typing import Dict, List, Any, Optional, Tuple from browser.playwright_manager import PlaywrightManager from browser.playwright_extensions import PlaywrightExtensions from browser.fingerprint_protection import FingerprintProtection from social_networks.base_automation import BaseAutomation from infrastructure.services.advanced_fingerprint_service import AdvancedFingerprintService from infrastructure.repositories.fingerprint_repository import FingerprintRepository from utils.password_generator import PasswordGenerator from utils.username_generator import UsernameGenerator from utils.birthday_generator import BirthdayGenerator from utils.human_behavior import HumanBehavior from utils.email_handler import EmailHandler # Importiere Helferklassen from .facebook_registration import FacebookRegistration from .facebook_login import FacebookLogin from .facebook_verification import FacebookVerification from .facebook_ui_helper import FacebookUIHelper from .facebook_utils import FacebookUtils from utils.logger import setup_logger # Konfiguriere Logger logger = setup_logger("facebook_automation") class FacebookAutomation(BaseAutomation): """ Hauptklasse für die Facebook-Automatisierung. Implementiert die Registrierung und Anmeldung bei Facebook mit Anti-Bot Features. """ def __init__(self, headless: bool = False, use_proxy: bool = False, proxy_type: str = None, save_screenshots: bool = True, screenshots_dir: str = None, slowmo: int = 0, debug: bool = False, email_domain: str = "z5m7q9dk3ah2v1plx6ju.com", enhanced_stealth: bool = True, fingerprint_noise: float = 0.5, window_position = None, fingerprint = None, language: str = "de"): """ Initialisiert die Facebook-Automatisierung. Args: headless: Ob der Browser im Headless-Modus ausgeführt werden soll use_proxy: Ob ein Proxy verwendet werden soll proxy_type: Proxy-Typ ("ipv4", "ipv6", "mobile") oder None für zufälligen Typ save_screenshots: Ob Screenshots gespeichert werden sollen screenshots_dir: Verzeichnis für Screenshots slowmo: Verzögerung zwischen Aktionen in Millisekunden debug: Ob Debug-Informationen angezeigt werden sollen email_domain: Domain für generierte E-Mail-Adressen enhanced_stealth: Ob erweiterter Stealth-Modus aktiviert werden soll fingerprint_noise: Menge an Rauschen für Fingerprint-Verschleierung (0.0-1.0) window_position: Position des Browser-Fensters fingerprint: Vordefinierter Fingerprint language: Sprache für Facebook ("de" oder "en") """ # Initialisiere die Basisklasse super().__init__( headless=headless, use_proxy=use_proxy, proxy_type=proxy_type, save_screenshots=save_screenshots, screenshots_dir=screenshots_dir, slowmo=slowmo, debug=debug, email_domain=email_domain, window_position=window_position ) # Facebook-spezifische Einstellungen self.language = language self.base_url = f"https://www.facebook.com/?locale={language}_DE" if language == "de" else "https://www.facebook.com" # Stealth-Modus-Einstellungen (wie bei Instagram) self.enhanced_stealth = enhanced_stealth self.fingerprint_noise = max(0.0, min(1.0, fingerprint_noise)) # Initialisiere Helferklassen self.registration = FacebookRegistration(self) self.login = FacebookLogin(self) self.verification = FacebookVerification(self) self.ui_helper = FacebookUIHelper(self) self.utils = FacebookUtils(self) # Zusätzliche Hilfsklassen self.password_generator = PasswordGenerator() self.username_generator = UsernameGenerator() self.birthday_generator = BirthdayGenerator() self.human_behavior = HumanBehavior(speed_factor=0.8, randomness=0.6) self.email_handler = EmailHandler() # Fuer E-Mail-Verifikation wie bei Instagram # Fingerprint Service für Account-gebundene Fingerprints (wie bei Instagram) self.fingerprint_service = AdvancedFingerprintService(FingerprintRepository()) self.account_fingerprint = None # Nutze übergebenen Fingerprint wenn vorhanden self.provided_fingerprint = fingerprint logger.info(f"Facebook-Automatisierung initialisiert (Sprache: {language})") def _initialize_browser(self) -> bool: """ Initialisiert den Browser mit Anti-Bot Features. Identisch zu Instagram für konsistente Fingerprint-Protection. Returns: bool: True bei Erfolg, False bei Fehler """ try: # Proxy-Konfiguration, falls aktiviert proxy_config = None if self.use_proxy: proxy_config = self.proxy_rotator.get_proxy(self.proxy_type) if not proxy_config: logger.warning(f"Kein Proxy vom Typ '{self.proxy_type}' verfügbar, verwende direkten Zugriff") # Browser initialisieren self.browser = PlaywrightManager( headless=self.headless, proxy=proxy_config, browser_type="chromium", screenshots_dir=self.screenshots_dir, slowmo=self.slowmo ) # Browser starten self.browser.start() # Erweiterten Fingerprint-Schutz aktivieren (wie bei Instagram) if self.enhanced_stealth: # Erstelle Extensions-Objekt extensions = PlaywrightExtensions(self.browser) # Methoden anhängen extensions.hook_into_playwright_manager() # Fingerprint-Schutz aktivieren if self.provided_fingerprint: logger.info("Verwende bereitgestellten Fingerprint für Account-Erstellung") if isinstance(self.provided_fingerprint, dict): from infrastructure.models.browser_fingerprint import BrowserFingerprint fingerprint_obj = BrowserFingerprint.from_dict(self.provided_fingerprint) else: fingerprint_obj = self.provided_fingerprint self.account_fingerprint = fingerprint_obj fingerprint_config = fingerprint_obj.to_config() else: # Generiere neuen Fingerprint self.account_fingerprint = self.fingerprint_service.generate_fingerprint("facebook") fingerprint_config = self.account_fingerprint.to_config() # Fingerprint-Protection mit Noise-Level protection = FingerprintProtection( noise_level=self.fingerprint_noise, fingerprint_config=fingerprint_config ) protection.apply(self.browser.page) logger.info(f"Fingerprint-Schutz aktiviert (Noise-Level: {self.fingerprint_noise})") # Facebook-spezifische Browser-Einstellungen self._apply_facebook_specific_settings() logger.info("Browser erfolgreich initialisiert") return True except Exception as e: logger.error(f"Fehler bei der Browser-Initialisierung: {e}") return False def _apply_facebook_specific_settings(self): """ Wendet Facebook-spezifische Browser-Einstellungen an. """ try: # Setze Facebook-spezifische Headers extra_headers = { 'Accept-Language': 'de-DE,de;q=0.9,en;q=0.8' if self.language == 'de' else 'en-US,en;q=0.9', 'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"Windows"', } self.browser.page.set_extra_http_headers(extra_headers) # Viewport für Desktop self.browser.page.set_viewport_size({ 'width': random.randint(1366, 1920), 'height': random.randint(768, 1080) }) logger.debug("Facebook-spezifische Browser-Einstellungen angewendet") except Exception as e: logger.warning(f"Fehler beim Anwenden Facebook-spezifischer Einstellungen: {e}") def register_account(self, first_name: str, last_name: str, birth_date: Dict[str, int], gender: str, email: str = None, phone_number: str = None, password: str = None, **kwargs) -> Dict[str, Any]: """ Registriert einen neuen Facebook-Account. Args: first_name: Vorname last_name: Nachname birth_date: Geburtsdatum als Dict mit 'day', 'month', 'year' gender: Geschlecht ('male', 'female', 'custom') email: E-Mail-Adresse (optional, wird generiert wenn nicht angegeben) phone_number: Telefonnummer (optional, alternativ zu E-Mail) password: Passwort (optional, wird generiert wenn nicht angegeben) **kwargs: Weitere optionale Parameter Returns: Dict[str, Any]: Ergebnis der Registrierung """ logger.info(f"Starte Facebook-Registrierung für {first_name} {last_name}") try: # Browser initialisieren if not self._initialize_browser(): return {"success": False, "error": "Browser konnte nicht initialisiert werden"} # Fingerprint rotieren für neue Registrierung if self.enhanced_stealth and hasattr(self.browser, 'rotate_fingerprint'): self.browser.rotate_fingerprint() logger.info("Browser-Fingerprint für Registrierung rotiert") # E-Mail generieren wenn nicht vorhanden if not email and not phone_number: email = self._generate_email(first_name, last_name) logger.info(f"Generierte E-Mail: {email}") # Passwort generieren wenn nicht vorhanden if not password: password = self.password_generator.generate_password( length=random.randint(12, 16), include_special=True ) logger.info("Passwort generiert") # Account-Daten vorbereiten account_data = { "first_name": first_name, "last_name": last_name, "birth_date": birth_date, "gender": gender, "email": email, "phone_number": phone_number, "password": password, "language": self.language, **kwargs } # Delegiere an Registration-Klasse result = self.registration.register_account(account_data) # Screenshot am Ende self._take_screenshot(f"registration_finished_{int(time.time())}") # Fingerprint-Statistiken aktualisieren bei Erfolg if result.get("success") and self.account_fingerprint: try: account_id = result.get("account_data", {}).get("account_id", f"fb_{int(time.time())}") self.fingerprint_service.update_fingerprint_stats( self.account_fingerprint.fingerprint_id, account_id, success=True ) logger.info("Fingerprint-Statistiken für erfolgreiche Registrierung aktualisiert") except Exception as e: logger.warning(f"Fehler beim Aktualisieren der Fingerprint-Statistiken: {e}") # Status aktualisieren self.status.update(result) return result except Exception as e: error_msg = f"Unerwarteter Fehler bei der Registrierung: {str(e)}" logger.error(error_msg, exc_info=True) # Fehler-Screenshot self._take_screenshot(f"registration_error_{int(time.time())}") self.status.update({ "success": False, "error": error_msg, "stage": "error" }) return self.status finally: # Browser offen lassen für Debugging logger.info("Registrierung abgeschlossen - Browser bleibt offen") def login_account(self, email_or_phone: str, password: str, account_id: Optional[str] = None, **kwargs) -> Dict[str, Any]: """ Meldet sich bei einem bestehenden Facebook-Account an. Args: email_or_phone: E-Mail-Adresse oder Telefonnummer password: Passwort account_id: Optional account ID für gespeicherten Fingerprint **kwargs: Weitere optionale Parameter Returns: Dict[str, Any]: Ergebnis der Anmeldung """ logger.info(f"Starte Facebook-Login für '{email_or_phone}'") try: # Browser initialisieren mit Account-Fingerprint wenn vorhanden if not self.browser or not hasattr(self.browser, 'page') or not self.browser.page: if account_id: # Verwende Account-spezifischen Fingerprint if not self._initialize_browser_with_fingerprint(account_id): return {"success": False, "error": "Browser konnte nicht mit Account-Fingerprint initialisiert werden"} else: # Verwende zufälligen Fingerprint if not self._initialize_browser(): return {"success": False, "error": "Browser konnte nicht initialisiert werden"} else: logger.info("Verwende bereits geöffneten Browser für Login") # Delegiere an Login-Klasse result = self.login.login_account(email_or_phone, password, **kwargs) # Screenshot am Ende self._take_screenshot(f"login_finished_{int(time.time())}") # Fingerprint-Statistiken aktualisieren if account_id and self.account_fingerprint and result.get("success"): try: self.fingerprint_service.update_fingerprint_stats( self.account_fingerprint.fingerprint_id, account_id, success=True ) logger.info("Fingerprint-Statistiken für erfolgreichen Login aktualisiert") except Exception as e: logger.warning(f"Fehler beim Aktualisieren der Fingerprint-Statistiken: {e}") # Status aktualisieren self.status.update(result) return result except Exception as e: error_msg = f"Unerwarteter Fehler beim Login: {str(e)}" logger.error(error_msg, exc_info=True) # Fehler-Screenshot self._take_screenshot(f"login_error_{int(time.time())}") self.status.update({ "success": False, "error": error_msg, "stage": "error" }) return self.status finally: # Browser offen lassen für User-Kontrolle logger.info("Login abgeschlossen - Browser bleibt offen") def _initialize_browser_with_fingerprint(self, account_id: str) -> bool: """ Initialisiert den Browser mit einem Account-spezifischen Fingerprint. Args: account_id: Account-ID für den Fingerprint Returns: bool: True bei Erfolg, False bei Fehler """ try: # Lade gespeicherten Fingerprint für Account saved_fingerprint = self.fingerprint_service.get_fingerprint_for_account(account_id, "facebook") if saved_fingerprint: logger.info(f"Verwende gespeicherten Fingerprint für Account {account_id}") self.provided_fingerprint = saved_fingerprint else: logger.info(f"Kein gespeicherter Fingerprint für Account {account_id}, generiere neuen") self.provided_fingerprint = self.fingerprint_service.generate_fingerprint("facebook") # Browser mit Fingerprint initialisieren return self._initialize_browser() except Exception as e: logger.error(f"Fehler bei Browser-Initialisierung mit Fingerprint: {e}") return False def _generate_email(self, first_name: str, last_name: str) -> str: """ Generiert eine E-Mail-Adresse basierend auf dem Namen. Args: first_name: Vorname last_name: Nachname Returns: str: Generierte E-Mail-Adresse """ # Entferne Umlaute und Sonderzeichen first_clean = first_name.lower().replace('ä', 'ae').replace('ö', 'oe').replace('ü', 'ue').replace('ß', 'ss') last_clean = last_name.lower().replace('ä', 'ae').replace('ö', 'oe').replace('ü', 'ue').replace('ß', 'ss') # Verschiedene E-Mail-Formate formats = [ f"{first_clean}.{last_clean}", f"{first_clean}{last_clean}", f"{first_clean[0]}{last_clean}", f"{first_clean}_{last_clean}", f"{last_clean}.{first_clean}", ] # Wähle zufälliges Format base_email = random.choice(formats) # Füge optional Zahlen hinzu if random.random() > 0.5: base_email += str(random.randint(1, 999)) # Füge Domain hinzu return f"{base_email}@{self.email_domain}"