Files
AccountForger-neuerUpload/social_networks/tiktok/tiktok_workflow.py
Claude Project Manager 04585e95b6 Initial commit
2025-08-01 23:50:28 +02:00

427 Zeilen
17 KiB
Python

"""
TikTok-Workflow - Definiert die Schritte für die TikTok-Anmeldung und -Registrierung
"""
from typing import Dict, List, Any, Optional, Tuple
import re
from utils.text_similarity import TextSimilarity
from utils.logger import setup_logger
# Konfiguriere Logger
logger = setup_logger("tiktok_workflow")
class TikTokWorkflow:
"""
Definiert die Workflow-Schritte für verschiedene TikTok-Aktionen
wie Registrierung, Anmeldung und Verifizierung.
"""
# Text-Ähnlichkeits-Threshold für Fuzzy-Matching
SIMILARITY_THRESHOLD = 0.7
# Initialisiere TextSimilarity für Matching
text_similarity = TextSimilarity(default_threshold=SIMILARITY_THRESHOLD)
# Mögliche alternative Texte für verschiedene UI-Elemente
TEXT_ALTERNATIVES = {
"email": ["E-Mail", "Email", "E-mail", "Mail", "email"],
"phone": ["Telefon", "Telefonnummer", "Phone", "Mobile", "mobile"],
"password": ["Passwort", "Password", "pass"],
"code": ["Code", "Bestätigungscode", "Verification code", "Sicherheitscode"],
"username": ["Benutzername", "Username", "user name"],
"submit": ["Registrieren", "Sign up", "Anmelden", "Login", "Log in", "Submit"],
"next": ["Weiter", "Next", "Continue", "Fortfahren"],
"skip": ["Überspringen", "Skip", "Later", "Später", "Not now", "Nicht jetzt"]
}
@staticmethod
def get_registration_workflow(registration_method: str = "email") -> List[Dict[str, Any]]:
"""
Gibt den Workflow für die TikTok-Registrierung zurück.
Args:
registration_method: "email" oder "phone"
Returns:
List[Dict[str, Any]]: Liste von Workflow-Schritten
"""
# Basisschritte für beide Methoden
common_steps = [
{
"name": "navigate_to_signup",
"description": "Zur TikTok-Startseite navigieren",
"url": "https://www.tiktok.com",
"wait_for": ["button#header-login-button", "button#top-right-action-bar-login-button"],
"fuzzy_match": None
},
{
"name": "click_login_button",
"description": "Anmelden-Button klicken",
"action": "click",
"target": "button#top-right-action-bar-login-button",
"wait_for": ["a[href*='/signup']", "div[role='dialog']"],
"fuzzy_match": ["Anmelden", "Sign in", "Log in"]
},
{
"name": "click_register_link",
"description": "Registrieren-Link klicken",
"action": "click",
"target": "a[href*='/signup']",
"wait_for": ["div[data-e2e='channel-item']"],
"fuzzy_match": ["Registrieren", "Sign up", "Register"]
},
{
"name": "click_phone_email_button",
"description": "Telefon/E-Mail-Option auswählen",
"action": "click",
"target": "div[data-e2e='channel-item']",
"wait_for": ["a[href*='/signup/phone-or-email/email']", "a[href*='/signup/phone-or-email/phone']"],
"fuzzy_match": ["Telefonnummer oder E-Mail-Adresse", "Phone or Email"]
}
]
# Spezifische Schritte je nach Registrierungsmethode
method_steps = []
if registration_method == "email":
method_steps.append({
"name": "click_email_registration",
"description": "Mit E-Mail registrieren auswählen",
"action": "click",
"target": "a[href*='/signup/phone-or-email/email']",
"wait_for": ["input[placeholder='E-Mail-Adresse']"],
"fuzzy_match": ["Mit E-Mail-Adresse registrieren", "Email", "E-Mail"]
})
else: # phone
method_steps.append({
"name": "click_phone_registration",
"description": "Mit Telefonnummer registrieren auswählen",
"action": "click",
"target": "a[href*='/signup/phone-or-email/phone']",
"wait_for": ["input[placeholder='Telefonnummer']"],
"fuzzy_match": ["Mit Telefonnummer registrieren", "Phone", "Telefon"]
})
# Geburtsdatum-Schritte
birthday_steps = [
{
"name": "select_birth_month",
"description": "Geburtsmonat auswählen",
"action": "click",
"target": "div.css-1fi2hzv-DivSelectLabel:contains('Monat')",
"wait_for": ["div[role='option']"],
"fuzzy_match": ["Monat", "Month"]
},
{
"name": "select_month_option",
"description": "Monats-Option auswählen",
"action": "select_option",
"target": "div[role='option']",
"value": "{MONTH_NAME}",
"wait_for": [],
"fuzzy_match": None
},
{
"name": "select_birth_day",
"description": "Geburtstag auswählen",
"action": "click",
"target": "div.css-1fi2hzv-DivSelectLabel:contains('Tag')",
"wait_for": ["div[role='option']"],
"fuzzy_match": ["Tag", "Day"]
},
{
"name": "select_day_option",
"description": "Tags-Option auswählen",
"action": "select_option",
"target": "div[role='option']",
"value": "{DAY}",
"wait_for": [],
"fuzzy_match": None
},
{
"name": "select_birth_year",
"description": "Geburtsjahr auswählen",
"action": "click",
"target": "div.css-1fi2hzv-DivSelectLabel:contains('Jahr')",
"wait_for": ["div[role='option']"],
"fuzzy_match": ["Jahr", "Year"]
},
{
"name": "select_year_option",
"description": "Jahres-Option auswählen",
"action": "select_option",
"target": "div[role='option']",
"value": "{YEAR}",
"wait_for": [],
"fuzzy_match": None
}
]
# Formularschritte für E-Mail
email_form_steps = [
{
"name": "fill_email",
"description": "E-Mail-Adresse eingeben",
"action": "fill",
"target": "input[placeholder='E-Mail-Adresse']",
"value": "{EMAIL}",
"fuzzy_match": TikTokWorkflow.TEXT_ALTERNATIVES["email"]
},
{
"name": "fill_password",
"description": "Passwort eingeben",
"action": "fill",
"target": "input[placeholder='Passwort']",
"value": "{PASSWORD}",
"fuzzy_match": TikTokWorkflow.TEXT_ALTERNATIVES["password"]
},
{
"name": "click_send_code",
"description": "Code senden klicken",
"action": "click",
"target": "button[data-e2e='send-code-button']",
"wait_for": ["input[placeholder*='sechsstelligen Code']"],
"fuzzy_match": ["Code senden", "Send code", "Senden"]
},
{
"name": "fill_verification_code",
"description": "Bestätigungscode eingeben",
"action": "fill",
"target": "input[placeholder*='sechsstelligen Code']",
"value": "{VERIFICATION_CODE}",
"fuzzy_match": TikTokWorkflow.TEXT_ALTERNATIVES["code"]
},
{
"name": "click_continue",
"description": "Weiter klicken",
"action": "click",
"target": "button[type='submit']",
"wait_for": ["input[placeholder='Benutzername']"],
"fuzzy_match": TikTokWorkflow.TEXT_ALTERNATIVES["next"]
}
]
# Formularschritte für Telefon
phone_form_steps = [
{
"name": "select_country_code",
"description": "Ländervorwahl auswählen",
"action": "click",
"target": "div[role='combobox']",
"wait_for": ["div[role='option']"],
"fuzzy_match": None
},
{
"name": "select_country_option",
"description": "Land auswählen",
"action": "select_option",
"target": "div[role='option']",
"value": "{COUNTRY_NAME}",
"wait_for": [],
"fuzzy_match": None
},
{
"name": "fill_phone",
"description": "Telefonnummer eingeben",
"action": "fill",
"target": "input[placeholder='Telefonnummer']",
"value": "{PHONE}",
"fuzzy_match": TikTokWorkflow.TEXT_ALTERNATIVES["phone"]
},
{
"name": "click_send_code",
"description": "Code senden klicken",
"action": "click",
"target": "button[data-e2e='send-code-button']",
"wait_for": ["input[placeholder*='sechsstelligen Code']"],
"fuzzy_match": ["Code senden", "Send code", "Senden"]
},
{
"name": "fill_verification_code",
"description": "Bestätigungscode eingeben",
"action": "fill",
"target": "input[placeholder*='sechsstelligen Code']",
"value": "{VERIFICATION_CODE}",
"fuzzy_match": TikTokWorkflow.TEXT_ALTERNATIVES["code"]
},
{
"name": "click_continue",
"description": "Weiter klicken",
"action": "click",
"target": "button[type='submit']",
"wait_for": ["input[placeholder='Benutzername']"],
"fuzzy_match": TikTokWorkflow.TEXT_ALTERNATIVES["next"]
}
]
# Benutzername-Schritte
username_steps = [
{
"name": "fill_username",
"description": "Benutzernamen eingeben",
"action": "fill",
"target": "input[placeholder='Benutzername']",
"value": "{USERNAME}",
"fuzzy_match": TikTokWorkflow.TEXT_ALTERNATIVES["username"]
},
{
"name": "click_register",
"description": "Registrieren klicken",
"action": "click",
"target": "button:contains('Registrieren')",
"wait_for": ["a[href='/foryou']", "button:contains('Überspringen')"],
"fuzzy_match": TikTokWorkflow.TEXT_ALTERNATIVES["submit"]
},
{
"name": "handle_skip_option",
"description": "Optional: Überspringen klicken",
"action": "click",
"target": "button:contains('Überspringen')",
"optional": True,
"wait_for": ["a[href='/foryou']"],
"fuzzy_match": TikTokWorkflow.TEXT_ALTERNATIVES["skip"]
}
]
# Vollständigen Workflow zusammenstellen
if registration_method == "email":
workflow = common_steps + method_steps + birthday_steps + email_form_steps + username_steps
else: # phone
workflow = common_steps + method_steps + birthday_steps + phone_form_steps + username_steps
return workflow
@staticmethod
def get_login_workflow() -> List[Dict[str, Any]]:
"""
Gibt den Workflow für die TikTok-Anmeldung zurück.
Returns:
List[Dict[str, Any]]: Liste von Workflow-Schritten
"""
login_steps = [
{
"name": "navigate_to_login",
"description": "Zur TikTok-Startseite navigieren",
"url": "https://www.tiktok.com",
"wait_for": ["button#header-login-button", "button#top-right-action-bar-login-button"],
"fuzzy_match": None
},
{
"name": "click_login_button",
"description": "Anmelden-Button klicken",
"action": "click",
"target": "button#top-right-action-bar-login-button",
"wait_for": ["div[role='dialog']"],
"fuzzy_match": ["Anmelden", "Sign in", "Log in"]
},
{
"name": "click_phone_email_button",
"description": "Telefon/E-Mail-Option auswählen",
"action": "click",
"target": "div[data-e2e='channel-item']",
"wait_for": ["input[type='text']"],
"fuzzy_match": ["Telefon-Nr./E-Mail/Anmeldename", "Phone or Email"]
},
{
"name": "fill_login_field",
"description": "Benutzername/E-Mail/Telefon eingeben",
"action": "fill",
"target": "input[type='text']",
"value": "{USERNAME_OR_EMAIL}",
"fuzzy_match": ["Email", "Benutzername", "Telefon"]
},
{
"name": "fill_password",
"description": "Passwort eingeben",
"action": "fill",
"target": "input[type='password']",
"value": "{PASSWORD}",
"fuzzy_match": TikTokWorkflow.TEXT_ALTERNATIVES["password"]
},
{
"name": "click_login",
"description": "Anmelden klicken",
"action": "click",
"target": "button[type='submit']",
"wait_for": ["a[href='/foryou']"],
"fuzzy_match": ["Anmelden", "Log in", "Login"]
}
]
return login_steps
@staticmethod
def get_verification_workflow() -> List[Dict[str, Any]]:
"""
Gibt den Workflow für die TikTok-Verifizierung zurück.
Returns:
List[Dict[str, Any]]: Liste von Workflow-Schritten
"""
verification_steps = [
{
"name": "fill_verification_code",
"description": "Bestätigungscode eingeben",
"action": "fill",
"target": "input[placeholder*='sechsstelligen Code']",
"value": "{VERIFICATION_CODE}",
"fuzzy_match": TikTokWorkflow.TEXT_ALTERNATIVES["code"]
},
{
"name": "click_continue",
"description": "Weiter klicken",
"action": "click",
"target": "button[type='submit']",
"wait_for": ["input[placeholder='Benutzername']", "a[href='/foryou']"],
"fuzzy_match": TikTokWorkflow.TEXT_ALTERNATIVES["next"]
}
]
return verification_steps
@staticmethod
def identify_current_step(page_title: str, page_url: str, visible_elements: List[str]) -> str:
"""
Identifiziert den aktuellen Schritt basierend auf dem Seitentitel, der URL und sichtbaren Elementen.
Args:
page_title: Titel der Seite
page_url: URL der Seite
visible_elements: Liste sichtbarer Elemente (Selektoren)
Returns:
str: Name des identifizierten Schritts
"""
# Auf der Startseite
if "tiktok.com" in page_url and not "/signup" in page_url and not "/login" in page_url:
return "navigate_to_signup"
# Anmelde-/Registrierungsauswahl
if "signup" in page_url or "login" in page_url:
if any("channel-item" in element for element in visible_elements):
return "click_phone_email_button"
# Geburtsdatum
if "Monat" in page_title or "Month" in page_title or any("Geburtsdatum" in element for element in visible_elements):
return "select_birth_month"
# E-Mail-/Telefon-Eingabe
if any("E-Mail-Adresse" in element for element in visible_elements):
return "fill_email"
if any("Telefonnummer" in element for element in visible_elements):
return "fill_phone"
# Bestätigungscode
if any("sechsstelligen Code" in element for element in visible_elements):
return "fill_verification_code"
# Benutzernamen-Erstellung
if any("Benutzername" in element for element in visible_elements):
return "fill_username"
# Erfolgreiche Anmeldung
if "foryou" in page_url or any("Für dich" in element for element in visible_elements):
return "logged_in"
return "unknown"