2024年最全java爬虫破解滑块验证码_计算缺口滑块图和完整滑块图者差距,华为面试 知乎

(1)Python所有方向的学习路线(新版)

这是我花了几天的时间去把Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

最近我才对这些路线做了一下新的更新,知识体系更全面了。

在这里插入图片描述

(2)Python学习视频

包含了Python入门、爬虫、数据分析和web开发的学习视频,总共100多个,虽然没有那么全面,但是对于入门来说是没问题的,学完这些之后,你可以按照我上面的学习路线去网上找其他的知识资源进行进阶。

在这里插入图片描述

(3)100多个练手项目

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了,只是里面的项目比较多,水平也是参差不齐,大家可以挑自己能做的项目去练练。

在这里插入图片描述

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

        },
        on: function (el, type, handler) {
            el.addEventListener(type, handler, false);
        },
        off: function (el, type, handler) {
            el.removeEventListener(type, handler, false);
        }
    };

//封装一个滑块类
function Slider() {
var args = arguments[0];
for (var i in args) {
this[i] = args[i]; //一种快捷的初始化配置
}
//直接进行函数初始化,表示生成实例对象就会执行初始化
this.init();
}

    Slider.prototype = {
        constructor: Slider,
        init: function () {
            this.getDom();
            this.dragBar(this.handler);
        },
        getDom: function () {
            this.slider = dog.$('#' + this.id);
            this.handler = dog.$('.handler');
            this.bg = dog.$('.drag_bg');
        },
        dragBar: function (handler) {
            var that = this,
                startX = 0,
                lastX = 0,
                doc = document,
                width = this.slider.offsetWidth,
                max = width - handler.offsetWidth,
                drag = {
                    down: function (e) {
                        var e = e || window.event;
                        that.slider.classList.add('unselect');
                        startX = e.clientX - handler.offsetLeft;
                        console.log('startX: ' + startX + ' px');
                        dog.on(doc, 'mousemove', drag.move);
                        dog.on(doc, 'mouseup', drag.up);
                        return false;
                    },
                    move: function (e) {
                        var e = e || window.event;
                        lastX = e.clientX - startX;
                        lastX = Math.max(0, Math.min(max, lastX)); //这一步表示距离大于0小于max,巧妙写法
                        console.log('lastX: ' + lastX + ' px');
                        if (lastX >= max) {
                            handler.classList.add('handler_ok_bg');
                            that.slider.classList.add('slide_ok');
                            dog.off(handler, 'mousedown', drag.down);
                            drag.up();
                        }
                        that.bg.style.width = lastX + 'px';
                        handler.style.left = lastX + 'px';
                    },
                    up: function (e) {
                        var e = e || window.event;
                        that.slider.classList.remove('unselect');
                        if (lastX < width) {
                            that.bg.classList.add('ani');
                            handler.classList.add('ani');
                            that.bg.style.width = 0;
                            handler.style.left = 0;
                            setTimeout(function () {
                                that.bg.classList.remove('ani');
                                handler.classList.remove('ani');
                            }, 300);
                        }
                        dog.off(doc, 'mousemove', drag.move);
                        dog.off(doc, 'mouseup', drag.up);
                    }
                };
            dog.on(handler, 'mousedown', drag.down);
        }
    };
    window.S = window.Slider = Slider;
})(window, document);
var defaults = {
    id: 'slider'
};
new S(defaults);

### 分析


1.查看滑块按钮大小


![](https://img-blog.csdnimg.cn/1c53ae741bd843f19aab19122d2e74e3.png)


 2.查看滑块大小


![](https://img-blog.csdnimg.cn/0fea6d3964b54bdea4035eab9fdff992.png)


 从上面2张图得出拖动距离为(300-40)px


### 爬虫代码



public static void main(String[] args) throws Exception {
System.setProperty(“webdriver.chrome.driver”,“D:\demo\selenumDemo\src\main\resources\chromedriver.exe”);
WebDriver driver = new ChromeDriver();
try {
driver.get(“file:///C:/Users/Administrator/Desktop/index.html”);
WebElement Slider = driver.findElement(By.cssSelector(“.handler.handler_bg”));// 拿到滑块按钮
Thread.sleep(2000L);
// 实例化鼠标操作对象Actions
Actions action = new Actions(driver);
action.dragAndDropBy(Slider,260,0).perform();// 移动一定位置

    Thread.sleep(5000L);
} catch (InterruptedException e) {
    e.printStackTrace();
}finally{
    // driver.close();// 关闭页面
    driver.quit();// 释放资源
}

}


**注意:**有的网站拖完后可能验证成功,有的可能失败,失败的童鞋也不要慌张,因为被网站检测出你用的是爬虫操作的,我有妙计!接着往下看!


先分分析一波!1.使用驱动打开浏览器



public static void openChrome(){
System.setProperty(“webdriver.chrome.driver”,“D:\demo\selenumDemo\src\main\resources\chromedriver.exe”);
// 1.打开Chrome浏览器
chromeDriver = new ChromeDriver();
chromeDriver.get(“url…”);
}


2.然后 f12打开console控制台输入:window.navigator.webdriver


![](https://img-blog.csdnimg.cn/61cfd3b32a304fc2bfdbd3189f1c32ce.png)


 发现值是true,但是我们正常手动打开浏览器他却是false或者undefined,如下图


![](https://img-blog.csdnimg.cn/9e2cf1f3a22b40479214e1aa4158b4b5.png)


 


所以得出结论网站通过代码获取这个参数,返回值undefined或者false是正常浏览器,返回true说明用的是Selenium模拟浏览器,所以解决还是要从驱动浏览器解决,在启动Chromedriver之前,来隐藏它



public static void openChrome(){
// 隐藏 window.navigator.webdriver
ChromeOptions option = new ChromeOptions();
option.setExperimentalOption(“useAutomationExtension”, false);
option.setExperimentalOption(“excludeSwitches”, Lists.newArrayList(“enable-automation”));
option.addArguments(“–disable-blink-features=AutomationControlled”);//主要是这句是关键

System.setProperty(“webdriver.chrome.driver”,“D:\demo\selenumDemo\src\main\resources\chromedriver.exe”);
// 1.打开Chrome浏览器
chromeDriver = new ChromeDriver(option);
chromeDriver.get(“URL…”);
}


然后再次启动查看就变成了false




---


## 破解缺口滑块


缺口滑块如下图:


![](https://img-blog.csdnimg.cn/bac8418af71e4be08b45c67b018a6677.png)


###  分析


我拿某网站的滑块源代码来分析,如下图可以看出缺口滑块图是由canvas绘制的。


![](https://img-blog.csdnimg.cn/410d4e0815e54b918c6fc6cb33e5f6c8.png)


 1.我们要做的是找到缺口的X坐标,所以需要拿到完整图片和缺口图片进行计算,但是我们只能看见一张缺口图片,但是我们只要在canvas的css加一行代码style="display:none"![](https://img-blog.csdnimg.cn/6bc4f116314644e78f3e445a0d43d0b2.png)


 然后再看就出现了没有拼图阻挡的缺口图


 ![](https://img-blog.csdnimg.cn/c57155875a6a4a9aa5a716ceafcfee05.png)


 2.然后在下面的canvas 修改style="display:block"就可以看到完整图片如下下图![](https://img-blog.csdnimg.cn/20ec33b78f2e4114b28203a021cae172.png)


然后再看发现看到了完整的图


 ![](https://img-blog.csdnimg.cn/28e6166673ac4558a842f80234ddc106.png)


 3.然后使用selenium的截图方法,把原图和缺口图保存下来,然后再拿着像素对比可以算出按钮位置与缺口X坐标




---


### 爬虫代码



public class ElementLocate {
private static ChromeDriver chromeDriver;

public static void main(String[] args) throws InterruptedException, IOException {
openChrome();// 打开浏览器等操作
try {
chromeDriver.manage().window().maximize();// 浏览器最大化
// 等待滑块加载完毕
new WebDriverWait(chromeDriver, 5)
.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(“//div[@aria-label=‘点击按钮进行验证’]”)));
// 点开滑块
chromeDriver.findElementByXPath(“//div[@aria-label=‘点击按钮进行验证’]”).click();// 点开验证框
operateSlider();// 操作滑块
} finally {
chromeDriver.quit();//测试完要停止 不然卡成球
}
}

private static void openChrome() {
// 配置浏览器
ChromeOptions option = new ChromeOptions();
option.setExperimentalOption(“useAutomationExtension”, false);
option.setExperimentalOption(“excludeSwitches”, Lists.newArrayList(“enable-automation”));
option.addArguments(“–disable-blink-features=AutomationControlled”);//主要是这句是关键,防止网站js检测出爬虫
// set浏览器驱动
System.setProperty(“webdriver.chrome.driver”, “D:\demo\selenumDemo\src\main\resources\chromedriver.exe”);
// 打开Chrome浏览器
chromeDriver = new ChromeDriver(option);
// 访问百度
chromeDriver.get(“https://account.zbj.com/login?lgtype=1&waytype=603&fromurl=https%3A%2F%2Fxiamen.zbj.com%2F”);
}

// 操作元素属性
private static void setAttribute(WebDriver driver, WebElement element, String attributeName, String value) {
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript(“arguments[0].setAttribute('” + attributeName + “', '” + value + “')”, element);
}

//删除元素属性
private void removeAttribute(WebDriver driver, WebElement element, String attributeName) {
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript(“argument[0].removeAttribute(argumentp[1]),argument[2]”, element, attributeName);
}

// 截图
private static File captureElement(File screenshot, WebElement element) {
try {
BufferedImage img = ImageIO.read(screenshot);
int width = element.getSize().getWidth();
int height = element.getSize().getHeight();
//获取指定元素的坐标
Point point = element.getLocation();
//从元素左上角坐标开始,按照元素的高宽对img进行裁剪为符合需要的图片
BufferedImage dest = img.getSubimage(point.getX(), point.getY(), width, height);
ImageIO.write(dest, “png”, screenshot);
} catch (IOException e) {
e.printStackTrace();
}
return screenshot;
}

// 操作滑块
private static void operateSlider() throws InterruptedException, IOException {
Thread.sleep(1000);// 重复获取元素必须sleep,否则会报错!

  //修改元素属性,显示缺口滑块图,这里需要等图片加载出来,如果网络慢没加载出来会报错
  WebElement que1 = chromeDriver.findElementByXPath("//div[@class='geetest_slicebg geetest_absolute']/canvas[@class='geetest_canvas_slice geetest_absolute']");
  setAttribute(chromeDriver, que1, "style", "display:none");
  // 截图滑块缺口图片
  WebElement quekou = chromeDriver.findElementByXPath("//canvas[@class='geetest_canvas_bg geetest_absolute']");
  File src = chromeDriver.getScreenshotAs(OutputType.FILE);
  FileUtils.copyFile(src, new File("D:\\result.png"));
  FileUtils.copyFile(captureElement(src, quekou), new File("D:\\test.png"));

  // 修改元素属性,显示完整滑块图
  WebElement que2 = chromeDriver.findElementByXPath("//canvas[@class='geetest_canvas_fullbg geetest_fade geetest_absolute']");
  setAttribute(chromeDriver, que2, "style", "display:block");
  // 截图滑块完整图
  WebElement wanzheng = chromeDriver.findElementByXPath("//canvas[@class='geetest_canvas_bg geetest_absolute']");
  File src2 = chromeDriver.getScreenshotAs(OutputType.FILE);
  FileUtils.copyFile(src2, new File("D:\\result1.png"));
  FileUtils.copyFile(captureElement(src2, wanzheng), new File("D:\\test1.png"));

  // 还原滑块
  WebElement huanyuan1 = chromeDriver.findElementByXPath("//canvas[@class='geetest_canvas_fullbg geetest_fade geetest_absolute']");
  setAttribute(chromeDriver, huanyuan1, "style", "display:none");
  WebElement huanyuan2 = chromeDriver.findElementByXPath("//canvas[@class='geetest_canvas_slice geetest_absolute']");
  setAttribute(chromeDriver, huanyuan2, "style", "display:block");

  // 计算缺口滑块图和完整滑块图者差距,5为滑块按钮和滑块图左边的差5px
  int moveDistance = getMoveDistance() - 5;
  // 拿到滑块按钮

如果你也是看准了Python,想自学Python,在这里为大家准备了丰厚的免费学习大礼包,带大家一起学习,给大家剖析Python兼职、就业行情前景的这些事儿。

一、Python所有方向的学习路线

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

二、学习软件

工欲善其必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。

三、全套PDF电子书

书籍的好处就在于权威和体系健全,刚开始学习的时候你可以只看视频或者听某个人讲课,但等你学完之后,你觉得你掌握了,这时候建议还是得去看一下书籍,看权威技术书籍也是每个程序员必经之路。

四、入门学习视频

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

四、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

五、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

成为一个Python程序员专家或许需要花费数年时间,但是打下坚实的基础只要几周就可以,如果你按照我提供的学习路线以及资料有意识地去实践,你就有很大可能成功!
最后祝你好运!!!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 25
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值