diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml new file mode 100644 index 0000000..d585656 --- /dev/null +++ b/dependency-reduced-pom.xml @@ -0,0 +1,53 @@ + + + 4.0.0 + com.example + crossref + 1.0-SNAPSHOT + + + + maven-compiler-plugin + 3.11.0 + + 8 + 8 + + + + maven-shade-plugin + 3.4.1 + + + package + + shade + + + + + com.seleniumLib.SeleniumLoginWithCookieRecorder + + + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + + + + + + + + UTF-8 + 8 + 8 + + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..582266f --- /dev/null +++ b/pom.xml @@ -0,0 +1,109 @@ + + + 4.0.0 + + com.example + crossref + 1.0-SNAPSHOT + + + 8 + 8 + UTF-8 + + + + + org.slf4j + slf4j-nop + 1.7.36 + + + + org.seleniumhq.selenium + selenium-java + 4.11.0 + + + + com.alibaba + fastjson + 1.2.37 + + + + com.google.guava + guava + 31.1-jre + + + + + org.apache.httpcomponents + httpclient + 4.5.14 + + + + + io.github.bonigarcia + webdrivermanager + 5.6.2 + + + + + com.fasterxml.jackson.core + jackson-databind + 2.15.2 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.11.0 + + 8 + 8 + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.4.1 + + + package + + shade + + + + + com.seleniumLib.SeleniumLoginWithCookieRecorder + + + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/seleniumLib/SeleniumLoginWithCookieRecorder.java b/src/main/java/com/seleniumLib/SeleniumLoginWithCookieRecorder.java new file mode 100644 index 0000000..7c38282 --- /dev/null +++ b/src/main/java/com/seleniumLib/SeleniumLoginWithCookieRecorder.java @@ -0,0 +1,712 @@ +package com.seleniumLib; + +import org.openqa.selenium.*; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.chrome.ChromeOptions; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; +import io.github.bonigarcia.wdm.WebDriverManager; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.google.gson.Gson; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.net.URI; +import java.time.Duration; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.text.SimpleDateFormat; + +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import com.google.gson.JsonObject; +import com.google.gson.JsonArray; +import com.google.gson.JsonParser; + +/** + * Selenium 模拟登录并获取 Cookie 的示例 + * 支持多种登录方式:表单登录、OAuth、AJAX 登录等 + */ +public class SeleniumLoginWithCookieRecorder { + + private WebDriver driver; + private WebDriverWait wait; + private String cookiesSavePath = "cookies.json"; + private ObjectMapper objectMapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); + private static final String API_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions"; + private static final String API_KEY = "sk-e5c86737c99a4c9da5efe3519ca2b539"; + private static final Gson gson = new Gson(); + + /** + * 识别验证码 + */ + public String recognizeCaptcha(String base64Img) { + try (CloseableHttpClient httpClient = HttpClients.createDefault()) { + // 构建请求 + HttpPost httpPost = new HttpPost(API_URL); + + // 设置 headers + httpPost.setHeader("Authorization", "Bearer " + API_KEY); + httpPost.setHeader("Content-Type", "application/json"); + httpPost.setHeader("Accept", "application/json"); + + // 构建请求体 + Map params = new HashMap<>(); + params.put("model", "qwen3-vl-plus"); + params.put("temperature", 0.3); + + // 构建 messages 数组 + List> messages = new ArrayList<>(); + Map userMessage = new HashMap<>(); + userMessage.put("role", "user"); + + // 构建 content 数组 + List> content = new ArrayList<>(); + + // 图片部分 + Map imageContent = new HashMap<>(); + imageContent.put("type", "image_url"); + imageContent.put("image_url", "data:image/png;base64," + base64Img); + content.add(imageContent); + + // 文本部分 + Map textContent = new HashMap<>(); + textContent.put("type", "text"); + textContent.put("text", "识别图片中验证码,区分大小写,要求只返回验证码即可"); + content.add(textContent); + + userMessage.put("content", content); + messages.add(userMessage); + + params.put("messages", messages); + + // 转换为 JSON + String jsonParams = gson.toJson(params); + System.out.println("请求参数: " + jsonParams); + + // 设置请求体 + httpPost.setEntity(new StringEntity(jsonParams, "UTF-8")); + + // 发送请求 + try (CloseableHttpResponse response = httpClient.execute(httpPost)) { + String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8"); + System.out.println("API 响应: " + responseBody); + + // 解析响应 + return extractCaptchaFromResponse(responseBody); + } + + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 从响应中提取验证码 + */ + private String extractCaptchaFromResponse(String jsonResponse) { + try { + JsonObject jsonObject = JsonParser.parseString(jsonResponse).getAsJsonObject(); + JsonArray choices = jsonObject.getAsJsonArray("choices"); + + if (choices != null && choices.size() > 0) { + JsonObject firstChoice = choices.get(0).getAsJsonObject(); + JsonObject message = firstChoice.getAsJsonObject("message"); + String content = message.get("content").getAsString(); + + // 清理内容,只返回验证码 + return content.trim(); + } + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + /** + * 初始化 WebDriver + */ + public void setupDriver() { + + // 自动下载和管理 ChromeDriver + + String devSystem = System.getProperty("os.name"); + if (!devSystem.toLowerCase().contains("windows")) { + System.setProperty("webdriver.chrome.driver", "/datacenter/java/lib/chromedriver"); + } else { + WebDriverManager.chromedriver().setup(); + } + + // Chrome 选项配置 + ChromeOptions options = new ChromeOptions(); + + // 可选:无头模式(不显示浏览器界面) + // options.addArguments("--headless"); + options.addArguments("--headless=new"); + + // 可选:禁用自动化提示 + options.addArguments("--disable-blink-features=AutomationControlled"); + options.setExperimentalOption("excludeSwitches", new String[] { "enable-automation" }); + options.setExperimentalOption("useAutomationExtension", false); + + // 用户代理伪装(模拟真实浏览器) + options.addArguments( + "--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"); + + // 其他优化选项 + options.addArguments("--no-sandbox"); + options.addArguments("--disable-dev-shm-usage"); + options.addArguments("--disable-gpu"); + options.addArguments("--window-size=1920,1080"); + options.addArguments("--start-maximized"); + options.addArguments("--disable-extensions"); + options.addArguments("--disable-plugins"); + options.addArguments("--disable-popup-blocking"); + options.addArguments("--disable-default-apps"); + options.addArguments("--disable-translate"); + options.addArguments("--disable-background-timer-throttling"); + options.addArguments("--disable-renderer-backgrounding"); + options.addArguments("--disable-backgrounding-occluded-windows"); + options.addArguments("--disable-features=TranslateUI,BlinkGenPropertyTrees"); + options.addArguments("--disable-component-update"); + options.addArguments("--disable-domain-reliability"); + options.addArguments("--disable-ipc-flooding-protection"); + options.addArguments("--disable-client-side-phishing-detection"); + options.addArguments("--disable-hang-monitor"); + options.addArguments("--disable-prompt-on-repost"); + options.addArguments("--disable-sync"); + options.addArguments("--disable-web-security"); + options.addArguments("--disable-site-isolation-trials"); + options.addArguments("--disable-features=VizDisplayCompositor"); + options.addArguments("--disable-software-rasterizer"); + options.addArguments("--disable-logging"); + options.addArguments("--log-level=3"); + options.addArguments("--silent"); + options.addArguments("--mute-audio"); + + driver = new ChromeDriver(options); + + // 执行JavaScript来隐藏WebDriver特征 + // driver.executeScript("Object.defineProperty(navigator, 'webdriver', {get: () + // => undefined})"); + // driver.executeScript("Object.defineProperty(navigator, 'plugins', {get: () => + // [1, 2, 3, 4, 5]})"); + // driver.executeScript("Object.defineProperty(navigator, 'languages', {get: () + // => ['zh-CN', 'zh', 'en']})"); + + wait = new WebDriverWait(driver, Duration.ofSeconds(15)); + System.out.println("WebDriver 初始化完成"); + } + + /** + * 通用表单登录 + */ + public void loginToCrossCheck(String username, String password, String filePath) { + try { + System.out.println("开始 Crossref 登录流程..."); + + // 打开登录页面 + driver.get("https://crossref-26027.turnitin.com/originality/inbox/713daa1b-0685-4cc7-89ec-6b6c7cbc0411"); + + // 增加页面加载等待时间 + Thread.sleep(3000); // 等待5秒确保页面完全加载 + + // 调试:打印页面标题和URL + System.out.println("当前页面标题: " + driver.getTitle()); + System.out.println("当前页面URL: " + driver.getCurrentUrl()); + + // 调试:打印页面源代码(前500字符) + // String pageSource = driver.getPageSource(); + // System.out.println("页面源代码片段: " + pageSource.substring(0, Math.min(500, + // pageSource.length()))); + + // 使用更稳健的等待策略 + WebDriverWait extendedWait = new WebDriverWait(driver, Duration.ofSeconds(30)); + + // 尝试多种元素定位方式 + WebElement usernameField = null; + try { + // 方式1:直接等待元素可见 + usernameField = extendedWait.until(ExpectedConditions.visibilityOfElementLocated(By.id("username"))); + System.out.println("通过id定位到username元素"); + } catch (Exception e1) { + try { + // 方式2:尝试CSS选择器 + usernameField = extendedWait.until( + ExpectedConditions.visibilityOfElementLocated(By.cssSelector("input[id='username']"))); + System.out.println("通过CSS选择器定位到username元素"); + } catch (Exception e2) { + try { + // 方式3:尝试name属性 + usernameField = extendedWait + .until(ExpectedConditions.visibilityOfElementLocated(By.name("username"))); + System.out.println("通过name属性定位到username元素"); + } catch (Exception e3) { + // 方式4:尝试XPath + usernameField = extendedWait.until(ExpectedConditions.visibilityOfElementLocated( + By.xpath("//input[contains(@id, 'username') or contains(@name, 'username')]"))); + System.out.println("通过XPath定位到username元素"); + } + } + } + + if (usernameField == null) { + System.err.println("无法定位到用户名输入框,页面可能没有正确加载"); + // captureScreenshot("element_not_found"); + return; + } + + // 输入用户名 + usernameField.clear(); + usernameField.sendKeys(username); + System.out.println("已输入用户名"); + + // 输入密码 + WebElement passwordField = extendedWait + .until(ExpectedConditions.visibilityOfElementLocated(By.id("password"))); + passwordField.clear(); + passwordField.sendKeys(password); + System.out.println("已输入密码"); + Thread.sleep(3000); + // 验证码处理 + String cap_first = "0"; + 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("验证码图片URL: " + src1); + + String result_cap = this.recognizeCaptcha(src1 + "YII="); + System.out.println("验证码识别结果: " + 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("已输入验证码"); + // captureScreenshot("captcha_done"); + Thread.sleep(3000); + } + } + } catch (Exception e) { + System.out.println("未找到验证码或验证码处理失败: " + e.getMessage()); + cap_first = "1"; + + } + + // 点击登录按钮 + WebElement signinButton = extendedWait.until( + ExpectedConditions.elementToBeClickable(By.cssSelector("button[data-testid='sign-in-btn']"))); + signinButton.click(); + System.out.println("已点击登录按钮"); + + boolean isLoggedIn = isLoggedIn(); + + // 处理验证码 + 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"); + // captureScreenshot("captcha_done"); + Thread.sleep(3000); + } + + // 点击登录按钮 + WebElement signinButton2 = extendedWait.until( + ExpectedConditions + .elementToBeClickable(By.cssSelector("button[data-testid='sign-in-btn']"))); + signinButton2.click(); + System.out.println("已点击登录按钮2"); + } + } catch (Exception e) { + System.out.println("未找到验证码或验证码处理失败2: " + e.getMessage()); + } + } + + // 等待登录结果 + Thread.sleep(3000); + + // 检查登录是否成功 + try { + // extendedWait.until(ExpectedConditions.urlContains("crossref-26027.turnitin.com/originality/inbox/")); + // System.out.println("登录成功,当前URL: " + driver.getCurrentUrl()); + + // 获取并保存 Cookie + isLoggedIn = isLoggedIn(); + if (isLoggedIn) { + saveNPCookiesToFile("crossref", filePath); + System.out.println("登录成功"); + } else { + System.out.println("登录失败"); + } + + } catch (Exception e) { + System.err.println("登录可能失败,当前URL: " + driver.getCurrentUrl()); + // captureScreenshot("login_possible_failure"); + } + + } catch (Exception e) { + System.err.println("登录过程中发生错误: " + e.getMessage()); + e.printStackTrace(); + // captureScreenshot("login_error"); + } + } + + /** + * 获取所有 Cookie 并保存到文件 + */ + public void saveCookiesToFile(String siteName) { + try { + Set cookies = driver.manage().getCookies(); + + System.out.println("\n========== " + siteName.toUpperCase() + " COOKIES =========="); + System.out.println("共获取到 " + cookies.size() + " 个 Cookie:"); + + // 创建 Cookie 数据对象 + CookieData cookieData = new CookieData(); + cookieData.setSite(siteName); + cookieData.setUrl(driver.getCurrentUrl()); + cookieData.setTimestamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + + for (Cookie cookie : cookies) { + System.out.println("--------------------------------"); + System.out.println("Name: " + cookie.getName()); + System.out.println( + "Value: " + (cookie.getValue().length() > 50 ? cookie.getValue().substring(0, 50) + "..." + : cookie.getValue())); + System.out.println("Domain: " + cookie.getDomain()); + System.out.println("Path: " + cookie.getPath()); + System.out.println("Expiry: " + cookie.getExpiry()); + System.out.println("Secure: " + cookie.isSecure()); + System.out.println("HttpOnly: " + cookie.isHttpOnly()); + + // 添加到数据列表 + cookieData.addCookie(cookie); + } + + // 保存到 JSON 文件 + String filename = siteName + "_cookies_" + + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + ".json"; + + objectMapper.writeValue(new File(filename), cookieData); + System.out.println("\nCookie 已保存到文件: " + filename); + + } catch (IOException e) { + System.err.println("保存 Cookie 文件失败: " + e.getMessage()); + } + } + + /** + * 获取所有 Cookie 并保存为 Netscape 格式的 cookie 文件 + */ + public void saveNPCookiesToFile(String siteName, String filePath) { + try { + Set cookies = driver.manage().getCookies(); + + System.out.println("\n========== " + siteName.toUpperCase() + " COOKIES =========="); + System.out.println("共获取到 " + cookies.size() + " 个 Cookie:"); + + // 创建 Netscape 格式的 cookie 文件 + // String filename = siteName + "_cookies_" + new + // SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + ".txt"; + String filename = filePath; + + try (BufferedWriter writer = new BufferedWriter(new FileWriter(filename))) { + // 写入 Netscape cookie 文件头部 + writer.write("# Netscape HTTP Cookie File"); + writer.newLine(); + writer.write("# https://curl.haxx.se/docs/http-cookies.html"); + writer.newLine(); + writer.write("# This file was generated by Selenium Cookie Exporter"); + writer.newLine(); + writer.write("# Site: " + siteName); + writer.newLine(); + writer.write("# URL: " + driver.getCurrentUrl()); + writer.newLine(); + writer.write("# Generated at: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + writer.newLine(); + writer.newLine(); + + // Netscape cookie 格式: + // domain \t inclusion \t path \t secure \t expiry \t name \t value + // - domain: cookie 的域名 + // - inclusion: 子域名是否可用 (TRUE/FALSE) + // - path: cookie 的路径 + // - secure: 是否只通过 HTTPS 传输 (TRUE/FALSE) + // - expiry: Unix 时间戳(秒),0 表示会话 cookie + // - name: cookie 名称 + // - value: cookie 值 + + for (Cookie cookie : cookies) { + System.out.println("--------------------------------"); + System.out.println("Name: " + cookie.getName()); + System.out.println( + "Value: " + (cookie.getValue().length() > 50 ? cookie.getValue().substring(0, 50) + "..." + : cookie.getValue())); + System.out.println("Domain: " + cookie.getDomain()); + System.out.println("Path: " + cookie.getPath()); + System.out.println("Expiry: " + cookie.getExpiry()); + System.out.println("Secure: " + cookie.isSecure()); + System.out.println("HttpOnly: " + cookie.isHttpOnly()); + + // 处理域名 + String domain = cookie.getDomain(); + if (domain != null && domain.startsWith(".")) { + domain = domain.substring(1); // 移除开头的点 + } + + // 处理 inclusion 字段 + // 如果 cookie 域名以 . 开头,则表示可用于所有子域名 + String inclusion = "FALSE"; + if (cookie.getDomain() != null && cookie.getDomain().startsWith(".")) { + inclusion = "TRUE"; + } + + // 处理路径 + String path = cookie.getPath(); + if (path == null || path.isEmpty()) { + path = "/"; + } + + // 处理过期时间 + long expiry = 0; + if (cookie.getExpiry() != null) { + expiry = cookie.getExpiry().getTime() / 1000; // 转换为 Unix 时间戳(秒) + } + + // 处理 secure 标志 + String secure = cookie.isSecure() ? "TRUE" : "FALSE"; + + // 构建 Netscape cookie 行 + String cookieLine = String.format("%s\t%s\t%s\t%s\t%d\t%s\t%s", + domain != null ? domain : "", + inclusion, + path, + secure, + expiry, + cookie.getName(), + cookie.getValue()); + + writer.write(cookieLine); + writer.newLine(); + } + + System.out.println("\nNetscape 格式 Cookie 文件已保存: " + filename); + + } catch (IOException e) { + System.err.println("写入 Cookie 文件失败: " + e.getMessage()); + } + + } catch (Exception e) { + System.err.println("保存 Cookie 文件失败: " + e.getMessage()); + e.printStackTrace(); + } + } + + /** + * 从文件加载 Cookie 并设置到浏览器 + */ + public void loadCookiesFromFile(String filename) { + try { + CookieData cookieData = objectMapper.readValue(new File(filename), CookieData.class); + + // 先导航到 Cookie 的域名 + driver.get(cookieData.getUrl()); + + // 清空现有 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()); + } + } + + /** + * 截图保存 + */ + private void captureScreenshot(String filename) { + try { + File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); + String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); + File dest = new File("screenshot_" + filename + "_" + timestamp + ".png"); + com.google.common.io.Files.copy(screenshot, dest); + System.out.println("截图已保存: " + dest.getAbsolutePath()); + } catch (Exception e) { + System.err.println("截图失败: " + e.getMessage()); + } + } + + /** + * 验证登录是否成功 + */ + public boolean isLoggedIn() { + try { + Set cookies = driver.manage().getCookies(); + for (Cookie cookie : cookies) { + if (cookie.getName().equals("jwtCookie")) { + return true; + } + } + } catch (Exception e) { + return false; + } + return false; + } + + /** + * 关闭浏览器 + */ + public void teardown() { + if (driver != null) { + // captureScreenshot("before_close"); + driver.quit(); + System.out.println("浏览器已关闭"); + } + } + + /** + * 主方法 - 示例运行 + */ + public static void main(String[] args) { + SeleniumLoginWithCookieRecorder recorder = new SeleniumLoginWithCookieRecorder(); + + try { + // 1. 初始化驱动 + recorder.setupDriver(); + if (args.length != 3) { + System.err.println("请提供用户名、密码和文件路径作为参数"); + return; + } + if (args[0].isEmpty() || args[1].isEmpty() || args[2].isEmpty()) { + System.err.println("用户名、密码或文件路径不能为空"); + return; + } + String user_name = args[0]; + String password = args[1]; + String filePath = args[2]; + + // 2. Crossref 登录示例(需要替换为真实账号) + recorder.loginToCrossCheck(user_name, password, filePath); + + // 3. 验证登录状态 + boolean isLoggedIn = recorder.isLoggedIn(); + System.out.println("登录状态: " + (isLoggedIn ? "成功" : "失败")); + + // 4. 可以在这里使用获取的 Cookie 进行后续操作 + // recorder.loadCookiesFromFile("github_cookies_20231215_143022.json"); + + } catch (Exception e) { + System.err.println("程序执行异常: " + e.getMessage()); + e.printStackTrace(); + } finally { + // 5. 清理资源 + recorder.teardown(); + } + } + + /** + * Cookie 数据模型类 + */ + static class CookieData { + private String site; + private String url; + private String timestamp; + private List cookies; + + // 构造函数、getter、setter + public CookieData() { + } + + public String getSite() { + return site; + } + + public void setSite(String site) { + this.site = site; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getTimestamp() { + return timestamp; + } + + public void setTimestamp(String timestamp) { + this.timestamp = timestamp; + } + + public List getCookies() { + return cookies; + } + + public void setCookies(List cookies) { + this.cookies = cookies; + } + + public void addCookie(Cookie cookie) { + // 这里需要将 org.openqa.selenium.Cookie 转换为可序列化的对象 + // 或者直接使用 Cookie 类(它本身是可序列化的) + // 简化处理:直接添加到列表 + if (this.cookies == null) { + this.cookies = new java.util.ArrayList<>(); + } + this.cookies.add(cookie); + } + } +} \ No newline at end of file diff --git a/src/main/resources/META-INF/MANIFEST.MF b/src/main/resources/META-INF/MANIFEST.MF new file mode 100644 index 0000000..c9b9b69 --- /dev/null +++ b/src/main/resources/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: com.seleniumLib.crossrefDownLib + diff --git a/target/classes/META-INF/MANIFEST.MF b/target/classes/META-INF/MANIFEST.MF new file mode 100644 index 0000000..c9b9b69 --- /dev/null +++ b/target/classes/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: com.seleniumLib.crossrefDownLib + diff --git a/target/maven-archiver/pom.properties b/target/maven-archiver/pom.properties new file mode 100644 index 0000000..6360862 --- /dev/null +++ b/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Tue Dec 23 18:30:25 CST 2025 +version=1.0-SNAPSHOT +groupId=com.example +artifactId=crossref diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000..e270302 --- /dev/null +++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,2 @@ +com\seleniumLib\SeleniumLoginWithCookieRecorder$CookieData.class +com\seleniumLib\SeleniumLoginWithCookieRecorder.class diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..2a6b158 --- /dev/null +++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1 @@ +D:\lzh\code\java_selenium_crosscheck_login\src\main\java\com\seleniumLib\SeleniumLoginWithCookieRecorder.java diff --git a/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst b/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst new file mode 100644 index 0000000..e69de29 diff --git a/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000..e69de29