python模擬嗶哩嗶哩滑塊登入驗(yàn)證的實(shí)現(xiàn)
準(zhǔn)備工具
- pip3 install PIL
- pip3 install opencv-python
- pip3 install numpy
- 谷歌驅(qū)動(dòng)
建議指定清華源下載速度會(huì)更快點(diǎn)
使用方法 : pip3 install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple/opencv-python/
谷歌驅(qū)動(dòng)
谷歌驅(qū)動(dòng)下載鏈接 :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á)到位置的距離。
難點(diǎn)
- 由于圖像采用放大的效果匹配出的距離偏大,難以把真實(shí)距離,并存在誤差。
- 由于嗶哩嗶哩滑塊驗(yàn)證進(jìn)一步采取做了措施,如果滑動(dòng)時(shí)間過短,會(huì)導(dǎo)致驗(yàn)證登入失敗。所以我這里采用變速的方法,在相同時(shí)間內(nèi)滑動(dòng)不同的距離。
- 誤差的存在是必不可少的,有時(shí)會(huì)導(dǎo)致驗(yàn)證失敗,這都是正?,F(xiàn)象。
流程
1.實(shí)例化谷歌瀏覽器 ,并打開嗶哩嗶哩登入頁面。
2.點(diǎn)擊登陸,彈出滑動(dòng)驗(yàn)證框。
3.全屏截圖、后按照尺寸裁剪各兩張。
5.模糊匹配兩張圖片,從而獲取匹配結(jié)果以及位置信息 。
6.將位置信息與頁面上的位移距離轉(zhuǎn)化,并盡可能少的減少誤差 。
7.變速的拖動(dòng)滑塊到指定位置,從而達(dá)到模擬登入。
效果圖

代碼實(shí)例
庫安裝好后,然后填寫配置區(qū)域后即可運(yùn)行。
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("點(diǎn)擊登入")
# 整個(gè)圖,跟滑塊整個(gè)圖
def screen(screenXpath):
img = WebDriverWait(driver, 20).until(
EC.visibility_of_element_located((By.XPATH, screenXpath))
)
driver.save_screenshot("allscreen.png") # 對整個(gè)瀏覽器頁面進(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()
# 計(jì)算距離
print(max_loc)
dis=str(max_loc).split()[0].split('(')[1].split(',')[0]
x_dis=int(dis)+135
t(x_dis)
#拖動(dòng)滑塊
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('移動(dòng)的步數(shù): ',distance)
ActionChains(driver).move_by_offset(xoffset=distance, yoffset=0).perform()
sleep(0.25)
ActionChains(driver).release().perform() #松開
# 計(jì)算步數(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模擬嗶哩嗶哩滑塊登入驗(yàn)證的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)python 滑塊登入驗(yàn)證內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 使用python+poco+夜神模擬器進(jìn)行自動(dòng)化測試實(shí)例
- Python爬蟲實(shí)現(xiàn)模擬點(diǎn)擊動(dòng)態(tài)頁面
- python模擬點(diǎn)擊網(wǎng)頁按鈕實(shí)現(xiàn)方法
- Python 寫了個(gè)新型冠狀病毒疫情傳播模擬程序
- python模擬預(yù)測一下新型冠狀病毒肺炎的數(shù)據(jù)
- 如何使用python實(shí)現(xiàn)模擬鼠標(biāo)點(diǎn)擊
- python爬蟲-模擬微博登錄功能
- 基于python實(shí)現(xiàn)模擬數(shù)據(jù)結(jié)構(gòu)模型
相關(guān)文章
Python爬取肯德基官網(wǎng)ajax的post請求實(shí)現(xiàn)過程
這篇文章主要介紹了Python爬取肯德基官網(wǎng)ajax的post請求實(shí)現(xiàn)過程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家學(xué)有所得,多多進(jìn)步2021-10-10
如何使用Python的Requests包實(shí)現(xiàn)模擬登陸
這篇文章主要為大家詳細(xì)介紹了使用Python的Requests包模擬登陸,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04

