收集整理了一份《2024年最新Python全套学习资料》免费送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Python知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来
如果你需要这些资料,可以添加V无偿获取:hxbc188 (备注666)
正文
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;
// 拿到滑块按钮
WebElement btn = chromeDriver.findElementByXPath("//div[@class='geetest_slider_button']");
// 拿到鼠标操作,实例化Actions
Actions actions = new Actions(chromeDriver);
// 把滑块->缺口距离分成多份
int[] nums = split(moveDistance);
// 移动滑块按钮
Random random = new Random();
String time = "35";
for (int i = 0; i < nums.length; i++) {
actions.clickAndHold(btn).moveByOffset(nums[i], 0)
.build().perform();
int times = Integer.parseInt(time + random.nextInt(10));
Thread.sleep(times);
}
// 模拟人操作
actions.clickAndHold(btn).moveByOffset(-1, 0).release()
.build().perform();
Thread.sleep(3000);// 滑块完成等待2秒判断是否验证成功
// 是否滑块成功
String attribute = chromeDriver.findElementByXPath("//div[@class='geetest_radar_tip']").getAttribute("aria-label");
System.out.println("attribute = " + attribute);
if (attribute.equals("网络不给力") ) {
chromeDriver.findElementByXPath("//div[@class='geetest_radar_tip']").click();
// 再次滑块
operateSlider();
}
}
// 整数拆分
private static int[] split(int num) {
int[] nums = new int[5];
Random rand = new Random();
for (int i = 0; i < nums.length - 1; i++) {
nums[i] = rand.nextInt(num);
num -= nums[i];
}
nums[nums.length - 1] = num;
return nums;
}
最后
🍅 硬核资料:关注即可领取PPT模板、简历模板、行业经典书籍PDF。
🍅 技术互助:技术群大佬指点迷津,你的问题可能不是问题,求资源在群里喊一声。
🍅 面试题库:由技术群里的小伙伴们共同投稿,热乎的大厂面试真题,持续更新中。
🍅 知识体系:含编程语言、算法、大数据生态圈组件(Mysql、Hive、Spark、Flink)、数据仓库、Python、前端等等。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
如果你需要这些资料,可以添加V无偿获取:hxbc188 (备注666)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
*:由技术群里的小伙伴们共同投稿,热乎的大厂面试真题,持续更新中。
🍅 知识体系:含编程语言、算法、大数据生态圈组件(Mysql、Hive、Spark、Flink)、数据仓库、Python、前端等等。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
如果你需要这些资料,可以添加V无偿获取:hxbc188 (备注666)
[外链图片转存中…(img-p5h1Zn24-1713844542956)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!