前言
不知不覺距離上次研究已經(jīng)快三年利用puppeteer破解極驗的滑動驗證,最近用puppeteer在做一些爬蟲的工作,遇到了需要滑動驗證的校驗,于是毫不猶豫想起以前破解的經(jīng)驗,通過對比,emmm...跟之前的有些差別,下面我們來分析一下。
分析
這個滑動驗證只存在兩張圖(如下圖)
1. 背景圖(包含缺口)
2. 滑塊圖
對比極驗的滑動驗證,缺少完整背景圖(不含缺口),這樣我們就無法去通過對比背景圖來獲取滑動的距離了。

bg.jpg
認(rèn)真觀察一下背景圖,我們能不能從中獲取到什么有用的信息來計算滑動距離呢?
于是,我發(fā)現(xiàn)背景圖缺口周圍的白邊。分析一下
1.白邊沒有透明度。(這個很重要,確保不會受到背景圖的顏色影響)
2.每次都是白邊,顏色不會變,白邊顏色值幾乎相同。
3.通過白邊計算滑動距離。
實現(xiàn)
- 這里只說明一下核心代碼,完整代碼就不放出了,畢竟最重要的只是計算滑動距離,有興趣可以自己嘗試。
原理:橫坐標(biāo)相同的情況下,記錄縱坐標(biāo)顏色值出現(xiàn)與白邊顏色相同的次數(shù),次數(shù)出現(xiàn)最多的橫坐標(biāo)就是滑動距離
// 計算滑動距離
calculateDistance = async (page) => {
const distance = await page.evaluate(() => {
// 1.背景圖轉(zhuǎn)canvas
const bgImg = document.getElementsByClassName('validate-main')[0].getElementsByTagName('img')[0]
const canvas = document.createElement('canvas')
const context = canvas.getContext('2d')
context.drawImage(bgImg, 0, 0, bgImg.naturalWidth, bgImg.naturalHeight)
// 2.保存橫坐標(biāo)和重復(fù)顏色出現(xiàn)次數(shù)
// 這個橫坐標(biāo)就是相當(dāng)于滑動距離,通過比較次數(shù)就可以獲取正確的滑動距離
const xAxis = {}
// 3.允許存在誤差比較
// 因為我使用拾色器獲取顏色值的,可以會存在小小誤差,所以我們允許存在誤差,這個不影響正確判斷
allowDeviation = (num1, num2) => {
const offset = 25
return -offset <= num1 - num2 && num1 - num2 <= offset
}
// 對比rgb數(shù)值
for (let i = 1; i < bgImg.naturalWidth; i++) {
let times = 0
// 因為缺口只會出現(xiàn)在中間位置,所以不用對比整個縱坐標(biāo),只需要對比中間位置即可
// 這里我們從上面45像素開始到下面55像素結(jié)束
for (let j = 45; j < bgImg.naturalHeight - 55; j++) {
const imgData = context.getImageData(1 * i, 1 * j, 1, 1).data
const r = imgData[0]
const g = imgData[1]
const b = imgData[2]
// 因為白色是255,可能存在誤差,所以這里我們?nèi)∩缘鸵稽c
// 基于230允許+-25誤差來比較
if (allowDeviation(r, 230) && allowDeviation(g, 230) && allowDeviation(b, 230)) {
// 記錄符合條件出現(xiàn)的次數(shù)
times++
xAxis[i] = times
}
}
// 去掉重復(fù)像素出現(xiàn)小于20的
if (xAxis[i] < 20) {
delete xAxis[i]
}
}
// 經(jīng)過測試通過上面過濾后就只剩下一個了,所以我直接取了
// 這里其實不嚴(yán)謹(jǐn)?shù)?,你可以通過對比出現(xiàn)最多次數(shù)來獲取
return Object.keys(xAxis)[0]
})
return distance
}
最后
其實市面上驗證方式層出不窮,諸如點擊出現(xiàn)文字、找到人物相同的圖片等等,對于這些puppeteer基本束手無策(有知道怎么破解的可以分享下哈)。這篇文章更多出于學(xué)習(xí)分享,大家遇到什么驗證問題可以來互相討論學(xué)習(xí)一下或評論區(qū)留言。