python模擬嗶哩嗶哩滑塊登入驗證的實現(xiàn)
準(zhǔn)備工具
- pip3 install PIL
- pip3 install opencv-python
- pip3 install numpy
- 谷歌驅(qū)動
建議指定清華源下載速度會更快點
使用方法 : pip3 install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple/opencv-python/
谷歌驅(qū)動
谷歌驅(qū)動下載鏈接 :http://npm.taobao.org/mirrors/chromedriver/
前言
本篇文章采用的是cv2的Canny邊緣檢測算法進(jìn)行圖像識別匹配。
Canny邊緣檢測算法參考鏈接:http://www.dbjr.com.cn/article/185336.htm
具體使用的是Canny的matchTemplate方法進(jìn)行模糊匹配,匹配方法用CV_TM_CCOEFF_NORMED歸一化相關(guān)系數(shù)匹配。得出的max_loc就是匹配出來的位置信息。從而達(dá)到位置的距離。
難點
- 由于圖像采用放大的效果匹配出的距離偏大,難以把真實距離,并存在誤差。
- 由于嗶哩嗶哩滑塊驗證進(jìn)一步采取做了措施,如果滑動時間過短,會導(dǎo)致驗證登入失敗。所以我這里采用變速的方法,在相同時間內(nèi)滑動不同的距離。
- 誤差的存在是必不可少的,有時會導(dǎo)致驗證失敗,這都是正?,F(xiàn)象。
流程
1.實例化谷歌瀏覽器 ,并打開嗶哩嗶哩登入頁面。
2.點擊登陸,彈出滑動驗證框。
3.全屏截圖、后按照尺寸裁剪各兩張。
5.模糊匹配兩張圖片,從而獲取匹配結(jié)果以及位置信息 。
6.將位置信息與頁面上的位移距離轉(zhuǎn)化,并盡可能少的減少誤差 。
7.變速的拖動滑塊到指定位置,從而達(dá)到模擬登入。
效果圖
代碼實例
庫安裝好后,然后填寫配置區(qū)域后即可運行。
from PIL import Image from time import sleep from selenium import webdriver from selenium.webdriver import ActionChains from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import cv2 import numpy as np import math ############ 配置區(qū)域 ######### zh='' #賬號 pwd='' #密碼 # chromedriver的路徑 chromedriver_path = "C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe" ####### end ######### options = webdriver.ChromeOptions() options.add_argument('--no-sandbox') options.add_argument('--window-size=1020,720') # options.add_argument('--start-maximized') # 瀏覽器窗口最大化 options.add_argument('--disable-gpu') options.add_argument('--hide-scrollbars') options.add_argument('test-type') options.add_experimental_option("excludeSwitches", ["ignore-certificate-errors", "enable-automation"]) # 設(shè)置為開發(fā)者模式 driver = webdriver.Chrome(options=options, executable_path=chromedriver_path) driver.get('https://passport.bilibili.com/login') # 登入 def login(): driver.find_element_by_id("login-username").send_keys(zh) driver.find_element_by_id("login-passwd").send_keys(pwd) driver.find_element_by_css_selector("#geetest-wrap > div > div.btn-box > a.btn.btn-login").click() print("點擊登入") # 整個圖,跟滑塊整個圖 def screen(screenXpath): img = WebDriverWait(driver, 20).until( EC.visibility_of_element_located((By.XPATH, screenXpath)) ) driver.save_screenshot("allscreen.png") # 對整個瀏覽器頁面進(jìn)行截圖 left = img.location['x']+160 #往右 top = img.location['y']+60 # 往下 right = img.location['x'] + img.size['width']+230 # 往左 bottom = img.location['y'] + img.size['height']+110 # 往上 im = Image.open('allscreen.png') im = im.crop((left, top, right, bottom)) # 對瀏覽器截圖進(jìn)行裁剪 im.save('1.png') print("截圖完成1") screen_two(screenXpath) screen_th(screenXpath) matchImg('3.png','2.png') # 滑塊部分圖 def screen_two(screenXpath): img = WebDriverWait(driver, 20).until( EC.visibility_of_element_located((By.XPATH, screenXpath)) ) left = img.location['x'] + 160 top = img.location['y'] + 80 right = img.location['x'] + img.size['width']-30 bottom = img.location['y'] + img.size['height'] + 90 im = Image.open('allscreen.png') im = im.crop((left, top, right, bottom)) # 對瀏覽器截圖進(jìn)行裁剪 im.save('2.png') print("截圖完成2") # 滑塊剩余部分圖 def screen_th(screenXpath): img = WebDriverWait(driver, 20).until( EC.visibility_of_element_located((By.XPATH, screenXpath)) ) left = img.location['x'] + 220 top = img.location['y'] + 60 right = img.location['x'] + img.size['width']+230 bottom = img.location['y'] + img.size['height'] +110 im = Image.open('allscreen.png') im = im.crop((left, top, right, bottom)) # 對瀏覽器截圖進(jìn)行裁剪 im.save('3.png') print("截圖完成3") #圖形匹配 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) # 畫圈 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('windows'+str(max_loc), imstack) cv2.waitKey(0) cv2.destroyAllWindows() # 計算距離 print(max_loc) dis=str(max_loc).split()[0].split('(')[1].split(',')[0] x_dis=int(dis)+135 t(x_dis) #拖動滑塊 def t(distances): draggable = driver.find_element_by_css_selector('div.geetest_slider.geetest_ready > div.geetest_slider_button') ActionChains(driver).click_and_hold(draggable).perform() #抓住 print(driver.title) num=getNum(distances) sleep(3) for distance in range(1,int(num)): print('移動的步數(shù): ',distance) ActionChains(driver).move_by_offset(xoffset=distance, yoffset=0).perform() sleep(0.25) ActionChains(driver).release().perform() #松開 # 計算步數(shù) def getNum(distances): p = 1+4*distances x1 = (-1 + math.sqrt(p)) / 2 x2 = (-1 - math.sqrt(p)) / 2 print(x1,x2) if x1>=0 and x2<0: return x1+2 elif(x1<0 and x2>=0): return x2+2 else: return x1+2 def main(): login() sleep(5) screenXpath = '/html/body/div[2]/div[2]/div[6]/div/div[1]/div[1]/div/a/div[1]/div/canvas[2]' screen(screenXpath) sleep(5) if __name__ == '__main__': main()
有能力的可以研究一下思路,然后寫出更好的解決辦法。
到此這篇關(guān)于python模擬嗶哩嗶哩滑塊登入驗證的實現(xiàn)的文章就介紹到這了,更多相關(guān)python 滑塊登入驗證內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python爬取肯德基官網(wǎng)ajax的post請求實現(xiàn)過程
這篇文章主要介紹了Python爬取肯德基官網(wǎng)ajax的post請求實現(xiàn)過程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家學(xué)有所得,多多進(jìn)步2021-10-10如何使用Python的Requests包實現(xiàn)模擬登陸
這篇文章主要為大家詳細(xì)介紹了使用Python的Requests包模擬登陸,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-04-04