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

selenium+opencv實(shí)現(xiàn)滑塊驗(yàn)證碼的登陸

 更新時(shí)間:2023年04月13日 09:33:59   作者:plexming  
很多網(wǎng)站登錄登陸時(shí)都要用到滑塊驗(yàn)證碼,本文主要介紹了selenium+opencv實(shí)現(xiàn)滑塊驗(yàn)證碼的登陸,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

很多網(wǎng)站登錄登陸時(shí)都要用到滑塊驗(yàn)證碼,在某些場(chǎng)景例如使用爬蟲爬取信息時(shí)常常受到阻礙,想著用opencv的模板匹配試試能不能實(shí)現(xiàn)模擬登陸。本來(lái)覺得網(wǎng)上資料多應(yīng)該還蠻容易,但實(shí)際上手還是搞了蠻久,在這里記錄一下整個(gè)流程,網(wǎng)站無(wú)所謂主要是要有滑動(dòng)驗(yàn)證碼:

環(huán)境

python 3.9, selenium和Opencv相關(guān)依賴,用于抓取圖片的requests包,具體安裝這里不多講了,其中selenium用的火狐版本。

selenium登錄網(wǎng)站

整體流程就是這個(gè)樣子:訪問網(wǎng)站->點(diǎn)擊登錄->輸入賬號(hào)密碼->搞定滑塊驗(yàn)證->登錄網(wǎng)站,其中最大的難點(diǎn)是滑塊驗(yàn)證碼,但在此之前我們當(dāng)然要先讓selenium自動(dòng)打開網(wǎng)站把賬號(hào)密碼輸好,我們通過find_element()方法定位輸入框之后執(zhí)行操作,元素的各個(gè)屬性F12就可以找到:

代碼如下:

options = webdriver.FirefoxOptions()
driver = webdriver.Firefox(options=options)
driver.get('網(wǎng)址')
driver.find_element("link text", "登錄").click()
name = driver.find_element("id", "name-input")
name.send_keys("賬號(hào)######") # 輸入賬號(hào)
pw = driver.find_element("id", "password-input")
pw.send_keys("密碼#########") # 輸入密碼
driver.find_element("id", "submit").click() # 提交

requests抓取驗(yàn)證碼圖片

為了做后續(xù)處理我們需要把滑塊驗(yàn)證碼相關(guān)圖片抓到本地,網(wǎng)上關(guān)于滑塊驗(yàn)證碼這塊很多都是用原圖和有缺口的圖對(duì)比來(lái)確定缺口位置的,但是我并沒有找到原圖,這里用到的是有缺口的背景圖和滑塊圖,如下:

滑塊圖:

有缺口的背景圖:

這里爬圖是selenium定位之后用requests包爬的,注意驗(yàn)證碼和登陸界面不在一個(gè)iframe里,selenium記得切到對(duì)應(yīng)iframe才能定位到圖片,代碼如下:

driver.switch_to.frame('tcaptcha_iframe')
 # 切換iframe
img = driver.find_element("id", "slideBg").get_attribute('src')
headers = {
    'Accept': "application/json, text/plain, */*",
    'User-Agent': "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"
} # 請(qǐng)求頭
r = requests.get(img, headers=headers)
with open('img.png', 'wb') as f:
    f.write(r.content)
block = driver.find_element("id", "slideBlock").get_attribute('src')
r = requests.get(block, headers=headers)
with open('block.png', 'wb') as f:
    f.write(r.content)

OpenCV識(shí)別缺口位置

接下來(lái)就是重點(diǎn),如何確定缺口位置來(lái)定位滑動(dòng)驗(yàn)證碼該往哪滑。這里主要用到OpenCV的模板匹配。 首先對(duì)滑塊也就是稍后匹配時(shí)用到的模板進(jìn)行處理,這里主要就是把形狀輪廓提取出來(lái)然后去掉多余的東西,先把原圖變成灰度圖:

tpl_gray = cv2.cvtColor(tpl, cv2.COLOR_BGR2GRAY)

可以看到邊緣有一圈陰影部分,我們需要把周圍這圈去掉,遍歷找到黑色像素點(diǎn)把它變成和周圍一樣。

width, height = tpl_gray.shape
    for h in range(height):
        for w in range(width):
            if tpl_gray[w, h] == 0:
                tpl_gray[w, h] = 96

處理后變成了這樣,然后把中間主體部分涂黑,也就是將圖片二值化。

binary = cv2.inRange(tpl_gray, 96, 96)  # 二值化
kernel = np.ones((8, 8), np.uint8)
template = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel) # 去白色噪點(diǎn)

處理完畢得到理想的模板圖:

接下來(lái)對(duì)帶有缺口的背景圖進(jìn)行處理,這個(gè)過程稍微麻煩一點(diǎn),不過思路還是比較清晰的,還是先轉(zhuǎn)化成灰度圖再二值化,這里有一個(gè)問題,不同驗(yàn)證碼圖片之間差距很大,有的顏色很顯眼,有的卻很清淡,比如下面這兩差別太大了,這就導(dǎo)致在二值化的過程中很難有一個(gè)固定的參數(shù)。

這里我根據(jù)圖片的平均灰度值設(shè)定了幾個(gè)區(qū)間,對(duì)不同區(qū)間的驗(yàn)證碼圖片傳入不同參數(shù)進(jìn)行二值化:

def avg_mean(img):
    mean_val, _, _, _ = cv2.mean(img)
    print("平均灰度:", mean_val)
    return mean_val
 
def match(img):
    gauss = cv2.GaussianBlur(img, [5, 5], 0)
    img_gray = cv2.cvtColor(gauss, cv2.COLOR_BGR2GRAY)
    cv2.imshow("111", img_gray)
    if avg_mean(img) > 140: # 二值化
        ret, target = cv2.threshold(img_gray, 105, 255, cv2.THRESH_BINARY)
    elif avg_mean(img) > 102:
        ret, target = cv2.threshold(img_gray, 95, 255, cv2.THRESH_BINARY) 
    else:
        ret, target = cv2.threshold(img_gray, 85, 255, cv2.THRESH_BINARY)

處理過的結(jié)果大概像這樣:

效果還是不錯(cuò)的,清晰的凸顯了缺口位置,最后把背景圖和模板傳入opencv的模板匹配方法,記錄下匹配到的坐標(biāo)即可。

result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
left_up = max_loc
print(left_up)
right_down = (left_up[0] + height, left_up[1] + width)
cv2.rectangle(img, left_up, right_down, (0, 0, 255), 2)
cv2.imshow('res', img)

這里框出來(lái)看看效果:

模擬拖動(dòng)滑塊

識(shí)別出位置之后就要算出滑塊移動(dòng)了多少距離,我們可以看到滑塊初始狀態(tài)距離邊緣有26個(gè)像素:

同時(shí)抓下來(lái)的圖片相比在網(wǎng)頁(yè)中放大了一倍,所以真實(shí)滑動(dòng)距離是: 

(left_up - 26*2)/2

于是用selenium的actionchains模擬拖動(dòng)滑塊:

def drag_block(l):
    drag = driver.find_element("id", "tcaptcha_drag_button")
    ActionChains(driver).click_and_hold(on_element=drag).perform()
    ActionChains(driver).move_to_element_with_offset(to_element=drag, xoffset=l, yoffset=0).perform()
    ActionChains(driver).release().perform()

這樣整個(gè)流程就搞定了,理論上這樣簡(jiǎn)單粗暴的自動(dòng)拖過去在很多時(shí)候會(huì)不奏效,還需要模擬人手動(dòng)拖動(dòng),不過因?yàn)槲易鰷y(cè)試的時(shí)候直接就成功了,所以沒寫下去,整體思路大概是加速減速停幾秒或者中間觸發(fā)幾個(gè)mouse_up(),mouse_down()事件。

腳本示例:

下面是測(cè)試時(shí)用到的腳本,selenium部分和主函數(shù),拿某個(gè)CTF靶場(chǎng)做的測(cè)試,僅供參考,根據(jù)實(shí)際網(wǎng)站不同肯定得改改:

import time
import requests
 
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
 
import block_loc
 
 
def drag_block(l):
    drag = driver.find_element("id", "tcaptcha_drag_button")
    ActionChains(driver).click_and_hold(on_element=drag).perform()
    ActionChains(driver).move_to_element_with_offset(to_element=drag, xoffset=l, yoffset=0).perform()
    ActionChains(driver).release().perform()
 
 
def login_in(username, password):
    headers = {
        'Accept': "application/json, text/plain, */*",
        'User-Agent': "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"
    }
    driver.get('網(wǎng)址')
    driver.find_element("link text", "登錄").click()
    name = driver.find_element("id", "name-input")
    name.send_keys(username)
    pw = driver.find_element("id", "password-input")
    pw.send_keys(password)
    driver.find_element("id", "submit").click()
    time.sleep(2)
    driver.switch_to.frame('tcaptcha_iframe')
    img = driver.find_element("id", "slideBg").get_attribute('src')
    r = requests.get(img, headers=headers)
    with open('img.png', 'wb') as f:
        f.write(r.content)
    block = driver.find_element("id", "slideBlock").get_attribute('src')
    r = requests.get(block, headers=headers)
    with open('block.png', 'wb') as f:
        f.write(r.content)
 
 
if __name__ == '__main__':
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)
    user = "##########"
    pw = "############"
    login_in(user, pw)
    image = "img.png"
    tpl = "block.png"
    length = block_loc.match(image, tpl)
    print(length)
    drag_block(length)

Opencv部分:

import cv2
import numpy as np
 
 
def avg_mean(img):
    mean_val, _, _, _ = cv2.mean(img)
    print("平均灰度:", mean_val)
    return mean_val
 
 
def match(image, temp):
    img = cv2.imread(image)
    tpl = cv2.imread(temp)
    tpl_gray = cv2.cvtColor(tpl, cv2.COLOR_BGR2GRAY)
    # cv2.imshow("111", tpl_gray)
    width, height = tpl_gray.shape
    for h in range(height):
        for w in range(width):
            if tpl_gray[w, h] == 0:
                tpl_gray[w, h] = 96
    binary = cv2.inRange(tpl_gray, 96, 96)
    kernel = np.ones((8, 8), np.uint8)
    template = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel)
    # cv2.imshow('tpl', template)
    print(img.shape)
    gauss = cv2.GaussianBlur(img, [5, 5], 0)
    img_gray = cv2.cvtColor(gauss, cv2.COLOR_BGR2GRAY)
    # cv2.imshow("111", img_gray)
    if avg_mean(img) > 140:
        ret, target = cv2.threshold(img_gray, 105, 255, cv2.THRESH_BINARY) # 二值化
    elif avg_mean(img) > 102:
        ret, target = cv2.threshold(img_gray, 95, 255, cv2.THRESH_BINARY)  # 二值化
    else:
        ret, target = cv2.threshold(img_gray, 80, 255, cv2.THRESH_BINARY)
    # cv2.imshow('target', target)
    result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
    left_up = max_loc
    print(left_up)
    right_down = (left_up[0] + height, left_up[1] + width)
    cv2.rectangle(img, left_up, right_down, (0, 0, 255), 2)
    # cv2.imshow('res', img)
    length = (left_up[0] - 26*2)/2
    return length

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

相關(guān)文章

  • Python中反轉(zhuǎn)二維數(shù)組的行和列問題

    Python中反轉(zhuǎn)二維數(shù)組的行和列問題

    這篇文章主要介紹了Python中反轉(zhuǎn)二維數(shù)組的行和列問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • python飛機(jī)大戰(zhàn)pygame碰撞檢測(cè)實(shí)現(xiàn)方法分析

    python飛機(jī)大戰(zhàn)pygame碰撞檢測(cè)實(shí)現(xiàn)方法分析

    這篇文章主要介紹了python飛機(jī)大戰(zhàn)pygame碰撞檢測(cè)實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了Python使用pygame實(shí)現(xiàn)飛機(jī)大戰(zhàn)游戲中碰撞檢測(cè)的原理與相關(guān)操作技巧,需要的朋友可以參考下
    2019-12-12
  • Python機(jī)器學(xué)習(xí)之決策樹算法

    Python機(jī)器學(xué)習(xí)之決策樹算法

    這篇文章主要為大家詳細(xì)介紹了Python機(jī)器學(xué)習(xí)之決策樹算法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Python PyQt5整理介紹

    Python PyQt5整理介紹

    PyQt5 是Digia的一套Qt5應(yīng)用框架與python的結(jié)合,同時(shí)支持2.x和3.x。這篇文章給大家整理了關(guān)于Python PyQt5的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2020-04-04
  • django之狀態(tài)保持-使用redis存儲(chǔ)session的例子

    django之狀態(tài)保持-使用redis存儲(chǔ)session的例子

    今天小編就為大家分享一篇django之狀態(tài)保持-使用redis存儲(chǔ)session的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧
    2019-07-07
  • 解讀! Python在人工智能中的作用

    解讀! Python在人工智能中的作用

    這篇文章主要幫助大家解讀Python在人工智能中的作用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • python找出列表中大于某個(gè)閾值的數(shù)據(jù)段示例

    python找出列表中大于某個(gè)閾值的數(shù)據(jù)段示例

    今天小編就為大家分享一篇python找出列表中大于某個(gè)閾值的數(shù)據(jù)段示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧
    2019-11-11
  • Python線程協(xié)作threading.Condition實(shí)現(xiàn)過程解析

    Python線程協(xié)作threading.Condition實(shí)現(xiàn)過程解析

    這篇文章主要介紹了Python線程協(xié)作threading.Condition實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • python多線程中獲取函數(shù)返回值的三種方法

    python多線程中獲取函數(shù)返回值的三種方法

    本文主要介紹了python多線程中獲取函數(shù)返回值的三種方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • python taipy庫(kù)輕松地將數(shù)據(jù)和機(jī)器學(xué)習(xí)模型轉(zhuǎn)為功能性Web應(yīng)用

    python taipy庫(kù)輕松地將數(shù)據(jù)和機(jī)器學(xué)習(xí)模型轉(zhuǎn)為功能性Web應(yīng)用

    taipy 是一個(gè)開源的 Python 庫(kù),任何具有基本 Python 技能的人都可以使用,對(duì)于數(shù)據(jù)科學(xué)家、機(jī)器學(xué)習(xí)工程師和 Python 程序員來(lái)說(shuō),它是一個(gè)方便的工具,借助 Taipy,你可以輕松地將數(shù)據(jù)和機(jī)器學(xué)習(xí)模型轉(zhuǎn)變?yōu)楣δ苄缘?nbsp;Web 應(yīng)用程序
    2024-01-01

最新評(píng)論

那坡县| 依兰县| 凤冈县| 曲周县| 华容县| 沈丘县| 福建省| 乌鲁木齐县| 湾仔区| 遂溪县| 涟水县| 册亨县| 襄城县| 新泰市| 正阳县| 卓尼县| 博爱县| 莎车县| 扶绥县| 崇左市| 迁西县| 北票市| 额尔古纳市| 祁东县| 濮阳县| 临高县| 巴东县| 伊宁县| 南部县| 西平县| 长岛县| 涿鹿县| 庆城县| 乐东| 陆川县| 宁津县| 泸西县| 桐梓县| 东海县| 江油市| 多伦县|