OpenCV 破解滑块验证码 -Java 篇(摘抄了别人的,做个记录吧)

OpenCV 破解滑块验证码 -Java 篇

验证码作为一种安全机制,可以有效防止暴力破解密码、发帖、灌水、刷票等,大家在做 Web

自动化的时候应该有碰到验证码这个难题,一般我们可以和开发沟通请求他们的帮助:去掉验证码或者设置一个万能验证码,而如果开发不帮忙我们该如何去解决呢?本篇文章以

Java 语言为例教你怎么破解验证码。

现在大多数网址会采用滑块验证码的方式,下面以腾讯的滑块验证码为例,先来看看破解的效果:

要破解滑块验证码,我们一般采取的思路如下:

获取滑块到背景缺口图的距离

通过 selenium 的 Actions 类完成滑动

关键点就在于如何获取滑块到背景缺口图的距离,现在主流的方案是通过 OpenCV(Open Source Computer Vision

Library)开源计算机视觉库来处理,openCV 有非常多图像处理方法,其是通过 C/C++ 开发的,但是对外有提供 Java,Python

的接口,所以不管是 Python 还是 Java 我们都可以使用 openCV 进行图像处理。

环境准备

Step1:下载 OpenCV

进入到官网https://opencv.org/releases/下载对应系统的 openCV 软件包,之后解压

Step2:配置环境变量

进入到 opencv -> build ->x64 ->vc15 ->bin 目录,将路径复制追加到 Path 环境变量中

Step3:Intellij 工程中添加 jar 包

Intellij 中选择 File -> Project Structure -> Modules -> Dependencies

点击 add -> JARS or directories... 选择 D:\software\opencv\build\java\opencv-450.jar 文件

验证码破解实现

首先我们通过 selenium 进入到验证码页面(以 QQ 空间为例)

//设置chromeDriver识别路径

System.setProperty("webdriver.chrome.driver", "src/test/resources/chromedriver.exe");

driver = new ChromeDriver();

driver.get("https://qzone.qq.com/");

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

//切换登录页面所在iframe

WebElement loginFrame = driver.findElement(By.id("login_frame"));

driver.switchTo().frame(loginFrame);

driver.findElement(By.id("switcher_plogin")).click();

driver.findElement(By.id("u")).sendKeys("362715381");

driver.findElement(By.id("p")).sendKeys("1234r2we");

driver.findElement(By.id("login_button")).click();

进入到验证码界面后,我们仔细观察会发现:滑块和背景是两张分开的图片,src 属性中保存的即为图片 URL 地址,所以我们可以通过 URL 将两者下载到本地

//切换到验证码所在的iframe

WebElement tcaptchaFrame = driver.findElement(By.id("tcaptcha_iframe"));

driver.switchTo().frame(tcaptchaFrame);

//定位滑块图片

WebElement slideBlock = driver.findElement(By.id("slideBlock"));

//定位验证码背景图

WebElement slideBg = driver.findElement(By.id("slideBg"));

//获取图片Url链接

String slideBlockUrl = slideBlock.getAttribute("src");

String slideBgUrl = slideBg.getAttribute("src");

//下载对应图片

System.out.println("图片下载开始...");

downloadImg(slideBlockUrl, "slideBlock.png");

downloadImg(slideBgUrl, "slideBg.png");

关键点在于获取滑块到滑动背景缺口图的横向距离,这里通过 OpenCV 的模板匹配技术 matchTemplate

然后再通过 selenium 的 Actions 类完成滑动,在滑动的时候需要注意不能直接从开始点滑到终止点(有些网站会判定脚本操作),其中 getMoveTrack 用于获取滑动轨迹,控制每阶段的滑动速度

//获取滑块到滑动背景缺口图的横向距离

double slideDistance = getSlideDistance(System.getProperty("user.dir")+"\\slideBlock.png", System.getProperty("user.dir")+"\\slideBg.png");

Actions actions = new Actions(driver);

WebElement dragElement = driver.findElement(By.id("tcaptcha_drag_button"));

//获取style属性值,其中设置了滑块初始偏离值  style=left: 23px;

//需要注意的是网页前端图片和本地图片比例是不同的,需要进行换算

slideDistance = slideDistance * 280 / 680 - 23;

actions.clickAndHold(dragElement).perform();

//根据滑动距离生成滑动轨迹,约定规则:开始慢->中间快->最后慢

List<Integer> moveTrack = getMoveTrack(slideDistance);

for (Integer index : moveTrack) {

    //Thread.sleep(20);

    actions.moveByOffset(index, 0).perform();

}

actions.release().perform();

getSlideDistance 方法实现

首先对滑块进行处理

1、灰度化

2、去除图片黑边

3、inRange 二值化转黑白图

效果如下:

代码实现:

代码实现

// 加载OpenCV本地库

System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

//对滑块进行处理

Mat slideBlockMat = Imgcodecs.imread(slideBlockPicPath);

//1、灰度化图片

Imgproc.cvtColor(slideBlockMat, slideBlockMat, Imgproc.COLOR_BGR2GRAY);

//2、去除周围黑边

for (int row = 0; row < slideBlockMat.height(); row++) {

    for (int col = 0; col < slideBlockMat.width(); col++) {

        if (slideBlockMat.get(row, col)[0] == 0) {

            slideBlockMat.put(row, col, 96);

        }

    }

}

//3、inRange二值化转黑白图

Core.inRange(slideBlockMat, Scalar.all(96), Scalar.all(96), slideBlockMat);


对滑动背景图进行处理

1、灰度化

2、二值化转黑白图

代码如下:

//对滑动背景图进行处理

Mat slideBgMat = Imgcodecs.imread(slideBgPicPath);

//1、灰度化图片

Imgproc.cvtColor(slideBgMat, slideBgMat, Imgproc.COLOR_BGR2GRAY);

//2、二值化

Imgproc.threshold(slideBgMat, slideBgMat, 127, 255, Imgproc.THRESH_BINARY);

Mat g_result = new Mat();

/*

* matchTemplate:在模板和输入图像之间寻找匹配,获得匹配结果图像

* result:保存匹配的结果矩阵

* TM_CCOEFF_NORMED标准相关匹配算法

*/

Imgproc.matchTemplate(slideBgMat, slideBlockMat, g_result, Imgproc.TM_CCOEFF_NORMED);

/* minMaxLoc:在给定的结果矩阵中寻找最大和最小值,并给出它们的位置

* maxLoc最大值

*/

Point matchLocation = Core.minMaxLoc(g_result).maxLoc;

//返回匹配点的横向距离

return matchLocation.x;

需要注意的是运行时需要指定 library 路径,不然会报如下错误

java.lang.UnsatisfiedLinkError: no opencv_java450 in java.library.path

选择 Edit Configuration -> VM options 中添加:

-Djava.library.path=D:\software\opencv\build\java\x64

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,036评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,046评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,411评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,622评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,661评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,521评论 1 304
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,288评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,200评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,644评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,837评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,953评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,673评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,281评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,889评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,011评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,119评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,901评论 2 355

推荐阅读更多精彩内容

  • 在前面一篇博客,介绍了 Selenium 的基本用法和爬虫开发过程中经常使用的一些小技巧,利用这些写出一个浏览器爬...
    FifiZhuang阅读 10,987评论 4 81
  • 很多小伙伴们反馈,在web自动化的过程中,经常会被登录的验证码给卡住,不知道如何去通过验证码的验证。 今天专门给大...
    测试汪大牛阅读 4,034评论 1 2
  • 很长一段时间没写文章了,今天来一篇,聊聊滑块验证码。之前一段时间在研究下滑块验证码相关的东西,拿腾讯的验证码来玩,...
    zhangke3016阅读 16,265评论 4 5
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,536评论 28 53
  • 信任包括信任自己和信任他人 很多时候,很多事情,失败、遗憾、错过,源于不自信,不信任他人 觉得自己做不成,别人做不...
    吴氵晃阅读 6,190评论 4 8