OpenCV 破解滑塊驗證碼 -Java 篇(摘抄了別人的,做個記錄吧)

OpenCV 破解滑塊驗證碼 -Java 篇

驗證碼作為一種安全機制,可以有效防止暴力破解密碼、發(fā)帖、灌水、刷票等,大家在做 Web

自動化的時候應該有碰到驗證碼這個難題,一般我們可以和開發(fā)溝通請求他們的幫助:去掉驗證碼或者設置一個萬能驗證碼,而如果開發(fā)不幫忙我們該如何去解決呢?本篇文章以

Java 語言為例教你怎么破解驗證碼。

現(xiàn)在大多數(shù)網(wǎng)址會采用滑塊驗證碼的方式,下面以騰訊的滑塊驗證碼為例,先來看看破解的效果:

要破解滑塊驗證碼,我們一般采取的思路如下:

獲取滑塊到背景缺口圖的距離

通過 selenium 的 Actions 類完成滑動

關鍵點就在于如何獲取滑塊到背景缺口圖的距離,現(xiàn)在主流的方案是通過 OpenCV(Open Source Computer Vision

Library)開源計算機視覺庫來處理,openCV 有非常多圖像處理方法,其是通過 C/C++ 開發(fā)的,但是對外有提供 Java,Python

的接口,所以不管是 Python 還是 Java 我們都可以使用 openCV 進行圖像處理。

環(huán)境準備

Step1:下載 OpenCV

進入到官網(wǎng)https://opencv.org/releases/下載對應系統(tǒng)的 openCV 軟件包,之后解壓

Step2:配置環(huán)境變量

進入到 opencv -> build ->x64 ->vc15 ->bin 目錄,將路徑復制追加到 Path 環(huán)境變量中

Step3:Intellij 工程中添加 jar 包

Intellij 中選擇 File -> Project Structure -> Modules -> Dependencies

點擊 add -> JARS or directories... 選擇 D:\software\opencv\build\java\opencv-450.jar 文件

驗證碼破解實現(xiàn)

首先我們通過 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();

進入到驗證碼界面后,我們仔細觀察會發(fā)現(xiàn):滑塊和背景是兩張分開的圖片,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 類完成滑動,在滑動的時候需要注意不能直接從開始點滑到終止點(有些網(wǎng)站會判定腳本操作),其中 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;

//需要注意的是網(wǎng)頁前端圖片和本地圖片比例是不同的,需要進行換算

slideDistance = slideDistance * 280 / 680 - 23;

actions.clickAndHold(dragElement).perform();

//根據(jù)滑動距離生成滑動軌跡,約定規(guī)則:開始慢->中間快->最后慢

List<Integer> moveTrack = getMoveTrack(slideDistance);

for (Integer index : moveTrack) {

? ? //Thread.sleep(20);

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

}

actions.release().perform();

getSlideDistance 方法實現(xiàn)

首先對滑塊進行處理

1、灰度化

2、去除圖片黑邊

3、inRange 二值化轉黑白圖

效果如下:

代碼實現(xiàn):

代碼實現(xiàn)

// 加載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

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 在前面一篇博客,介紹了 Selenium 的基本用法和爬蟲開發(fā)過程中經常使用的一些小技巧,利用這些寫出一個瀏覽器爬...
    FifiZhuang閱讀 11,222評論 4 81
  • 很多小伙伴們反饋,在web自動化的過程中,經常會被登錄的驗證碼給卡住,不知道如何去通過驗證碼的驗證。 今天專門給大...
    測試汪大牛閱讀 4,236評論 1 2
  • 很長一段時間沒寫文章了,今天來一篇,聊聊滑塊驗證碼。之前一段時間在研究下滑塊驗證碼相關的東西,拿騰訊的驗證碼來玩,...
    zhangke3016閱讀 16,546評論 4 5
  • 我是黑夜里大雨紛飛的人啊 1 “又到一年六月,有人笑有人哭,有人歡樂有人憂愁,有人驚喜有人失落,有的覺得收獲滿滿有...
    陌忘宇閱讀 8,848評論 28 54
  • 信任包括信任自己和信任他人 很多時候,很多事情,失敗、遺憾、錯過,源于不自信,不信任他人 覺得自己做不成,別人做不...
    吳氵晃閱讀 6,371評論 4 8

友情鏈接更多精彩內容