网站首页 > 技术文章 正文
前言
本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。
作者:卡卡叮
PS:如有需要Python学习资料的小伙伴可以私信小编
这篇文章主要介绍了python模拟哔哩哔哩滑块登入验证的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
准备工具
- pip3 install PIL
- pip3 install opencv-python
- pip3 install numpy
谷歌驱动
建议指定清华源下载速度会更快点
使用方法 :
pip3 install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple/opencv-python/
谷歌驱动
谷歌驱动下载链接 :http://npm.taobao.org/mirrors/chromedriver/
本篇文章采用的是cv2的Canny边缘检测算法进行图像识别匹配。
Canny边缘检测算法参考链接:https://www.jb51.net/article/185336.htm
具体使用的是Canny的matchTemplate方法进行模糊匹配,匹配方法用CV_TM_CCOEFF_NORMED归一化相关系数匹配。得出的max_loc就是匹配出来的位置信息。从而达到位置的距离。
难点
由于图像采用放大的效果匹配出的距离偏大,难以把真实距离,并存在误差。
由于哔哩哔哩滑块验证进一步采取做了措施,如果滑动时间过短,会导致验证登入失败。所以我这里采用变速的方法,在相同时间内滑动不同的距离。
误差的存在是必不可少的,有时会导致验证失败,这都是正常现象。
流程
1.实例化谷歌浏览器 ,并打开哔哩哔哩登入页面。
2.点击登陆,弹出滑动验证框。
3.全屏截图、后按照尺寸裁剪各两张。
5.模糊匹配两张图片,从而获取匹配结果以及位置信息 。
6.将位置信息与页面上的位移距离转化,并尽可能少的减少误差 。
7.变速的拖动滑块到指定位置,从而达到模拟登入。
效果图
代码实例
库安装好后,然后填写配置区域后即可运行。
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
############ 配置区域 #########
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"]) # 设置为开发者模式
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") # 对整个浏览器页面进行截图
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)) # 对浏览器截图进行裁剪
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)) # 对浏览器截图进行裁剪
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)) # 对浏览器截图进行裁剪
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')
# 调整大小
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('移动的步数: ',distance)
ActionChains(driver).move_by_offset(xoffset=distance, yoffset=0).perform()
sleep(0.25)
ActionChains(driver).release().perform() #松开
# 计算步数
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()
有能力的可以研究一下思路,然后写出更好的解决办法。
猜你喜欢
- 2024-09-27 Linux 理解K8S Deployment配置的详细解释输出
- 2024-09-27 XSLT 元素 x元素是啥
- 2024-09-27 「airTest」 airTest入门与原理 airtest assert
- 2024-09-27 用人脸识别抓取王思聪吃热狗——真香
- 2024-09-27 必学组合函数INDEX和MATCH,真的比VLOOKUP函数好用?分情况,未必
- 2024-09-27 opencv多目标匹配 opencv多目标识别
- 2024-09-27 Python OpenCV 的知识体系梳理 opencv-python-tutorial
- 2024-09-27 「技术分享」截图录屏-截长图的实现原理
- 2024-09-27 视觉信息辅助激光导航AGV的应用 智能agv的激光导航包含
- 2024-09-27 自动点赞工具软件的技术实现(艾思软件)
你 发表评论:
欢迎- 最近发表
-
- 在 Spring Boot 项目中使用 activiti
- 开箱即用-activiti流程引擎(active 流程引擎)
- 在springBoot项目中整合使用activiti
- activiti中的网关是干什么的?(activiti包含网关)
- SpringBoot集成工作流Activiti(完整源码和配套文档)
- Activiti工作流介绍及使用(activiti工作流会签)
- SpringBoot集成工作流Activiti(实际项目演示)
- activiti工作流引擎(activiti工作流引擎怎么用)
- 工作流Activiti初体验及在数据库中生成的表
- Activiti工作流浅析(activiti6.0工作流引擎深度解析)
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)