基于Selenium模块实现滑块验证码破解
前言
有些网站页面会在 访问时进行滑块验证,针对此问题,此篇文章中会介绍如何基于 Selenium 模块实现滑块验证码的破解 ,并以模拟登录豆瓣网,破解其滑块验证码 为例进行讲解。
正文
1、滑块验证码破解原理
使用 Selenium 模块 完全模拟人的行为,按住滑块,移动到缺口位置。
2、滑块验证码破解步骤
- 先将滑块一次性快速移动到某一位置,再滑块位置到缺口位置的距离划分为五份等距离
- 前4/5的距离快速滑动
- 后1/5的距离先匀加速移动,再匀减速移动,最终到达缺口位置
注意:以上步骤完全模拟人的行为,如果滑动过快会被网站认定为爬虫程序
3、滑块验证码破解-加速度函数
针对步骤2、3中的前4/5的距离快速滑动,后1/5的距离先匀加速移动,再匀减速移动,最终到达缺口位置,需要一个加速度函数来实现此功能
# 加速度函数
def get_tracks(distance):
"""
拿到移动轨迹,模拟人的滑动行为,先匀加速后匀减速
匀变速运动基本公式:
1.v=v₀+at
2.s=v₀t+1/2*at²
:param distance:滑块一次性快速移动到某一位置后剩下的距离,进行五等分
:return:位置/轨迹列表,列表内的一个元素代表0.3s的位移
"""
v = 0 # 初速度
t = 0.3 # 单位时间为0.3s来统计轨迹,轨迹即0.3内的位移
tracks = [] # 位置/轨迹列表,列表内的一个元素代表0.3s的位移
current = 0 # 当前的位移
mid = distance * 4 / 5 # 到达mid值开始减速,前4/5匀加速,后1/5匀减速
while current < distance:
if current < mid: # 加速度越小,单位时间内的位移越小,模拟的轨迹就越多越详细
a = 2
else:
a = -3
v0 = v # 初速度
s = v0 * t + 0.5 * a * (t ** 2) # 0.3s内的位移
current += s # 当前的位置
tracks.append(round(s)) # 添加到轨迹列表
v = v0 + a * t # 速度已经达到v,该速度作为下次的初速度
return tracks # tracks:[第1个0.3s的移动距离,第2个0.3s的移动距离,......]
4、滑块验证码破解案例
-
案例需求:豆瓣网登录界面输入用户名密码后,进入滑块验证界面后使用 Selenium+Chrome 进行节点的定位并进行移动。
-
url地址:https://www.douban.com/
-
如何进入滑块验证界面可参考:【Python_Selenium学习笔记(七)】基于Selenium模块实现切换frame
-
切换到滑块验证iframe子页面:
'//*[@id="tcaptcha_iframe_dy"]'
-
按住开始滑动位置按钮 - 先移动180个像素:
start_node = driver.find_element(By.XPATH, '//*[@id="tcOperation"]/div[6]') ActionChains(driver).click_and_hold(on_element=start_node).perform() # 点击并按住 ActionChains(driver).move_to_element_with_offset(to_element=start_node, xoffset=145, yoffset=0).perform() # 移动到距离某一节点多少距离的位置 time.sleep(1)
-
使用加速度函数移动剩下的距离:
tracks = get_tracks(45) for track in tracks: ActionChains(driver).move_by_offset(xoffset=track, yoffset=0).perform() # move_by_offset:鼠标从当前位置移动多少的距离
-
延迟释放鼠标:release()
time.sleep(1) ActionChains(driver).release().perform()
-
完整代码:
import time from selenium import webdriver from selenium.webdriver import ActionChains from selenium.webdriver.common.by import By # 加速度函数 def get_tracks(distance): """ 拿到移动轨迹,模拟人的滑动行为,先匀加速后匀减速 匀变速运动基本公式: 1.v=v₀+at 2.s=v₀t+1/2*at² :param distance:滑块一次性快速移动到某一位置后剩下的距离,进行五等分 :return:位置/轨迹列表,列表内的一个元素代表0.3s的位移 """ v = 0 # 初速度 t = 0.3 # 单位时间为0.3s来统计轨迹,轨迹即0.3内的位移 tracks = [] # 位置/轨迹列表,列表内的一个元素代表0.3s的位移 current = 0 # 当前的位移 mid = distance * 4 / 5 # 到达mid值开始减速,前4/5匀加速,后1/5匀减速 while current < distance: if current < mid: # 加速度越小,单位时间内的位移越小,模拟的轨迹就越多越详细 a = 2 else: a = -3 v0 = v # 初速度 s = v0 * t + 0.5 * a * (t ** 2) # 0.3s内的位移 current += s # 当前的位置 tracks.append(round(s)) # 添加到轨迹列表 v = v0 + a * t # 速度已经达到v,该速度作为下次的初速度 return tracks # tracks:[第1个0.3s的移动距离,第2个0.3s的移动距离,......] driver = webdriver.Chrome() # 创建浏览器对象 driver.get(url="https://www.douban.com/") # 1、先切换到 iframe子页面 iframe_node = driver.find_element(By.XPATH, '//*[@id="anony-reg-new"]/div/div[1]/iframe') # //*[@id="anony-reg-new"]/div/div[1]/iframe driver.switch_to.frame(iframe_node) # 切换到 iframe子页面 # /html/body/div[1] # 2、找到密码登录 并点击 driver.find_element(By.XPATH, '/html/body/div[1]/div[1]/ul[1]/li[2]').click() # 3、找到找到手机号/邮箱、密码的输入框,和登录豆瓣按键 username = driver.find_element(By.XPATH, '//*[@id="username"]') username.send_keys("13885124596") password = driver.find_element(By.XPATH, '//*[@id="password"]') password.send_keys("123456") driver.find_element(By.XPATH, '/html/body/div[1]/div[2]/div[1]/div[5]/a').click() time.sleep(1) # 4、切换到新的iframe子页面-滑块验证 verify_iframe = driver.find_element(By.XPATH, '//*[@id="tcaptcha_iframe_dy"]') # //*[@id="tcaptcha_iframe_dy"] driver.switch_to.frame(verify_iframe) # 5、按住开始滑动位置按钮 - 先移动180个像素 start_node = driver.find_element(By.XPATH, '//*[@id="tcOperation"]/div[6]') ActionChains(driver).click_and_hold(on_element=start_node).perform() # 点击并按住 ActionChains(driver).move_to_element_with_offset(to_element=start_node, xoffset=145, yoffset=0).perform() # 移动到距离某一节点多少距离的位置 time.sleep(1) # 6、使用加速度函数移动剩下的距离 tracks = get_tracks(45) for track in tracks: ActionChains(driver).move_by_offset(xoffset=track, yoffset=0).perform() # move_by_offset:鼠标从当前位置移动多少的距离 # 7、延迟释放鼠标:release() time.sleep(1) ActionChains(driver).release().perform() time.sleep(1)
-
实现效果