本文将介绍如何使用Nim语言和Selenium WebDriver来破解极验滑动验证码。我们将详细介绍每一步的实现过程,包括模拟点击、识别滑动缺口、计算位移以及模拟拖动滑块。
识别流程
打开网页并切换为滑动验证模式。
识别滑动缺口的位置,计算位移。
模拟拖动滑块。
若认证失败,重复调用。
实现步骤与代码
初始化
首先,初始化Selenium WebDriver对象并配置参数。极验验证码测试页面的网址如下:
nim
import selenium更多内容联系1436423940
import os
const
border = 6
url = "https://www.geetest.com/type/"
type
CrackGeetest = object
driver: WebDriver
proc open(crack: var CrackGeetest) =
crack.driver.get(url)
proc close(crack: var CrackGeetest) =
crack.driver.quit()
proc change_to_slide(crack: var CrackGeetest) =
let slideOption = crack.driver.wait_for_element_by_css(".products-content ul > li:nth-child(2)", 10)
slideOption.click()
proc get_geetest_button(crack: var CrackGeetest) =
let button = crack.driver.wait_for_element_by_css(".geetest_radar_tip", 10)
button.click()
proc wait_pic(crack: var CrackGeetest) =
crack.driver.wait_for_element_by_css(".geetest_popup_wrap", 10)
proc get_screenshot(crack: var CrackGeetest): string =
let screenshot = crack.driver.screenshot_as_base64()
let screenshotFile = "screenshot.png"
write_file(screenshotFile, decode_base64(screenshot))
return screenshotFile
proc get_position(crack: var CrackGeetest): tuple[top, bottom, left, right: int] =
let img = crack.driver.find_element_by_class_name("geetest_canvas_img")
let location = img.location()
let size = img.size()
return (location.y, location.y + size.height, location.x, location.x + size.width)
proc get_slider(crack: var CrackGeetest): WebElement =
crack.driver.wait_for_element_by_class_name("geetest_slider_button", 10)
proc get_geetest_image(crack: var CrackGeetest, name: string): string =
let (top, bottom, left, right) = crack.get_position()
let screenshotFile = crack.get_screenshot()
let croppedFile = "cropped_" & name & ".png"
discard exec_shell_cmd("convert " & screenshotFile & " -crop " & $right - $left & "x" & $bottom - $top & "+" & $left & "+" & $top & " " & croppedFile)
return croppedFile
proc delete_style(crack: var CrackGeetest) =
crack.driver.execute_script("document.querySelectorAll('canvas')[2].style=''")
proc is_pixel_equal(img1, img2: string, x, y: int): bool =
let cmd = "compare -metric AE -subimage-search -dissimilarity-threshold 0.1 " & img1 & " " & img2 & " diff.png"
let result = exec_shell_cmd(cmd)
return result.exit_code == 0
proc get_gap(crack: var CrackGeetest, img1, img2: string): int =
var left = 60
for i in left..(img1.width):
for j in 0..(img1.height):
if not is_pixel_equal(img1, img2, i, j):
return i
return left
proc get_track(distance: int): seq[int] =
var track: seq[int] = @[]
var current = 0
let mid = distance * 3 div 5
const t = 0.2
var v = 0
let distance = distance + 14
while current < distance:
let a = if current < mid: 2 else: -1.5
let v0 = v
v = v0 + a * t
let move = v0 * t + 0.5 * a * t * t
current += move
track.add(int(move))
return track
proc move_to_gap(crack: var CrackGeetest, slider: WebElement, tracks: seq[int]) =
crack.driver.actions().click_and_hold(slider).perform()
for move in tracks:
crack.driver.actions().move_by_offset(move, 0).perform()
for move in @[-1, -1, -2, -2, -3, -2, -2, -1, -1]:
crack.driver.actions().move_by_offset(move, 0).perform()
crack.shake_mouse()
crack.driver.actions().release().perform()
proc shake_mouse(crack: var CrackGeetest) =
crack.driver.actions().move_by_offset(-3, 0).perform()
crack.driver.actions().move_by_offset(2, 0).perform()
proc crack(crack: var CrackGeetest) =
crack.open()
crack.change_to_slide()
crack.get_geetest_button()
crack.wait_pic()
let slider = crack.get_slider()
let image1 = crack.get_geetest_image("captcha1")
crack.delete_style()
let image2 = crack.get_geetest_image("captcha2")
let gap = crack.get_gap(image1, image2) - border
let track = get_track(gap)
crack.move_to_gap(slider, track)
let success = crack.driver.wait_for_element_with_text("geetest_success_radar_tip_content", "验证成功", 10)
if success != "":
echo "验证成功"
else:
echo "验证失败,重试中..."
crack.crack()
crack.close()
when isMainModule:
var crack = CrackGeetest(driver: newWebDriver())
crack.crack()