Files
test-main/social_networks/tiktok/tiktok_registration.py
Claude Project Manager 08ed938105 Initial commit
2025-07-03 21:11:05 +02:00

987 Zeilen
40 KiB
Python

# social_networks/tiktok/tiktok_registration.py
"""
TikTok-Registrierung - Klasse für die Kontoerstellung bei TikTok
"""
import logging
import time
import random
import re
from typing import Dict, List, Any, Optional, Tuple
from .tiktok_selectors import TikTokSelectors
from .tiktok_workflow import TikTokWorkflow
# Konfiguriere Logger
logger = logging.getLogger("tiktok_registration")
class TikTokRegistration:
"""
Klasse für die Registrierung von TikTok-Konten.
Enthält alle Methoden zur Kontoerstellung.
"""
def __init__(self, automation):
"""
Initialisiert die TikTok-Registrierung.
Args:
automation: Referenz auf die Hauptautomatisierungsklasse
"""
self.automation = automation
self.browser = None # Wird zur Laufzeit auf automation.browser gesetzt
self.selectors = TikTokSelectors()
self.workflow = TikTokWorkflow.get_registration_workflow()
logger.debug("TikTok-Registrierung initialisiert")
def register_account(self, full_name: str, age: int, registration_method: str = "email",
phone_number: str = None, **kwargs) -> Dict[str, Any]:
"""
Führt den vollständigen Registrierungsprozess für einen TikTok-Account durch.
Args:
full_name: Vollständiger Name für den Account
age: Alter des Benutzers
registration_method: "email" oder "phone"
phone_number: Telefonnummer (nur bei registration_method="phone")
**kwargs: Weitere optionale Parameter
Returns:
Dict[str, Any]: Ergebnis der Registrierung mit Status und Account-Daten
"""
# Hole Browser-Referenz von der Hauptklasse
self.browser = self.automation.browser
# Validiere die Eingaben
if not self._validate_registration_inputs(full_name, age, registration_method, phone_number):
return {
"success": False,
"error": "Ungültige Eingabeparameter",
"stage": "input_validation"
}
# Account-Daten generieren
account_data = self._generate_account_data(full_name, age, registration_method, phone_number, **kwargs)
# Starte den Registrierungsprozess
logger.info(f"Starte TikTok-Registrierung für {account_data['username']} via {registration_method}")
try:
# 1. Zur Startseite navigieren
if not self._navigate_to_homepage():
return {
"success": False,
"error": "Konnte nicht zur TikTok-Startseite navigieren",
"stage": "navigation",
"account_data": account_data
}
# 2. Cookie-Banner behandeln
self._handle_cookie_banner()
# 3. Anmelden-Button klicken
if not self._click_login_button():
return {
"success": False,
"error": "Konnte nicht auf Anmelden-Button klicken",
"stage": "login_button",
"account_data": account_data
}
# 4. Registrieren-Link klicken
if not self._click_register_link():
return {
"success": False,
"error": "Konnte nicht auf Registrieren-Link klicken",
"stage": "register_link",
"account_data": account_data
}
# 5. Telefon/E-Mail-Option auswählen
if not self._click_phone_email_option():
return {
"success": False,
"error": "Konnte nicht auf Telefon/E-Mail-Option klicken",
"stage": "phone_email_option",
"account_data": account_data
}
# 6. E-Mail oder Telefon als Registrierungsmethode wählen
if not self._select_registration_method(registration_method):
return {
"success": False,
"error": f"Konnte Registrierungsmethode '{registration_method}' nicht auswählen",
"stage": "registration_method",
"account_data": account_data
}
# 7. Geburtsdatum eingeben
if not self._enter_birthday(account_data["birthday"]):
return {
"success": False,
"error": "Fehler beim Eingeben des Geburtsdatums",
"stage": "birthday",
"account_data": account_data
}
# 8. Registrierungsformular ausfüllen
if not self._fill_registration_form(account_data, registration_method):
return {
"success": False,
"error": "Fehler beim Ausfüllen des Registrierungsformulars",
"stage": "registration_form",
"account_data": account_data
}
# 9. Bestätigungscode abrufen und eingeben
if not self._handle_verification(account_data, registration_method):
return {
"success": False,
"error": "Fehler bei der Verifizierung",
"stage": "verification",
"account_data": account_data
}
# 10. Benutzernamen erstellen
if not self._create_username(account_data):
return {
"success": False,
"error": "Fehler beim Erstellen des Benutzernamens",
"stage": "username",
"account_data": account_data
}
# 11. Erfolgreiche Registrierung überprüfen
if not self._check_registration_success():
return {
"success": False,
"error": "Registrierung fehlgeschlagen oder konnte nicht verifiziert werden",
"stage": "final_check",
"account_data": account_data
}
# Registrierung erfolgreich abgeschlossen
logger.info(f"TikTok-Account {account_data['username']} erfolgreich erstellt")
return {
"success": True,
"stage": "completed",
"account_data": account_data
}
except Exception as e:
error_msg = f"Unerwarteter Fehler bei der TikTok-Registrierung: {str(e)}"
logger.error(error_msg, exc_info=True)
return {
"success": False,
"error": error_msg,
"stage": "exception",
"account_data": account_data
}
def _validate_registration_inputs(self, full_name: str, age: int,
registration_method: str, phone_number: str) -> bool:
"""
Validiert die Eingaben für die Registrierung.
Args:
full_name: Vollständiger Name für den Account
age: Alter des Benutzers
registration_method: "email" oder "phone"
phone_number: Telefonnummer (nur bei registration_method="phone")
Returns:
bool: True wenn alle Eingaben gültig sind, False sonst
"""
# Vollständiger Name prüfen
if not full_name or len(full_name) < 3:
logger.error("Ungültiger vollständiger Name")
return False
# Alter prüfen
if age < 13:
logger.error("Benutzer muss mindestens 13 Jahre alt sein")
return False
# Registrierungsmethode prüfen
if registration_method not in ["email", "phone"]:
logger.error(f"Ungültige Registrierungsmethode: {registration_method}")
return False
# Telefonnummer prüfen, falls erforderlich
if registration_method == "phone" and not phone_number:
logger.error("Telefonnummer erforderlich für Registrierung via Telefon")
return False
return True
def _generate_account_data(self, full_name: str, age: int, registration_method: str,
phone_number: str, **kwargs) -> Dict[str, Any]:
"""
Generiert Account-Daten für die Registrierung.
Args:
full_name: Vollständiger Name für den Account
age: Alter des Benutzers
registration_method: "email" oder "phone"
phone_number: Telefonnummer (nur bei registration_method="phone")
**kwargs: Weitere optionale Parameter
Returns:
Dict[str, Any]: Generierte Account-Daten
"""
# Benutzername generieren
username = kwargs.get("username")
if not username:
username = self.automation.username_generator.generate_username("tiktok", full_name)
# Passwort generieren
password = kwargs.get("password")
if not password:
password = self.automation.password_generator.generate_password("tiktok")
# E-Mail generieren (falls nötig)
email = None
if registration_method == "email":
email_prefix = username.lower().replace(".", "").replace("_", "")
email = f"{email_prefix}@{self.automation.email_domain}"
# Geburtsdatum generieren
birthday = self.automation.birthday_generator.generate_birthday_components("tiktok", age)
# Account-Daten zusammenstellen
account_data = {
"username": username,
"password": password,
"full_name": full_name,
"email": email,
"phone": phone_number,
"birthday": birthday,
"age": age,
"registration_method": registration_method
}
logger.debug(f"Account-Daten generiert: {account_data['username']}")
return account_data
def _navigate_to_homepage(self) -> bool:
"""
Navigiert zur TikTok-Startseite.
Returns:
bool: True bei Erfolg, False bei Fehler
"""
try:
# Zur Startseite navigieren
self.browser.navigate_to(TikTokSelectors.BASE_URL)
# Warten, bis die Seite geladen ist
self.automation.human_behavior.wait_for_page_load()
# Screenshot erstellen
self.automation._take_screenshot("tiktok_homepage")
# Prüfen, ob die Seite korrekt geladen wurde
if not self.browser.is_element_visible(TikTokSelectors.LOGIN_BUTTON, timeout=5000):
logger.warning("TikTok-Startseite nicht korrekt geladen")
return False
logger.info("Erfolgreich zur TikTok-Startseite navigiert")
return True
except Exception as e:
logger.error(f"Fehler beim Navigieren zur TikTok-Startseite: {e}")
return False
def _handle_cookie_banner(self) -> bool:
"""
Behandelt den Cookie-Banner, falls angezeigt.
Returns:
bool: True wenn Banner behandelt wurde oder nicht existiert, False bei Fehler
"""
# Cookie-Dialog-Erkennung
if self.browser.is_element_visible(TikTokSelectors.COOKIE_DIALOG, timeout=2000):
logger.info("Cookie-Banner erkannt")
# Ablehnen-Button suchen und klicken
reject_success = self.automation.ui_helper.click_button_fuzzy(
TikTokSelectors.get_button_texts("reject_cookies"),
TikTokSelectors.COOKIE_REJECT_BUTTON
)
if reject_success:
logger.info("Cookie-Banner erfolgreich abgelehnt")
self.automation.human_behavior.random_delay(0.5, 1.5)
return True
else:
logger.warning("Konnte Cookie-Banner nicht ablehnen, versuche zu akzeptieren")
# Akzeptieren-Button als Fallback
accept_success = self.browser.click_element(TikTokSelectors.COOKIE_ACCEPT_BUTTON)
if accept_success:
logger.info("Cookie-Banner erfolgreich akzeptiert")
self.automation.human_behavior.random_delay(0.5, 1.5)
return True
else:
logger.error("Konnte Cookie-Banner weder ablehnen noch akzeptieren")
return False
else:
logger.debug("Kein Cookie-Banner erkannt")
return True
def _click_login_button(self) -> bool:
"""
Klickt auf den Anmelden-Button auf der Startseite.
Returns:
bool: True bei Erfolg, False bei Fehler
"""
try:
# Versuche zuerst den Hauptbutton
if self.browser.is_element_visible(TikTokSelectors.LOGIN_BUTTON, timeout=2000):
result = self.browser.click_element(TikTokSelectors.LOGIN_BUTTON)
if result:
logger.info("Anmelden-Button erfolgreich geklickt")
self.automation.human_behavior.random_delay(0.5, 1.5)
return True
# Versuche alternativ den Button in der oberen rechten Ecke
if self.browser.is_element_visible(TikTokSelectors.LOGIN_BUTTON_TOP_RIGHT, timeout=2000):
result = self.browser.click_element(TikTokSelectors.LOGIN_BUTTON_TOP_RIGHT)
if result:
logger.info("Anmelden-Button (oben rechts) erfolgreich geklickt")
self.automation.human_behavior.random_delay(0.5, 1.5)
return True
# Versuche es mit Fuzzy-Button-Matching
result = self.automation.ui_helper.click_button_fuzzy(
["Anmelden", "Log in", "Login"],
TikTokSelectors.LOGIN_BUTTON_FALLBACK
)
if result:
logger.info("Anmelden-Button über Fuzzy-Matching erfolgreich geklickt")
self.automation.human_behavior.random_delay(0.5, 1.5)
return True
logger.error("Konnte keinen Anmelden-Button finden")
return False
except Exception as e:
logger.error(f"Fehler beim Klicken auf den Anmelden-Button: {e}")
return False
def _click_register_link(self) -> bool:
"""
Klickt auf den Registrieren-Link im Login-Dialog.
Returns:
bool: True bei Erfolg, False bei Fehler
"""
try:
# Warten, bis der Login-Dialog angezeigt wird
self.automation.human_behavior.random_delay(1.0, 2.0)
# Prüfen, ob wir bereits im Registrierungsdialog sind
if self.browser.is_element_visible(TikTokSelectors.REGISTER_DIALOG_TITLE, timeout=2000):
logger.info("Bereits im Registrierungsdialog")
return True
# Versuche, den Registrieren-Link zu finden und zu klicken
if self.browser.is_element_visible(TikTokSelectors.REGISTER_LINK, timeout=2000):
result = self.browser.click_element(TikTokSelectors.REGISTER_LINK)
if result:
logger.info("Registrieren-Link erfolgreich geklickt")
self.automation.human_behavior.random_delay(0.5, 1.5)
return True
# Versuche es mit Fuzzy-Button-Matching
result = self.automation.ui_helper.click_button_fuzzy(
["Registrieren", "Sign up", "Konto erstellen", "Register"],
TikTokSelectors.REGISTER_LINK_FALLBACK
)
if result:
logger.info("Registrieren-Link über Fuzzy-Matching erfolgreich geklickt")
self.automation.human_behavior.random_delay(0.5, 1.5)
return True
# Prüfe, ob der Text "Du hast noch kein Konto? Registrieren" vorhanden ist
register_link_text = "Du hast noch kein Konto? Registrieren"
elements = self.browser.page.query_selector_all("*")
for element in elements:
if register_link_text in element.inner_text():
# Finde das "Registrieren"-Wort und klicke darauf
matches = re.search(r"(.*?)(Registrieren)$", element.inner_text())
if matches:
# Versuche, nur auf das Wort "Registrieren" zu klicken
element.click()
logger.info("Auf 'Registrieren' Text geklickt")
self.automation.human_behavior.random_delay(0.5, 1.5)
return True
logger.error("Konnte keinen Registrieren-Link finden")
return False
except Exception as e:
logger.error(f"Fehler beim Klicken auf den Registrieren-Link: {e}")
return False
def _click_phone_email_option(self) -> bool:
"""
Klickt auf die Telefon/E-Mail-Option im Registrierungsdialog.
Returns:
bool: True bei Erfolg, False bei Fehler
"""
try:
# Warten, bis der Registrierungsdialog angezeigt wird
self.automation.human_behavior.random_delay(1.0, 2.0)
# Prüfen, ob wir bereits die Optionen für Telefon/E-Mail sehen
if self.browser.is_element_visible(TikTokSelectors.EMAIL_FIELD, timeout=2000) or \
self.browser.is_element_visible(TikTokSelectors.PHONE_FIELD, timeout=2000):
logger.info("Bereits auf der Telefon/E-Mail-Registrierungsseite")
return True
# Versuche, die Telefon/E-Mail-Option zu finden und zu klicken
if self.browser.is_element_visible(TikTokSelectors.PHONE_EMAIL_OPTION, timeout=2000):
result = self.browser.click_element(TikTokSelectors.PHONE_EMAIL_OPTION)
if result:
logger.info("Telefon/E-Mail-Option erfolgreich geklickt")
self.automation.human_behavior.random_delay(0.5, 1.5)
return True
# Versuche es mit Fuzzy-Button-Matching
result = self.automation.ui_helper.click_button_fuzzy(
["Telefonnummer oder E-Mail-Adresse nutzen", "Use phone or email", "Phone or email"],
TikTokSelectors.PHONE_EMAIL_OPTION_FALLBACK
)
if result:
logger.info("Telefon/E-Mail-Option über Fuzzy-Matching erfolgreich geklickt")
self.automation.human_behavior.random_delay(0.5, 1.5)
return True
logger.error("Konnte keine Telefon/E-Mail-Option finden")
return False
except Exception as e:
logger.error(f"Fehler beim Klicken auf die Telefon/E-Mail-Option: {e}")
return False
def _select_registration_method(self, registration_method: str) -> bool:
"""
Wählt die Registrierungsmethode (E-Mail oder Telefon).
Args:
registration_method: "email" oder "phone"
Returns:
bool: True bei Erfolg, False bei Fehler
"""
try:
# Warten, bis die Registrierungsmethoden-Seite geladen ist
self.automation.human_behavior.random_delay(1.0, 2.0)
if registration_method == "email":
# Wenn bereits das E-Mail-Feld sichtbar ist, sind wir schon auf der richtigen Seite
if self.browser.is_element_visible(TikTokSelectors.EMAIL_FIELD, timeout=1000):
logger.info("Bereits auf der E-Mail-Registrierungsseite")
return True
# Suche nach dem "Mit E-Mail-Adresse registrieren" Link
if self.browser.is_element_visible(TikTokSelectors.EMAIL_OPTION, timeout=2000):
result = self.browser.click_element(TikTokSelectors.EMAIL_OPTION)
if result:
logger.info("E-Mail-Registrierungsmethode erfolgreich ausgewählt")
self.automation.human_behavior.random_delay(0.5, 1.5)
return True
# Versuche es mit Fuzzy-Button-Matching
result = self.automation.ui_helper.click_button_fuzzy(
["Mit E-Mail-Adresse registrieren", "Register with email", "E-Mail-Adresse"],
TikTokSelectors.EMAIL_OPTION_FALLBACK
)
if result:
logger.info("E-Mail-Option über Fuzzy-Matching erfolgreich geklickt")
self.automation.human_behavior.random_delay(0.5, 1.5)
return True
elif registration_method == "phone":
# Wenn bereits das Telefon-Feld sichtbar ist, sind wir schon auf der richtigen Seite
if self.browser.is_element_visible(TikTokSelectors.PHONE_FIELD, timeout=1000):
logger.info("Bereits auf der Telefon-Registrierungsseite")
return True
# Suche nach dem "Mit Telefonnummer registrieren" Link
if self.browser.is_element_visible(TikTokSelectors.PHONE_OPTION, timeout=2000):
result = self.browser.click_element(TikTokSelectors.PHONE_OPTION)
if result:
logger.info("Telefon-Registrierungsmethode erfolgreich ausgewählt")
self.automation.human_behavior.random_delay(0.5, 1.5)
return True
# Versuche es mit Fuzzy-Button-Matching
result = self.automation.ui_helper.click_button_fuzzy(
["Mit Telefonnummer registrieren", "Register with phone", "Telefonnummer"],
TikTokSelectors.PHONE_OPTION_FALLBACK
)
if result:
logger.info("Telefon-Option über Fuzzy-Matching erfolgreich geklickt")
self.automation.human_behavior.random_delay(0.5, 1.5)
return True
logger.error(f"Konnte Registrierungsmethode '{registration_method}' nicht auswählen")
return False
except Exception as e:
logger.error(f"Fehler beim Auswählen der Registrierungsmethode: {e}")
return False
def _enter_birthday(self, birthday: Dict[str, int]) -> bool:
"""
Gibt das Geburtsdatum ein.
Args:
birthday: Dictionary mit 'year', 'month', 'day' Schlüsseln
Returns:
bool: True bei Erfolg, False bei Fehler
"""
try:
# Warten, bis die Geburtstagsauswahl angezeigt wird
self.automation.human_behavior.random_delay(1.0, 2.0)
# Monat auswählen
month_dropdown = self.browser.wait_for_selector(TikTokSelectors.BIRTHDAY_MONTH_DROPDOWN, timeout=5000)
if not month_dropdown:
logger.error("Monat-Dropdown nicht gefunden")
return False
month_dropdown.click()
self.automation.human_behavior.random_delay(0.3, 0.8)
# Monat-Option auswählen
month_option = self.browser.wait_for_selector(
TikTokSelectors.get_month_option_selector(birthday["month"]),
timeout=3000
)
if month_option:
month_option.click()
logger.info(f"Monat {birthday['month']} ausgewählt")
else:
# Fallback: Monat über Select-Funktion auswählen
month_success = self.browser.select_option(
TikTokSelectors.BIRTHDAY_MONTH_DROPDOWN,
str(birthday["month"])
)
if not month_success:
logger.error(f"Konnte Monat {birthday['month']} nicht auswählen")
return False
self.automation.human_behavior.random_delay(0.3, 0.8)
# Tag auswählen
day_dropdown = self.browser.wait_for_selector(TikTokSelectors.BIRTHDAY_DAY_DROPDOWN, timeout=3000)
if not day_dropdown:
logger.error("Tag-Dropdown nicht gefunden")
return False
day_dropdown.click()
self.automation.human_behavior.random_delay(0.3, 0.8)
# Tag-Option auswählen
day_option = self.browser.wait_for_selector(
TikTokSelectors.get_day_option_selector(birthday["day"]),
timeout=3000
)
if day_option:
day_option.click()
logger.info(f"Tag {birthday['day']} ausgewählt")
else:
# Fallback: Tag über Select-Funktion auswählen
day_success = self.browser.select_option(
TikTokSelectors.BIRTHDAY_DAY_DROPDOWN,
str(birthday["day"])
)
if not day_success:
logger.error(f"Konnte Tag {birthday['day']} nicht auswählen")
return False
self.automation.human_behavior.random_delay(0.3, 0.8)
# Jahr auswählen
year_dropdown = self.browser.wait_for_selector(TikTokSelectors.BIRTHDAY_YEAR_DROPDOWN, timeout=3000)
if not year_dropdown:
logger.error("Jahr-Dropdown nicht gefunden")
return False
year_dropdown.click()
self.automation.human_behavior.random_delay(0.3, 0.8)
# Jahr-Option auswählen
year_option = self.browser.wait_for_selector(
TikTokSelectors.get_year_option_selector(birthday["year"]),
timeout=3000
)
if year_option:
year_option.click()
logger.info(f"Jahr {birthday['year']} ausgewählt")
else:
# Fallback: Jahr über Select-Funktion auswählen
year_success = self.browser.select_option(
TikTokSelectors.BIRTHDAY_YEAR_DROPDOWN,
str(birthday["year"])
)
if not year_success:
logger.error(f"Konnte Jahr {birthday['year']} nicht auswählen")
return False
logger.info(f"Geburtsdatum {birthday['month']}/{birthday['day']}/{birthday['year']} erfolgreich eingegeben")
return True
except Exception as e:
logger.error(f"Fehler beim Eingeben des Geburtsdatums: {e}")
return False
def _fill_registration_form(self, account_data: Dict[str, Any], registration_method: str) -> bool:
"""
Füllt das Registrierungsformular aus.
Args:
account_data: Account-Daten für die Registrierung
registration_method: "email" oder "phone"
Returns:
bool: True bei Erfolg, False bei Fehler
"""
try:
# Je nach Registrierungsmethode das entsprechende Feld ausfüllen
if registration_method == "email":
# E-Mail-Feld ausfüllen
email_success = self.automation.ui_helper.fill_field_fuzzy(
["E-Mail-Adresse", "Email", "E-Mail"],
account_data["email"],
TikTokSelectors.EMAIL_FIELD
)
if not email_success:
logger.error("Konnte E-Mail-Feld nicht ausfüllen")
return False
logger.info(f"E-Mail-Feld ausgefüllt: {account_data['email']}")
elif registration_method == "phone":
# Telefonnummer-Feld ausfüllen (ohne Ländervorwahl)
phone_number = account_data["phone"]
if phone_number.startswith("+"):
# Entferne Ländervorwahl, wenn vorhanden
parts = phone_number.split(" ", 1)
if len(parts) > 1:
phone_number = parts[1]
phone_success = self.automation.ui_helper.fill_field_fuzzy(
["Telefonnummer", "Phone number", "Phone"],
phone_number,
TikTokSelectors.PHONE_FIELD
)
if not phone_success:
logger.error("Konnte Telefonnummer-Feld nicht ausfüllen")
return False
logger.info(f"Telefonnummer-Feld ausgefüllt: {phone_number}")
self.automation.human_behavior.random_delay(0.5, 1.5)
# Bei E-Mail-Registrierung auch das Passwort-Feld ausfüllen
if registration_method == "email":
password_success = self.automation.ui_helper.fill_field_fuzzy(
["Passwort", "Password"],
account_data["password"],
TikTokSelectors.PASSWORD_FIELD
)
if not password_success:
logger.error("Konnte Passwort-Feld nicht ausfüllen")
return False
logger.info("Passwort-Feld ausgefüllt")
self.automation.human_behavior.random_delay(0.5, 1.5)
# Code senden Button klicken
send_code_success = self.automation.ui_helper.click_button_fuzzy(
["Code senden", "Send code", "Send verification code"],
TikTokSelectors.SEND_CODE_BUTTON
)
if not send_code_success:
logger.error("Konnte 'Code senden'-Button nicht klicken")
return False
logger.info("'Code senden'-Button erfolgreich geklickt")
return True
except Exception as e:
logger.error(f"Fehler beim Ausfüllen des Registrierungsformulars: {e}")
return False
def _handle_verification(self, account_data: Dict[str, Any], registration_method: str) -> bool:
"""
Behandelt den Verifizierungsprozess (E-Mail/SMS).
Args:
account_data: Account-Daten mit E-Mail/Telefon
registration_method: "email" oder "phone"
Returns:
bool: True bei Erfolg, False bei Fehler
"""
try:
# Warten, bis der Bestätigungscode gesendet wurde
self.automation.human_behavior.wait_for_page_load()
self.automation.human_behavior.random_delay(2.0, 4.0)
# Verifizierungscode je nach Methode abrufen
if registration_method == "email":
# Verifizierungscode von E-Mail abrufen
verification_code = self._get_email_confirmation_code(account_data["email"])
else:
# Verifizierungscode von SMS abrufen
verification_code = self._get_sms_confirmation_code(account_data["phone"])
if not verification_code:
logger.error("Konnte keinen Verifizierungscode abrufen")
return False
logger.info(f"Verifizierungscode erhalten: {verification_code}")
# Verifizierungscode-Feld ausfüllen
code_success = self.automation.ui_helper.fill_field_fuzzy(
["Gib den sechsstelligen Code ein", "Enter verification code", "Verification code"],
verification_code,
TikTokSelectors.VERIFICATION_CODE_FIELD
)
if not code_success:
logger.error("Konnte Verifizierungscode-Feld nicht ausfüllen")
return False
self.automation.human_behavior.random_delay(1.0, 2.0)
# Weiter-Button klicken
continue_success = self.automation.ui_helper.click_button_fuzzy(
["Weiter", "Continue", "Next", "Submit"],
TikTokSelectors.CONTINUE_BUTTON
)
if not continue_success:
logger.error("Konnte 'Weiter'-Button nicht klicken")
return False
logger.info("Verifizierungscode eingegeben und 'Weiter' geklickt")
# Warten nach der Verifizierung
self.automation.human_behavior.wait_for_page_load()
self.automation.human_behavior.random_delay(1.0, 2.0)
return True
except Exception as e:
logger.error(f"Fehler bei der Verifizierung: {e}")
return False
def _get_email_confirmation_code(self, email: str) -> Optional[str]:
"""
Ruft den Bestätigungscode von einer E-Mail ab.
Args:
email: E-Mail-Adresse, an die der Code gesendet wurde
Returns:
Optional[str]: Der Bestätigungscode oder None, wenn nicht gefunden
"""
try:
# Warte auf die E-Mail
verification_code = self.automation.email_handler.get_verification_code(
email_domain=self.automation.email_domain,
platform="tiktok",
timeout=120 # Warte bis zu 2 Minuten auf den Code
)
if verification_code:
return verification_code
# Wenn kein Code gefunden wurde, prüfen, ob der Code vielleicht direkt angezeigt wird
verification_code = self._extract_code_from_page()
if verification_code:
logger.info(f"Verifizierungscode direkt von der Seite extrahiert: {verification_code}")
return verification_code
logger.warning(f"Konnte keinen Verifizierungscode für {email} finden")
return None
except Exception as e:
logger.error(f"Fehler beim Abrufen des E-Mail-Bestätigungscodes: {e}")
return None
def _get_sms_confirmation_code(self, phone: str) -> Optional[str]:
"""
Ruft den Bestätigungscode aus einer SMS ab.
Hier müsste ein SMS-Empfangs-Service eingebunden werden.
Args:
phone: Telefonnummer, an die der Code gesendet wurde
Returns:
Optional[str]: Der Bestätigungscode oder None, wenn nicht gefunden
"""
# Diese Implementierung ist ein Platzhalter
# In einer echten Implementierung würde hier ein SMS-Empfangs-Service verwendet
logger.warning("SMS-Verifizierung ist noch nicht implementiert")
# Versuche, den Code trotzdem zu extrahieren, falls er auf der Seite angezeigt wird
return self._extract_code_from_page()
def _extract_code_from_page(self) -> Optional[str]:
"""
Versucht, einen Bestätigungscode direkt von der Seite zu extrahieren.
Returns:
Optional[str]: Der extrahierte Code oder None, wenn nicht gefunden
"""
try:
# Gesamten Seiteninhalt abrufen
page_content = self.browser.page.content()
# Mögliche Regex-Muster für Bestätigungscodes
patterns = [
r"Dein Code ist (\d{6})",
r"Your code is (\d{6})",
r"Bestätigungscode: (\d{6})",
r"Confirmation code: (\d{6})",
r"(\d{6}) ist dein TikTok-Code",
r"(\d{6}) is your TikTok code"
]
for pattern in patterns:
match = re.search(pattern, page_content)
if match:
return match.group(1)
return None
except Exception as e:
logger.error(f"Fehler beim Extrahieren des Codes von der Seite: {e}")
return None
def _create_username(self, account_data: Dict[str, Any]) -> bool:
"""
Erstellt einen Benutzernamen.
Args:
account_data: Account-Daten
Returns:
bool: True bei Erfolg, False bei Fehler
"""
try:
# Warten, bis die Benutzernamen-Seite geladen ist
self.automation.human_behavior.wait_for_page_load()
# Prüfen, ob wir auf der Benutzernamen-Seite sind
if not self.browser.is_element_visible(TikTokSelectors.USERNAME_FIELD, timeout=5000):
logger.warning("Benutzernamen-Feld nicht gefunden, möglicherweise ist dieser Schritt übersprungen worden")
# Versuche, den "Überspringen"-Button zu klicken, falls vorhanden
skip_visible = self.browser.is_element_visible(TikTokSelectors.SKIP_USERNAME_BUTTON, timeout=2000)
if skip_visible:
self.browser.click_element(TikTokSelectors.SKIP_USERNAME_BUTTON)
logger.info("Benutzernamen-Schritt übersprungen")
return True
# Möglicherweise wurde der Benutzername automatisch erstellt
logger.info("Benutzernamen-Schritt möglicherweise automatisch abgeschlossen")
return True
# Benutzernamen eingeben
username_success = self.automation.ui_helper.fill_field_fuzzy(
["Benutzername", "Username"],
account_data["username"],
TikTokSelectors.USERNAME_FIELD
)
if not username_success:
logger.error("Konnte Benutzernamen-Feld nicht ausfüllen")
return False
logger.info(f"Benutzernamen-Feld ausgefüllt: {account_data['username']}")
self.automation.human_behavior.random_delay(1.0, 2.0)
# Registrieren-Button klicken
register_success = self.automation.ui_helper.click_button_fuzzy(
["Registrieren", "Register", "Sign up", "Submit"],
TikTokSelectors.REGISTER_BUTTON
)
if not register_success:
logger.error("Konnte 'Registrieren'-Button nicht klicken")
return False
logger.info("'Registrieren'-Button erfolgreich geklickt")
# Warten nach der Registrierung
self.automation.human_behavior.wait_for_page_load()
return True
except Exception as e:
logger.error(f"Fehler beim Erstellen des Benutzernamens: {e}")
return False
def _check_registration_success(self) -> bool:
"""
Überprüft, ob die Registrierung erfolgreich war.
Returns:
bool: True wenn erfolgreich, False sonst
"""
try:
# Warten nach der Registrierung
self.automation.human_behavior.wait_for_page_load(multiplier=2.0)
# Screenshot erstellen
self.automation._take_screenshot("registration_final")
# Erfolg anhand verschiedener Indikatoren prüfen
success_indicators = TikTokSelectors.SUCCESS_INDICATORS
for indicator in success_indicators:
if self.browser.is_element_visible(indicator, timeout=3000):
logger.info(f"Erfolgsindikator gefunden: {indicator}")
return True
# Alternativ prüfen, ob wir auf der TikTok-Startseite sind
current_url = self.browser.page.url
if "tiktok.com" in current_url and "/signup" not in current_url and "/login" not in current_url:
logger.info(f"Erfolg basierend auf URL: {current_url}")
return True
logger.warning("Keine Erfolgsindikatoren gefunden")
return False
except Exception as e:
logger.error(f"Fehler beim Überprüfen des Registrierungserfolgs: {e}")
return False