最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python+dddocr實(shí)現(xiàn)自動(dòng)化通過多缺口滑塊驗(yàn)證

 更新時(shí)間:2025年06月12日 10:05:32   作者:冷月半明  
滑塊驗(yàn)證是一種常見的反爬蟲手段,多缺口滑塊驗(yàn)證則是在背景圖上有多個(gè)缺口,滑塊需要精確拖動(dòng)到正確的缺口位置,下面我們就來看看如何使用Python實(shí)現(xiàn)自動(dòng)化通過多缺口滑塊驗(yàn)證吧

一、什么是滑塊驗(yàn)證

滑塊驗(yàn)證是一種常見的反爬蟲手段,用戶需要按住滑塊拖動(dòng)到指定位置,才能通過驗(yàn)證。多缺口滑塊驗(yàn)證則是在背景圖上有多個(gè)缺口,滑塊需要精確拖動(dòng)到正確的缺口位置。

手動(dòng)操作很簡(jiǎn)單,但自動(dòng)化通過卻難倒了不少爬蟲新手。本文將帶你用 Python + DrissionPage 實(shí)現(xiàn)自動(dòng)化滑塊驗(yàn)證。

二、核心思路

  • 識(shí)別滑塊和背景圖:獲取頁面上的滑塊和背景圖片。
  • 識(shí)別缺口位置:用 OCR 或圖像處理算法識(shí)別缺口的準(zhǔn)確位置。
  • 模擬人類拖動(dòng)滑塊:用代碼模擬鼠標(biāo)按下、移動(dòng)、釋放,完成滑塊驗(yàn)證。

三、代碼實(shí)戰(zhàn)

1. 環(huán)境準(zhǔn)備

  • Python 3.8+
  • DrissionPage
  • pillow(用于圖片處理)
  • ddddocr(滑塊識(shí)別)
pip install DrissionPage pillow ddddocr

2. 主要代碼結(jié)構(gòu)

2.1 滑塊識(shí)別核心:recognize_slider_distance

滑塊驗(yàn)證的關(guān)鍵是如何準(zhǔn)確識(shí)別滑塊需要移動(dòng)的距離。下面詳細(xì)講解 recognize_slider_distance 的實(shí)現(xiàn)原理和代碼:

import base64
import numpy as np
from PIL import Image
import io
import ddddocr

def base64_decode(str):
    return base64.b64decode(str)

def slider_puzzle_qg(p_puzzle_path: str = ''):
    """
    將小拼圖去除透明邊緣,返回處理后的base64圖片和位置信息
    """
    image = Image.open(p_puzzle_path)
    width, height = image.size
    pixels = image.load()
    _a = 0  # 頂部透明行數(shù)
    _b = 0  # 有效拼圖高度
    _c = 0  # 底部透明行數(shù)
    k = []  # 有效像素
    buffered = io.BytesIO()
    for x in range(height):
        data_pixel = []
        for y in range(width):
            r, g, b, a = pixels[y, x]
            data_pixel += [(r, g, b, a)]
        NumPy_data_pixel = np.array(data_pixel)
        if np.all(NumPy_data_pixel == 0):
            if _b == 0:
                _a += 1
            else:
                if _c == 0:
                    new_image = Image.new('RGBA', (width, _b), color=(0, 0, 0, 0))
                    new_image.putdata(k)
                    new_image.save(buffered, format="PNG")
                _c += 1
        else:
            _b += 1
            k += data_pixel
    return {
        '最頂層-頂層距離': _a,
        '中間層-拼圖的高度': _b,
        '最底層-底層距離': _c,
        'base64': base64.b64encode(buffered.getvalue()).decode()
    }

def background_cutting(b_puzzle_path: str = '', b_size_h: int = 0, p_size_h: int = 0):
    """
    按小拼圖的高度切割背景圖,返回base64
    """
    image = Image.open(b_puzzle_path)
    width, height = image.size
    left, right = 0, width
    top, bottom = b_size_h, b_size_h + p_size_h
    cropped_image = image.crop((left, top, right, bottom))
    buffered = io.BytesIO()
    cropped_image.save(buffered, format="PNG")
    return {'base64': base64.b64encode(buffered.getvalue()).decode()}

def recognize_slider_distance(xiaopintu_path, beijingtu_path):
    """
    識(shí)別滑塊需要移動(dòng)的距離
    :param xiaopintu_path: 小拼圖路徑
    :param beijingtu_path: 背景圖路徑
    :return: 滑動(dòng)距離
    """
    det = ddddocr.DdddOcr(det=False, ocr=False, show_ad=False)
    xiaopintu_data = slider_puzzle_qg(p_puzzle_path=xiaopintu_path)
    beijingtu_data = background_cutting(b_puzzle_path=beijingtu_path, b_size_h=xiaopintu_data['最頂層-頂層距離'],
                                        p_size_h=xiaopintu_data['中間層-拼圖的高度'])
    res1 = det.slide_match(base64_decode(beijingtu_data['base64']), base64_decode(xiaopintu_data['base64']),
                           simple_target=True)
    res1 = res1['target'][0]
    # 為了更像人類操作,可以加一點(diǎn)偏移
    res = res1 * 1.1 - 4
    return res

原理說明:

  • 先用 slider_puzzle_qg 去除小拼圖的透明邊緣,獲得有效區(qū)域和高度。
  • background_cutting 按小拼圖的高度切割背景圖,獲得滑道。
  • 用 ddddocr 的 slide_match 方法,計(jì)算小拼圖在滑道中的最佳匹配位置(即缺口橫坐標(biāo))。
  • 最后加一點(diǎn)偏移,模擬人類誤差,防止被反爬蟲檢測(cè)。

2.2 登錄與滑塊拖動(dòng)

下面是完整的登錄與滑塊拖動(dòng)自動(dòng)化代碼示例,適合新手理解:

import random
import time
import base64
from DrissionPage import Chromium, ChromiumOptions
from utils.ocr_util import recognize_slider_distance  # 上文已詳細(xì)講解
from service.logger import logger

# 創(chuàng)建瀏覽器實(shí)例
co = ChromiumOptions().set_browser_path(r'C:\Path\To\chrome.exe')
tab = Chromium().latest_tab

def base64_decode(data):
    return base64.b64decode(data + '==')

def login_with_slider(tab, username, password):
    try:
        # 1. 打開登錄頁面(URL已脫敏)
        tab.get('https://your-domain.com/login')
        # 2. 輸入賬號(hào)密碼
        username_ele = tab.ele('@@tag()=input@@placeholder=請(qǐng)輸入賬號(hào)')
        password_ele = tab.ele('@@tag()=input@@placeholder=請(qǐng)輸入密碼')
        username_ele.input(username)
        password_ele.input(password)
        # 3. 點(diǎn)擊登錄按鈕
        login_button = tab.ele('@@tag()=span@@text():登 錄')
        login_button.click(by_js=True)

        # 4. 獲取滑塊和背景圖片
        background_image_ele = tab.ele('@@tag()=div@@class=verify-img-panel').ele('@@tag()=img')
        gap_image_ele = tab.ele('@@tag()=div@@class=verify-sub-block').ele('@@tag()=img')
        xiaopintu_data = gap_image_ele.attr('src').split("data:image/png;base64,")[-1]
        background_img_data = background_image_ele.attr('src').split("data:image/png;base64,")[-1]
        with open('beijingtu.png', 'wb') as f:
            f.write(base64_decode(background_img_data))
        with open('xiaopintu.png', 'wb') as f:
            f.write(base64_decode(xiaopintu_data))

        # 5. 識(shí)別滑塊需要移動(dòng)的距離
        distance = recognize_slider_distance(xiaopintu_path="xiaopintu.png", beijingtu_path="beijingtu.png")
        tab.wait.ele_displayed('@@tag()=div@@class=verify-move-block', timeout=10)
        slider = tab.ele('@@tag()=div@@class=verify-move-block').wait.clickable(timeout=10)
        if not slider:
            logger.error('未找到滑塊元素,請(qǐng)檢查類名或頁面結(jié)構(gòu)')
            return False
        else:
            tab.run_js('arguments[0].style.border="2px solid red"', slider)
            logger.info(' 找到滑塊元素,開始滑動(dòng)')
            # 6. 獲取滑塊中心點(diǎn)坐標(biāo)
            slider_rect = tab.run_js('''
                const rect = arguments[0].getBoundingClientRect();
                return {
                    x: rect.x + rect.width / 2,
                    y: rect.y + rect.height / 2
                }
            ''', slider)
            try:
                # 7. 用 JS 模擬鼠標(biāo)事件拖動(dòng)滑塊
                tab.run_js('''
                    function simulateMouseEvent(element, eventType, x, y) {
                        const event = new MouseEvent(eventType, {
                            view: window,
                            bubbles: true,
                            cancelable: true,
                            clientX: x,
                            clientY: y
                        });
                        element.dispatchEvent(event);
                    }
                    const slider = arguments[0];
                    const startX = arguments[1];
                    const startY = arguments[2];
                    const distance = arguments[3];
                    simulateMouseEvent(slider, 'mousedown', startX, startY);
                    const segments = 5;
                    const segmentDistance = distance / segments;
                    let currentX = startX;
                    for (let i = 0; i < segments; i++) {
                        currentX += segmentDistance;
                        simulateMouseEvent(slider, 'mousemove', currentX, startY);
                    }
                    currentX -= 5;
                    simulateMouseEvent(slider, 'mousemove', currentX, startY);
                    simulateMouseEvent(slider, 'mouseup', currentX, startY);
                ''', slider, slider_rect['x'], slider_rect['y'], distance)
                logger.info(' 滑動(dòng)操作已發(fā)送')
                time.sleep(1)
            except Exception as e:
                logger.error(f' 滑動(dòng)出錯(cuò): {e}')
                return False
        # 8. 后續(xù)驗(yàn)證、UKey等操作略
        return True
    except Exception as e:
        logger.error(f"登錄失敗,錯(cuò)誤信息:{e}")
        return False

代碼說明:

步驟1-3:自動(dòng)化輸入賬號(hào)、密碼并點(diǎn)擊登錄。

步驟4:獲取滑塊和背景圖片,保存為本地文件。

步驟5:調(diào)用 recognize_slider_distance 識(shí)別滑塊需要移動(dòng)的距離。

步驟6:獲取滑塊元素的中心點(diǎn)坐標(biāo)。

步驟7:用 JavaScript 分段模擬鼠標(biāo)拖動(dòng)滑塊,模擬人類操作。此處也可以使用drisionpage操作元素例如:

# 向右移動(dòng)鼠標(biāo)
# tab_.actions.right(distance - 10)
time.sleep(0.05)
# tab_.actions.right(10)

步驟8:后續(xù)如UKey驗(yàn)證等可根據(jù)實(shí)際需求補(bǔ)充。

3. 關(guān)鍵技術(shù)點(diǎn)說明

  • 圖片識(shí)別recognize_slider_distance 利用 ddddocr 的滑塊識(shí)別能力,極大簡(jiǎn)化了滑塊距離的計(jì)算。
  • 圖片預(yù)處理:去除透明邊緣、切割滑道,是提升識(shí)別準(zhǔn)確率的關(guān)鍵。
  • JS 模擬鼠標(biāo)事件:直接用 JS 觸發(fā) mousedownmousemove、mouseup,比傳統(tǒng)動(dòng)作鏈更容易繞過部分反爬蟲。
  • 分段移動(dòng):模擬人手抖動(dòng),分多段移動(dòng)更像真人。
  • 異常處理:每一步都要加 try/except,方便調(diào)試。

四、常見問題與排查

1.滑塊沒動(dòng)?

  • 檢查元素選擇器是否準(zhǔn)確。
  • 檢查 JS 事件是否被頁面攔截。
  • 嘗試加大分段數(shù),或調(diào)整每段距離。

2.識(shí)別距離不準(zhǔn)?

  • 檢查圖片保存是否完整。
  • 調(diào)整識(shí)別算法參數(shù)。
  • 檢查小拼圖和背景圖的預(yù)處理是否正確。

3.驗(yàn)證失???

  • 檢查是否有額外的行為驗(yàn)證(如軌跡分析、行為分析)。
  • 嘗試加大拖動(dòng)時(shí)間,模擬更慢的拖動(dòng)。

五、總結(jié)

自動(dòng)化通過多缺口滑塊驗(yàn)證并不神秘,關(guān)鍵在于:

  • 正確識(shí)別滑塊和缺口位置(圖片預(yù)處理+滑塊識(shí)別)
  • 用 JS 或動(dòng)作鏈模擬真實(shí)拖動(dòng)
  • 多調(diào)試、多嘗試,遇到問題多看日志

到此這篇關(guān)于Python+dddocr實(shí)現(xiàn)自動(dòng)化通過多缺口滑塊驗(yàn)證的文章就介紹到這了,更多相關(guān)Python滑塊驗(yàn)證內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Django 過濾器匯總及自定義過濾器使用詳解

    Django 過濾器匯總及自定義過濾器使用詳解

    這篇文章主要介紹了Django 過濾器匯總及自定義過濾器使用詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-07-07
  • 使用Python?Seaborn創(chuàng)建熱力圖的制作指南

    使用Python?Seaborn創(chuàng)建熱力圖的制作指南

    熱力圖作為一種直觀的數(shù)據(jù)可視化工具,通過顏色深淺和漸變映射數(shù)據(jù)值,廣泛應(yīng)用于數(shù)據(jù)密度分析、趨勢(shì)挖掘和跨維度對(duì)比,本文將結(jié)合Python的seaborn庫,從熱力圖的核心原理到實(shí)際操作案例,逐步講解如何利用熱力圖揭示數(shù)據(jù)背后的隱藏規(guī)律,需要的朋友可以參考下
    2025-08-08
  • 使用Python從零實(shí)現(xiàn)一個(gè)最基礎(chǔ)的MCP協(xié)議

    使用Python從零實(shí)現(xiàn)一個(gè)最基礎(chǔ)的MCP協(xié)議

    模型上下文協(xié)議是?Anthropic?在2024年提出的一種開放標(biāo)準(zhǔn)協(xié)議,用于標(biāo)準(zhǔn)化?AI?模型與外部工具和數(shù)據(jù)源的集成方式,本示例將展示如何使用?Python?實(shí)現(xiàn)一個(gè)最基礎(chǔ)的?MCP?協(xié)議,包括?MCP?服務(wù)器和?MCP?客戶端兩部分,需要的朋友可以參考下
    2026-04-04
  • python包pdfkit(wkhtmltopdf)?將HTML轉(zhuǎn)換為PDF的操作方法

    python包pdfkit(wkhtmltopdf)?將HTML轉(zhuǎn)換為PDF的操作方法

    pdfkit,把HTML+CSS格式的文件轉(zhuǎn)換成PDF格式文檔的一種工具。它就是html轉(zhuǎn)成pdf工具包wkhtmltopdf的Python封裝。所以,必須手動(dòng)安裝wkhtmltopdf,這篇文章主要介紹了python包pdfkit(wkhtmltopdf)將HTML轉(zhuǎn)換為PDF,需要的朋友可以參考下
    2022-04-04
  • python讀取和保存圖片5種方法對(duì)比

    python讀取和保存圖片5種方法對(duì)比

    為大家分享一下python讀取和保存圖片5種方法與比較,python中對(duì)象之間的賦值是按引用傳遞的,如果需要拷貝對(duì)象,需要用到標(biāo)準(zhǔn)庫中的copy模塊
    2018-09-09
  • 使用Python設(shè)置PDF中圖片的透明度的實(shí)現(xiàn)方法

    使用Python設(shè)置PDF中圖片的透明度的實(shí)現(xiàn)方法

    在PDF文檔的設(shè)計(jì)與內(nèi)容創(chuàng)作過程中,圖像的透明度設(shè)置是一個(gè)重要的操作,尤其是在處理圖文密集型PDF文檔時(shí),本文將介紹如何使用Python添加指定透明度的圖片到PDF文檔或調(diào)整PDF文檔中現(xiàn)有圖片的透明度,需要的朋友可以參考下
    2024-09-09
  • Python進(jìn)行區(qū)間取值案例講解

    Python進(jìn)行區(qū)間取值案例講解

    這篇文章主要介紹了Python進(jìn)行區(qū)間取值案例講解,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • Python?find()、rfind()方法及作用

    Python?find()、rfind()方法及作用

    這篇文章主要介紹了Python?find()、rfind()方法,find方法的作用檢索是否指定的字符串,如果存在返回首次出現(xiàn)該字符串的索引,如果不存在返回-1,rfind 方法的作用和find方法作用相同,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • python中Selenium+Webdriver實(shí)現(xiàn)自動(dòng)化登錄

    python中Selenium+Webdriver實(shí)現(xiàn)自動(dòng)化登錄

    本文主要介紹了python中Selenium+Webdriver實(shí)現(xiàn)自動(dòng)化登錄,包括測(cè)試環(huán)境的搭建、代碼編寫、以及注意事項(xiàng)等,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09
  • Python利用prettytable實(shí)現(xiàn)格式化輸出內(nèi)容

    Python利用prettytable實(shí)現(xiàn)格式化輸出內(nèi)容

    Python有一個(gè)第三方模塊叫?prettytable,專門用來將數(shù)據(jù)格式輸出。本文將通過示例為大家詳細(xì)講講prettytable的用法,感興趣的可以了解一下
    2022-07-07

最新評(píng)論

城步| 萍乡市| 常州市| 大埔县| 衡山县| 郴州市| 弋阳县| 平塘县| 昌邑市| 巴南区| 石城县| 潞城市| 福安市| 黑山县| 容城县| 耒阳市| 宁夏| 封丘县| 吉隆县| 常熟市| 通州区| 西丰县| 菏泽市| 巴林左旗| 锡林郭勒盟| 岳池县| 尼玛县| 米脂县| 西宁市| 望城县| 仁布县| 马公市| 綦江县| 集贤县| 如东县| 泽州县| 大港区| 伊宁市| 盐津县| 淳化县| 鹿泉市|