diff --git a/src/main/java/com/seleniumLib/SeleniumLoginWithCookieRecorder.java b/src/main/java/com/seleniumLib/SeleniumLoginWithCookieRecorder.java index 9d9bdc0..855e4e7 100644 --- a/src/main/java/com/seleniumLib/SeleniumLoginWithCookieRecorder.java +++ b/src/main/java/com/seleniumLib/SeleniumLoginWithCookieRecorder.java @@ -227,7 +227,7 @@ public class SeleniumLoginWithCookieRecorder { /** * 通用表单登录 */ - public void loginToCrossCheck(String username, String password, String filePath, String tenant, + public boolean loginToCrossCheck(String username, String password, String filePath, String tenant, String capture_path) { try { System.out.println("开始 Crossref 登录流程..."); @@ -295,7 +295,7 @@ public class SeleniumLoginWithCookieRecorder { if (usernameField == null) { System.err.println("无法定位到用户名输入框,页面可能没有正确加载"); // captureScreenshot("element_not_found"); - return; + return false; } // 输入用户名 @@ -376,119 +376,20 @@ public class SeleniumLoginWithCookieRecorder { Thread.sleep(15000); } - /* - * // 第二次处理验证码 - * if (cap_first.equals("1") || !isLoggedIn) { - * Thread.sleep(3000); - * // 验证码处理 - * try { - * WebElement captchaImage = extendedWait - * .until(ExpectedConditions - * .presenceOfElementLocated(By.cssSelector("img[alt='Captcha image']"))); - * String src1 = captchaImage.getAttribute("src"); - * - * if (src1 != null && !src1.isEmpty()) { - * src1 = src1.replace("data:image/png;base64,", "").replace("\n", "").trim(); - * // System.out.println("验证码图片URL2: " + src1); - * - * String result_cap = this.recognizeCaptcha(src1 + "YII="); - * System.out.println("验证码识别结果2: " + result_cap); - * - * if (result_cap != null && !result_cap.trim().isEmpty()) { - * result_cap = result_cap.replace(" ", ""); - * WebElement captchaField = extendedWait - * .until(ExpectedConditions.visibilityOfElementLocated(By.id("captcha-input"))) - * ; - * captchaField.clear(); - * captchaField.sendKeys(result_cap); - * System.out.println("已输入验证码2: " + result_cap); - * if (!capture_path.isEmpty()) { - * captureScreenshot("captcha_write_done2", capture_path); - * } - * Thread.sleep(3000); - * } - * - * // 点击登录按钮 - * WebElement signinButton2 = extendedWait.until( - * ExpectedConditions - * .elementToBeClickable(By.cssSelector("button[data-testid='sign-in-btn']"))); - * signinButton2.click(); - * System.out.println("已点击登录按钮2"); - * if (!capture_path.isEmpty()) { - * captureScreenshot("login_button_click2", capture_path); - * } - * } - * } catch (Exception e) { - * System.out.println("未找到验证码或验证码处理失败2: " + e.getMessage()); - * } - * } - * - * isLoggedIn = isLoggedIn(); - * // 第三次次处理验证码 - * if (!isLoggedIn) { - * Thread.sleep(3000); - * // 验证码处理 - * try { - * WebElement captchaImage = extendedWait - * .until(ExpectedConditions - * .presenceOfElementLocated(By.cssSelector("img[alt='Captcha image']"))); - * String src1 = captchaImage.getAttribute("src"); - * - * if (src1 != null && !src1.isEmpty()) { - * src1 = src1.replace("data:image/png;base64,", "").replace("\n", "").trim(); - * // System.out.println("验证码图片URL2: " + src1); - * - * String result_cap = this.recognizeCaptcha(src1 + "YII="); - * System.out.println("验证码识别结果3: " + result_cap); - * - * if (result_cap != null && !result_cap.trim().isEmpty()) { - * result_cap = result_cap.replace(" ", ""); - * WebElement captchaField = extendedWait - * .until(ExpectedConditions.visibilityOfElementLocated(By.id("captcha-input"))) - * ; - * captchaField.clear(); - * captchaField.sendKeys(result_cap); - * System.out.println("已输入验证码3: " + result_cap); - * if (!capture_path.isEmpty()) { - * captureScreenshot("captcha_write_done3", capture_path); - * } - * Thread.sleep(3000); - * } - * - * // 点击登录按钮 - * WebElement signinButton3 = extendedWait.until( - * ExpectedConditions - * .elementToBeClickable(By.cssSelector("button[data-testid='sign-in-btn']"))); - * signinButton3.click(); - * System.out.println("已点击登录按钮3"); - * if (!capture_path.isEmpty()) { - * captureScreenshot("login_button_click3", capture_path); - * } - * } - * } catch (Exception e) { - * System.out.println("未找到验证码或验证码处理失败3: " + e.getMessage()); - * } - * } - */ // 等待登录结果 Thread.sleep(5000); // 检查登录是否成功 try { - // extendedWait.until(ExpectedConditions.urlContains("crossref-26027.turnitin.com/originality/inbox/")); - // System.out.println("登录成功,当前URL: " + driver.getCurrentUrl()); // 获取并保存 Cookie boolean isLoggedIn = isLoggedIn(); if (isLoggedIn) { saveNPCookiesToFile("crossref", filePath); System.out.println("登录成功"); - // 每隔五分钟刷新一下页面,保持登录状态 - // for (int i = 0; i < 12; i++) { - // Thread.sleep(300000); // 5分钟 - // driver.navigate().refresh(); - // System.out.println("已刷新页面"); - // } + // 清空cookie + driver.manage().deleteAllCookies(); + return true; } else { System.out.println("登录失败"); // // 获取错误提示文本 @@ -499,17 +400,24 @@ public class SeleniumLoginWithCookieRecorder { if (!capture_path.isEmpty()) { captureScreenshot("login_error", capture_path); } + // 清空cookie + driver.manage().deleteAllCookies(); + return false; } } catch (Exception e) { System.err.println("登录可能失败,当前URL: " + driver.getCurrentUrl()); // captureScreenshot("login_possible_failure"); + return false; } } catch (Exception e) { + // 清空cookie + driver.manage().deleteAllCookies(); System.err.println("登录过程中发生错误: " + e.getMessage()); e.printStackTrace(); // captureScreenshot("login_error"); + return false; } } @@ -664,41 +572,6 @@ public class SeleniumLoginWithCookieRecorder { } } - /** - * 从文件加载 Cookie 并设置到浏览器 - */ - public void loadCookiesFromFile(String filename) { - try { - // 文件中保存的是Netscape 格式的 Cookie 怎么改下面的代码 - - CookieData cookieData = objectMapper.readValue(new File(filename), CookieData.class); - - // 先导航到 Cookie 的域名,https://crossref-26027.turnitin.com/home/ - // driver.get(cookieData.getUrl()); - driver.get("https://crossref-26027.turnitin.com/home/"); - - // 清空现有 Cookie - driver.manage().deleteAllCookies(); - - // 添加 Cookie - for (Cookie cookie : cookieData.getCookies()) { - try { - driver.manage().addCookie(cookie); - System.out.println("已添加 Cookie: " + cookie.getName()); - } catch (Exception e) { - System.err.println("添加 Cookie 失败 (" + cookie.getName() + "): " + e.getMessage()); - } - } - - // 刷新页面使 Cookie 生效 - driver.navigate().refresh(); - System.out.println("Cookie 加载完成,页面已刷新"); - - } catch (IOException e) { - System.err.println("加载 Cookie 文件失败: " + e.getMessage()); - } - } - public boolean loadCookiesAndAccessSite(String cookieFile, String tenant, String capture_path) { try { try { @@ -797,22 +670,50 @@ public class SeleniumLoginWithCookieRecorder { driver.navigate().refresh(); Thread.sleep(5000); // 使用CSS选择器 + WebElement element = driver.findElement(By.cssSelector("h1[data-test-id='page-title']")); String text = element.getText(); - element.click(); - element.click(); + + // 随机点击次数1~3下,确保元素可见 + int clickCount = (int) (Math.random() * 3) + 1; + for (int i = 0; i < clickCount; i++) { + element.click(); + } + + // 随机获取一个元素点击,不包括链接元素,按钮元素。 + try { + List elements = driver.findElements(By.cssSelector("*:not(a):not(button)")); + System.out.println("页面元素数量: " + elements.size()); + if (!elements.isEmpty()) { + int clickElementCount = (int) (Math.random() * 2) + 1; + for (int i = 0; i < clickElementCount; i++) { + int randomIndex = (int) (Math.random() * elements.size()); + WebElement randomElement = elements.get(randomIndex); + randomElement.click(); + } + } + } catch (Exception e) { + System.out.println("随机元素不存在"); + } + System.out.println("获取的文字是: " + text); // 包含指定文本 if (text.contains("Welcome")) { System.out.println("使用cookie刷新成功"); saveNPCookiesToFile("crossref", cookieFile); + // 清空cookie + driver.manage().deleteAllCookies(); return true; } else { System.out.println("使用cookie刷新失败"); + // 清空cookie + driver.manage().deleteAllCookies(); return false; } } catch (Exception e) { System.err.println("Cookie 刷新失败: " + e.getMessage()); + // 清空cookie + driver.manage().deleteAllCookies(); return false; } // return false; @@ -877,6 +778,9 @@ public class SeleniumLoginWithCookieRecorder { String capture_path = ""; String only_keep_cookie = "0"; String only_login = "0"; + String json_accounts = ""; + String waitTime = ""; + ArrayList arr_accounts = new ArrayList<>(); // 传的参数增加参数名 for (int i = 0; i < args.length; i++) { @@ -890,6 +794,9 @@ public class SeleniumLoginWithCookieRecorder { proxy = args[i + 1]; } else if (args[i].equals("-t")) { tenant = args[i + 1]; + } else if (args[i].equals("-json_accounts")) { + json_accounts = args[i + 1]; + arr_accounts = new Gson().fromJson(json_accounts, ArrayList.class); } else if (args[i].equals("-help")) { help = "1"; } else if (args[i].equals("-only_keep_cookie")) { @@ -911,10 +818,12 @@ public class SeleniumLoginWithCookieRecorder { } if (help.equals("1")) { System.out.println("参数说明:"); - System.out.println("-u '用户名',必填"); - System.out.println("-p '密码',必填"); - System.out.println("-f '保存 Cookie 的文件路径及文件名',必填"); + System.out.println("-u '用户名',无-json_accounts时必填"); + System.out.println("-p '密码',无-json_accounts时必填,-only_keep_cookie时可不填"); + System.out.println("-f '保存 Cookie 的文件路径及文件名',无-json_accounts时必填"); System.out.println("-t '租户 ID'(可选,默认crossref-26027)"); + System.out.println( + "-json_accounts '多个账号json格式:[{\"username\":\"\",\"password\":\"\",\"tenant\":\"\",\"filePath\":\"\",\"waitTime\":\"\"},...]',选填,可替代-u/-p/-t/-f参数"); System.out.println("-proxy '代理配置字串'(可选,例如 'socks5://host:port') "); System.out.println("-capture_path '截图保存路径'(可选,没有此参数,则不截图)"); System.out.println("-only_keep_cookie: 只做cookie保活,不登录"); @@ -923,26 +832,81 @@ public class SeleniumLoginWithCookieRecorder { return; } - if (user_name.isEmpty() || password.isEmpty() || filePath.isEmpty()) { - System.err.println("用户名、密码、文件路径不能为空。-help 查看帮助信息"); + if ((user_name.isEmpty() || (password.isEmpty() && !only_keep_cookie.equals("1")) || filePath.isEmpty()) + && arr_accounts.isEmpty()) { + System.err.println("-help 查看帮助信息。用户名、密码、文件路径不能为空或-json_accounts参数不能为空。"); return; } + // 将-u/-p/-t/-f参数添加到arr_accounts中 + if (arr_accounts.isEmpty()) { + Map accountMap = new HashMap<>(); + accountMap.put("username", user_name); + accountMap.put("password", password); + accountMap.put("tenant", tenant); + accountMap.put("filePath", filePath); + accountMap.put("waitTime", "1"); + arr_accounts.add(accountMap); + } + + // 检查元素是否有username、password、tenant、filePath + for (Object obj : arr_accounts) { + // 检查元素是否为 Map 类型 + if (obj instanceof Map) { + Map accountMap = (Map) obj; + user_name = (String) accountMap.get("username"); + password = (String) accountMap.get("password"); + tenant = (String) accountMap.get("tenant"); + filePath = (String) accountMap.get("filePath"); + // 检测是否有username、password、tenant、filePath,并且不能为空,为空则删除 + if (user_name.isEmpty() || tenant.isEmpty() || filePath.isEmpty()) { + arr_accounts.remove(accountMap); + String currentTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); + System.out.println("" + currentTime + "|" + user_name + + "|保活失败|数组元素删除,因为username、password、tenant、filePath不能为空"); + } + } else { + System.out.println("数组元素不是 Map 类型"); + } + } + // 1. 初始化驱动(带代理配置) recorder.setupDriver(proxy); if (only_login.equals("1")) { System.out.println("-only_login: 只登录,不做cookie保活"); } else { - // 如果文件存在,加载文件中的 Cookie - if (Files.exists(Paths.get(filePath))) { - System.out.println("文件存在,加载文件中的 Cookie:" + filePath); - boolean testLoggedIn = recorder.loadCookiesAndAccessSite(filePath, tenant, capture_path); - if (testLoggedIn) { - System.out.println("cookie保活成功"); - return; - } else { - System.out.println("cookie保活失败"); + // 遍历数组中的每个元素,保活cookie + for (Object obj : arr_accounts) { + // 检查元素是否为 Map 类型 + Map accountMap = (Map) obj; + user_name = (String) accountMap.get("username"); + password = (String) accountMap.get("password"); + tenant = (String) accountMap.get("tenant"); + filePath = (String) accountMap.get("filePath"); + waitTime = String.valueOf(accountMap.get("waitTime")); + + // 如果文件存在,加载文件中的 Cookie + if (Files.exists(Paths.get(filePath))) { + System.out.println("文件存在,加载文件中的 Cookie:" + filePath); + boolean testLoggedIn = recorder.loadCookiesAndAccessSite(filePath, tenant, capture_path); + String currentTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); + if (testLoggedIn) { + System.out.println("" + currentTime + "|" + user_name + "|cookie保活成功"); + // return; + } else { + System.out.println("" + currentTime + "|" + user_name + "|cookie保活失败"); + } + } + + // 等待间隔 + if (waitTime != null && !waitTime.isEmpty()) { + try { + System.out.println("等待 " + waitTime + " 秒后继续下一个账号"); + Thread.sleep((int) Double.parseDouble(waitTime) * 1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } } } } @@ -951,18 +915,37 @@ public class SeleniumLoginWithCookieRecorder { System.out.println("-only_keep_cookie: 只做cookie保活,不登录"); return; } - // System.exit(0); - // return; - // 2. Crossref 登录示例(需要替换为真实账号) - - recorder.loginToCrossCheck(user_name, password, filePath, tenant, capture_path); - // 3. 验证登录状态 - boolean isLoggedIn = recorder.isLoggedIn(); - System.out.println("登录状态: " + (isLoggedIn ? "成功" : "失败")); + // 遍历数组中的每个元素,登录并保存cookie + for (Object obj : arr_accounts) { + // 检查元素是否为 Map 类型 + Map accountMap = (Map) obj; + user_name = (String) accountMap.get("username"); + password = (String) accountMap.get("password"); + tenant = (String) accountMap.get("tenant"); + filePath = (String) accountMap.get("filePath"); + waitTime = String.valueOf(accountMap.get("waitTime")); + // 2. Crossref 登录示例(需要替换为真实账号) + boolean isLoggedIn = recorder.loginToCrossCheck(user_name, password, filePath, tenant, capture_path); + + // 3. 验证登录状态 + // boolean isLoggedIn = recorder.isLoggedIn(); + String currentTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); + System.out.println( + "" + currentTime + "|" + user_name + "|登录" + (isLoggedIn ? "成功" : "失败") + ""); - // 4. 可以在这里使用获取的 Cookie 进行后续操作 - // recorder.loadCookiesFromFile("github_cookies_20231215_143022.json"); + // 清空cookie + recorder.driver.manage().deleteAllCookies(); + // 等待间隔 + if (waitTime != null && !waitTime.isEmpty()) { + try { + System.out.println("等待 " + waitTime + " 秒后继续下一个账号"); + Thread.sleep((int) Double.parseDouble(waitTime) * 1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } } catch (Exception e) { System.err.println("程序执行异常: " + e.getMessage());