puppeteer與滑動驗證2.0

前言

不知不覺距離上次研究已經(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ū)留言。

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

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容