UI自动化PlayWright实现滑块验证(滑块轨迹为贝塞尔曲线避免反爬机制)
在现代网络应用中,为了防止恶意爬虫和自动化脚本的攻击,验证码成为了保障安全的重要手段。滑动验证码是其中一种常见的形式,它要求用户通过滑动滑块来完成验证。本文将详细介绍如何使用 Python 编写代码来破解滑动验证码,同时模拟人类的操作轨迹,提高破解的成功率。
·
在现代网络应用中,为了防止恶意爬虫和自动化脚本的攻击,验证码成为了保障安全的重要手段。滑动验证码是其中一种常见的形式,它要求用户通过滑动滑块来完成验证。本文将详细介绍如何使用 Python 编写代码来破解滑动验证码,同时模拟人类的操作轨迹,提高破解的成功率。
整体思路
破解滑动验证码的核心思路分为以下几个步骤:
- 获取背景图和滑动图:从网页中提取背景图和滑动图的 URL,并下载保存到本地。
- 计算滑动距离:使用 OpenCV 库进行模板匹配,找出滑动图在背景图中的位置,从而计算出需要滑动的距离。
- 生成移动轨迹:使用贝塞尔曲线生成模拟人类操作的移动轨迹。
- 模拟鼠标操作:使用 Puppeteer 或类似的工具模拟鼠标的滑动操作,完成验证码的验证。
代码实现
1. 生成贝塞尔曲线的坐标点
import random
import numpy as np
import bezier
def generate_bezier_curve(start_x, end_x, control_points=2):
"""
生成贝塞尔曲线的坐标点
:param start_x: 起始 x 坐标
:param end_x: 结束 x 坐标
:param control_points: 控制点数量
:return: 贝塞尔曲线的 x 坐标列表
"""
nodes = [
[start_x] + [random.uniform(start_x, end_x) for _ in range(control_points)] + [end_x],
[0] * (control_points + 2)
]
curve = bezier.Curve(np.asfortranarray(nodes), degree=control_points + 1)
samples = [curve.evaluate(t)[0][0] for t in [i / 30 for i in range(31)]]
return samples
2. 计算滑动距离
import cv2
import time
def get_move_x(image_path, template_path, image_height, image_width, template_height, template_width):
# 背景图
image = cv2.imread(image_path)
image_resize = cv2.resize(image, (int(image_width), int(image_height)))
# 处理图像,保留大部分白色
ret, thresholded_image = cv2.threshold(image_resize, 220, 255, cv2.THRESH_BINARY)
# 灰度图像
gray_image1 = cv2.cvtColor(thresholded_image, cv2.COLOR_BGR2GRAY)
# 提高对比度
denoised_image1 = cv2.equalizeHist(gray_image1)
# 边缘检测
image_canny = cv2.Canny(denoised_image1, threshold1=500, threshold2=900)
# 滑动图
template = cv2.imread(template_path)
template_resize = cv2.resize(template, (int(template_width), int(template_height)))
template_gray = cv2.cvtColor(template_resize, cv2.COLOR_BGR2GRAY)
denoised_image2 = cv2.equalizeHist(template_gray)
template_canny = cv2.Canny(denoised_image2, threshold1=650, threshold2=900)
# 进行模板匹配
result = cv2.matchTemplate(image_canny, template_canny, cv2.TM_CCOEFF_NORMED)
# 获取匹配结果的位置
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
top_left2 = max_loc
bottom_right2 = (top_left2[0] + template_resize.shape[1], top_left2[1] + template_resize.shape[0])
# 在输入图像上绘制矩形标记
cv2.rectangle(image_resize, top_left2, bottom_right2, (0, 0, 255), 2)
cv2.imwrite('./test/Result' + str(int(time.time())) + '.jpg', image_resize)
# x位置
return max_loc[0]
3. 滑动验证码
def solve_geetest_slider(self):
global resp
element = self.pageObj.locator(".****") #滑块背景图元素定位
expect(element).to_be_visible(timeout=100000)
style = element.get_attribute('style') #获取滑块背景图地址
if style:
start_index = style.find('url("') + 5
end_index = style.find('")', start_index)
if start_index != -1 and end_index != -1:
image_url = style[start_index:end_index]
print(f"Found background image URL: {image_url}")
# 下载并保存图片
resp = requests.get(image_url)
with open('bg.jpeg', 'wb') as f:
f.write(resp.content)
# 滑动图
templateEl = self.pageObj.locator(".****").nth(0) #滑块缺块图元素定位
expect(templateEl).to_be_visible(timeout=100000)
style = templateEl.get_attribute('style') #获取滑块缺块图地址
if style:
start_index = style.find('url("') + 5
end_index = style.find('")', start_index)
if start_index != -1 and end_index != -1:
image_url = style[start_index:end_index]
print(f"Found background image URL: {image_url}")
# 下载并保存图片
resp = requests.get(image_url)
with open('template.png', 'wb') as f:
f.write(resp.content)
# 获取滑动距离
image_height = element.bounding_box()["height"]
image_width = element.bounding_box()["width"]
template_height = templateEl.bounding_box()["height"]
template_width = templateEl.bounding_box()["width"]
print('----------------------------')
print(image_height, image_width, template_height, template_width)
x = get_move_x("bg.jpeg", "template.png", image_height, image_width, template_height, template_width)
# x 加偏移量
print(x)
box = self.pageObj.locator(".*****").bounding_box() #滑道元素定位
self.pageObj.locator(".geetest_btn").nth(0).hover() #滑块元素定位
self.pageObj.mouse.down()
# 移动鼠标
start = 1
end = x + 40
# 使用贝塞尔曲线生成移动轨迹
curve_points = generate_bezier_curve(start, end)
for i, number in enumerate(curve_points):
target_x = box["x"] + number
target_y = box["y"] + random.randint(-10, 10)
# 模拟真实的鼠标移动
self.pageObj.mouse.move(target_x, target_y, steps=4)
# 添加随机的时间间隔
time.sleep(random.uniform(0.05, 0.2))
# 模拟真实的鼠标悬停和点击
self.pageObj.mouse.move(box["x"] + end, box["y"] + random.randint(-10, 10), steps=4)
time.sleep(random.uniform(0.2, 0.5))
self.pageObj.mouse.up()
代码解释
- 生成贝塞尔曲线的坐标点:
generate_bezier_curve函数使用bezier库生成贝塞尔曲线的坐标点,模拟人类的滑动轨迹。 - 计算滑动距离:
get_move_x函数使用 OpenCV 库进行模板匹配,找出滑动图在背景图中的位置,从而计算出需要滑动的距离。 - 解决极验滑动验证码:
solve_geetest_slider函数使用 Playwright 库模拟鼠标的滑动操作,完成验证码的验证。
注意事项
- 此代码仅用于学习和研究目的,请勿用于非法活动。
- 极验验证码可能会不断更新和改进,代码可能需要根据实际情况进行调整。
- 在使用代码时,请确保已经安装了所需的库,如
OpenCV、Playwright、requests等
更多推荐



所有评论(0)