破解B站登录的滑动验证
本帖最后由 1830521742 于 2020-3-25 13:09 编辑思路:
1.获取滑动的背景图(B站的滑动模块位置是不固定的,另外源码里又没找到原图,所以就写个循环不停的获取图片,然后PS进行拼接,得出正确的背景图
2.判断原背景图和加了滑动模块的背景图的像素差距来找出x轴的移动距离
3.使用位移公式来求出正常人的滑动模块轨迹
4.使用python+selenium完成模拟人手鼠标的拖拽
5.完成破解
from selenium import webdriver
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import os
from PIL import Image
from selenium.webdriver import ActionChains
import random
def get_snap(driver):
driver.save_screenshot('snap.png')
snap_obj = Image.open('snap.png')
return snap_obj
def get_image(driver):
image = driver.find_element_by_class_name('geetest_canvas_slice')
time.sleep(1)
size = image.size
location = image.location
left = location['x']
top = location['y']
right = left + size['width']
bottom = top + size['height']
snap_obj = get_snap(driver)
img_obj = snap_obj.crop((left, top, right, bottom))
img_obj.save('image1.png')
for i in range(1, 11):
image2 = Image.open('bilibili_image/image{}.png'.format(str(i)))
rgb = (image2.load())
rgb2 = (img_obj.load())
if rgb == rgb2 and rgb == rgb2 and rgb == rgb2:
img_obj.save('image1.png')
return img_obj, image2
def find_jl(image_obj1, image_obj2):
start_x = 58
# 从坐标系(58,10开始往下扫描)
start_y = 10
for x in range(start_x, image_obj1.size):
for y in range(start_y, image_obj1.size - 16):
rgb = image_obj1.load()
rgb2 = image_obj2.load()
if abs(rgb - rgb2) > 60 and abs(rgb - rgb2) > 60 and abs(rgb - rgb2) > 60:
# print(rgb)
return x - 6
def get_tracks(distance):
distance += 20
# v = V0+a*t
# S = v*t+0.5*a*(t**2)
v0 = 0
s = 0
t = 0.4
mid = distance * 3 / 5
forward_tracks = []
back_tracks = [-1, -1, -1, -1, -2, -2, -2, -2, -3, -3, -3, 1]
while s < distance:
if s < mid:
a = 2
else:
a = -3
v = v0
track = v * t + 0.5 * a * (t ** 2)
track = round(track)
v0 = v + a * t
s += track
forward_tracks.append(track)
return forward_tracks, back_tracks
def RUN(driver, track):
slider_button = driver.find_element_by_class_name('geetest_slider_button')
ActionChains(driver).click_and_hold(slider_button).perform()
time.sleep(0.3)
for i in track:
ActionChains(driver).move_by_offset(xoffset=i, yoffset=0).perform()
time.sleep(0.2)
for j in track:
ActionChains(driver).move_by_offset(xoffset=j, yoffset=0).perform()
time.sleep(0.3)
random_number = random.uniform(0, 2)
ActionChains(driver).move_by_offset(xoffset=-random_number, yoffset=0).perform()
time.sleep(random.uniform(0.5, 1))
ActionChains(driver).move_by_offset(xoffset=random_number, yoffset=0).perform()
ActionChains(driver).release().perform()
def main(user_id, password):
os.system("taskkill /f /im chromedriver.exe")
url = 'https://passport.bilibili.com/login'
# 1.登录页面
driver = webdriver.Chrome()
timeout = WebDriverWait(driver, 3)
driver.get(url)
# 2.输入账号和密码点登录
timeout.until(EC.element_to_be_clickable((By.ID, 'login-username')))
user_button = driver.find_element_by_id('login-username')
user_button.send_keys(user_id)
time.sleep(random.uniform(0, 1))
password_button = driver.find_element_by_id('login-passwd')
password_button.send_keys(password)
login_button = driver.find_element_by_class_name('btn-login')
login_button.click()
time.sleep(1)
# 3.得到滑动图片
# for i in range(100):
# if i >= 1:
# driver.find_element_by_class_name('geetest_panel_error_content').click()
# time.sleep(1)
# for j in range(5):
# get_image(driver, str(i)+str(j))
# time.sleep(0.5)
# driver.find_element_by_class_name('geetest_refresh_1').click()
# time.sleep(1)
image_obj = get_image(driver)
# 4.计算滑动距离
distance = find_jl(image_obj, image_obj)
# 5.通过匀加速位移度算法,算出人手滑动轨迹
track = get_tracks(distance)
# 6.执行
RUN(driver, track)
# 7.关闭浏览器
time.sleep(5)
driver.close()
if __name__ == '__main__':
user_id = 'user'
password = 'password'
main(user_id, password)
源码+原图地址:链接: https://pan.baidu.com/s/1Ie2aHUJW8xvh-GQcM5AfYA 提取码: si9f
本帖最后由 liuyq 于 2020-3-25 11:00 编辑
Python 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 16:07:46) on win32
Type "copyright", "credits" or "license()" for more information.
>>>
======== RESTART: C:\Users\liuyq\Desktop\bilibili_\login_bilibili.py ========
Traceback (most recent call last):
File "C:\Users\liuyq\Desktop\bilibili_\login_bilibili.py", line 132, in <module>
main(user_id, password)
File "C:\Users\liuyq\Desktop\bilibili_\login_bilibili.py", line 119, in main
distance = find_jl(image_obj, image_obj)
TypeError: 'NoneType' object is not subscriptable
>>>
运行出错,截图滑动图片位置不正确。 1830521742 发表于 2020-3-25 12:37
能不能发一下是哪个图片验证出错?
是image1这个截图如下图,不是正确的验证图片。
原因我找到了,我是WIN10系统,显示设置是125%,改成100%就可以了,但还是有时候会出现错误提示。
还有个问题就是由于滑动移动太慢而出现验证失败的问题
支持技术分享 666,支持 666,厉害 666 多谢分享 这个牛批了哟,思路好清晰 我就看看不说话。 其实这个思想其他网站改改就能用 厉害了,前来学习 chenmg 发表于 2020-3-25 09:42
其实这个思想其他网站改改就能用
对的!不过这个思路暂时没有解决左边模块和 右边模块贴的太近的问题,原因是左边的模块形状和出现的位置会有变化。 导致像素识别过程容易扫描到左边的模块,进而导致识别错误。解决方式目前是加个循环,来判断拖动结果。如果没成就刷新界面重新识别。