From 6e94ecd5c50011a4ddda49d5625620df400837dd Mon Sep 17 00:00:00 2001 From: 71x14 <1110flanon2010@gmail.com> Date: Thu, 15 May 2025 16:58:14 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F:=20=D1=82=D0=BE=D0=BB=D1=8C=D0=BA?= =?UTF-8?q?=D0=BE=20=D0=BE=D1=84=D0=B8=D1=86=D0=B8=D0=B0=D0=BB=D1=8C=D0=BD?= =?UTF-8?q?=D1=8B=D0=B9=20SMS-Activate,=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20proxy=20=D0=B8=20=D0=B3=D0=B5?= =?UTF-8?q?=D0=BD=D0=B5=D1=80=D0=B0=D1=82=D0=BE=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../account/GoogleAccountGeneratorImpl.java | 13 +- .../google/accountgen/proxy/ProxyManager.java | 47 +- .../GoogleRegistrationHandler.java | 496 +++++++++--------- .../accountgen/sms/SmsActivateService.java | 4 +- src/main/resources/application.yml | 2 +- 5 files changed, 288 insertions(+), 274 deletions(-) diff --git a/src/main/java/com/google/accountgen/account/GoogleAccountGeneratorImpl.java b/src/main/java/com/google/accountgen/account/GoogleAccountGeneratorImpl.java index dcd3190..c4a0e26 100644 --- a/src/main/java/com/google/accountgen/account/GoogleAccountGeneratorImpl.java +++ b/src/main/java/com/google/accountgen/account/GoogleAccountGeneratorImpl.java @@ -512,16 +512,17 @@ public class GoogleAccountGeneratorImpl implements GoogleAccountGenerator if (useProxy && proxyManager.hasProxies()) { chosenProxy = proxyManager.getNextProxy(); - // Парсим логин и пароль (login:pass@host:port) - // HTTP(S)-прокси с Basic Auth - String proxyUri = (proxyLogin + ":" + proxyPass + "@") + chosenProxy; - String scheme = chosenProxy.startsWith("http") ? "" : "http://"; - String finalProxy = "--proxy-server=" + scheme + chosenProxy; + if (chosenProxy == null) { + logger.error("Не удалось получить ни одного подходящего прокси с proxy6.net. Проверьте фильтры IP/тип или наличие активных прокси."); + throw new RuntimeException("Нет доступных прокси для использования. Проверьте настройки proxy6.net и фильтры в ProxyManager."); + } + // Используем только host:port без логина и пароля + String finalProxy = "--proxy-server=http://" + chosenProxy; options.addArguments(finalProxy); org.openqa.selenium.Proxy httpProxy = new org.openqa.selenium.Proxy(); httpProxy.setHttpProxy(chosenProxy).setSslProxy(chosenProxy); options.setCapability(CapabilityType.PROXY, httpProxy); - logger.info("HTTP(S) proxy настроен: {}{}", scheme, chosenProxy); + logger.info("HTTP(S) proxy настроен: http://{}", chosenProxy); } diff --git a/src/main/java/com/google/accountgen/proxy/ProxyManager.java b/src/main/java/com/google/accountgen/proxy/ProxyManager.java index 8122544..c34baaf 100644 --- a/src/main/java/com/google/accountgen/proxy/ProxyManager.java +++ b/src/main/java/com/google/accountgen/proxy/ProxyManager.java @@ -24,7 +24,7 @@ public class ProxyManager private static final Logger logger = LoggerFactory.getLogger(ProxyManager.class); - private final String API_URL = "https://papaproxy.net/api/getproxy/?format=json&type=http_ip&login=%s&password=%s"; + private static final String API_URL = "https://px6.link/api/cecd79b327-8f5b6b51aa-63cc268d0a/getproxy?state=active&limit=1000"; private final List proxyList = new ArrayList<>(); private final Random random = new Random(); @Value("${proxyLogin}") @@ -34,22 +34,24 @@ public class ProxyManager public void init() { - String fullUrl = String.format(API_URL, proxyLogin, proxypass); try { - String response = sendRequest(fullUrl); + String response = sendRequest(API_URL); ObjectMapper mapper = new ObjectMapper(); - - for (MappingIterator it = mapper.readValues(mapper.createParser(response), Map.class); it.hasNext(); ) - { - Map jsonNode = it.next(); - String host = jsonNode.get("host"); - String port = jsonNode.get("port"); - proxyList.add(host + ":" + port); + Map root = mapper.readValue(response, Map.class); + if (!"yes".equals(root.get("status"))) { + throw new RuntimeException("Ошибка получения прокси: " + root.get("error")); } - } - catch (Exception e) - { + Map> proxies = (Map>) root.get("list"); + proxyList.clear(); + for (Map proxy : proxies.values()) { + String host = (String) proxy.get("host"); + String port = (String) proxy.get("port"); + if (host != null && port != null) { + proxyList.add(host + ":" + port); + } + } + } catch (Exception e) { throw new RuntimeException(e); } } @@ -60,8 +62,7 @@ public class ProxyManager */ public boolean hasProxies() { - return true; - // return !proxyList.isEmpty(); + return !proxyList.isEmpty(); } /** @@ -69,18 +70,10 @@ public class ProxyManager */ public String getNextProxy() { - // if (proxyList.isEmpty()) - // { - // return null; - // } - // return proxyList.get(random.nextInt(proxyList.size())); - - String host = "pool.proxy.market"; - String port = "10000"; - // return proxyLogin + ":" + proxypass + "@" + host + ":" + port; - - //HARDCODE TRUSTED PROXY THROUGHPUT LOCAL - return "localhost:8080"; + if (proxyList.isEmpty()) { + return null; + } + return proxyList.get(random.nextInt(proxyList.size())); } diff --git a/src/main/java/com/google/accountgen/registration/GoogleRegistrationHandler.java b/src/main/java/com/google/accountgen/registration/GoogleRegistrationHandler.java index 5cb142b..f86b490 100644 --- a/src/main/java/com/google/accountgen/registration/GoogleRegistrationHandler.java +++ b/src/main/java/com/google/accountgen/registration/GoogleRegistrationHandler.java @@ -247,33 +247,123 @@ public class GoogleRegistrationHandler public void fillBirthdayAndGenderPage(UserData userData) { logger.info("Заполнение страницы даты рождения и пола"); + try { + // День + WebElement dayInput = findElementWithWait(By.cssSelector("input[name='day']")); + int day = userData.getBirthDay() > 0 ? userData.getBirthDay() : 1 + random.nextInt(28); + typeWithRandomDelay(dayInput, String.valueOf(day)); - WebElement dayInput = findElementWithWait(By.cssSelector(GoogleRegistrationSelectors.DAY_INPUT)); - WebElement monthSelect = findElementWithWait(By.cssSelector(GoogleRegistrationSelectors.MONTH_SELECT)); - WebElement yearInput = findElementWithWait(By.cssSelector(GoogleRegistrationSelectors.YEAR_INPUT)); - WebElement genderSelect = findElementWithWait(By.cssSelector(GoogleRegistrationSelectors.GENDER_SELECT)); + // Год + WebElement yearInput = findElementWithWait(By.cssSelector("input[name='year']")); + int year = userData.getBirthYear() > 1900 ? userData.getBirthYear() : 1980 + random.nextInt(30); + typeWithRandomDelay(yearInput, String.valueOf(year)); - // Заполняем день - typeWithRandomDelay(dayInput, String.valueOf(userData.getBirthDay())); + // Месяц (кастомный дропдаун) + try { + WebElement monthDropdown = null; + try { + monthDropdown = driver.findElement(By.xpath("//div[@role='combobox'][.//span[text()='Month']]")); + } catch (Exception e) { + List comboboxes = driver.findElements(By.xpath("//div[@role='combobox']")); + if (!comboboxes.isEmpty()) { + monthDropdown = comboboxes.get(0); + } + } + if (monthDropdown == null) { + logger.error("Не удалось найти дропдаун месяца!"); + makeScreenshot("month_dropdown_not_found"); + } else { + logger.info("Найден дропдаун месяца: {}", monthDropdown.getAttribute("outerHTML")); + ((JavascriptExecutor) driver).executeScript("arguments[0].click();", monthDropdown); + Thread.sleep(500); + // Ищем ul с опциями только для месяца + WebElement monthList = null; + try { + monthList = monthDropdown.findElement(By.xpath("following-sibling::div/ul")); + } catch (Exception e) { + logger.error("Не удалось найти ul с опциями месяца: {}", e.getMessage()); + makeScreenshot("month_ul_not_found"); + } + final int selectedMonth = userData.getBirthMonth() > 0 ? userData.getBirthMonth() : 1 + random.nextInt(12); + List monthOptions = monthList != null ? monthList.findElements(By.cssSelector("li[role='option'][data-value]")) : List.of(); + WebElement monthOption = monthOptions.stream().filter(opt -> String.valueOf(selectedMonth).equals(opt.getAttribute("data-value"))).findFirst().orElse(null); + if (monthOption == null && !monthOptions.isEmpty()) { + monthOption = monthOptions.get(random.nextInt(monthOptions.size())); + logger.warn("Не найден нужный месяц, выбран случайный: {}", monthOption.getText()); + } + if (monthOption != null) { + logger.info("Кликаю по опции месяца: {}", monthOption.getAttribute("outerHTML")); + ((JavascriptExecutor) driver).executeScript("arguments[0].click();", monthOption); + } else { + logger.error("Не удалось найти ни одного варианта месяца!"); + makeScreenshot("month_dropdown_not_found"); + } + } + } catch (Exception e) { + logger.error("Ошибка при выборе месяца: {}", e.getMessage()); + makeScreenshot("month_dropdown_error"); + } - // Выбираем месяц из выпадающего списка - Select monthDropdown = new Select(monthSelect); - monthDropdown.selectByValue(String.valueOf(userData.getBirthMonth())); + // Пол (кастомный дропдаун) + try { + WebElement genderDropdown = null; + try { + genderDropdown = driver.findElement(By.xpath("//div[@role='combobox'][.//span[text()='Gender']]")); + } catch (Exception e) { + List comboboxes = driver.findElements(By.xpath("//div[@role='combobox']")); + if (comboboxes.size() > 1) { + genderDropdown = comboboxes.get(1); + } + } + if (genderDropdown == null) { + logger.error("Не удалось найти дропдаун пола!"); + makeScreenshot("gender_dropdown_not_found"); + } else { + logger.info("Найден дропдаун пола: {}", genderDropdown.getAttribute("outerHTML")); + ((JavascriptExecutor) driver).executeScript("arguments[0].click();", genderDropdown); + Thread.sleep(500); + // Ищем ul с опциями только для пола + WebElement genderList = null; + try { + genderList = genderDropdown.findElement(By.xpath("following-sibling::div/ul")); + } catch (Exception e) { + logger.error("Не удалось найти ul с опциями пола: {}", e.getMessage()); + makeScreenshot("gender_ul_not_found"); + } + final String genderValue; + if (userData.getGender() != null) { + genderValue = userData.getGender().toString().equals("MALE") ? "1" : (userData.getGender().toString().equals("FEMALE") ? "2" : null); + } else { + genderValue = null; + } + List genderOptions = genderList != null ? genderList.findElements(By.cssSelector("li[role='option'][data-value]")) : List.of(); + WebElement genderOption = genderOptions.stream().filter(opt -> genderValue != null && genderValue.equals(opt.getAttribute("data-value"))).findFirst().orElse(null); + if (genderOption == null && !genderOptions.isEmpty()) { + genderOption = genderOptions.get(random.nextInt(genderOptions.size())); + logger.warn("Не найден нужный пол, выбран случайный: {}", genderOption.getText()); + } + if (genderOption != null) { + logger.info("Кликаю по опции пола: {}", genderOption.getAttribute("outerHTML")); + ((JavascriptExecutor) driver).executeScript("arguments[0].click();", genderOption); + } else { + logger.error("Не удалось найти ни одного варианта пола!"); + makeScreenshot("gender_dropdown_not_found"); + } + } + } catch (Exception e) { + logger.error("Ошибка при выборе пола: {}", e.getMessage()); + makeScreenshot("gender_dropdown_error"); + } - // Заполняем год - typeWithRandomDelay(yearInput, String.valueOf(userData.getBirthYear())); - - // Выбираем пол - Select genderDropdown = new Select(genderSelect); - // 1 - Male, 2 - Female - genderDropdown.selectByValue(userData.getGender() == UserData.Gender.MALE ? "1" : "2"); - - // Нажимаем кнопку "Next" - WebElement nextButton = findElementWithWait( - By.cssSelector(GoogleRegistrationSelectors.NEXT_BUTTON_BIRTHDAY_PAGE)); - nextButton.click(); - - logger.info("Страница даты рождения и пола заполнена успешно"); + // Нажимаем кнопку "Next" + WebElement nextButton = findElementWithWait(By.cssSelector(GoogleRegistrationSelectors.NEXT_BUTTON_BIRTHDAY_PAGE)); + nextButton.click(); + logger.info("Страница даты рождения и пола заполнена успешно"); + } catch (Exception e) { + logger.error("Ошибка при заполнении даты рождения и пола: {}", e.getMessage()); + makeScreenshot("birthday_gender_error"); + throw e; + } } /** @@ -1036,241 +1126,171 @@ public class GoogleRegistrationHandler WebDriverWait shortWait = new WebDriverWait(driver, Duration.ofSeconds(5)); // Короткое ожидание для Next // --- Экран "Choose your settings" --- -// logger.info("Обработка экрана 'Choose your settings'..."); -// sleep(2000); -// takeScreenshot(driver, "choose_settings_screen"); -// -// // Пробуем нажать опцию "Choose in 1 step" если она доступна -// boolean oneStepClicked = false; -// try -// { -// // Сначала пробуем более надежный XPath -// String oneStepXPath = "//div[@role='radiogroup']//div[.//span[contains(text(), 'Choose in 1 step')]]//input"; -// WebElement oneStepRadio = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(oneStepXPath))); -// // Кликаем на родительский div -// WebElement parentDiv = oneStepRadio.findElement(By.xpath("./ancestor::div[@role='radio']")); -// wait.until(ExpectedConditions.elementToBeClickable(parentDiv)).click(); -// logger.info("Нажата опция 'Choose in 1 step' через XPath"); -// oneStepClicked = true; -// } -// catch (Exception xpathEx) -// { -// logger.warn("Не удалось нажать на 'Choose in 1 step' через XPath: {}", xpathEx.getMessage()); -// try -// { -// // Пробуем менее надежный data-value селектор -// WebElement oneStepOption = wait.until(ExpectedConditions.elementToBeClickable( -// By.cssSelector("div[jsname='ornU0b'][data-value='1']"))); -// oneStepOption.click(); -// logger.info("Нажата опция 'Choose in 1 step' стандартным методом (data-value)"); -// oneStepClicked = true; -// } -// catch (Exception e) -// { -// logger.warn("Не удалось нажать на 'Choose in 1 step' стандартным методом: {}", e.getMessage()); -// try -// { -// // Пробуем JS как крайний вариант -// ((JavascriptExecutor) driver).executeScript( -// "document.querySelector(\"div[jsname='ornU0b'][data-value='1']\").click();"); -// logger.info("Нажата опция 'Choose in 1 step' через JavaScript"); -// oneStepClicked = true; -// } -// catch (Exception jsEx) -// { -// logger.error("Не удалось нажать на 'Choose in 1 step' никаким способом: {}", jsEx.getMessage()); -// // Если не удалось выбрать, возможно, стоит прервать или перейти к следующему шагу, если он уже выбран -// } -// } -// } -// -// // Если успешно кликнули "Choose in 1 step", *немедленно* нажимаем "Next" для этого экрана -// if (oneStepClicked) -// { -// sleep(1000); // Пауза после клика на радио -// takeScreenshot(driver, "after_choose_in_one_step"); -// logger.info("Ищем и нажимаем кнопку 'Next' *сразу после* выбора 'Choose in 1 step'..."); -// try -// { -// String nextButtonXPath = "//button[@jsname='LgbsSe' and .//span[text()='Next']]"; -// WebElement nextButton = shortWait.until( -// ExpectedConditions.elementToBeClickable(By.xpath(nextButtonXPath))); -// nextButton.click(); -// logger.info("Кнопка 'Next' нажата после 'Choose in 1 step'."); -// sleep(2500); // Увеличиваем паузу для загрузки следующей страницы -// } -// catch (Exception e) -// { -// logger.error("Не удалось найти или нажать кнопку 'Next' сразу после 'Choose in 1 step': {}", -// e.getMessage()); -// makeScreenshot("choose_settings_next_button_error"); -// // Продолжаем выполнение, т.к. возможно, мы уже на следующем шаге или кнопка Next другая -// } -// } -// else -// { -// logger.warn("Не удалось кликнуть 'Choose in 1 step', пропускаем нажатие Next на этом шаге."); -// } -// -// -// // --- Последующие экраны (Confirm/Reject/I agree) --- -// // Эта логика остается для обработки экранов, которые могут появиться ПОСЛЕ нажатия Next выше -// -// takeScreenshot(driver, "privacy_settings_intermediate"); -// -// // Пробуем нажать "Reject all" если она доступна (может появиться на следующем шаге) -// logger.info("Проверка наличия кнопки 'Reject all'..."); -// try -// { -// WebElement rejectAllButton = shortWait.until( -// ExpectedConditions.elementToBeClickable( // Используем shortWait -// By.xpath("//button[contains(@aria-label, 'Reject all') or contains(., 'Reject all')]"))); -// rejectAllButton.click(); -// logger.info("Нажата кнопка 'Reject all'"); -// sleep(2000); -// takeScreenshot(driver, "after_reject_all"); -// } -// catch (Exception e) -// { -// logger.info("Кнопка 'Reject all' не найдена или не кликабельна: {}", e.getMessage()); -// // Пробуем JS как запасной вариант -// try -// { -// ((JavascriptExecutor) driver).executeScript( -// "Array.from(document.querySelectorAll('button')).find(el => el.textContent.includes('Reject all')).click();"); -// logger.info("Нажата кнопка 'Reject all' через JavaScript"); -// sleep(2000); -// takeScreenshot(driver, "after_reject_all_js"); -// } -// catch (Exception jsEx) -// { -// logger.info("Кнопка 'Reject all' не найдена и через JavaScript: {}", jsEx.getMessage()); -// } -// } -// -// // Пробуем нажать "Confirm" если она доступна -// logger.info("Проверка наличия кнопки 'Confirm'..."); -// try -// { -// WebElement confirmButton = shortWait.until(ExpectedConditions.elementToBeClickable( // Используем shortWait -// By.xpath("//button[contains(@aria-label, 'Confirm') or contains(., 'Confirm')]"))); -// confirmButton.click(); -// logger.info("Нажата кнопка 'Confirm'"); -// sleep(2000); -// takeScreenshot(driver, "after_confirm"); -// } -// catch (Exception e) -// { -// logger.info("Кнопка 'Confirm' не найдена или не кликабельна: {}", e.getMessage()); -// // Пробуем JS -// try -// { -// ((JavascriptExecutor) driver).executeScript( -// "Array.from(document.querySelectorAll('button')).find(el => el.textContent.includes('Confirm')).click();"); -// logger.info("Нажата кнопка 'Confirm' через JavaScript"); -// sleep(2000); -// takeScreenshot(driver, "after_confirm_js"); -// } -// catch (Exception jsEx) -// { -// logger.info("Кнопка 'Confirm' не найдена и через JavaScript: {}", jsEx.getMessage()); -// } -// } + logger.info("Обработка экрана 'Choose your settings'..."); + sleep(2000); + takeScreenshot(driver, "choose_settings_screen"); - // Нажимаем "I agree" на странице условий использования - logger.info("Проверка наличия кнопки 'I agree'..."); + boolean oneStepClicked = false; + try { + // Находим radio-кнопку по data-value + WebElement oneStepRadio = wait.until(ExpectedConditions.elementToBeClickable( + By.cssSelector("div[role='radio'][data-value='1']") + )); + // Скроллим к элементу + ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView({block: 'center'});", oneStepRadio); + sleep(300); + oneStepRadio.click(); + logger.info("Нажата опция 'Choose in 1 step' по CSS-селектору"); + // Ждем, что aria-checked станет true + wait.until(ExpectedConditions.attributeToBe(oneStepRadio, "aria-checked", "true")); + oneStepClicked = true; + } catch (Exception cssEx) { + logger.warn("Не удалось нажать на 'Choose in 1 step' по CSS: {}", cssEx.getMessage()); + try { + // Fallback: клик через JS + ((JavascriptExecutor) driver).executeScript( + "var el = document.querySelector('div[role=\\'radio\\'][data-value=\\'1\\']'); if(el) el.click();" + ); + logger.info("Нажата опция 'Choose in 1 step' через JavaScript"); + oneStepClicked = true; + } catch (Exception jsEx) { + logger.error("Не удалось нажать на 'Choose in 1 step' никаким способом: {}", jsEx.getMessage()); + } + } + + // Если успешно кликнули "Choose in 1 step", *немедленно* нажимаем "Next" для этого экрана + if (oneStepClicked) { + sleep(1000); // Пауза после клика на радио + takeScreenshot(driver, "after_choose_in_one_step"); + logger.info("Ищем и нажимаем кнопку 'Next' *сразу после* выбора 'Choose in 1 step'..."); + try { + WebElement nextButton = shortWait.until( + ExpectedConditions.elementToBeClickable( + By.xpath("//button[@jsname='LgbsSe' and .//span[text()='Next']]") + ) + ); + nextButton.click(); + logger.info("Кнопка 'Next' нажата после 'Choose in 1 step'."); + sleep(2500); // Пауза для загрузки следующей страницы + } catch (Exception e) { + logger.error("Не удалось найти или нажать кнопку 'Next' сразу после 'Choose in 1 step': {}", e.getMessage()); + makeScreenshot("choose_settings_next_button_error"); + } + } else { + logger.warn("Не удалось кликнуть 'Choose in 1 step', пропускаем нажатие Next на этом шаге."); + } + + // --- Последующие экраны (Confirm/Reject/I agree) --- + takeScreenshot(driver, "privacy_settings_intermediate"); + + // Пробуем нажать "Reject all" если она доступна (может появиться на следующем шаге) + logger.info("Проверка наличия кнопки 'Reject all'..."); try { - WebElement agreeButton = wait.until(ExpectedConditions.elementToBeClickable( - By.xpath(GoogleRegistrationSelectors.I_AGREE_BUTTON_XPATH))); - agreeButton.click(); - logger.info("Успешно нажата кнопка 'I agree' по XPath селектору"); + WebElement rejectAllButton = shortWait.until( + ExpectedConditions.elementToBeClickable( // Используем shortWait + By.xpath("//button[contains(@aria-label, 'Reject all') or contains(., 'Reject all')]"))); + rejectAllButton.click(); + logger.info("Нажата кнопка 'Reject all'"); sleep(2000); - takeScreenshot(driver, "after_i_agree"); + takeScreenshot(driver, "after_reject_all"); } catch (Exception e) { - logger.warn("Не удалось нажать на 'I agree' по XPath селектору: {}", e.getMessage()); - // Пробуем другие селекторы и JS... + logger.info("Кнопка 'Reject all' не найдена или не кликабельна: {}", e.getMessage()); + // Пробуем JS как запасной вариант try { - WebElement agreeButton = wait.until(ExpectedConditions.elementToBeClickable( - By.cssSelector(GoogleRegistrationSelectors.I_AGREE_BUTTON))); - agreeButton.click(); - logger.info("Успешно нажата кнопка 'I agree' по CSS селектору"); + ((JavascriptExecutor) driver).executeScript( + "Array.from(document.querySelectorAll('button')).find(el => el.textContent.includes('Reject all')).click();"); + logger.info("Нажата кнопка 'Reject all' через JavaScript"); sleep(2000); - takeScreenshot(driver, "after_i_agree_css"); + takeScreenshot(driver, "after_reject_all_js"); } - catch (Exception cssEx) + catch (Exception jsEx) { - logger.warn("Не удалось нажать на 'I agree' по CSS селектору: {}", cssEx.getMessage()); - try - { - // JavaScript-клик для кнопки "I agree" + logger.info("Кнопка 'Reject all' не найдена и через JavaScript: {}", jsEx.getMessage()); + } + } + + // Пробуем нажать "Confirm" если она доступна + logger.info("Проверка наличия кнопки 'Confirm'..."); + try + { + WebElement confirmButton = shortWait.until(ExpectedConditions.elementToBeClickable( // Используем shortWait + By.xpath("//button[contains(@aria-label, 'Confirm') or contains(., 'Confirm')]"))); + confirmButton.click(); + logger.info("Нажата кнопка 'Confirm'"); + sleep(2000); + takeScreenshot(driver, "after_confirm"); + } + catch (Exception e) + { + logger.info("Кнопка 'Confirm' не найдена или не кликабельна: {}", e.getMessage()); + // Пробуем JS + try + { + ((JavascriptExecutor) driver).executeScript( + "Array.from(document.querySelectorAll('button')).find(el => el.textContent.includes('Confirm')).click();"); + logger.info("Нажата кнопка 'Confirm' через JavaScript"); + sleep(2000); + takeScreenshot(driver, "after_confirm_js"); + } + catch (Exception jsEx) + { + logger.info("Кнопка 'Confirm' не найдена и через JavaScript: {}", jsEx.getMessage()); + } + } + + // --- Кнопка "I agree" на Privacy and Terms --- + logger.info("Проверка наличия кнопки 'I agree'..."); + try { + // Сначала пробуем по XPath (ищет span с текстом I agree) + WebElement agreeButton = shortWait.until(ExpectedConditions.elementToBeClickable( + By.xpath("//button[@jsname='LgbsSe' and .//span[text()='I agree']]") + )); + ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView({block: 'center'});", agreeButton); + sleep(300); + agreeButton.click(); + logger.info("Кнопка 'I agree' нажата по XPath"); + sleep(2000); + takeScreenshot(driver, "after_i_agree"); + } catch (Exception e) { + logger.warn("Не удалось нажать на 'I agree' по XPath: {}", e.getMessage()); + // Пробуем по CSS + try { + WebElement agreeButton = shortWait.until(ExpectedConditions.elementToBeClickable( + By.cssSelector("button[jsname='LgbsSe'] span.VfPpkd-vQzf8d") + )); + // Проверяем текст + if ("I agree".equals(agreeButton.getText().trim())) { + WebElement button = agreeButton.findElement(By.xpath("./ancestor::button")); + ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView({block: 'center'});", button); + sleep(300); + button.click(); + logger.info("Кнопка 'I agree' нажата по CSS"); + sleep(2000); + takeScreenshot(driver, "after_i_agree_css"); + } else { + throw new Exception("Не найден нужный span с текстом I agree"); + } + } catch (Exception cssEx) { + logger.warn("Не удалось нажать на 'I agree' по CSS: {}", cssEx.getMessage()); + // Пробуем через JS + try { ((JavascriptExecutor) driver).executeScript( - "Array.from(document.querySelectorAll('button')).find(el => " + "el.textContent.includes('I agree') || " + "(el.querySelector('span') && el.querySelector('span').textContent.includes('I agree'))).click();"); - logger.info("Нажата кнопка 'I agree' через JavaScript"); + "Array.from(document.querySelectorAll('button')).find(b => b.textContent.trim() === 'I agree' || (b.querySelector('span') && b.querySelector('span').textContent.trim() === 'I agree'))?.click();" + ); + logger.info("Кнопка 'I agree' нажата через JavaScript"); sleep(2000); takeScreenshot(driver, "after_i_agree_js"); - } - catch (Exception jsEx) - { + } catch (Exception jsEx) { logger.error("Не удалось нажать на 'I agree' никаким способом: {}", jsEx.getMessage()); - // Если даже JS не сработал, возможно, стоит прервать регистрацию throw new RuntimeException("Не удалось нажать кнопку 'I agree'"); } } } - - // Проверяем, появился ли диалог "Confirm personalisation?" -// logger.info("Проверка наличия диалога 'Confirm personalisation?'..."); -// try -// { -// sleep(1000); -// takeScreenshot(driver, "check_personalisation_dialog"); -// -// // Ищем кнопку "Confirm" в диалоге -// WebElement confirmPersonalisationButton = shortWait.until(ExpectedConditions.elementToBeClickable( -// By.xpath(GoogleRegistrationSelectors.CONFIRM_PERSONALISATION_XPATH))); -// confirmPersonalisationButton.click(); -// logger.info("Успешно нажата кнопка 'Confirm' в диалоге персонализации по XPath селектору"); -// sleep(2000); -// takeScreenshot(driver, "after_confirm_personalisation"); -// } -// catch (Exception e) -// { -// logger.info("Диалог 'Confirm personalisation?' не обнаружен или не кликабелен: {}", e.getMessage()); -// // Пробуем JS -// try -// { -// ((JavascriptExecutor) driver).executeScript( -// "var buttons = Array.from(document.querySelectorAll('button')); " + "for (var i = 0; i < buttons.length; i++) { " + " var btn = buttons[i]; " + " if ((btn.textContent && btn.textContent.indexOf('Confirm') >= 0) || " + " (btn.getAttribute('jsname') === 'ssJRIf')) { " + " btn.click(); break; " + " } " + "}"); -// logger.info("Нажата кнопка 'Confirm' в диалоге персонализации через JavaScript"); -// sleep(2000); -// takeScreenshot(driver, "after_confirm_personalisation_js"); -// } -// catch (Exception jsEx) -// { -// logger.info("Кнопка 'Confirm' в диалоге персонализации не найдена и через JavaScript: {}", -// jsEx.getMessage()); -// } -// } -// -// // Проверяем наличие финальной кнопки Next (если она есть после всех шагов) -// logger.info("Проверка наличия финальной кнопки 'Next'..."); -// try -// { -// WebElement finalNextButton = shortWait.until(ExpectedConditions.elementToBeClickable( -// By.xpath("//button[@jsname='LgbsSe' and .//span[text()='Next']]"))); -// finalNextButton.click(); -// logger.info("Нажата финальная кнопка 'Next'."); -// sleep(2000); -// takeScreenshot(driver, "after_final_next_button"); -// } -// catch (Exception e) -// { -// logger.info("Финальная кнопка 'Next' не найдена или не кликабельна (возможно, ее нет): {}", e.getMessage()); -// } + // --- Конец блока 'I agree' --- takeScreenshot(driver, "after_privacy_settings_attempts"); logger.info("Завершена обработка настроек конфиденциальности"); diff --git a/src/main/java/com/google/accountgen/sms/SmsActivateService.java b/src/main/java/com/google/accountgen/sms/SmsActivateService.java index 55b0404..da75b65 100644 --- a/src/main/java/com/google/accountgen/sms/SmsActivateService.java +++ b/src/main/java/com/google/accountgen/sms/SmsActivateService.java @@ -19,9 +19,9 @@ public class SmsActivateService { - private final String API_URL = "https://give-sms.com/stubs/handler_api.php"; + private final String API_URL = "https://sms-activate.ru/stubs/handler_api.php"; - private final String API2_URL = "https://api.sms-activate.world/v2/api/"; + private final String API2_URL = "https://sms-activate.ru/stubs/handler_api.php"; @Value("${default_country}") private int defaultCountry; diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 79db725..7379939 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,5 +1,5 @@ #sms_activate_api_key: cd64e325c15813edc722867BB6171B94 -sms_activate_api_key: pPmJIKmh7RepulVySCPf +sms_activate_api_key: 96615419f3eccA65f7679ce65cA17dA9 captcha_api_key: deeb0d134a47e88dffab6dc48a5a0906 captcha_service_type: TWOCAPTCHA