python 模擬網(wǎng)站登錄——滑塊驗(yàn)證碼的識(shí)別
普通滑動(dòng)驗(yàn)證
以http://admin.emaotai.cn/login.aspx為例這類驗(yàn)證碼只需要我們將滑塊拖動(dòng)指定位置,處理起來比較簡(jiǎn)單。拖動(dòng)之前需要先將滾動(dòng)條滾動(dòng)到指定元素位置。
import time from selenium import webdriver from selenium.webdriver import ActionChains # 新建selenium瀏覽器對(duì)象,后面是geckodriver.exe下載后本地路徑 browser = webdriver.Firefox() # 網(wǎng)站登陸頁(yè)面 url = 'http://admin.emaotai.cn/login.aspx' # 瀏覽器訪問登錄頁(yè)面 browser.get(url) browser.maximize_window() browser.implicitly_wait(5) draggable = browser.find_element_by_id('nc_1_n1z') # 滾動(dòng)指定元素位置 browser.execute_script("arguments[0].scrollIntoView();", draggable) time.sleep(2) ActionChains(browser).click_and_hold(draggable).perform() # 拖動(dòng) ActionChains(browser).move_by_offset(xoffset=247, yoffset=0).perform() ActionChains(browser).release().perform()
拼圖滑動(dòng)驗(yàn)證
我們以歐模網(wǎng)很多網(wǎng)站使用的都是類似的方式。因?yàn)轵?yàn)證碼及拼圖都有明顯明亮的邊界,圖片辨識(shí)度比較高。所以我們嘗試先用cv2的邊緣檢測(cè)識(shí)別出邊界,然后進(jìn)行模糊匹配,匹配出拼圖在驗(yàn)證碼圖片的位置。
邊緣檢測(cè)
cv2模塊提供了多種邊緣檢測(cè)算子,包括Sobel、Scharr、Laplacian、prewitt、Canny或Marr—Hildreth等,每種算子得出的結(jié)果不同。這里我們用Canny算子,測(cè)試了很多算子,這種效果最好。
我們通過一個(gè)程序調(diào)整一下canny算子的閾值,使得輸出圖片只包含拼圖輪廓。
import cv2 lowThreshold = 0 maxThreshold = 100 # 最小閾值范圍 0 ~ 500 # 最大閾值范圍 100 ~ 1000 def canny_low_threshold(intial): blur = cv2.GaussianBlur(img, (3, 3), 0) canny = cv2.Canny(blur, intial, maxThreshold) cv2.imshow('canny', canny) def canny_max_threshold(intial): blur = cv2.GaussianBlur(img, (3, 3), 0) canny = cv2.Canny(blur, lowThreshold, intial) cv2.imshow('canny', canny) # 參數(shù)0以灰度方式讀取 img = cv2.imread('vcode.png', 0) cv2.namedWindow('canny', cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO) cv2.createTrackbar('Min threshold', 'canny', lowThreshold, max_lowThreshold, canny_low_threshold) cv2.createTrackbar('Max threshold', 'canny', maxThreshold, max_maxThreshold, canny_max_threshold) canny_low_threshold(0) # esc鍵退出 if cv2.waitKey(0) == 27: cv2.destroyAllWindows()
測(cè)試了若干個(gè)圖片發(fā)現(xiàn)最小閾值100、最大閾值500輸出結(jié)果比較理想。
拼圖匹配
我們用cv2的matchTemplate方法進(jìn)行模糊匹配,匹配方法用CV_TM_CCOEFF_NORMED歸一化相關(guān)系數(shù)匹配。
【1】 平方差匹配 method=CV_TM_SQDIFF square dirrerence(error)
這類方法利用平方差來進(jìn)行匹配,最好匹配為0.匹配越差,匹配值越大.
【2】標(biāo)準(zhǔn)平方差匹配 method=CV_TM_SQDIFF_NORMED standard square dirrerence(error)
【3】 相關(guān)匹配 method=CV_TM_CCORR
這類方法采用模板和圖像間的乘法操作,所以較大的數(shù)表示匹配程度較高,0標(biāo)識(shí)最壞的匹配效果.
【4】 標(biāo)準(zhǔn)相關(guān)匹配 method=CV_TM_CCORR_NORMED
【5】 相關(guān)匹配 method=CV_TM_CCOEFF
這類方法將模版對(duì)其均值的相對(duì)值與圖像對(duì)其均值的相關(guān)值進(jìn)行匹配,1表示完美匹配,
-1表示糟糕的匹配,0表示沒有任何相關(guān)性(隨機(jī)序列).
【6】標(biāo)準(zhǔn)相關(guān)匹配 method=CV_TM_CCOEFF_NORMED
canndy_test.py:
import cv2 import numpy as np def matchImg(imgPath1,imgPath2): imgs = [] # 原始圖像,用于展示 sou_img1 = cv2.imread(imgPath1) sou_img2 = cv2.imread(imgPath2) # 原始圖像,灰度 # 最小閾值100,最大閾值500 img1 = cv2.imread(imgPath1, 0) blur1 = cv2.GaussianBlur(img1, (3, 3), 0) canny1 = cv2.Canny(blur1, 100, 500) cv2.imwrite('temp1.png', canny1) img2 = cv2.imread(imgPath2, 0) blur2 = cv2.GaussianBlur(img2, (3, 3), 0) canny2 = cv2.Canny(blur2, 100, 500) cv2.imwrite('temp2.png', canny2) target = cv2.imread('temp1.png') template = cv2.imread('temp2.png') # 調(diào)整顯示大小 target_temp = cv2.resize(sou_img1, (350, 200)) target_temp = cv2.copyMakeBorder(target_temp, 5, 5, 5, 5, cv2.BORDER_CONSTANT, value=[255, 255, 255]) template_temp = cv2.resize(sou_img2, (200, 200)) template_temp = cv2.copyMakeBorder(template_temp, 5, 5, 5, 5, cv2.BORDER_CONSTANT, value=[255, 255, 255]) imgs.append(target_temp) imgs.append(template_temp) theight, twidth = template.shape[:2] # 匹配拼圖 result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED) # 歸一化 cv2.normalize( result, result, 0, 1, cv2.NORM_MINMAX, -1 ) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result) # 匹配后結(jié)果畫圈 cv2.rectangle(target,max_loc,(max_loc[0]+twidth,max_loc[1]+theight),(0,0,255),2) target_temp_n = cv2.resize(target, (350, 200)) target_temp_n = cv2.copyMakeBorder(target_temp_n, 5, 5, 5, 5, cv2.BORDER_CONSTANT, value=[255, 255, 255]) imgs.append(target_temp_n) imstack = np.hstack(imgs) cv2.imshow('stack'+str(max_loc), imstack) cv2.waitKey(0) cv2.destroyAllWindows() matchImg('vcode_data/out_'+str(1)+'.png','vcode_data/in_'+str(1)+'.png')
我們測(cè)試幾組數(shù)據(jù),發(fā)現(xiàn)準(zhǔn)確率拿來玩玩尚可。max_loc就是匹配出來的位置信息,我們只需要按照位置進(jìn)行拖動(dòng)即可。
完整程序
完整流程
1.實(shí)例化瀏覽器
2.點(diǎn)擊登陸,彈出滑動(dòng)驗(yàn)證框
3.分別新建標(biāo)簽頁(yè)打開背景圖及拼圖
4.全屏截圖后按照尺寸裁剪
5.模糊匹配兩張圖片,獲取匹配結(jié)果位置信息
6.將位置信息轉(zhuǎn)為頁(yè)面上的位移距離
7.拖動(dòng)滑塊到指定位置
import time import cv2 import canndy_test from selenium import webdriver from selenium.webdriver import ActionChains # 新建selenium瀏覽器對(duì)象,后面是geckodriver.exe下載后本地路徑 browser = webdriver.Firefox() # 網(wǎng)站登陸頁(yè)面 url = 'https://www.om.cn/login' # 瀏覽器訪問登錄頁(yè)面 browser.get(url) handle = browser.current_window_handle # 等待3s用于加載腳本文件 browser.implicitly_wait(3) # 點(diǎn)擊登陸按鈕,彈出滑動(dòng)驗(yàn)證碼 btn = browser.find_element_by_class_name('login_btn1') btn.click() # 獲取iframe元素,切到iframe frame = browser.find_element_by_id('tcaptcha_iframe') browser.switch_to.frame(frame) time.sleep(1) # 獲取背景圖src targetUrl = browser.find_element_by_id('slideBg').get_attribute('src') # 獲取拼圖src tempUrl = browser.find_element_by_id('slideBlock').get_attribute('src') # 新建標(biāo)簽頁(yè) browser.execute_script("window.open('');") # 切換到新標(biāo)簽頁(yè) browser.switch_to.window(browser.window_handles[1]) # 訪問背景圖src browser.get(targetUrl) time.sleep(3) # 截圖 browser.save_screenshot('temp_target.png') w = 680 h = 390 img = cv2.imread('temp_target.png') size = img.shape top = int((size[0] - h) / 2) height = int(h + ((size[0] - h) / 2)) left = int((size[1] - w) / 2) width = int(w + ((size[1] - w) / 2)) cropped = img[top:height, left:width] # 裁剪尺寸 cv2.imwrite('temp_target_crop.png', cropped) # 新建標(biāo)簽頁(yè) browser.execute_script("window.open('');") browser.switch_to.window(browser.window_handles[2]) browser.get(tempUrl) time.sleep(3) browser.save_screenshot('temp_temp.png') w = 136 h = 136 img = cv2.imread('temp_temp.png') size = img.shape top = int((size[0] - h) / 2) height = int(h + ((size[0] - h) / 2)) left = int((size[1] - w) / 2) width = int(w + ((size[1] - w) / 2)) cropped = img[top:height, left:width] cv2.imwrite('temp_temp_crop.png', cropped) browser.switch_to.window(handle) # 模糊匹配兩張圖片 move = canndy_test.matchImg('temp_target_crop.png', 'temp_temp_crop.png') # 計(jì)算出拖動(dòng)距離 distance = int(move / 2 - 27.5) + 2 draggable = browser.find_element_by_id('tcaptcha_drag_thumb') ActionChains(browser).click_and_hold(draggable).perform() # 拖動(dòng) ActionChains(browser).move_by_offset(xoffset=distance, yoffset=0).perform() ActionChains(browser).release().perform() time.sleep(10)
tips:可能會(huì)存在第一次不成功的情況,雖然拖動(dòng)到了指定位置但是提示網(wǎng)絡(luò)有問題、拼圖丟失??梢赃M(jìn)行循環(huán)迭代直到拼成功為止。通過判斷iframe中id為slideBg的元素是否存在,如果成功了則不存在,失敗了會(huì)刷新拼圖讓你重新拖動(dòng)。
if(isEleExist(browser,'slideBg')): # retry else: return def isEleExist(browser,id): try: browser.find_element_by_id(id) return True except: return False
以上就是python 模擬網(wǎng)站登錄——滑塊驗(yàn)證碼的識(shí)別的詳細(xì)內(nèi)容,更多關(guān)于python 模擬網(wǎng)站登錄的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Python基于Django實(shí)現(xiàn)驗(yàn)證碼登錄功能
- python爬蟲模擬登錄之圖片驗(yàn)證碼實(shí)現(xiàn)詳解
- python網(wǎng)絡(luò)爬蟲之模擬登錄 自動(dòng)獲取cookie值 驗(yàn)證碼識(shí)別的具體實(shí)現(xiàn)
- 教你怎么用python批量登錄帶有驗(yàn)證碼的網(wǎng)站
- Python爬蟲爬取ts碎片視頻+驗(yàn)證碼登錄功能
- python3定位并識(shí)別圖片驗(yàn)證碼實(shí)現(xiàn)自動(dòng)登錄功能
- Python +Selenium解決圖片驗(yàn)證碼登錄或注冊(cè)問題(推薦)
- Python 郵箱登錄驗(yàn)證碼功能實(shí)現(xiàn)代碼
相關(guān)文章
python 計(jì)算數(shù)據(jù)偏差和峰度的方法
今天小編就為大家分享一篇python 計(jì)算數(shù)據(jù)偏差和峰度的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-06-06python自動(dòng)化測(cè)試selenium核心技術(shù)處理彈框
這篇文章主要為大家介紹了python自動(dòng)化測(cè)試selenium核心技術(shù)處理彈框的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-11-11python?使用?with?open()?as?讀寫文件的操作方法
這篇文章主要介紹了python?使用?with?open()as?讀寫文件的操作代碼,寫文件和讀文件是一樣的,唯一區(qū)別是調(diào)用open()函數(shù)時(shí),傳入標(biāo)識(shí)符'w'或者'wb'表示寫文本文件或?qū)懚M(jìn)制文件,需要的朋友可以參考下2022-11-11Python學(xué)習(xí)之集合的常用方法總結(jié)
集合并不是一種數(shù)據(jù)處理類型,而是一種中間類型。集合(set)是一個(gè)無(wú)序、不重復(fù)的元素序列,經(jīng)常被用來處理兩個(gè)列表進(jìn)行交并差的處理性。本文將詳細(xì)講解集合的一些常用方法,感興趣的可以了解一下2022-03-03python使用 zip 同時(shí)迭代多個(gè)序列示例
這篇文章主要介紹了python使用 zip 同時(shí)迭代多個(gè)序列,結(jié)合實(shí)例形式分析了Python使用zip遍歷迭代長(zhǎng)度相等與不等的序列相關(guān)操作技巧,需要的朋友可以參考下2019-07-07Python Pytorch深度學(xué)習(xí)之核心小結(jié)
今天小編就為大家分享一篇關(guān)于Pytorch核心小結(jié)的文章,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-10-10