python模拟哔哩哔哩滑块登入验证的实现


Posted in Python onApril 24, 2020

准备工具

  • 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://3water.com/article/185336.htm

具体使用的是Canny的matchTemplate方法进行模糊匹配,匹配方法用CV_TM_CCOEFF_NORMED归一化相关系数匹配。得出的max_loc就是匹配出来的位置信息。从而达到位置的距离。

难点

  • 由于图像采用放大的效果匹配出的距离偏大,难以把真实距离,并存在误差。
  • 由于哔哩哔哩滑块验证进一步采取做了措施,如果滑动时间过短,会导致验证登入失败。所以我这里采用变速的方法,在相同时间内滑动不同的距离。
  • 误差的存在是必不可少的,有时会导致验证失败,这都是正常现象。

流程

1.实例化谷歌浏览器 ,并打开哔哩哔哩登入页面。

2.点击登陆,弹出滑动验证框。

3.全屏截图、后按照尺寸裁剪各两张。

5.模糊匹配两张图片,从而获取匹配结果以及位置信息 。

6.将位置信息与页面上的位移距离转化,并尽可能少的减少误差 。

7.变速的拖动滑块到指定位置,从而达到模拟登入。

效果图

python模拟哔哩哔哩滑块登入验证的实现

代码实例

库安装好后,然后填写配置区域后即可运行。

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()

有能力的可以研究一下思路,然后写出更好的解决办法。

到此这篇关于python模拟哔哩哔哩滑块登入验证的实现的文章就介绍到这了,更多相关python 滑块登入验证内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python获取apk文件URL地址实例
Nov 01 Python
编写Python脚本来实现最简单的FTP下载的教程
May 04 Python
Python计算已经过去多少个周末的方法
Jul 25 Python
python+selenium实现登录账户后自动点击的示例
Dec 22 Python
Python常用数据类型之间的转换总结
Sep 06 Python
利用Python绘制有趣的万圣节南瓜怪效果
Oct 31 Python
new_zeros() pytorch版本的转换方式
Feb 18 Python
深入了解python列表(LIST)
Jun 08 Python
从零开始的TensorFlow+VScode开发环境搭建的步骤(图文)
Aug 31 Python
Python实现钉钉/企业微信自动打卡的示例代码
Feb 02 Python
Python使用random模块实现掷骰子游戏的示例代码
Apr 29 Python
Python内置的数据类型及使用方法
Apr 13 Python
200行python代码实现贪吃蛇游戏
Apr 24 #Python
python Canny边缘检测算法的实现
Apr 24 #Python
python实现文字版扫雷
Apr 24 #Python
离线状态下在jupyter notebook中使用plotly实例
Apr 24 #Python
python3中sys.argv的实例用法
Apr 24 #Python
VScode连接远程服务器上的jupyter notebook的实现
Apr 23 #Python
Python实现仿射密码的思路详解
Apr 23 #Python
You might like
PHP制作3D扇形统计图以及对图片进行缩放操作实例
2014/10/23 PHP
PHP和Shell实现检查SAMBA与NFS Server是否存在
2015/01/07 PHP
php投票系统之增加与删除投票(管理员篇)
2016/07/01 PHP
PHP创建多级目录的两种方法
2016/10/28 PHP
PHP中TP5 上传文件的实例详解
2017/07/31 PHP
如何在Laravel5.8中正确地应用Repository设计模式
2019/11/26 PHP
Mootools 1.2教程 选项卡效果(Tabs)
2009/09/15 Javascript
ExtJs 3.1 XmlTreeLoader Example Error
2010/02/09 Javascript
js跨浏览器实现将字符串转化为xml对象的方法
2013/09/25 Javascript
jquery.validate.js插件使用经验记录
2014/07/02 Javascript
基于Bootstrap实现图片轮播效果
2016/05/22 Javascript
JavaScript中const、var和let区别浅析
2016/10/11 Javascript
JS中检测数据类型的几种方式及优缺点小结
2016/12/12 Javascript
Vue键盘事件用法总结
2017/04/18 Javascript
AngularJS实现页面跳转后自动弹出对话框实例代码
2017/08/02 Javascript
Vue组件化开发思考
2018/02/02 Javascript
angularJS的radio实现单项二选一的使用方法
2018/02/28 Javascript
基于vue实现可搜索下拉框定制组件
2020/03/26 Javascript
jQuery实现获取选中复选框的值实例详解
2018/06/28 jQuery
基于Angularjs-router动态改变Title值的问题
2018/08/30 Javascript
kafka调试中遇到Connection to node -1 could not be established. Broker may not be available.
2019/09/17 Javascript
利用vue3+ts实现管理后台(增删改查)
2020/10/30 Javascript
javascript this指向相关问题及改变方法
2020/11/19 Javascript
react项目从新建到部署的实现示例
2021/02/19 Javascript
Python实现查找数组中任意第k大的数字算法示例
2019/01/23 Python
Python 中包/模块的 `import` 操作代码
2019/04/22 Python
numpy.ndarray 实现对特定行或列取值
2019/12/05 Python
浅析python 动态库m.so.1.0错误问题
2020/05/09 Python
HTML5拖拽的简单实例
2016/05/30 HTML / CSS
SQL Server笔试题
2012/01/10 面试题
数控专业毕业生求职信范文
2013/09/21 职场文书
向领导表决心的话
2014/03/11 职场文书
出生公证书
2015/01/23 职场文书
因身体原因离职的辞职信范文
2015/05/12 职场文书
2016入党积极分子心得体会
2016/01/06 职场文书
python 对图片进行简单的处理
2021/06/23 Python