2022最新版腾讯防水墙(二代)识别
戳这里→康康你手机号在过多少网站注册过!!!
友情推荐:新一代安全短信
* 验证码地址:https://007.qq.com/online.html
* 使用OpenCv模板匹配
* 成功率90%左右
* Java + Selenium + OpenCV
最近不少爬虫界面的朋友发现,原来可以识别腾讯防水墙的代码报错了, 怎么回事 ?
原来是腾讯防水墙做了升级
产品样例
背景图
和工具体混在一起的滑动图
截取图:
改进主要特点:
1 将滑块图片混合在工具条中,透明度不同,外边加了边框
2 iframe , 名字有原来的 tcaptcha_iframe ,变为 tcaptcha_iframe_dy
分析:
关键点在于滑块的变化,由于滑块混合,第一步肯定要做切割,
切割完后如果简单做二值化, 就会形成外框 ,这样下一步的就无法做模板匹配
掌握了特点, 就有了解决的思路,办法总比困难多
最后完美解决,识别率也不太高, 在 99% 左右吧
来吧!展示!
结果图1 : 五边形
结果图2 : 四边形
结果图3 :
注意!!!
· 在模拟滑动时不能按照相同速度或者过快的速度滑动,需要向人滑动时一样先快后慢,这样才不容易被识别。
模拟滑动代码↓↓↓
/*** 模拟人工移动* @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;}
看操作,no bb,直接上代码
/*** v2 版本* * @param driver* @return*/public RetEntity moveExec(WebDriver driver, boolean isLocal) {File bFile = null;File sFile = null;RetEntity retEntity = new RetEntity();retEntity.setRet(-1);try {// 获取到验证区域WebElement iframe = ChromeDriverManager.waitElement(driver, By.id("tcaptcha_iframe_dy"), 100);if (iframe == null) {System.out.println("moveExec() tcaptcha_iframe|timeout!!!");retEntity.setMsg("tcaptcha_iframe|timeout!!");return retEntity;}driver.switchTo().frame(iframe);sleep(500);// 获取带阴影的背景图WebElement wegSlideBg = driver.findElement(By.id("slideBg"));String cssValue = wegSlideBg != null ? wegSlideBg.getCssValue("background-image") : null;String bgUrl = (cssValue != null && cssValue.contains("\"")) ? cssValue.split("\"")[1] : null;if (bgUrl == null) {retEntity.setMsg("bgUrl=" + bgUrl);return retEntity;}Long time = System.currentTimeMillis();// 获取小图 URL (替换img_index=1为 img_index=0)String slUrl = bgUrl.replaceAll("img_index=1", "img_index=0");System.out.println("bgUrl=" + bgUrl);System.out.println("slUrl=" + slUrl);bFile = new File(dataPath + time + "-b.png");sFile = new File(dataPath + time + "-s.png");int getMode = 0;Map<String, byte[]> retMap = (getMode == 0) ? getTwoImg(driver, bgUrl, slUrl, bFile, sFile) : getTwoImgOpen(driver, bgUrl, slUrl, bFile, sFile);if (retMap != null) {byte[] bigBytes = retMap.get("big");byte[] smallBytes = retMap.get("small");String distanceStr = null, width = null;String ckSum = GenChecksumUtil.genChecksum(bigBytes);String[] outArray = openCv2.getOpenCvDistance(ckSum, bigBytes, smallBytes, "tencent_v2", 3);distanceStr = (outArray != null && outArray.length >= 2) ? outArray[1] : null;width = (outArray != null && outArray.length >= 2) ? outArray[0] : null;Double left = 27.0 * 672 / 340;// 起点距左边距离Double act = (Double.parseDouble(distanceStr) - left - Double.parseDouble(width)) * 340.0 / 672.0;Integer distance = act.intValue();System.out.println("moveExec() distance(" + distanceStr + ")=" + distance);if (distance == null || distance <= 0) {return retEntity;}if (getMode != 0)driver.switchTo().frame(iframe);WebElement moveElemet = ChromeDriverManager.waitElement(driver, By.className("tc-slider-normal"), 500);sleep(500);// 滑动GeetCanvasApi.move(driver, moveElemet, distance);sleep(400);// 滑动结果String gtInfo = ChromeDriverManager.waitElement(driver, By.id("statusSuccess"), 100).getText();if (gtInfo == null || "".equals(gtInfo)) {sleep(200);gtInfo = ChromeDriverManager.waitElement(driver, By.id("statusError"), 100).getText();}System.out.println("moveExec() gtInfo=" + gtInfo);if (gtInfo.contains("验证成功")) {retEntity.setRet(0);retEntity.setMsg(gtInfo);logger.info(retEntity.toString());} else if (gtInfo.contains("再试一次") || gtInfo.contains("恍惚了") || gtInfo.contains("半路丢了")) {retEntity.setRet(-1);retEntity.setMsg("失败");}} else {logger.error("retMap=" + retMap);retEntity.setMsg("retMap=" + retMap);return retEntity;}return retEntity;} catch (Exception e) {StringBuffer er = new StringBuffer("moveExec() " + e.toString() + "\n");for (StackTraceElement elment : e.getStackTrace())er.append(elment.toString() + "\n");logger.error(er.toString());System.out.println(er.toString());retEntity.setMsg(er.toString());return retEntity;} finally {if (retEntity.getRet() == 0) {System.out.println("moveExec() del file...");if (bFile != null)bFile.delete();if (sFile != null)sFile.delete();}}}private Map<String, byte[]> getTwoImg(WebDriver driver, String bgUrl, String slUrl, File bFile, File sFile) {try {FileUtils.copyURLToFile(new URL(bgUrl), bFile);FileUtils.copyURLToFile(new URL(slUrl), sFile);BufferedImage sBI = ImageIO.read(sFile);sBI = sBI.getSubimage(135, 478, 129, sBI.getHeight() - 478);ImageIO.write(sBI, "png", sFile);byte[] bigBytes = FileUtils.readFileToByteArray(bFile);byte[] smallBytes = FileUtils.readFileToByteArray(sFile);Map<String, byte[]> retMap = new HashMap<String, byte[]>();retMap.put("big", bigBytes);retMap.put("small", smallBytes);return retMap;} catch (Exception e) {StringBuffer er = new StringBuffer("getTwoImgOpen() " + e.toString() + "\n");for (StackTraceElement elment : e.getStackTrace())er.append(elment.toString() + "\n");logger.error(er.toString());System.out.println(er.toString());return null;}}/*** * @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() + ")");elseSystem.out.print(".");Thread.sleep(50);}}if (isWait)System.out.println(" outTime!");return null;}
戳这里→康康你手机号在过多少网站注册过!!!
友情推荐:新一代安全短信
相关阅读
谷歌图形验证码在AI 面前已经形同虚设,所以谷歌宣布退出验证码服务, 那么当所有的图形验证码都被破解时
《腾讯防水墙滑动拼图验证码》
《百度旋转图片验证码》
《网易易盾滑动拼图验证码》
《顶象区域面积点选验证码》
《顶象滑动拼图验证码》
《极验滑动拼图验证码》
《使用深度学习来破解 captcha 验证码》
《验证码终结者-基于CNN+BLSTM+CTC的训练部署套件》