破解bilibili滑动验证码,pyautogui实现

背景:

本文主要以pyautogui库模拟人操作,替代了selenium.webdriver.Keys,由于pyautogui封装了缓动/渐变函数,所以省去了计算加速度等数学物理公式,使用少量代码便可完成破解工作。

思路:

本文思路来源自https://www.cnblogs.com/98WDJ/p/11050559.html

整体解决步骤:

1、截取带滑块的验证图片

2、截取未带滑块的完整图片

3、对比两张图片的rgb,计算出滑动距离

4、pyautogui模拟人滑动相应距离

文章末尾有完整代码

实现:

首先声明一个全局变量,获取浏览器的工具栏高度

browser_tool_height=driver.execute_script("return window.outerHeight-window.innerHeight")       #工具栏高度

实现一个截图函数,截取图片的方法使用pyautogui的screenshot函数

def screen_shot(pic_name):
    vpic=driver.find_element_by_class_name("geetest_canvas_img")
    vpic_pos_x=vpic.location["x"]       #浏览器中图片的起点x
    vpic_pos_y=vpic.location["y"]       #浏览器中图片的起点y

    vpic_width=vpic.size["width"]       #图片宽
    vpic_height=vpic.size["height"]     #图片高

    # pyautogui.moveTo(vpic_pos_x, vpic_pos_y + browser_tool_height,duration=1)     #这两句可以方便看到自己截取图片的位置,可注释掉
    # pyautogui.moveTo(vpic_pos_x+vpic_width, vpic_pos_y + browser_tool_height+vpic_height,duration=1)

    pyautogui.screenshot(pic_name+'.png', region=(vpic_pos_x, vpic_pos_y + browser_tool_height, vpic_width, vpic_height)) #截屏函数。region为一个元祖,内容为初始x,y和偏移坐标

1、截取带滑块的图片

screen_shot("before")

改变js,显示原图

driver.execute_script("var x=document.getElementsByClassName('geetest_canvas_fullbg geetest_fade geetest_absolute')[0];"
                          "x.style.display='block';"
                          "x.style.opacity=1"
                          )

2、截取不带滑块的原图

screen_shot("end")

3、对比两张图片的rgb,计算出滑动距离

before=Image.open('before.png')     #加载带滑块的图片
end=Image.open('end.png')           #加载不带滑块的图片
def get_distance(img1,img2):
    start_x=54
    gap=5

    threhold=60     #阈值
    for x in range(start_x,img1.size[0]):
        for y in range(img1.size[1]):
            rgb1=img1.load()[x,y]
            rgb2=img2.load()[x,y]
            res1=abs(rgb1[0]-rgb2[0])
            res2=abs(rgb1[1]-rgb2[1])
            res3=abs(rgb1[2]-rgb2[2])
            if not (res1<threhold and res2<threhold and res3<threhold):
                return x-gap
slice_distance=get_distance(before,end)
print("slice_distance: ",slice_distance)

4、pyautogui模拟人滑动相应距离

drag_button=driver.find_element_by_class_name("geetest_slider_button")
drag_button_x=drag_button.location["x"]
drag_button_y=drag_button.location["y"]+browser_tool_height
pyautogui.moveTo(drag_button_x+50,drag_button_y+50)     #鼠标移动到滑动按钮
'''
模拟人先滑过缺口,再滑回来的动作
tween=pyautogui.easeInQuad      开始很慢,不断加速
tween=pyautogui.easeOutQuad     开始很快,不断减速
'''
pyautogui.mouseDown()
pyautogui.moveTo(drag_button_x+50+slice_distance+50,drag_button_y+50,  duration=1, tween=pyautogui.easeInQuad)
pyautogui.moveTo(drag_button_x+50+slice_distance,drag_button_y+50,  duration=1, tween=pyautogui.easeOutQuad)
pyautogui.mouseUp()

完整代码:

from selenium import webdriver
import time
import pyautogui
from PIL import Image


driver=webdriver.Chrome()

driver.get("https://passport.bilibili.com/login")
time.sleep(1)
driver.find_element_by_id("login-username").send_keys("111")
driver.find_element_by_id("login-passwd").send_keys("222")

time.sleep(1)
driver.find_element_by_class_name("btn-login").click()
time.sleep(1)
browser_tool_height=driver.execute_script("return window.outerHeight-window.innerHeight")       #工具栏高度

def screen_shot(pic_name):
    vpic=driver.find_element_by_class_name("geetest_canvas_img")
    vpic_pos_x=vpic.location["x"]       #浏览器中图片的起点x
    vpic_pos_y=vpic.location["y"]       #浏览器中图片的起点y

    vpic_width=vpic.size["width"]       #图片宽
    vpic_height=vpic.size["height"]     #图片高

    # pyautogui.moveTo(vpic_pos_x, vpic_pos_y + browser_tool_height,duration=1)     #这两句可以方便看到自己截取图片的位置,可注释掉
    # pyautogui.moveTo(vpic_pos_x+vpic_width, vpic_pos_y + browser_tool_height+vpic_height,duration=1)

    pyautogui.screenshot(pic_name+'.png', region=(vpic_pos_x, vpic_pos_y + browser_tool_height, vpic_width, vpic_height)) #截屏函数。region为一个元祖,内容为初始x,y和偏移坐标

screen_shot("before")
driver.execute_script("var x=document.getElementsByClassName('geetest_canvas_fullbg geetest_fade geetest_absolute')[0];"
                          "x.style.display='block';"
                          "x.style.opacity=1"
                          )
screen_shot("end")



before=Image.open('before.png')     #加载带滑块的图片
end=Image.open('end.png')           #加载不带滑块的图片
def get_distance(img1,img2):
    start_x=54
    gap=5

    threhold=60     #阈值
    for x in range(start_x,img1.size[0]):
        for y in range(img1.size[1]):
            rgb1=img1.load()[x,y]
            rgb2=img2.load()[x,y]
            res1=abs(rgb1[0]-rgb2[0])
            res2=abs(rgb1[1]-rgb2[1])
            res3=abs(rgb1[2]-rgb2[2])
            if not (res1<threhold and res2<threhold and res3<threhold):
                return x-gap
slice_distance=get_distance(before,end)
print("slice_distance: ",slice_distance)


drag_button=driver.find_element_by_class_name("geetest_slider_button")
drag_button_x=drag_button.location["x"]
drag_button_y=drag_button.location["y"]+browser_tool_height
pyautogui.moveTo(drag_button_x+50,drag_button_y+50)     #鼠标移动到滑动按钮
'''
模拟人先滑过缺口,再滑回来的动作
tween=pyautogui.easeInQuad      开始很慢,不断加速
tween=pyautogui.easeOutQuad     开始很快,不断减速
'''
pyautogui.mouseDown()
pyautogui.moveTo(drag_button_x+50+slice_distance+50,drag_button_y+50,  duration=1, tween=pyautogui.easeInQuad)
pyautogui.moveTo(drag_button_x+50+slice_distance,drag_button_y+50,  duration=1, tween=pyautogui.easeOutQuad)
pyautogui.mouseUp()


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值