思路
-
分别截取带缺口的图片和完整的图片
-
对比两张图片获取缺口的位置
-
通过计算获得滑块的移动轨迹
-
移动滑块
一、计算滑块缺口位置
from random import randint
from PIL import Image
# 额外距离, 多走几步,防止机器人判断
another_length = randint(3, 5)
def pixel_compare(image1, image2, x, y):
"""比较色值差异"""
# 取两张图片的像素点
pixel1 = image1.load()[x, y]
pixel2 = image2.load()[x, y]
# 设定阈值
threshold = 60
# 计算RGB色值的差
r = abs(pixel1[0] - pixel2[0])
g = abs(pixel1[1] - pixel2[1])
b = abs(pixel1[2] - pixel2[2])
# print(r, g, b)
# 判断: 若大于阈值,则判断为滑块位置
if r < threshold and g < threshold and b < threshold:
return True
else:
return False
def get_distance(image1, image2):
"""计算偏移量"""
global another_length
i1 = Image.open(image1)
i2 = Image.open(image2)
# 图片中心线
left = 75
# 滑块与边框距离
border = 6
for i in range(left, i1.size[0]):
for j in range(i2.size[1]):
if not pixel_compare(i1, i2, i, j):
left = i
return left - border + another_length
return left - border + another_length
二、根据缺口计算滑块移动路径
from random import randint
# 截图保存路径
save_path = ""
# 额外距离
another_length = randint(3, 5)
def get_track(image1, image2):
"""根据偏移量获取移动轨迹"""
global another_length, save_path
distance = get_distance(image1, image2)
# distance = get_distance_by_full_bg(image1, image2, save_path
if distance > 200:
return [distance]
track = []
# 当前位移
current = 0
mid = distance * 4 / 5
# 计算间隔
t = 0.2
# 初速度
v = 0
while current < distance:
if current < mid:
# 加速度为 5
a = 5
else:
# 加速度为 -10
a = -10
# 初速度
v0 = v
# 当前速度
v = v0 + a * t
# 移动距离
l = v * t + 1 / 2 * a * t ** 2
# 当前位移
current += l
# 加入轨迹, 四舍五入
track.append(round(l))
if track[-1] > 2:
track[-1] = 2
if track[-1] == 2:
track[-1] = 1
# 最后部分偏移
track.append(~another_length + 1)
# 路径增加偏移
index = track.index(1) + 1
length = len(track) - 1
for i in range(5):
# 移动路线修缮,避免移动曲线过于平滑
offset = [num for num in range(-3, 4) if num != 0][randint(0, 4)]
if offset < 0:
add1 = randint(index, length)
add2 = randint(0, length)
else:
add1 = randint(0, length)
add2 = randint(index, length)
track[add1] += offset
track[add2] -= offset
return track
三、移动滑块
from selenium.webdriver.common.action_chains import ActionChains
from random import randint
from time import sleep
def move_slider(website, **kwargs):
"""移动滑块"""
name = kwargs.get('name', '滑块')
xpath = kwargs.get('xpath')
image1 = kwargs.get('image1')
image2 = kwargs.get('image2')
try:
track = get_track(image1, image2)
if track[0] > 200:
return track[0]
# 滑块元素
slider = website.find_element_by_xpath(xpath=xpath)
# 拖拽动作
ActionChains(website).click_and_hold(slider).perform()
sleep(0.15)
for i in track:
# 随机上下浮动鼠标
ActionChains(website).move_by_offset(xoffset=i, yoffset=randint(-2, 2)).perform()
# 释放元素
sleep(1)
ActionChains(website).release(slider).perform()
sleep(1)
# 随机拿开鼠标
ActionChains(website).move_by_offset(xoffset=randint(200, 300), yoffset=randint(200, 300)).perform()
return True
except Exception as e:
return False