本文主要使用python + selenium来破解旋转突破的验证码;其中用到numpy和OpenCV(CV2)来进行图片拼接,转换,遮罩,识别等,共分三个部分:
js_code = '''
w1 = document.getElementsByClassName('control-tips')[0].clientWidth; //滑块容器宽
w2 = document.getElementsByClassName('control-btn slideDragBtn')[0].offsetWidth; //滑块宽
zoom = (w2-w1)/360;
return zoom
'''
zoom = driver.execute_js(js_code)
distance = int(zoom * angle) # 角度转换为滑块拖动距离,
# distance = int(zoom * (360-angle)) 有的滑块拖动是逆时针旋转则angle = 360-angle
def get_track(distance:int)->list:
'''
根据偏移量distance获取移动轨迹
返回:
移动轨迹
'''
track = [] # 移动轨迹
current = 0 # 当前位移
mid = distance * 2 / 3 # 减速阈值
t = 0.2 # 计算间隔
v = 0 # 初速度
while current < distance:
if current < mid:
a = random.randint(30, 40) # 加速度为正
else:
a = -random.randint(40, 80) # 加速度为负
v0 = v # 初速度v0
v = v0 + a * t # 当前速度v = v0 + at
# 移动距离x = v0t + 1/2 * a * t^2
move = v0 * t + 1 / 2 * a * t * t
current += move # 当前位移
track.append(round(move)) # 加入轨迹
rest = sum(track) - distance
while rest > 0:
if rest > 3:
max = 3
else:
max = rest
move = -random.randint(1, max)
track.append(round(move))
rest += move
if rest <= 2:
move = -rest
track.append(round(move))
break
return track
拖动滑块的一个坑就是,我们有时候只会关注到x轴拖动,并尽可能模拟加速再减速的拖动过程防止被机器设别,但是有的网址会检测y轴的变化(正常人拖动时,y轴不可能完全不移动),我当时为了这坑忙活了一整天,在x轴上模拟各种方法,就是不被机器识别,最后才找到了症结所在
track_list = get_track(distance)
slide_button = driver.find_element_by_xpath(
'//div[@class="control-btn slideDragBtn"]')
# 开始拖拽滑块
ActionChains(driver).click_and_hold(slide_button).perform()
for track in track_list:
ActionChains(driver).move_by_offset(
xoffset=track, yoffset=random.randint(0, 5) - 3).perform() # 特别注意yoffset要随机变动,否则会被识别为机器拖动
# 释放滑块
ActionChains(driver).release(slide_button).perform()
至此,旋转图片验证码的识别和破解执行完毕!