爬虫-滑动验证码解决方案

一、像这种需要点击输入,拖动模拟人工操作,且不好抓包处理的,我们可以用模拟浏览器解决掉他。

    如selenium +chrome/phantomJs等。

    首先我们要找到两张图片:没有缺口和有缺口的图片(用于对比找到缺口位置)

获取图片流的方法可以用如下方法;

/**
     * @param file  图像地址,可以是网址或者本地路径
     * @return  返回图像流
     */
    public  BufferedImage getImage(String file) {
        URL url;
        BufferedImage bi = null;
        String http = "http";
        String https = "https";
        String get = "GET";
        try {
            //https
            if (file.trim().startsWith(https)) {
                url = new URL(file);
                HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
                conn.setRequestMethod(get);
            //http
            } else if (file.trim().startsWith(http)) {
                url = new URL(file);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod(get);
             //本地文件
            } else {
                url = new File(file).toURI().toURL();
            }
            //图片流
             bi = ImageIO.read(url.openStream());


        } catch (Exception e) {
            e.printStackTrace();
        }
            return  bi ;
    }

        有了两张对比图片,我们就需要遍历检测图片存在不同的位置,一般肉眼看起来同一个颜色的RGB值也可能不同,所以需要设置阈值,具体阈值需要自己测试分析,我一般会遍历打印两图片缺口部分及附近像素的RGB值来取阈值。
       下面上取缺口位置的代码,其中我对遍历的x,y值做了限制去除图片边界影响,大家可以视具体情况分析使用
/**
     * @param origin    原图片流
     * @param slice     有缺口图片流
     * @return  缺口偏移值
     */
    public int getSliceOffset(BufferedImage origin,BufferedImage slice){
        int offset = 0;
        int xMax = 300;
        int yMax = 100;
        int xyMin = 2;
        //遍历x
        out:for(int x =xyMin;x<=xMax;x++){
            //遍历y
            for(int y=xyMin;y<=yMax;y++){
                //若量图片RGB差值不在阈值范围内,则为缺口位置,阈值需要自己定义
                if(Math.abs(origin.getRGB(x,y)-slice.getRGB(x,y))>5000000){
                    offset = x;
                    break out;
                }
            }
        }
        return  offset;

    }

有了缺口位置,大家就需要找到滑块元素,将其拖动到缺口位置,具体位置可能还需要0-5的微调,所以推荐先使用可视化模拟浏览器如chromeDriver,fireFoxDriver等,之后测试验证成功后转为无界面浏览器提升性能。

拖动滑块验证代码如下:

WebDriver webDriver;
        //配置phantomJsDriver路径、userAgent、是否加载图片
        System.setProperty( PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY, phantomJsPath);
        DesiredCapabilities dc = new DesiredCapabilities();
        dc.setCapability("phantomjs.page.settings.userAgent", ua);
        dc.setCapability("phantomjs.page.settings.loadImages","true");
        webDriver = new PhantomJSDriver(dc);
        //  打开网址homePage
        webDriver.get(homePage);
/**
*这里需要大家自己找到两张对比图片,调用上面的遍历方法返回缺口偏移值,拖动滑块移动偏移值及误差校正
*/
        Actions action =new Actions(webDriver);
//参数:需要拖动的滑块元素(Element),x偏移值,y偏移值(一般只需要x偏移值,y为0)
action.dragAndDropBy(slide, offset - 7, 0).perform();
 

此篇文章为滑动验证码入门篇,暂不考虑图片乱序以及检测机器滑动验证码先加速后减速的情况。

你可能感兴趣的:(爬虫,滑动验证码,selenium,WebDriver,java,验证码识别)