启动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 "";
    }
}