From 51011f9e97c7836874d660d1d1bf117ac69c4543 Mon Sep 17 00:00:00 2001 From: Claude Project Manager Date: Sun, 14 Sep 2025 03:19:39 +0200 Subject: [PATCH] TikTok - Geburtstagsfeld gefixt --- social_networks/tiktok/tiktok_registration.py | 180 +++++++++++------- 1 file changed, 116 insertions(+), 64 deletions(-) diff --git a/social_networks/tiktok/tiktok_registration.py b/social_networks/tiktok/tiktok_registration.py index 1176d6d..ede1cda 100644 --- a/social_networks/tiktok/tiktok_registration.py +++ b/social_networks/tiktok/tiktok_registration.py @@ -709,22 +709,27 @@ class TikTokRegistration: self.automation._take_screenshot("birthday_page") # Verschiedene Monat-Dropdown-Selektoren versuchen + # WICHTIG: TikTok ändert CSS-Klassen dynamisch, daher viele Fallbacks month_selectors = [ - "div.css-1fi2hzv-DivSelectLabel:has-text('Monat')", # Exakt TikTok-Klasse - "div.e1phcp2x1:has-text('Monat')", # TikTok-Klasse alternative - "div:has-text('Monat')", # Text-basiert (funktioniert!) - self.selectors.BIRTHDAY_MONTH_DROPDOWN, # select[name='month'] - "div[data-e2e='date-picker-month']", # TikTok-spezifisch - "button[data-testid='month-selector']", # Test-ID - "div:has-text('Month')", # Englisch - "[aria-label*='Month']", # Aria-Label - "[aria-label*='Monat']", # Deutsch - "div[role='combobox']:has-text('Monat')", # Combobox - ".month-selector", # CSS-Klasse - ".date-picker-month", # CSS-Klasse - "//div[contains(text(), 'Monat')]", # XPath - "//button[contains(text(), 'Monat')]", # XPath Button - "//select[@name='month']" # XPath Select + # Neue TikTok CSS-Klassen (2025) + "div[class*='DivSelectLabel']:has-text('Monat')", # Partial class match + "div.eoyer411:has-text('Monat')", # Neue spezifische Klasse + + # Generische Selektoren (stabiler) + "div:has-text('Monat'):has(svg)", # Dropdown mit SVG-Pfeil + "div:text-is('Monat')", # Exakter Text + "div:has-text('Monat')", # Text-basiert + + # Alte Selektoren (Fallback) + "div.css-1fi2hzv-DivSelectLabel:has-text('Monat')", # Alt TikTok-Klasse + "div.e1phcp2x1:has-text('Monat')", # Alt TikTok-Klasse + + # Alternative Ansätze + self.selectors.BIRTHDAY_MONTH_DROPDOWN, # select[name='month'] + "div[data-e2e='date-picker-month']", # TikTok-spezifisch + "div:has-text('Month')", # Englisch + "[aria-label*='Monat']", # Aria-Label + "div[role='combobox']:has-text('Monat')" # Combobox ] month_dropdown = None @@ -753,17 +758,29 @@ class TikTokRegistration: month_selected = False month_option_selectors = [ - f"div.css-vz5m7n-DivOption:has-text('{month_name}')", # Exakte TikTok-Klasse + Monatsname - f"div.e1phcp2x5:has-text('{month_name}')", # TikTok-Klasse alternative + Monatsname + # Neue TikTok Selektoren (2025) mit ID-Pattern + f"#Month-options-item-{birthday['month']-1}", # ID-basiert (0-indexed) + f"div#Month-options-item-{birthday['month']-1}", # Mit div prefix + + # Neue CSS-Klassen + f"div[class*='DivOption']:has-text('{month_name}')", # Partial class match + f"div.eoyer415:has-text('{month_name}')", # Neue spezifische Klasse + + # Role-basierte Selektoren (stabiler) f"[role='option']:has-text('{month_name}')", # Role + Monatsname + f"div[role='option']:has-text('{month_name}')", # Div mit Role + + # Text-basierte Selektoren + f"div:text-is('{month_name}')", # Exakter Text f"div:has-text('{month_name}')", # Einfach Monatsname - f"//div[@role='option'][contains(text(), '{month_name}')]", # XPath + Monatsname - f"option[value='{birthday['month']}']", # Standard HTML (Fallback) - f"div[data-value='{birthday['month']}']", # Custom Dropdown (Fallback) - f"li[data-value='{birthday['month']}']", # List-Item (Fallback) - f"button:has-text('{birthday['month']:02d}')", # Button mit Monatszahl (Fallback) - f"div:has-text('{birthday['month']:02d}')", # Div mit Monatszahl (Fallback) - f"[role='option']:has-text('{birthday['month']:02d}')" # Role-based Zahl (Fallback) + + # Alte Selektoren (Fallback) + f"div.css-vz5m7n-DivOption:has-text('{month_name}')", # Alt TikTok-Klasse + f"div.e1phcp2x5:has-text('{month_name}')", # Alt TikTok-Klasse + + # Alternative Fallbacks + f"option[value='{birthday['month']}']", # Standard HTML + f"div[data-value='{birthday['month']}']" # Custom Dropdown ] for i, option_selector in enumerate(month_option_selectors): @@ -786,21 +803,25 @@ class TikTokRegistration: # Tag-Dropdown finden day_selectors = [ - "div.css-1fi2hzv-DivSelectLabel:has-text('Tag')", # Exakt TikTok-Klasse - "div.e1phcp2x1:has-text('Tag')", # TikTok-Klasse alternative - "div:has-text('Tag')", # Text-basiert + # Neue TikTok CSS-Klassen (2025) + "div[class*='DivSelectLabel']:has-text('Tag')", # Partial class match + "div.eoyer411:has-text('Tag')", # Neue spezifische Klasse + + # Generische Selektoren (stabiler) + "div:has-text('Tag'):has(svg)", # Dropdown mit SVG-Pfeil + "div:text-is('Tag')", # Exakter Text + "div:has-text('Tag')", # Text-basiert + + # Alte Selektoren (Fallback) + "div.css-1fi2hzv-DivSelectLabel:has-text('Tag')", # Alt TikTok-Klasse + "div.e1phcp2x1:has-text('Tag')", # Alt TikTok-Klasse + + # Alternative Ansätze self.selectors.BIRTHDAY_DAY_DROPDOWN, # select[name='day'] "div[data-e2e='date-picker-day']", # TikTok-spezifisch - "button[data-testid='day-selector']", # Test-ID "div:has-text('Day')", # Englisch - "[aria-label*='Day']", # Aria-Label - "[aria-label*='Tag']", # Deutsch - "div[role='combobox']:has-text('Tag')", # Combobox - ".day-selector", # CSS-Klasse - ".date-picker-day", # CSS-Klasse - "//div[contains(text(), 'Tag')]", # XPath - "//button[contains(text(), 'Tag')]", # XPath Button - "//select[@name='day']" # XPath Select + "[aria-label*='Tag']", # Aria-Label + "div[role='combobox']:has-text('Tag')" # Combobox ] day_dropdown = None @@ -825,16 +846,25 @@ class TikTokRegistration: # Tag-Option auswählen - TikTok verwendet einfache Zahlen day_selected = False day_option_selectors = [ - f"div.css-vz5m7n-DivOption:has-text('{birthday['day']}')", # Exakte TikTok-Klasse + Tag - f"div.e1phcp2x5:has-text('{birthday['day']}')", # TikTok-Klasse alternative + Tag + # Neue TikTok Selektoren (2025) mit ID-Pattern + f"#Day-options-item-{birthday['day']-1}", # ID-basiert (0-indexed) + f"div#Day-options-item-{birthday['day']-1}", # Mit div prefix + + # Neue CSS-Klassen + f"div[class*='DivOption']:has-text('{birthday['day']}')", # Partial class match + f"div.eoyer415:has-text('{birthday['day']}')", # Neue spezifische Klasse + + # Role-basierte Selektoren (stabiler) f"[role='option']:has-text('{birthday['day']}')", # Role + Tag + f"div[role='option']:has-text('{birthday['day']}')", # Div mit Role + + # Text-basierte Selektoren + f"div:text-is('{birthday['day']}')", # Exakter Text f"div:has-text('{birthday['day']}')", # Einfach Tag - f"//div[@role='option'][contains(text(), '{birthday['day']}')]", # XPath + Tag - f"option[value='{birthday['day']}']", # Standard HTML (Fallback) - f"div[data-value='{birthday['day']}']", # Custom Dropdown (Fallback) - f"li[data-value='{birthday['day']}']", # List-Item (Fallback) - f"button:has-text('{birthday['day']:02d}')", # Button mit führender Null (Fallback) - f"div:has-text('{birthday['day']:02d}')" # Div mit führender Null (Fallback) + + # Alte Selektoren (Fallback) + f"div.css-vz5m7n-DivOption:has-text('{birthday['day']}')", # Alt TikTok-Klasse + f"div.e1phcp2x5:has-text('{birthday['day']}')" # Alt TikTok-Klasse ] for i, option_selector in enumerate(day_option_selectors): @@ -857,21 +887,25 @@ class TikTokRegistration: # Jahr-Dropdown finden year_selectors = [ - "div.css-1fi2hzv-DivSelectLabel:has-text('Jahr')", # Exakt TikTok-Klasse - "div.e1phcp2x1:has-text('Jahr')", # TikTok-Klasse alternative - "div:has-text('Jahr')", # Text-basiert + # Neue TikTok CSS-Klassen (2025) + "div[class*='DivSelectLabel']:has-text('Jahr')", # Partial class match + "div.eoyer411:has-text('Jahr')", # Neue spezifische Klasse + + # Generische Selektoren (stabiler) + "div:has-text('Jahr'):has(svg)", # Dropdown mit SVG-Pfeil + "div:text-is('Jahr')", # Exakter Text + "div:has-text('Jahr')", # Text-basiert + + # Alte Selektoren (Fallback) + "div.css-1fi2hzv-DivSelectLabel:has-text('Jahr')", # Alt TikTok-Klasse + "div.e1phcp2x1:has-text('Jahr')", # Alt TikTok-Klasse + + # Alternative Ansätze self.selectors.BIRTHDAY_YEAR_DROPDOWN, # select[name='year'] "div[data-e2e='date-picker-year']", # TikTok-spezifisch - "button[data-testid='year-selector']", # Test-ID "div:has-text('Year')", # Englisch - "[aria-label*='Year']", # Aria-Label - "[aria-label*='Jahr']", # Deutsch - "div[role='combobox']:has-text('Jahr')", # Combobox - ".year-selector", # CSS-Klasse - ".date-picker-year", # CSS-Klasse - "//div[contains(text(), 'Jahr')]", # XPath - "//button[contains(text(), 'Jahr')]", # XPath Button - "//select[@name='year']" # XPath Select + "[aria-label*='Jahr']", # Aria-Label + "div[role='combobox']:has-text('Jahr')" # Combobox ] year_dropdown = None @@ -895,17 +929,35 @@ class TikTokRegistration: # Jahr-Option auswählen - TikTok verwendet vierstellige Jahreszahlen year_selected = False + # Berechne den Index für das Jahr (normalerweise absteigend sortiert) + # Annahme: Jahre von aktuellem Jahr bis 1900, also Index = aktuelles_jahr - gewähltes_jahr + current_year = 2025 # oder datetime.now().year + year_index = current_year - birthday['year'] + year_option_selectors = [ - f"div.css-vz5m7n-DivOption:has-text('{birthday['year']}')", # Exakte TikTok-Klasse + Jahr - f"div.e1phcp2x5:has-text('{birthday['year']}')", # TikTok-Klasse alternative + Jahr + # Neue TikTok Selektoren (2025) mit ID-Pattern + f"#Year-options-item-{year_index}", # ID-basiert (Index berechnet) + f"div#Year-options-item-{year_index}", # Mit div prefix + + # Neue CSS-Klassen + f"div[class*='DivOption']:has-text('{birthday['year']}')", # Partial class match + f"div.eoyer415:has-text('{birthday['year']}')", # Neue spezifische Klasse + + # Role-basierte Selektoren (stabiler) f"[role='option']:has-text('{birthday['year']}')", # Role + Jahr + f"div[role='option']:has-text('{birthday['year']}')", # Div mit Role + + # Text-basierte Selektoren + f"div:text-is('{birthday['year']}')", # Exakter Text f"div:has-text('{birthday['year']}')", # Einfach Jahr - f"//div[@role='option'][contains(text(), '{birthday['year']}')]", # XPath + Jahr - f"option[value='{birthday['year']}']", # Standard HTML (Fallback) - f"div[data-value='{birthday['year']}']", # Custom Dropdown (Fallback) - f"li[data-value='{birthday['year']}']", # List-Item (Fallback) - f"button:has-text('{birthday['year']}')", # Button (Fallback) - f"span:has-text('{birthday['year']}')" # Span (Fallback) + + # Alte Selektoren (Fallback) + f"div.css-vz5m7n-DivOption:has-text('{birthday['year']}')", # Alt TikTok-Klasse + f"div.e1phcp2x5:has-text('{birthday['year']}')", # Alt TikTok-Klasse + + # Alternative Fallbacks + f"option[value='{birthday['year']}']", # Standard HTML + f"div[data-value='{birthday['year']}']" # Custom Dropdown ] for i, option_selector in enumerate(year_option_selectors):