0


java+opencv+selenium实现滑块滑动破解

上一条博客【写文章-CSDN创作中心】我们对需要的环境进行了配置,也打开了浏览器进行对输入框操作,但是操作过程中遇到滑块,这一篇文章我们来解决这个问题

** 滑块的操作思路:**

1、web自动化测试出现验证码【让滑块出现】

2、获取滑块和背景的图片地址

3、将背景图和滑块图下载到本地

4、人工智能匹配滑块验证码

5、缩放比例和移动距离算出来

6、模拟滑动解决

7、人工智能模拟和跟踪滑动轨迹

8、滑动失败重试机制

直接放代码,基础教学没有对代码过度抽取,很容易就看懂了,大佬勿喷

public class Test10 {

    private final static String driver = "webdriver.chrome.driver";
    private final static String chromeDriver = "C:\\Users\\d\\AppData\\Local\\Google\\Chrome\\Application\\chromedriver.exe";
    private final static String openCvDll = "D:\\Program Files (x86)\\opencv\\build\\java\\x64\\opencv_java460.dll";

    //网站需要的账号密码
    private final static String usernmae = "****";
    private final static String password = "*****";

    static {
        // 引入谷歌驱动 控制浏览器
        System.setProperty(driver, chromeDriver);
        // 引入opencv的dll
        System.load(openCvDll);
    }

    public static void main(String[] args) throws InterruptedException {
        System.out.println("正在打开浏览器");
        //1、获取谷歌浏览器控制 打开浏览器
        WebDriver driver = new ChromeDriver();
        driver.manage().window().maximize();//浏览器最大化
        //2、超时等待30秒
        Duration duration = Duration.ofSeconds(30);
        driver.manage().timeouts().implicitlyWait(duration);
        //3、跳转到智慧树网址
        driver.get("https://passport.zhihuishu.com/login?service=https://onlineservice-api.zhihuishu.com/login/gologin#signin");

        //4、解决机器打开验证不成功【脚本打开和人为打开浏览器会有一个标识,通过这个代码进行修改】
        ((JavascriptExecutor) driver).executeScript("Object.defineProperties(navigator,{ webdriver:{ get: () => false } })");

        //5、获取到账号和密码的输入框 lUsername 并填写内容
        driver.findElement(By.id("lUsername")).sendKeys(usernmae);
        driver.findElement(By.id("lPassword")).sendKeys(password);
        //6、找到登录按钮模拟点击
        driver.findElement(By.className("wall-sub-btn")).click();

        //7、这个时候可能会弹出来滑块
        Boolean flag = true;
        int i = 1;
        do {
            System.out.println("第" + i++ + "次进行验证");
            //8、这时候可能有滑块出现yidun_slider
            WebElement sliderBJ = null;
            WebElement sliderHK = null;
            try {
                //9、如果没拿到,说明直接登录了,没有触发出来滑块
                sliderBJ = driver.findElement(By.className("yidun_bg-img"));
                sliderHK = driver.findElement(By.className("yidun_jigsaw"));
            } catch (Exception e) {
                e.printStackTrace();
            }
            //10、解决图片下载不了的问题
            TimeUnit.SECONDS.sleep(1);

            //11、如果不为空需要处理滑块
            if (sliderBJ != null && sliderHK != null) {
                //11.1、先得到距离,这里需要opencv  先搭建一下
                //11.2、获取到背景图的地址和滑块的地址
                String srcBJ = sliderBJ.getAttribute("src");
                String srcHK = sliderHK.getAttribute("src");
                //11.3、拿到url后缀
                String houZhui = srcBJ.substring(srcBJ.lastIndexOf("."));
                String houZhuiHK = srcHK.substring(srcBJ.lastIndexOf("."));
                //11.4、将图片下载到本地
                downloadPicture(srcBJ, "D:\\img\\beijing" + houZhui);
                downloadPicture(srcHK, "D:\\img\\huakuai" + houZhuiHK);
                //11.5、从本地读取背景原图
                Mat src = Imgcodecs.imread("D:\\img\\beijing" + houZhui, Imgcodecs.IMREAD_GRAYSCALE);
                Mat srcBenDiHK = Imgcodecs.imread("D:\\img\\huakuai" + houZhuiHK, Imgcodecs.IMREAD_GRAYSCALE);
                //11.6、创建一个新的背景图,方便做标记
                Mat clone = src.clone();
                Mat result = new Mat();

                //11.7、匹配小图在大图中的位置  用标准模式去比较 然后把返回结果给result
                Imgproc.matchTemplate(src, srcBenDiHK, result, Imgproc.TM_CCORR_NORMED);
                Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat());

                //11.8、获取匹配结果坐标
                Core.MinMaxLocResult minMaxLocResult = Core.minMaxLoc(result);
                Point maxLoc = minMaxLocResult.maxLoc;

                //11.9、在图上做标记
                Imgproc.rectangle(clone, maxLoc,
                        new Point(maxLoc.x + srcBenDiHK.cols(), maxLoc.y + srcBenDiHK.rows()),
                        new Scalar(0, 255, 0));
                Imgcodecs.imwrite("D:\\img\\close.jpg", clone);

                //11.10、将背景图存储在本地
                Imgcodecs.imwrite("D:\\img\\beijing" + houZhui, src);
                Imgcodecs.imwrite("D:\\img\\huakuai" + houZhuiHK, srcBenDiHK);

                double distance = maxLoc.x - maxLoc.y;
                //11.11、模拟移动
                move(driver, sliderHK, (int) distance + 20);

                //11.12、移动后看看是否还存在不
                try {
                    TimeUnit.SECONDS.sleep(2);
                    driver.findElement(By.className("yidun_bg-img"));
                } catch (Exception e) {
                    flag = false;
                    System.out.println("验证成功");
                }
            }
        } while (flag);
        System.out.println("循环结束,验证成功");
    }

    /*
     *
     * 下载图片到本地
     * */
    private static void downloadPicture(String urlList, String path) {
        URL url = null;
        try {
            url = new URL(urlList);
            DataInputStream dataInputStream = new DataInputStream(url.openStream());

            FileOutputStream fileOutputStream = new FileOutputStream(new File(path));
            ByteArrayOutputStream output = new ByteArrayOutputStream();

            byte[] buffer = new byte[1024];
            int length;

            while ((length = dataInputStream.read(buffer)) > 0) {
                output.write(buffer, 0, length);
            }
            fileOutputStream.write(output.toByteArray());
            dataInputStream.close();
            fileOutputStream.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 模拟人工移动
     *
     * @param driver
     */
    public static void move(WebDriver driver, WebElement element, int distance) throws InterruptedException {
        int randomTime = 0;
        if (distance > 90) {
            randomTime = 250;
        } else if (distance > 80 && distance <= 90) {
            randomTime = 150;
        }
        List<Integer> track = getMoveTrack(distance - 2);
        int moveY = 0;
        try {
            //初始化鼠标对象
            Actions actions = new Actions(driver);
            //鼠标按住左键不动
            actions.clickAndHold(element).perform();
            Thread.sleep(200);
            for (int i = 0; i < track.size(); i++) {
                //把元素滑动到执行坐标
                actions.moveByOffset(track.get(i), moveY).perform();
                Thread.sleep(new Random().nextInt(300) + randomTime);
            }
            Thread.sleep(200);
            actions.release(element).perform();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据距离获取滑动轨迹
     *
     * @param
     * @return
     */
    public static List<Integer> getMoveTrack(int distance) {
        List<Integer> track = new ArrayList<>();// 移动轨迹
        Random random = new Random();
        int current = 0;// 已经移动的距离
        int mid = (int) distance * 4 / 5;// 减速阈值
        int a = 0;
        int move = 0;// 每次循环移动的距离
        while (true) {
            a = random.nextInt(10);
            if (current <= mid) {
                move += a;// 不断加速
            } else {
                move -= a;
            }
            if ((current + move) < distance) {
                track.add(move);
            } else {
                track.add(distance - current);
                break;
            }
            current += move;
        }
        return track;
    }

}

因为贴出来的代码里面账号密码不是正确的,提示错误就可以了,具体的看操作流程

** opencv的安装流程在这文章里面没有,需要自己单独安装或者评论滴滴**


本文转载自: https://blog.csdn.net/qq_52545155/article/details/126895074
版权归原作者 沐阳gg 所有, 如有侵权,请联系我们删除。

“java+opencv+selenium实现滑块滑动破解”的评论:

还没有评论