滑动验证最新版破解
- 1,打开浏览器,并输入查询内容
- 2,执行js,生成带缺口和不带缺口的验证码图片
- 3,拿到滑动验证码需要移动的距离
- 4,生成滑动轨迹
- 5,拖动滑块到缺口处
- 6,返回html
-
- 结束语:
1,打开浏览器,并输入查询内容
class CrackGeetest():
def __init__(self, url, proxy, word, searchId, bowtonID):
self.url = url
self.word = word # 搜索关键词
self.proxy = proxy # 加上代理IP
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--proxy-server=%s' % self.proxy)
# self.browser = webdriver.Chrome(chrome_options=chrome_options, executable_path='D:\\chromedriver')
self.browser = webdriver.Chrome(chrome_options=chrome_options)
self.wait = WebDriverWait(self.browser, 80)
self.browser.set_page_load_timeout(40)
self.searchId = searchId # 搜索框的ID,用于定位
self.bowtonID = bowtonID # 点击按钮的ID,用于定位
self.threshold = 60 # 验证码图片对比中RGB的差值,可调
self.left = 50 # 验证码图片的对比中的起始坐标,即拖动模块的右边线位置
self.deviation = 7 # 误差值,这个值是多次测试得出的经验值
self.page_count = []
def open(self):
"""
打开浏览器,并输入查询内容
"""
self.browser.maximize_window()
self.browser.get(self.url)
if '无法访问此网站' in self.browser.page_source or '未连接到互联网' in self.browser.page_source or '该网页无法正常运作' in self.browser.page_source: # 判断是否正常打开网页
self.browser.quit()
keyword = self.wait.until(EC.presence_of_element_located((By.ID, self.searchId)))
bowton = self.wait.until(EC.presence_of_element_located((By.ID, self.bowtonID)))
try:
keyword.send_keys(self.word) # 发送关键词
except:
keyword.send_keys(self.word)
try:
bowton.send_keys(Keys.ENTER) # 此处有坑!!!可能打开的窗口大小不同,导致网页上的元素重叠在一起,不能进行点击,因此直接进行Enter键进入
except:
bowton.send_keys(Keys.ENTER)
2,执行js,生成带缺口和不带缺口的验证码图片
def get_image(self):
"""
获取验证码图片
:return: 验证码图片对象
"""
times = random.uniform(3, 5)
times = round(times, 2)
time.sleep(times)
bg_js = 'return document.getElementsByClassName("geetest_canvas_bg geetest_absolute")[0].toDataURL("image/png");' # 带缺口验证码图片js
fullbg_js = 'return document.getElementsByClassName("geetest_canvas_fullbg geetest_fade geetest_absolute")[0].toDataURL("image/png");' # 完整验证码图片js
# 执行 JS 代码并拿到图片 base64 数据
bg_info = self.browser.execute_script(bg_js) # 执行js文件得到带图片信息的图片数据
bg_base64 = bg_info.split(',')[1] # 拿到base64编码的图片信息
bg_bytes = base64.b64decode(bg_base64) # 转为bytes类型
bg_image = Image.open(BytesIO(bg_bytes)) # image读取图片信息
fullbg_info = self.browser.execute_script(fullbg_js) # 执行js文件得到带图片信息的图片数据
fullbg_base64 = fullbg_info.split(',')[1] # 拿到base64编码的图片信息
fullbg_bytes = base64.b64decode(fullbg_base64) # 转为bytes类型
fullbg_image = Image.open(BytesIO(fullbg_bytes)) # image读取图片信息
return bg_image,fullbg_image
3,拿到滑动验证码需要移动的距离
def get_distance(self,image1,image2):
"""
拿到滑动验证码需要移动的距离
:param image1: 没有缺口的图片对象
:param image2: 带缺口的图片对象
:return: 需要移动的距离
"""
i = 0
for i in range(self.left, image1.size[0]):
for j in range(image1.size[1]):
rgb1 = image1.load()[i, j]
rgb2 = image2.load()[i, j]
res1 = abs(rgb1[0] - rgb2[0])
res2 = abs(rgb1[1] - rgb2[1])
res3 = abs(rgb1[2] - rgb2[2])
if not (res1 < self.threshold and res2 < self.threshold and res3 < self.threshold):
distance = i -self.deviation
return distance
logging.debug('未识别出验证码中的不同位置,或图片定位出现异常')
return i # 如果没有识别出不同位置,则象征性的滑动,以刷新下一张验证码
4,生成滑动轨迹
这个轨迹是研究蛮久才出来的,因为极限验证会通过用户滑动轨迹的大数据,经过机器学习,来判定轨迹是机器滑动和人为滑动,之前网上先加速运动,再减速,什么区间震荡轨迹,刚开始还行,后面成功率就会越来越低,我的这个滑动轨迹至今还蛮稳定
def get_track(self,distance):
"""
:param distance:
:return: 滑动轨迹
"""
track = []
current = 0
mid = int(distance * round(random.uniform(0.6, 0.7), 2))
jiansu = distance - mid # 需要减速的距离
# 计算间隔
t = 0.2
# 初速度
v = 0
while current < distance:
if current < mid:
# 设置加速度动态变化
# Chrome 浏览器的加速度
ap = random.uniform(3, 5)
times = round(ap, 2)
a = times
# 初速度v0
v0 = v
v = v0 + a * t
move = v0 * t + 1 / 2 * a * t * t + 0.5
# 当前位移
current += move
# 加入轨迹
track.append(round(move))
else:
a = -1 * (v * v) / (2 * jiansu) #减速的速度
v0 = v
v = v0 + a * t
if distance > 120:
move = v0 * t + 1 / 2 * a * t * t - 1.5 # 1.5,1,0.5都是噪声,因为刚开始的减速距离挺大,为了尽量是最后的轨迹能够到1,就加了一些噪声
elif distance <= 120 and distance >= 60:
move = v0 * t + 1 / 2 * a * t * t - 1
else:
move = v0 * t + 1 / 2 * a * t * t - 0.5
if move < 1: # 减速运动如果后面move会越来越小,如果不让小于1的固定为1的话,有时候会进死循环
move = 1
current += move
track.append(round(move))
return track
5,拖动滑块到缺口处
def move_to_gap(self, slider, track):
"""
拖动滑块到缺口处
:param slider: 滑块
:param track: 轨迹
:return:
"""
ActionChains(self.browser).click_and_hold(slider).perform()
for x in track:
ActionChains(self.browser).move_by_offset(xoffset=x, yoffset=0).perform()
time.sleep(0.5)
ActionChains(self.browser).release().perform()
6,返回html
def check_html(self, html): # 检测一些html,如果成功,就可以返回html,不成功,就可以重试
if 'geetest_success_radar_tip_content' in html:
return True
else:
return False
结束语:
第一次写博客,学艺不精,往各位同仁不要见笑,希望能和各位多多交流,学无止境!!!上面只写了主要步骤,另外还有翻页,重试等没展示。在此申明,此博客只用于学习交流,不得进行非法用途!