启动doMain会截图验证码区间保存到本地并提交给图灵api返回坐标
实现自动点击正确答案
maven
<!--http工具类--> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.10</version> </dependency> <!-- 数据格式化--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.73</version> </dependency> <!-- selenium--> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>3.4.0</version> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>22.0</version> </dependency>
启动类doMain
package reptilia.com.controller; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.TypeReference; import lombok.SneakyThrows; import org.apache.commons.lang3.StringUtils; import org.openqa.selenium.*; import org.openqa.selenium.Point; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeOptions; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.interactions.Actions; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.web.client.RestTemplate; import reptilia.com.utils.CustomScreenshot; import reptilia.com.utils.doTuLing; import javax.imageio.ImageIO; import java.awt.*; import java.awt.event.InputEvent; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.*; import java.util.List; class doMain { @SneakyThrows public static void main(String[] args) throws InterruptedException { System.setProperty("webdriver.chrome.driver", "D:\\chromedriver4.exe"); ChromeOptions option = new ChromeOptions(); option.setExperimentalOption("excludeSwitches", new String[]{"enable-automation"}); // option.addArguments("headless"); option.addArguments("User-Agent=" + "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"); option.setExperimentalOption("excludeSwitches", new String[]{"enable-automation"}); option.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation")); option.setExperimentalOption("useAutomationExtension", false); option.addArguments("--disable-blink-features=AutomationControlled"); ChromeDriver driver = new ChromeDriver(option); String url = "https://ah.gsxt.gov.cn/index.html"; driver.manage().window().maximize(); driver.get(url); //输入内容 new WebDriverWait(driver, 120) .until(ExpectedConditions.elementToBeClickable(By.xpath("/html/body/div[5]/div[1]/div[1]"))); driver.findElements(By.cssSelector("#keyword")).get(0).click(); Actions actions = new Actions(driver); actions.sendKeys(Keys.chord(Keys.LEFT_CONTROL, "66")).build().perform(); //点击按钮 new WebDriverWait(driver, 120) .until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@id=\"btn_query\"]"))).click(); // // 定位要截图的元素 new WebDriverWait(driver, 120) .until(ExpectedConditions.elementToBeClickable(By.xpath("/html/body/div[7]/div[1]/div[1]"))); WebElement elementToCapture = driver.findElement(By.xpath("/html/body/div[7]/div[1]/div[1]")); // // 进行截图 CustomScreenshot customScreenshot = new CustomScreenshot(); File screenshotFile = customScreenshot.localScreenshot(driver, elementToCapture); try { // 使用 ImageIO 将指定区域截图保存为文件 BufferedImage fullScreenImage = ImageIO.read(screenshotFile); ImageIO.write(fullScreenImage, "png", new File("element_screenshot.png")); //判断类型 System.out.println(driver.findElement(By.xpath("/html/body/div[7]/div[1]/div[1]/div[1]/div[1]/div[2]")).findElements(By.tagName("img")).size()); String num = ""; int letSize = driver.findElement(By.xpath("/html/body/div[7]/div[1]/div[1]/div[1]/div[1]/div[2]")).findElements(By.tagName("img")).size(); if (letSize == 3) { num = "44040235"; } else if (letSize == 1) { num = "30492402"; } else if (letSize == 0) { num = "35484990"; } doTuLing doTuling = new doTuLing(); clickImg(doTuling.toInMain("E:\\idea_project\\reptilia_project\\element_screenshot.png", num), elementToCapture, actions); // clickImg2("",elementToCapture,actions); } catch (IOException e) { e.printStackTrace(); } } @SneakyThrows private static void clickImg(String oo, WebElement elementToCapture, Actions actions) { // String oo = "{\"code\": 1, \"message\": \"\", \"data\": {\"顺序1\": {\"X坐标值\": 67, \"Y坐标值\": 191}, \"顺序2\": {\"X坐标值\": 169, \"Y坐标值\": 191}, \"顺序3\": {\"X坐标值\": 66, \"Y坐标值\": 101}}}"; Map<String, Object> map = JSONObject.parseObject(oo, new TypeReference<Map<String, Object>>() { }); Map<String, Map<String, Object>> dataMap = (Map<String, Map<String, Object>>) map.get("data"); List<Map.Entry<String, Map<String, Object>>> entryList = new ArrayList<>(dataMap.entrySet()); for (int i = entryList.size() - 1; i >= 0; i--) { Map.Entry<String, Map<String, Object>> entry = entryList.get(i); String key = entry.getKey(); Map<String, Object> coordinates = entry.getValue(); int xCoordinate = (int) coordinates.get("X坐标值"); int yCoordinate = (int) coordinates.get("Y坐标值"); // int xCoordinate = (int) Math.round(xCoordinateInt * 0.01); // int yCoordinate = (int) Math.round(yCoordinateInt * 0.01); System.out.println(key + " - X: " + xCoordinate + ", Y: " + yCoordinate); //点击 actions.dragAndDropBy(elementToCapture, xCoordinate-170, yCoordinate-180).click().perform(); Thread.sleep(2000); // actions.moveToElement(elementToCapture, xCoordinate, yCoordinate).contextClick().perform(); } } private static void clickImg2(String oo, WebElement elementToCapture, Actions actions) { //顺序3 - X: 234, Y: 164 //顺序2 - X: 77, Y: 89 //顺序1 - X: 78, Y: 185 // actions.moveToElement(elementToCapture, 234, 164).click().perform(); // actions.moveToElement(elementToCapture, 78-160, 185-118).contextClick().perform(); actions.dragAndDropBy(elementToCapture, 78-160, 185-15).contextClick().perform(); } }
调整窗体类CustomScreenshot
package reptilia.com.utils; import org.openqa.selenium.*; import java.io.File; /** * 自定义截图 * * @author erichary */ public class CustomScreenshot { /** * 向下滑动次数 */ private int scrollTimes = 10; /** * 上次高度 */ private int lastHeight = 0; /** * 重置窗口大小(调整至可以正常截图) * * @param driver 驱动对象 */ private void resetWindowSizeToScreenshot(WebDriver driver) { // 窗口最大化 resetWindowSize(driver); // 向下滑动页面:到指定次数 || 高度不再变化,退出 JavascriptExecutor javascriptExecutor = (JavascriptExecutor) driver; for (int i = 0; i < this.scrollTimes; i++) { // 获取当前高度 Object thisHeightObject = javascriptExecutor.executeScript("return document.body.scrollHeight;"); int thisHeight = Integer.parseInt(String.valueOf(thisHeightObject)); // 判断高度 if (this.lastHeight != thisHeight) { // 向下滑动 javascriptExecutor.executeScript("window.scrollBy(0,10000)"); // 滑动后赋值 this.lastHeight = thisHeight; } else { // 高度相同,跳出 break; } } // 设置窗口高度 Dimension size = driver.manage().window().getSize(); driver.manage().window().setSize(new Dimension(size.width, this.lastHeight)); } /** * 重置窗口大小(最大化窗口) * * @param driver 驱动对象 */ private void resetWindowSize(WebDriver driver) { driver.manage().window().maximize(); } /** * 全屏截图(当前可视范围) * * @param driver 驱动对象 * @return 截图内容 */ public File fullScreenshot(WebDriver driver) { // 调整窗口 resetWindowSize(driver); // 截图 File file = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); // 调整窗口 resetWindowSize(driver); return file; } /** * 全屏截图(长图) * * @param driver 驱动对象 * @return 截图内容 */ public File fullScreenshotLong(WebDriver driver) { // 调整窗口 resetWindowSizeToScreenshot(driver); // 截图 File file = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); // 调整窗口 resetWindowSize(driver); return file; } /** * 局域截图(单图) * * @param driver 驱动对象 * @param element 要截图的文档节点对象 * @return 截图内容 */ public File localScreenshot(WebDriver driver, WebElement element) { // 调整窗口 resetWindowSizeToScreenshot(driver); // 截图 File file = element.getScreenshotAs(OutputType.FILE); // 调整窗口 resetWindowSize(driver); return file; } public int getScrollTimes() { return scrollTimes; } public void setScrollTimes(int scrollTimes) { this.scrollTimes = scrollTimes; } public int getLastHeight() { return lastHeight; } public void setLastHeight(int lastHeight) { this.lastHeight = lastHeight; } }
图灵工具类doTuLing
package reptilia.com.utils;// 导入所需的库 import ch.qos.logback.classic.Level; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.util.Base64; public class doTuLing { public static String ImageToBase64(String path) { try { // 读取图片文件 BufferedImage image = ImageIO.read(new File(path)); // 创建一个字节数组输出流,用于存储图片的字节数据 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); // 将图片写入字节数组输出流(这里以 png 格式为例,你也可以使用其他格式,如 JPEG) ImageIO.write(image, "png", outputStream); // 将字节数组转换为 Base64 编码的字符串 String base64Image = Base64.getEncoder().encodeToString(outputStream.toByteArray()); // System.out.println(base64Image); // 输出 Base64 编码的字符串 return base64Image; } catch (IOException e) { e.printStackTrace(); return ""; } } public String toInMain(String fileDir,String num) { try { // 需要发送POST请求的URL地址 String url = "http://www.fdyscloud.com.cn/tuling/predict"; // 创建URL对象 URL obj = new URL(url); // 打开HTTP连接并返回HttpURLConnection对象 HttpURLConnection con = (HttpURLConnection) obj.openConnection(); // 设置请求方法为POST con.setRequestMethod("POST"); // 设置请求头部信息(如:内容类型、用户代理等) con.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); con.setRequestProperty("User-Agent", "Mozilla/5.0"); // 设置是否向HttpURLConnection输出,因为这是POST请求,参数要放在HTTP正文内,因此需要设为true con.setDoOutput(true); // 构建要发送的JSON参数 String username = "账号"; String password = "密码"; String ID = num; String b64 = ImageToBase64(fileDir); String jsonInputString = String.format( "{\"username\":\"%s\", \"password\":\"%s\", \"ID\":\"%s\", \"b64\":\"%s\", \"version\":\"3.1.1\"}", username, password, ID, b64); // 获取HttpURLConnection的输出流,用于发送POST请求参数 DataOutputStream wr = new DataOutputStream(con.getOutputStream()); // 将JSON参数写入输出流 wr.write(jsonInputString.getBytes(StandardCharsets.UTF_8)); // 关闭输出流 wr.flush(); wr.close(); // 获取服务器响应的状态码 int responseCode = con.getResponseCode(); // 读取服务器响应内容 BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); String inputLine; StringBuilder response = new StringBuilder(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } // 关闭输入流 in.close(); // 输出服务器响应结果 System.out.println("Response Code: " + responseCode); System.out.println("Response Content: " + response.toString()); return String.valueOf(response); } catch (Exception e) { e.printStackTrace(); } return ""; } }