Python實(shí)現(xiàn)滑塊拼圖驗(yàn)證碼詳解
滑動拼圖驗(yàn)證碼可以算是滑塊驗(yàn)證碼的進(jìn)階版本,其驗(yàn)證機(jī)制相對復(fù)雜。本節(jié)將介紹兩種滑動拼圖驗(yàn)證碼:初級版和高級版本。
初級版滑塊拼圖驗(yàn)證碼
- 初級版滑動拼圖驗(yàn)證碼是在普通滑塊驗(yàn)證碼的基礎(chǔ)上增加了隨機(jī)的滑動距離,用戶需要根據(jù)拼圖的缺口位置來決定滑塊的滑動位置。
- 如下左圖所示為一個滑塊拼圖驗(yàn)證碼的起始狀態(tài),注意此時還沒有顯示拼圖和缺口。單擊滑塊后就會出現(xiàn)拼圖和缺口,如下右圖所示。之后會利用這一特性來找到拼圖和缺口的位置。
- 下面開始編寫代碼。首先用Selenium打開網(wǎng)頁,代碼如下:
from selenium import webdriver browser =webdriver.Chrome() url = r'D:\works\python_crawl1\《Python爬蟲(進(jìn)階與進(jìn)通)》代碼匯總\2.驗(yàn)證碼反爬\4.滑動拼圖驗(yàn)證碼\滑動拼圖驗(yàn)證碼初級\index.html' browser.get(url) #用模擬瀏覽器打開網(wǎng)頁
- 然后定位滑塊并模擬單擊滑塊,讓拼圖和缺口顯現(xiàn)出來。雖然此時單擊滑塊會顯示驗(yàn)證失敗,但這是為了幫助我們獲取拼圖和缺口的真實(shí)位置,以計算滑塊需要滑動的距離,代碼如下:
slider = browser.find_element_by_xpath('//*[@id="slideBtn"]') #定位滑塊 slider.click() # 模擬單擊滑塊,讓拼圖和缺口顯現(xiàn)出來 time.sleep(3) #等待3秒
- 接著需要找到缺口的位置,初級版滑動拼圖驗(yàn)證碼可以直接在網(wǎng)頁源代碼中找到。如下圖所示,用元素定位工具選中缺口,在網(wǎng)頁源代碼中查看缺口的left屬性值,即缺口的左邊界到整張圖片的左邊界的距離,這里為135像素。
如下圖所示,用同樣的方法查看拼圖的left屬性值,即拼圖的左邊界到整張圖片的左邊界的距離,這里為2像素。
因?yàn)槠磮D的初始left屬性值始終為2像素,所以只需要提取缺口的left屬性值。這里用正則表達(dá)式來提取,代碼如下:
import re data = browser.page_source #獲取網(wǎng)頁源代碼 p_qk = '<div class="slide-box-shadow".*?left: (.*?)px' #編寫正則表達(dá)式 qk_left = re.findall(p_qk,data,re.S) #提取缺口的left屬性值
獲得qk_left如下:
將缺口和拼圖的left屬性值相減,就可以得到滑塊需要滑動的距離,代碼如下:
distance = float(qk_left[0]) - float(2) #用float()函數(shù)將數(shù)據(jù)都切換為浮點(diǎn)數(shù)(即帶小數(shù)點(diǎn)的數(shù))
計算結(jié)果如下:
計算出滑動距離后,用2.3節(jié)講解的方法進(jìn)行模擬滑動即可,代碼如下:
action = webdriver.ActionChains(browser) # 啟動動作鏈 action.click_and_hold(slider).perform() #按住滑塊 action.move_by_offset(distance,0) #移動滑塊,其中的distance是之前計算出來的需要滑動的距離,第二個參數(shù)0則為y軸方向移動的距離,因?yàn)檫@里不需要y軸方向移動,所以為設(shè)置為0 action.release().perform() #釋放滑塊
完整代碼如下:
# 完整代碼如下 import time from selenium import webdriver # 1.訪問網(wǎng)址 browser =webdriver.Chrome() url = r'D:\works\python_crawl1\《Python爬蟲(進(jìn)階與進(jìn)通)》代碼匯總\2.驗(yàn)證碼反爬\4.滑動拼圖驗(yàn)證碼\滑動拼圖驗(yàn)證碼初級\index.html' browser.get(url) #用模擬瀏覽器打開網(wǎng)頁 # 2.定位滑塊并模擬單擊,讓缺口顯現(xiàn)出來 slider = browser.find_element_by_xpath('//*[@id="slideBtn"]') #定位滑塊 slider.click() # 模擬單擊滑塊,讓拼圖和缺口顯現(xiàn)出來 time.sleep(3) #等待3秒 # 3.獲得缺口位置 data = browser.page_source #獲取網(wǎng)頁源代碼 p_qk = '<div class="slide-box-shadow".*?left: (.*?)px' #編寫正則表達(dá)式 qk_left = re.findall(p_qk,data,re.S) #提取缺口的left屬性值 print(qk_left) # 4.計算滑塊需要滑動的距離 distance = float(qk_left[0]) - float(2) #用float()函數(shù)將數(shù)據(jù)都切換為浮點(diǎn)數(shù)(即帶小數(shù)點(diǎn)的數(shù)) print(distance) # 5.開始滑動 action = webdriver.ActionChains(browser) # 啟動動作鏈 action.click_and_hold(slider).perform() #按住滑塊 action.move_by_offset(distance,0) #移動滑塊,其中的260是之前計算出來的需要滑動的距離 action.release().perform() #釋放滑塊
補(bǔ)充知識點(diǎn)
如果不希望滑動得太快,可以將滑動距離分為3段,讓滑塊分3次滑動,每次滑動后等待一定時間,代碼如下:
x1 = distance / 3 x2 = x1 x3 = distance - x1 - x2 action.move_by_offset(x1,0) time.sleep(1) action.move_by_offset(x2,0) time.sleep(1) action.move_by_offset(x3,0) time.sleep(1) action.release().perform()
高級版滑動拼圖驗(yàn)證碼
- 初級版滑動拼圖驗(yàn)證碼將拼圖和缺口的位置都寫在網(wǎng)頁源代碼中,我們可以直接根據(jù)left屬性值計算滑動距離,從而通過驗(yàn)證。而高級版滑動拼圖驗(yàn)證碼將缺口融入背景圖,我們無法在網(wǎng)頁源代碼中找到拼圖和缺口的位置,這就為這種驗(yàn)證碼的模擬驗(yàn)證增加了不小的難度。
- 人類是通過對比無缺口的圖像和有缺口的圖像,從而計算出滑塊需要滑動的距離。在命令行窗口中執(zhí)行命令“pip install pillow”即可安裝PIL庫。
- 首先用Selenium庫打開網(wǎng)頁,代碼如下:
from selenium import webdriver browser = webdriver.Chrome() url = r'D:\works\python_crawl1\《Python爬蟲(進(jìn)階與進(jìn)通)》代碼匯總\2.驗(yàn)證碼反爬\4.滑動拼圖驗(yàn)證碼\滑動拼圖驗(yàn)證碼高級\index.html' browser.get(url) #用模擬瀏覽器打開網(wǎng)頁
通過XPath表達(dá)式定位驗(yàn)證碼原始圖片,截圖并保存,代碼如下:
browser.find_element_by_xpath('//*[@id="jigsawCanvas"]').screenshot('origin.png') #截圖無缺口圖像
截取到的無缺口圖像如下圖所示:
接著模擬單擊滑塊,會出現(xiàn)缺口,再次截圖并保存,代碼如下:
slider = browser.find_element_by_xpath('//*[@id="jigsawCircle"]') #定位滑塊 slider.click() #模擬單擊滑塊,讓圖像出現(xiàn)缺口 browser.find_element_by_xpath('//*[@id="jigsawCanvas"]').screenshot('after.png') #截取有缺口的圖片
截取到的有缺口圖像如下圖所示:
可以看到,無缺口圖像和有缺口圖像知識缺口處不同,其他地方完全相同。對比兩幅圖像的像素,將不同的像素找出來,就能知道缺口的位置。PIL庫提供的ImageChops模塊可以對比兩幅圖像的異同,并給出缺口的位置。通過如下代碼從PIL庫中導(dǎo)入需要使用的模塊:
from PIL import Image,ImageChops
用Image模塊中的open()函數(shù)打開要對比的兩張截圖,代碼如下:
image_a = Image.open('origin.png').convert('RGB') image_b = Image.open('after.png').convert('RGB')
接著用ImageChops模塊中的difference()函數(shù)對比兩張截圖的像素,并獲取不同之處的坐標(biāo)值(注意,這種驗(yàn)證碼的缺口位置每次都會變化,所以每次獲得的坐標(biāo)值也不一樣)代碼如下:
x = ImageChops.difference(image_a,image_b).getbbox() print(x)
(261, 21, 313, 72)
getbbox()函數(shù)會以元組的形式返回缺口的一組坐標(biāo)值。
distance = x[0] #第1個元素為缺口的左邊界到圖像的左邊界的距離 distance
接著用開發(fā)者工具查看白色圓角矩形的left屬性值,也就是圓角矩形的左邊界到圖像的左邊界的距離,如下圖所示:
將前面獲取的兩個距離相減,就是滑塊需要移動的距離。下面來移動滑塊,代碼如下:
action = webdriver.ActionChains(browser) # 啟動動作鏈 action.click_and_hold(slider).perform() #按住滑塊 action.move_by_offset(distance-10,0) #移動滑塊,其中的260是之前計算出來的需要滑動的距離 action.release().perform() #釋放滑塊
完整代碼如下:
from selenium import webdriver import time from PIL import Image,ImageChops # 1.訪問網(wǎng)址 browser = webdriver.Chrome() url = r'D:\works\python_crawl1\《Python爬蟲(進(jìn)階與進(jìn)通)》代碼匯總\2.驗(yàn)證碼反爬\4.滑動拼圖驗(yàn)證碼\滑動拼圖驗(yàn)證碼高級\index.html' browser.get(url) #用模擬瀏覽器打開網(wǎng)頁 time.sleep(2) # 2.獲取無缺口圖像 browser.find_element_by_xpath('//*[@id="jigsawCanvas"]').screenshot('origin.png') #截圖無缺口圖像 # 3.獲取有缺口圖像 slider = browser.find_element_by_xpath('//*[@id="jigsawCircle"]') #定位滑塊 slider.click() #模擬單擊滑塊,讓圖像出現(xiàn)缺口 browser.find_element_by_xpath('//*[@id="jigsawCanvas"]').screenshot('after.png') #截取有缺口的圖片 # 4.比較兩幅圖像,獲取需要移動的距離 image_a = Image.open('origin.png').convert('RGB') image_b = Image.open('after.png').convert('RGB') x = ImageChops.difference(image_a,image_b).getbbox() print(x) distance = x[0] #第1個元素為缺口的左邊界到圖像的左邊界的距離 distance # 5.開始滑動 action = webdriver.ActionChains(browser) # 啟動動作鏈 action.click_and_hold(slider).perform() #按住滑塊 action.move_by_offset(distance-10,0) #移動滑塊,其中的260是之前計算出來的需要滑動的距離 action.release().perform() #釋放滑塊
運(yùn)行結(jié)果如下,可以看到成功地通過了驗(yàn)證
到此這篇關(guān)于Python實(shí)現(xiàn)滑塊拼圖驗(yàn)證碼詳解的文章就介紹到這了,更多相關(guān)Python滑塊拼圖驗(yàn)證碼內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用python腳本實(shí)現(xiàn)查詢火車票工具
這篇文章主要介紹了使用python腳本實(shí)現(xiàn)查詢火車票工具,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2018-07-07Python產(chǎn)生一個數(shù)值范圍內(nèi)的不重復(fù)的隨機(jī)數(shù)的實(shí)現(xiàn)方法
這篇文章主要介紹了Python產(chǎn)生一個數(shù)值范圍內(nèi)的不重復(fù)的隨機(jī)數(shù)的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08手把手教你實(shí)現(xiàn)Python重試超時裝飾器
這篇文章主要為大家介紹了實(shí)現(xiàn)Python重試超時裝飾器教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2023-05-05Python爬蟲爬取電影票房數(shù)據(jù)及圖表展示操作示例
這篇文章主要介紹了Python爬蟲爬取電影票房數(shù)據(jù)及圖表展示操作,結(jié)合實(shí)例形式分析了Python爬蟲爬取、解析電影票房數(shù)據(jù)并進(jìn)行圖表展示操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2020-03-03darknet框架中YOLOv3對數(shù)據(jù)集進(jìn)行訓(xùn)練和預(yù)測詳解
這篇文章主要為大家介紹了darknet框架中YOLOv3對數(shù)據(jù)集進(jìn)行訓(xùn)練和預(yù)測使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11