使用java + selenium + OpenCV破解网易易盾滑动验证码的示例

网易易盾:dun.163.com

* 验证码地址:https://dun.163.com/trial/jigsaw
* 使用OpenCv模板匹配
* Java + Selenium + OpenCV

产品样例


接下来就是见证奇迹的时刻!

注意!!!
· 在模拟滑动时不能按照相同速度或者过快的速度滑动,需要向人滑动时一样先快后慢,这样才不容易被识别。
模拟滑动代码↓↓↓

/**
	 * 模拟人工移动
	 * @param driver
	 * @param element页面滑块
	 * @param distance需要移动距离
	 */
	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 = 1;
		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 distance需要移动的距离
	 * @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;
	}

操作过程

/**
	 * 获取网易验证滑动距离
	 *
	 * @return
	 */
	public static String dllPath = "C://chrome//opencv_java440.dll";

	public double getDistance(String bUrl, String sUrl) {
		System.load(dllPath);
		File bFile = new File("C:/EasyDun_b.png");
		File sFile = new File("C:/EasyDun_s.png");
		try {
			FileUtils.copyURLToFile(new URL(bUrl), bFile);
			FileUtils.copyURLToFile(new URL(sUrl), sFile);
			BufferedImage bgBI = ImageIO.read(bFile);
			BufferedImage sBI = ImageIO.read(sFile);
			// 裁剪
			cropImage(bgBI, sBI, bFile, sFile);
			Mat s_mat = Imgcodecs.imread(sFile.getPath());
			Mat b_mat = Imgcodecs.imread(bFile.getPath());

			//阴影部分为黑底时需要转灰度和二值化,为白底时不需要
			// 转灰度图像
			Mat s_newMat = new Mat();
			Imgproc.cvtColor(s_mat, s_newMat, Imgproc.COLOR_BGR2GRAY);
			// 二值化图像
			binaryzation(s_newMat);
			Imgcodecs.imwrite(sFile.getPath(), s_newMat);

			int result_rows = b_mat.rows() - s_mat.rows() + 1;
			int result_cols = b_mat.cols() - s_mat.cols() + 1;
			Mat g_result = new Mat(result_rows, result_cols, CvType.CV_32FC1);
			Imgproc.matchTemplate(b_mat, s_mat, g_result, Imgproc.TM_SQDIFF); // 归一化平方差匹配法TM_SQDIFF 相关系数匹配法TM_CCOEFF

			Core.normalize(g_result, g_result, 0, 1, Core.NORM_MINMAX, -1, new Mat());
			Point matchLocation = new Point();
			MinMaxLocResult mmlr = Core.minMaxLoc(g_result);
			matchLocation = mmlr.maxLoc; // 此处使用maxLoc还是minLoc取决于使用的匹配算法
			Imgproc.rectangle(b_mat, matchLocation, new Point(matchLocation.x + s_mat.cols(), matchLocation.y + s_mat.rows()), new Scalar(0, 255, 0, 0));
			Imgcodecs.imwrite(bFile.getPath(), b_mat);
			return matchLocation.x + s_mat.cols() - sBI.getWidth() + 12;
		} catch (Throwable e) {
			e.printStackTrace();
			return 0;
		} finally {
			 bFile.delete();
			 sFile.delete();
		}
	}

	/**
	 * 图片亮度调整
	 *
	 * @param image
	 * @param param
	 * @throws IOException
	 */
	public void bloding(BufferedImage image, int param) throws IOException {
		if (image == null) {
			return;
		} else {
			int rgb, R, G, B;
			for (int i = 0; i < image.getWidth(); i++) {
				for (int j = 0; j < image.getHeight(); j++) {
					rgb = image.getRGB(i, j);
					R = ((rgb >> 16) & 0xff) - param;
					G = ((rgb >> 8) & 0xff) - param;
					B = (rgb & 0xff) - param;
					rgb = ((clamp(255) & 0xff) << 24) | ((clamp(R) & 0xff) << 16) | ((clamp(G) & 0xff) << 8) | ((clamp(B) & 0xff));
					image.setRGB(i, j, rgb);

				}
			}
		}
	}

	// 判断a,r,g,b值,大于256返回256,小于0则返回0,0到256之间则直接返回原始值
	private int clamp(int rgb) {
		if (rgb > 255)
			return 255;
		if (rgb < 0)
			return 0;
		return rgb;
	}

	/**
	 * 生成半透明小图并裁剪
	 *
	 * @param image
	 * @return
	 */
	private void cropImage(BufferedImage bigImage, BufferedImage smallImage, File bigFile, File smallFile) {
		int y = 0;
		int h_ = 0;
		try {
			// 2 生成半透明图片
			bloding(bigImage, 75);
			for (int w = 0; w < smallImage.getWidth(); w++) {
				for (int h = smallImage.getHeight() - 2; h >= 0; h--) {
					int rgb = smallImage.getRGB(w, h);
					int A = (rgb & 0xFF000000) >>> 24;
					if (A >= 100) {
						rgb = (127 << 24) | (rgb & 0x00ffffff);
						smallImage.setRGB(w, h, rgb);
					}
				}
			}
			for (int h = 1; h < smallImage.getHeight(); h++) {
				for (int w = 1; w < smallImage.getWidth(); w++) {
					int rgb = smallImage.getRGB(w, h);
					int A = (rgb & 0xFF000000) >>> 24;
					if (A > 0) {
						if (y == 0)
							y = h;
						h_ = h - y;
						break;
					}
				}
			}
			smallImage = smallImage.getSubimage(0, y, smallImage.getWidth(), h_);
			bigImage = bigImage.getSubimage(0, y, bigImage.getWidth(), h_);
			ImageIO.write(bigImage, "png", bigFile);
			ImageIO.write(smallImage, "png", smallFile);
		} catch (Throwable e) {
			System.out.println(e.toString());
		}
	}

	/**
	 *
	 * @param mat
	 *   二值化图像
	 */
	public static void binaryzation(Mat mat) {
		int BLACK = 0;
		int WHITE = 255;
		int ucThre = 0, ucThre_new = 127;
		int nBack_count, nData_count;
		int nBack_sum, nData_sum;
		int nValue;
		int i, j;
		int width = mat.width(), height = mat.height();
		// 寻找最佳的阙值
		while (ucThre != ucThre_new) {
			nBack_sum = nData_sum = 0;
			nBack_count = nData_count = 0;

			for (j = 0; j < height; ++j) {
				for (i = 0; i < width; i++) {
					nValue = (int) mat.get(j, i)[0];

					if (nValue > ucThre_new) {
						nBack_sum += nValue;
						nBack_count++;
					} else {
						nData_sum += nValue;
						nData_count++;
					}
				}
			}
			nBack_sum = nBack_sum / nBack_count;
			nData_sum = nData_sum / nData_count;
			ucThre = ucThre_new;
			ucThre_new = (nBack_sum + nData_sum) / 2;
		}
		// 二值化处理
		int nBlack = 0;
		int nWhite = 0;
		for (j = 0; j < height; ++j) {
			for (i = 0; i < width; ++i) {
				nValue = (int) mat.get(j, i)[0];
				if (nValue > ucThre_new) {
					mat.put(j, i, WHITE);
					nWhite++;
				} else {
					mat.put(j, i, BLACK);
					nBlack++;
				}
			}
		}
		// 确保白底黑字
		if (nBlack > nWhite) {
			for (j = 0; j < height; ++j) {
				for (i = 0; i < width; ++i) {
					nValue = (int) (mat.get(j, i)[0]);
					if (nValue == 0) {
						mat.put(j, i, WHITE);
					} else {
						mat.put(j, i, BLACK);
					}
				}
			}
		}
	}
	// 延时加载
	private static WebElement waitWebElement(WebDriver driver, By by, int count) throws Exception {
		WebElement webElement = null;
		boolean isWait = false;
		for (int k = 0; k < count; k++) {
			try {
				webElement = driver.findElement(by);
				if (isWait)
					System.out.println(" ok!");
				return webElement;
			} catch (org.openqa.selenium.NoSuchElementException ex) {
				isWait = true;
				if (k == 0)
					System.out.print("waitWebElement(" + by.toString() + ")");
				else
					System.out.print(".");
				Thread.sleep(50);
			}
		}
		if (isWait)
			System.out.println(" outTime!");
		return null;
	}

注意:有一个问题还没有解决,还无法区分阴影部分是黑色还是白色。 因为两种的情况不同,所以处理方式也不同。阴影部分为黑底时需要转灰度和二值化,为白底时不需要。黑底使用归一化平方差匹配算法 TM_SQDIFF ,而白底使用相关系数匹配算法 TM_CCOEFF。

到此这篇关于使用java + selenium + OpenCV破解网易易盾滑动验证码的文章就介绍到这了,更多相关java滑动验证码内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 使用java + selenium + OpenCV破解腾讯防水墙滑动验证码功能

    * 验证码地址:https://007.qq.com/online.html * 使用OpenCv模板匹配 * 成功率90%左右 * Java + Selenium + OpenCV 产品样例 来吧!展示! 注意!!! · 在模拟滑动时不能按照相同速度或者过快的速度滑动,需要向人滑动时一样先快后慢,这样才不容易被识别. 模拟滑动代码↓↓↓ /** * 模拟人工移动 * @param driver * @param element页面滑块 * @param distance需要移动距离 */ pu

  • JavaWeb简单用户登录注册实例代码(有验证码)

    需求 编写login登录界面(用户名,密码,验证码,登陆按钮,注册按钮) 设计关系数据库(编号,用户名,密码) 编写注册功能,将数据存储在数据库中.(姓名不能重复,设为主键,重复会注册失败) 编写登录功能 .首先获取验证码,先判断验证码是否正确,不正确则显示验证码错误.验证码正确后再获取用户名和密码,进行数据库的搜索比对,若正确则重定向到成功的界面,并且将用户名显示. jar包 技术选型 Servlet + JSP + Mysql + JDBCTemplate + Druid + BeanUti

  • Java 生成图片验证码3种方法(字母、加减乘除、中文)

    第一种方法 全是字母和数字组成 package com.myFirstSpring.util; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; import javax.imageio.ImageIO; import java

  • 使用java + OpenCV破解顶象面积验证码的示例

    前言 我们又来破解验证码啦,今天上场的是–顶象面积验证码 根据场景来看,我们需要根据图片中分隔好的区域找到面积最大的一块来点击它. 那么我们把它拆分成以下几个步骤: 检测出图中标记的点将检测出来的点连成线根据线分割出的区域计算各区域面积,并得到最大面积在该区域面积中选取一个坐标点作为结果 一.检测出图中标记的点 第一个问题,怎么检测出图片中被标记出来的点? 这里使用哈里斯角点检测,这里采用OpenCV中的cornerHarris()来实现. 参考下面两篇文章,感兴趣的话可以阅读一下: Harri

  • 使用java + selenium + OpenCV破解网易易盾滑动验证码的示例

    网易易盾:dun.163.com * 验证码地址:https://dun.163.com/trial/jigsaw * 使用OpenCv模板匹配 * Java + Selenium + OpenCV 产品样例 接下来就是见证奇迹的时刻! 注意!!! · 在模拟滑动时不能按照相同速度或者过快的速度滑动,需要向人滑动时一样先快后慢,这样才不容易被识别. 模拟滑动代码↓↓↓ /** * 模拟人工移动 * @param driver * @param element页面滑块 * @param dista

  • 详解Python结合Genetic Algorithm算法破解网易易盾拼图验证

    首先看一下目标的验证形态是什么样子的 是一种通过验证推理的验证方式,用来防人机破解的确是很有效果,但是,But,这里面已经会有一些破绽,比如: (以上是原图和二值化之后的结果) (这是正常图片) 像划红线的这些地方,可以看到有明显的突变,并且二值化之后边缘趋于直线,但是正常图像是不会有这种这么明显的突变现象. 初识潘多拉 后来,我去翻阅了机器视觉的相关文章和论文,发现了一个牛逼的算法,这个算法就是——Genetic Algorithm遗传算法,最贴心的的是,作者利用这个算法实现了一个功能,“拼图

  • Python 网易易盾滑块验证功能的实现

    目录 操作环境 分析 解决方案 使用selenium请求url,并触发滑块验证 获取验证图片并计算滑块距离 生成滑动轨迹 滑动模块 效果 资源下载 记一次 网易易盾滑块验证分析并通过 操作环境 win10 . mac Python3.9 selenium.PIL.numpy.scipy.matplotlib 分析 网易易盾滑块验证,就长下面这个样子 具体验证原理有兴趣的可自行查询官方文档:网易易盾开发文档 话不多少,借助之前写阿里云盾滑块和极验滑块的经验,直接上代码,详细可参考:[python3

  • selenium+java破解极验滑动验证码的示例代码

    摘要 分析验证码素材图片混淆原理,并采用selenium模拟人拖动滑块过程,进而破解验证码. 人工验证的过程 1.打开威锋网注册页面 2.移动鼠标至小滑块,一张完整的图片会出现(如下图1) 3.点击鼠标左键,图片中间会出现一个缺块(如下图2) 4.移动小滑块正上方图案至缺块处 5.验证通过 selenium模拟验证的过程 加载威锋网注册页面 下载图片1和缺块图片2 根据两张图片的差异计算平移的距离x 模拟鼠标点击事件,点击小滑块向右移动x 验证通过 详细分析 1.打开chrome浏览器控制台,会

  • 利用Java+Selenium+OpenCV模拟实现网页滑动验证

    目录 一.需求分析 二.模拟步骤 1.使用selenium打开某音网页 2.找到小滑块以及小滑块所在的背景图 3.计算小滑块需要滑动的距离 4.按住小滑块并滑动 三.学习过程中比较棘手的问题 1.截图问题 2.返回结果与实际滑动距离相差太多,甚至无规律可循 3.openCV的下载安装 四.总结 目前很多网页都有滑动验证,目的就是防止不良爬虫扒他们网站的数据,我这次本着学习的目的使用Java和selenium学习解决滑动验证的问题,前前后后花了一周时间(抄代码),终于成功了某音的滑动验证! 效果展

  • Java + Selenium + OpenCV解决自动化测试中的滑块验证问题

    目录 1.滑块验证思路 2.使用OpenCV进行图片解析 2.1 OpenCV引入项目 2.2 实现图片解析,计算所需距离 2.3 算法解析说明 3.Selenium处理滑块滑动 4.最终效果 最近工作过程中,一个常用的被测网站突然增加了滑块验证环节,导致整个自动化项目失效了. 为了解决这个滑块验证问题,在网上查阅了一些资料后,总结并实现了解决方案,现记录如下. 1.滑块验证思路 被测对象的滑块对象长这个样子.相对而言是比较简单的一种形式,需要将左侧的拼图通过下方的滑块进行拖动,嵌入到右侧空槽中

  • 使用puppeteer破解极验的滑动验证码

    基本的流程: 1. 打开前端网,点击登录. 2. 填写账号,密码. 3. 点解验证按钮,通过滑动验证,最后成功登陆. 代码实现: github上可以checkout. 具体代码如下所示: run.js const puppeteer = require('puppeteer'); const devices = require('puppeteer/DeviceDescriptors'); const iPhone = devices['iPhone 6 Plus']; let timeout

  • Java实现滑动验证码的示例代码

    最近滑动验证码在很多网站逐步流行起来,一方面对用户体验来说,比较新颖,操作简单,另一方面相对图形验证码来说,安全性并没有很大的降低.当然到目前为止,没有绝对的安全验证,只是不断增加攻击者的绕过成本. 接下来分析下滑动验证码的核心流程: 后端随机生成抠图和带有抠图阴影的背景图片,后台保存随机抠图位置坐标 前端实现滑动交互,将抠图拼在抠图阴影之上,获取到用户滑动距离值,比如以下示例 前端将用户滑动距离值传入后端,后端校验误差是否在容许范围内. 这里单纯校验用户滑动距离是最基本的校验,出于更高的安全考

随机推荐