495 lines
28 KiB
Java
495 lines
28 KiB
Java
package com.google.accountgen;
|
||
|
||
import com.google.accountgen.config.AppProperties;
|
||
import com.google.accountgen.cookies.CookieManager;
|
||
import com.google.accountgen.proxy.ProxyManager;
|
||
import com.google.accountgen.service.AccountManager;
|
||
import com.google.accountgen.service.DarkShoppingService;
|
||
import com.google.accountgen.service.EmailService;
|
||
import com.google.accountgen.service.TwoCaptchaService;
|
||
import com.google.accountgen.youtube.YouTubeMusicHandler;
|
||
import com.google.accountgen.login.GoogleLoginHandler;
|
||
import io.github.bonigarcia.wdm.WebDriverManager;
|
||
import org.openqa.selenium.*;
|
||
import org.openqa.selenium.logging.LogType;
|
||
import org.openqa.selenium.logging.LoggingPreferences;
|
||
import org.openqa.selenium.remote.CapabilityType;
|
||
import org.openqa.selenium.support.ui.ExpectedConditions;
|
||
import org.openqa.selenium.support.ui.WebDriverWait;
|
||
import org.slf4j.Logger;
|
||
import org.slf4j.LoggerFactory;
|
||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||
import org.springframework.context.event.EventListener;
|
||
import org.springframework.stereotype.Component;
|
||
import org.openqa.selenium.chrome.ChromeOptions;
|
||
import org.openqa.selenium.chrome.ChromeDriver;
|
||
|
||
import java.io.BufferedReader;
|
||
import java.io.IOException;
|
||
import java.io.InputStreamReader;
|
||
import java.net.HttpURLConnection;
|
||
import java.net.URL;
|
||
import java.nio.charset.StandardCharsets;
|
||
import java.nio.file.Files;
|
||
import java.nio.file.Path;
|
||
import java.time.Duration;
|
||
import java.util.Collections;
|
||
import java.util.Objects;
|
||
import java.util.Optional;
|
||
import java.util.logging.Level;
|
||
import java.io.File;
|
||
|
||
@Component
|
||
public class AccountProcessingService {
|
||
|
||
private static final Logger logger = LoggerFactory.getLogger(AccountProcessingService.class);
|
||
|
||
private final AppProperties appProperties;
|
||
private final DarkShoppingService darkShoppingService;
|
||
private final AccountManager accountManager;
|
||
private final EmailService emailService;
|
||
private final ProxyManager proxyManager;
|
||
private final CookieManager cookieManager;
|
||
private final TwoCaptchaService twoCaptchaService;
|
||
|
||
private String chosenProxy;
|
||
|
||
public AccountProcessingService(AppProperties appProperties, ProxyManager proxyManager, TwoCaptchaService twoCaptchaService) {
|
||
this.appProperties = appProperties;
|
||
this.proxyManager = proxyManager;
|
||
this.cookieManager = new CookieManager(appProperties.getCookies().getDirectory());
|
||
this.twoCaptchaService = twoCaptchaService;
|
||
|
||
this.darkShoppingService = new DarkShoppingService(
|
||
appProperties.getDarkshopping().getApiKey(),
|
||
appProperties.getAccounts().getDirectory()
|
||
);
|
||
this.accountManager = new AccountManager(
|
||
appProperties.getAccounts().getDirectory(),
|
||
this.darkShoppingService,
|
||
appProperties.getDarkshopping().getProductId(),
|
||
appProperties.getDarkshopping().getPurchaseQuantity()
|
||
);
|
||
if (appProperties.getImap() != null && appProperties.getImap().getHost() != null && !appProperties.getImap().getHost().isEmpty() && !appProperties.getImap().getHost().equals("imap.example.com")) {
|
||
this.emailService = new EmailService(
|
||
appProperties.getImap().getHost(),
|
||
appProperties.getImap().getPort(),
|
||
appProperties.getImap().getUsername(),
|
||
appProperties.getImap().getPassword(),
|
||
appProperties.getImap().isSsl()
|
||
);
|
||
logger.info("IMAP service configured for host: {}", appProperties.getImap().getHost());
|
||
} else {
|
||
this.emailService = null;
|
||
logger.info("IMAP service is not configured or uses default placeholder values.");
|
||
}
|
||
WebDriverManager.chromedriver().setup();
|
||
if (appProperties.isUseProxy()) {
|
||
logger.info("Proxy usage is enabled. Initializing ProxyManager...");
|
||
this.proxyManager.init();
|
||
bindProxy6ToIp();
|
||
}
|
||
}
|
||
|
||
private WebDriver setupChromeDriver(String accountEmailForCookies) {
|
||
logger.info("Настройка и запуск обычного ChromeDriver");
|
||
Path tempProfile = null;
|
||
WebDriver driver = null;
|
||
try {
|
||
ChromeOptions options = new ChromeOptions();
|
||
options.setPageLoadStrategy(PageLoadStrategy.EAGER);
|
||
options.addArguments("--user-agent=" + com.google.accountgen.service.FingerprintUtils.getRandomUserAgent());
|
||
String windowSize = com.google.accountgen.service.FingerprintUtils.getRandomWindowSize();
|
||
options.addArguments("--window-size=" + windowSize);
|
||
options.addArguments("--lang=" + com.google.accountgen.service.FingerprintUtils.getRandomLang());
|
||
tempProfile = Files.createTempDirectory("chrome-profile-");
|
||
options.addArguments("--user-data-dir=" + tempProfile.toAbsolutePath());
|
||
logger.info("Используется временный профиль Chrome: {}", tempProfile);
|
||
LoggingPreferences logPrefs = new LoggingPreferences();
|
||
logPrefs.enable(LogType.BROWSER, Level.ALL);
|
||
logPrefs.enable(LogType.PERFORMANCE, Level.OFF);
|
||
options.setCapability("goog:loggingPrefs", logPrefs);
|
||
options.addArguments("--no-sandbox");
|
||
options.addArguments("--disable-dev-shm-usage");
|
||
options.addArguments("--disable-extensions");
|
||
options.addArguments("--disable-blink-features=AutomationControlled");
|
||
options.addArguments("--disable-notifications");
|
||
options.addArguments("--disable-popup-blocking");
|
||
options.addArguments("--log-level=3");
|
||
options.addArguments("--silent");
|
||
options.addArguments("--disable-infobars");
|
||
|
||
// Удаление "Chrome is being controlled by automated test software"
|
||
options.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation"));
|
||
options.setExperimentalOption("useAutomationExtension", false);
|
||
|
||
if (appProperties.isUseProxy() && proxyManager.hasProxies()) {
|
||
chosenProxy = proxyManager.getNextProxy();
|
||
if (chosenProxy != null) {
|
||
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 настроен: {}", chosenProxy);
|
||
} else {
|
||
logger.error("Не удалось получить прокси от ProxyManager, хотя прокси включены и должны быть доступны.");
|
||
}
|
||
} else if (appProperties.isUseProxy()) {
|
||
logger.warn("Прокси включены в конфигурации, но ProxyManager не имеет доступных прокси.");
|
||
}
|
||
|
||
logger.info("Создаём обычный ChromeDriver");
|
||
driver = new ChromeDriver(options);
|
||
|
||
logger.info("Attempting to load cookies for account: {}", accountEmailForCookies);
|
||
driver.get("https://www.google.com");
|
||
randomSleep(500, 1500);
|
||
cookieManager.loadCookiesFromJson(driver, accountEmailForCookies);
|
||
logger.info("Cookies loaded (if any). Proceeding with navigator properties override.");
|
||
|
||
org.openqa.selenium.JavascriptExecutor js = (org.openqa.selenium.JavascriptExecutor) driver;
|
||
js.executeScript("Object.defineProperty(navigator, 'webdriver', {get: () => undefined});");
|
||
js.executeScript("Object.defineProperty(navigator, 'languages', {get: () => ['en-US', 'en']});");
|
||
js.executeScript("Object.defineProperty(navigator, 'plugins', {get: () => [1,2,3,4,5]});");
|
||
js.executeScript("Intl.DateTimeFormat.prototype.resolvedOptions = function() { return { timeZone: '" + com.google.accountgen.service.FingerprintUtils.getRandomTimezone() + "' }; };");
|
||
logger.info("Экземпляр ChromeDriver успешно создан.");
|
||
return driver;
|
||
} catch (Exception e) {
|
||
logger.error("Критическая ошибка при настройке или запуске ChromeDriver", e);
|
||
if (driver != null) {
|
||
try { driver.quit(); } catch (Exception dq) { logger.error("Error quitting driver during setup error handling", dq); }
|
||
}
|
||
if (tempProfile != null) {
|
||
deleteTempProfileDirectory(tempProfile);
|
||
}
|
||
throw new RuntimeException("Не удалось инициализировать ChromeDriver", e);
|
||
}
|
||
}
|
||
|
||
@EventListener(ApplicationReadyEvent.class)
|
||
public void processAccounts() {
|
||
logger.info("Starting account processing...");
|
||
|
||
Optional<AccountManager.AccountDetails> accountDetailsOpt = accountManager.getNextAccount();
|
||
|
||
if (accountDetailsOpt.isEmpty()) {
|
||
logger.warn("No accounts available to process. Exiting.");
|
||
return;
|
||
}
|
||
|
||
AccountManager.AccountDetails accountDetails = accountDetailsOpt.get();
|
||
logger.info("Processing account: {} with proxy: {}", accountDetails.email(), chosenProxy != null ? chosenProxy : "none");
|
||
|
||
WebDriver driver = setupChromeDriver(accountDetails.email());
|
||
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
|
||
|
||
// Интенсивный прогрев перед основной логикой
|
||
performIntensiveWarmup(driver, wait, accountDetails.email());
|
||
|
||
YouTubeMusicHandler musicHandler = new YouTubeMusicHandler(driver);
|
||
GoogleLoginHandler loginHandler = new GoogleLoginHandler(driver, wait, twoCaptchaService);
|
||
|
||
Path tempProfilePath = null;
|
||
if (driver instanceof HasCapabilities) {
|
||
Capabilities capabilities = ((HasCapabilities) driver).getCapabilities();
|
||
String chromeUserDataDirArg = capabilities.getCapability(ChromeOptions.CAPABILITY).toString();
|
||
if (chromeUserDataDirArg.contains("user-data-dir=")) {
|
||
try {
|
||
String pathStr = chromeUserDataDirArg.split("user-data-dir=")[1].split(",")[0].trim();
|
||
tempProfilePath = Path.of(pathStr);
|
||
} catch (Exception e) {
|
||
logger.warn("Could not parse temp profile path from capabilities: {}", chromeUserDataDirArg, e);
|
||
}
|
||
}
|
||
} else {
|
||
logger.warn("Driver does not implement HasCapabilities, cannot get user-data-dir.");
|
||
}
|
||
|
||
try {
|
||
loginHandler.navigateToYouTubeMusicAndHandlePopups();
|
||
loginHandler.clickSignInOnYouTubeMusic();
|
||
loginHandler.performGoogleLogin(accountDetails);
|
||
loginHandler.handlePostLoginPopups();
|
||
|
||
wait.until(ExpectedConditions.or(
|
||
ExpectedConditions.urlContains("music.youtube.com"),
|
||
ExpectedConditions.visibilityOfElementLocated(By.xpath("//ytmusic-popup-container//ytmusic-settings-button | //a[@aria-label='Account'] | //yt-img-shadow[@class='style-scope ytmusic-nav-bar no-transition' and @height='32']"))
|
||
));
|
||
|
||
String currentUrl = driver.getCurrentUrl();
|
||
logger.info("Current URL after login attempt: {}", currentUrl);
|
||
boolean loggedInSuccessfully = false;
|
||
|
||
if (currentUrl.contains("music.youtube.com")) {
|
||
try {
|
||
wait.until(ExpectedConditions.visibilityOfElementLocated(
|
||
By.xpath("//ytmusic-popup-container//ytmusic-settings-button | //a[@aria-label='Account'] | //yt-img-shadow[@class='style-scope ytmusic-nav-bar no-transition' and @height='32']")
|
||
));
|
||
logger.info("Successfully logged into YouTube Music for account: {}", accountDetails.email());
|
||
loggedInSuccessfully = true;
|
||
cookieManager.saveCookiesToJson(driver, accountDetails.email());
|
||
} catch (TimeoutException e) {
|
||
logger.warn("Could not confirm login on YouTube Music. Account icon not found. Current URL: {}", driver.getCurrentUrl());
|
||
loggedInSuccessfully = true;
|
||
cookieManager.saveCookiesToJson(driver, accountDetails.email());
|
||
}
|
||
} else if (currentUrl.contains("myaccount.google.com") || currentUrl.contains("accounts.google.com")) {
|
||
logger.info("Redirected to a Google account page, attempting to navigate to YouTube Music again to confirm login.");
|
||
driver.get("https://music.youtube.com/");
|
||
sleep(3000);
|
||
try {
|
||
wait.until(ExpectedConditions.visibilityOfElementLocated(
|
||
By.xpath("//ytmusic-popup-container//ytmusic-settings-button | //a[@aria-label='Account'] | //yt-img-shadow[@class='style-scope ytmusic-nav-bar no-transition' and @height='32']")
|
||
));
|
||
logger.info("Successfully confirmed login on YouTube Music after redirect: {}", accountDetails.email());
|
||
loggedInSuccessfully = true;
|
||
cookieManager.saveCookiesToJson(driver, accountDetails.email());
|
||
} catch (TimeoutException e) {
|
||
logger.warn("Could not confirm login on YouTube Music after redirect. Account icon not found. Current URL: {}", driver.getCurrentUrl());
|
||
loggedInSuccessfully = true;
|
||
cookieManager.saveCookiesToJson(driver, accountDetails.email());
|
||
}
|
||
} else if (driver.findElements(By.xpath("//*[contains(text(),'Verify it\'s you') or contains(text(),'Подтвердите, что это вы')]")).size() > 0 ||
|
||
driver.findElements(By.xpath("//*[contains(text(),'recovery email') or contains(text(),'резервный адрес электронной почты')]")).size() > 0) {
|
||
logger.warn("Google requires verification for account {}. This scenario is not handled by automated login.", accountDetails.email());
|
||
} else {
|
||
logger.warn("Login may have failed for account: {}. Not on YouTube Music and no clear verification page. Current URL: {}", accountDetails.email(), currentUrl);
|
||
loggedInSuccessfully = true;
|
||
cookieManager.saveCookiesToJson(driver, accountDetails.email());
|
||
}
|
||
|
||
if (loggedInSuccessfully) {
|
||
boolean playClicked = musicHandler.playFirstTrackOrVideo();
|
||
if (playClicked) {
|
||
logger.info("Клик по первому видео/треку выполнен успешно после логина.");
|
||
} else {
|
||
logger.warn("Не удалось кликнуть по первому видео/треку после логина.");
|
||
}
|
||
accountManager.markAccountAsUsed(accountDetails);
|
||
logger.info("Account {} processed successfully. Proceeding to gather POT token and cookies.", accountDetails.email());
|
||
|
||
String potToken = musicHandler.getPotToken();
|
||
if (potToken != null && !potToken.isEmpty()) {
|
||
logger.info("POT Token for {}: {}", accountDetails.email(), potToken);
|
||
} else {
|
||
logger.warn("Failed to retrieve POT token for account: {}", accountDetails.email());
|
||
}
|
||
|
||
String cookiesNetscape = cookieManager.exportCookiesToNetscape(driver);
|
||
if (cookiesNetscape != null && !cookiesNetscape.isEmpty()) {
|
||
logger.info("Cookies (Netscape format) for {}: \n{}", accountDetails.email(), cookiesNetscape);
|
||
} else {
|
||
logger.warn("Failed to export cookies for account: {}", accountDetails.email());
|
||
}
|
||
|
||
logger.info("Waiting for 10 seconds to observe the page (demonstration)...");
|
||
sleep(10000);
|
||
|
||
} else {
|
||
logger.error("Login failed or unconfirmed for account {}. Marking as potentially problematic but not used.", accountDetails.email());
|
||
}
|
||
|
||
} catch (NoSuchWindowException e) {
|
||
logger.error("Browser window was closed unexpectedly during processing for account {}. Proxy: {}. Error: {}", accountDetails.email(), chosenProxy, e.getMessage());
|
||
makeGlobalScreenshot(driver, "error_window_closed_" + accountDetails.email().split("@")[0]);
|
||
} catch (TimeoutException e) {
|
||
logger.error("TimeoutException during processing for account {}. Proxy: {}. Current URL: {}. Error: {}", accountDetails.email(), chosenProxy, driver != null ? driver.getCurrentUrl() : "N/A", e.getMessage());
|
||
makeGlobalScreenshot(driver, "error_timeout_" + accountDetails.email().split("@")[0]);
|
||
} catch (WebDriverException e) {
|
||
logger.error("WebDriverException during processing for account {}. Proxy: {}. Error: {}", accountDetails.email(), chosenProxy, e.getMessage(), e);
|
||
makeGlobalScreenshot(driver, "error_webdriver_" + accountDetails.email().split("@")[0]);
|
||
} catch (Exception e) {
|
||
logger.error("An unexpected error occurred during login or captcha solving for account {}. Proxy: {}. Error: {}", accountDetails.email(), chosenProxy, e.getMessage(), e);
|
||
makeGlobalScreenshot(driver, "error_unexpected_login_" + accountDetails.email().split("@")[0]);
|
||
} finally {
|
||
if (driver != null) {
|
||
try {
|
||
logger.info("Quitting WebDriver for account: {}", accountDetails.email());
|
||
driver.quit();
|
||
} catch (Exception e) {
|
||
logger.error("Error quitting WebDriver for account: {}: {}", accountDetails.email(), e.getMessage());
|
||
}
|
||
}
|
||
if (tempProfilePath != null) {
|
||
deleteTempProfileDirectory(tempProfilePath);
|
||
}
|
||
logger.info("Finished processing for account: {} with proxy: {}", accountDetails.email(), chosenProxy != null ? chosenProxy : "none");
|
||
chosenProxy = null;
|
||
}
|
||
}
|
||
|
||
private void sleep(long millis) {
|
||
try {
|
||
Thread.sleep(millis);
|
||
} catch (InterruptedException e) {
|
||
Thread.currentThread().interrupt();
|
||
logger.warn("Sleep interrupted");
|
||
}
|
||
}
|
||
|
||
private void bindProxy6ToIp() {
|
||
if (appProperties.getProxy6() == null || appProperties.getProxy6().getApiKey() == null || appProperties.getProxy6().getApiKey().isEmpty()) {
|
||
logger.warn("Proxy6 API key is not configured. Skipping IP binding.");
|
||
return;
|
||
}
|
||
String apiKey = appProperties.getProxy6().getApiKey();
|
||
String ip = "95.26.162.41";
|
||
String urlString = String.format("https://px6.link/api/%s/ipauth?ip=%s", apiKey, ip);
|
||
|
||
try {
|
||
URL url = new URL(urlString);
|
||
HttpURLConnection con = (HttpURLConnection) url.openConnection();
|
||
con.setRequestMethod("GET");
|
||
con.setConnectTimeout(15000);
|
||
con.setReadTimeout(15000);
|
||
|
||
int status = con.getResponseCode();
|
||
BufferedReader in = new BufferedReader(
|
||
new InputStreamReader((status == 200) ? con.getInputStream() : con.getErrorStream(),
|
||
StandardCharsets.UTF_8));
|
||
String inputLine;
|
||
StringBuilder content = new StringBuilder();
|
||
while ((inputLine = in.readLine()) != null) {
|
||
content.append(inputLine);
|
||
}
|
||
in.close();
|
||
con.disconnect();
|
||
|
||
if (status != 200 || !content.toString().contains("\"status\":\"yes\"")) {
|
||
logger.warn("Ошибка привязки IP к proxy6: " + content);
|
||
} else {
|
||
logger.info("Прокси успешно привязаны к IP через proxy6.net!");
|
||
}
|
||
} catch (Exception e) {
|
||
logger.error("Ошибка при привязке proxy6 к IP", e);
|
||
}
|
||
}
|
||
|
||
private void makeGlobalScreenshot(WebDriver driver, String filename) {
|
||
if (driver instanceof TakesScreenshot) {
|
||
try {
|
||
File screenshotFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
|
||
Path destinationDir = Path.of("screenshots", "global");
|
||
Files.createDirectories(destinationDir);
|
||
Path screenshotPath = destinationDir.resolve(filename + ".png");
|
||
Files.copy(screenshotFile.toPath(), screenshotPath, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
|
||
logger.info("Global screenshot taken: {}", screenshotPath);
|
||
} catch (IOException | WebDriverException ex) {
|
||
logger.error("Failed to take global screenshot: {}", ex.getMessage());
|
||
}
|
||
} else {
|
||
logger.warn("Driver does not implement TakesScreenshot, cannot take global screenshot.");
|
||
}
|
||
}
|
||
|
||
private void deleteTempProfileDirectory(Path profilePath) {
|
||
if (profilePath != null) {
|
||
try {
|
||
logger.info("Attempting to delete temporary profile directory: {}", profilePath);
|
||
try (java.util.stream.Stream<Path> walk = Files.walk(profilePath)) {
|
||
walk.sorted(java.util.Comparator.reverseOrder())
|
||
.map(Path::toFile)
|
||
.peek(f -> logger.debug("Deleting: {}", f.getAbsolutePath()))
|
||
.forEach(File::delete);
|
||
}
|
||
logger.info("Successfully deleted temporary profile directory: {}", profilePath);
|
||
} catch (IOException e) {
|
||
logger.error("Failed to delete temporary profile directory {}: {}", profilePath, e.getMessage());
|
||
}
|
||
}
|
||
}
|
||
|
||
private void randomSleep(int minMs, int maxMs) {
|
||
try {
|
||
Thread.sleep(minMs + new java.util.Random().nextInt(maxMs - minMs + 1));
|
||
} catch (InterruptedException e) {
|
||
Thread.currentThread().interrupt();
|
||
}
|
||
}
|
||
|
||
private void performIntensiveWarmup(WebDriver driver, WebDriverWait wait, String accountEmail) {
|
||
logger.info("Starting intensive warm-up for account: {}", accountEmail);
|
||
try {
|
||
// 1. Google Search & Interaction
|
||
if (!driver.getCurrentUrl().contains("google.com")) {
|
||
driver.get("https://www.google.com/");
|
||
randomSleep(1500, 2500);
|
||
}
|
||
// Принять куки Google, если есть
|
||
try {
|
||
WebElement acceptGoogleCookiesButton = new WebDriverWait(driver, Duration.ofSeconds(7))
|
||
.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[.//span[normalize-space()='Принять все' or normalize-space()='Accept all']]")));
|
||
acceptGoogleCookiesButton.click();
|
||
logger.info("Accepted Google cookies consent (e.g., 'Принять все') during intensive warm-up.");
|
||
randomSleep(500, 1500);
|
||
} catch (TimeoutException e) {
|
||
logger.info("Google cookies consent button (e.g., 'Принять все') not found or not clickable during warm-up.");
|
||
}
|
||
|
||
String[] searchQueries = {"latest tech news", "popular music videos", "weather forecast", "best cooking recipes"};
|
||
String searchQuery = searchQueries[new java.util.Random().nextInt(searchQueries.length)];
|
||
|
||
WebElement searchBox = wait.until(ExpectedConditions.visibilityOfElementLocated(By.name("q")));
|
||
typeWithDelayActions(driver, searchBox, searchQuery, 80, 180);
|
||
searchBox.sendKeys(Keys.ENTER);
|
||
logger.info("Warm-up: Searched Google for '{}'", searchQuery);
|
||
randomSleep(2000, 4000);
|
||
|
||
for (int i = 0; i < 2; i++) { // 2 скролла
|
||
((JavascriptExecutor) driver).executeScript("window.scrollBy(0, arguments[0]);", 300 + new java.util.Random().nextInt(400));
|
||
randomSleep(1000, 2000);
|
||
}
|
||
|
||
// 2. Visit YouTube & Interact
|
||
driver.get("https://www.youtube.com/");
|
||
logger.info("Warm-up: Navigated to YouTube.com");
|
||
randomSleep(3000, 5000);
|
||
|
||
// Принять куки YouTube, если есть (могут отличаться от Google)
|
||
try {
|
||
WebElement acceptYouTubeCookiesButton = new WebDriverWait(driver, Duration.ofSeconds(7))
|
||
.until(ExpectedConditions.elementToBeClickable(
|
||
By.xpath("//button[.//yt-formatted-string[contains(text(),'Accept all') or contains(text(),'Принять все')]] | //tp-yt-paper-button[contains(@aria-label,'Accept') or contains(@aria-label,'Принять')]")
|
||
));
|
||
acceptYouTubeCookiesButton.click();
|
||
logger.info("Accepted YouTube cookies during intensive warm-up.");
|
||
randomSleep(1000, 2000);
|
||
} catch (TimeoutException e) {
|
||
logger.info("No YouTube cookies consent button found during warm-up.");
|
||
}
|
||
|
||
for (int i = 0; i < 2; i++) { // 2 скролла на YouTube
|
||
((JavascriptExecutor) driver).executeScript("window.scrollBy(0, arguments[0]);", 400 + new java.util.Random().nextInt(500));
|
||
randomSleep(1500, 2500);
|
||
}
|
||
logger.info("Warm-up: Scrolled on YouTube homepage.");
|
||
|
||
// Опционально: кликнуть на случайное видео (требует аккуратных селекторов)
|
||
// WebElement firstVideo = driver.findElement(By.cssSelector("ytd-rich-item-renderer #video-title-link"));
|
||
// if (firstVideo != null && firstVideo.isDisplayed()) { firstVideo.click(); randomSleep(5000, 8000); driver.navigate().back(); }
|
||
|
||
// 3. Visit another common site (e.g., Wikipedia - lightweight)
|
||
// driver.get("https://www.wikipedia.org/");
|
||
// logger.info("Warm-up: Navigated to Wikipedia.org");
|
||
// randomSleep(2000, 3000);
|
||
// ((JavascriptExecutor) driver).executeScript("window.scrollBy(0, arguments[0]);", 200 + new java.util.Random().nextInt(200));
|
||
// randomSleep(1000, 1500);
|
||
|
||
logger.info("Intensive warm-up finished for account: {}. Total duration approx ~1-2 mins.", accountEmail);
|
||
// Общая длительность этого прогрева будет зависеть от задержек. Можно добавить больше шагов для 3+ минут.
|
||
|
||
} catch (Exception e) {
|
||
logger.warn("Error during intensive warm-up for account {}: {}. Proceeding with login attempt.", accountEmail, e.getMessage());
|
||
makeGlobalScreenshot(driver, "intensive_warmup_error_" + accountEmail.replace("@", "_"));
|
||
}
|
||
}
|
||
|
||
// Вспомогательный метод для посимвольного ввода, если он нужен здесь
|
||
// Если такой уже есть в GoogleLoginHandler, лучше его переиспользовать или вынести в утилиты
|
||
private void typeWithDelayActions(WebDriver driver, WebElement element, String text, int minDelay, int maxDelay) {
|
||
org.openqa.selenium.interactions.Actions actions = new org.openqa.selenium.interactions.Actions(driver);
|
||
for (char c : text.toCharArray()) {
|
||
actions.sendKeys(element, String.valueOf(c)).perform();
|
||
randomSleep(minDelay, maxDelay);
|
||
}
|
||
}
|
||
} |