通过 PID 算法模拟手工拖动滑块的轨迹

通过 PID 算法模拟手工拖动滑块的轨迹

首页角色扮演代号轨迹更新时间:2024-06-03
PID 基础概念

PID(Proportional-Integral-Derivative)算法是一种常用的控制算法,主要用于对各种系统和过程进行自动控制。它基于对系统当前状态的反馈信息,通过计算误差信号的比例、积分和导数部分,来决定控制器输出的大小和方向,从而实现对系统的稳定控制。

具体来说,PID算法包括三个部分:

  1. 比例控制(P):根据当前误差信号的大小,直接产生一个与误差成正比的控制输出,用于快速响应系统的变化。
  2. 积分控制(I):将误差信号在一段时间内积累起来,并产生一个与误差积分值成正比的控制输出,用于消除系统的静态误差。
  3. 导数控制(D):根据误差信号的变化率,产生一个与误差变化率成正比的控制输出,用于减小系统的超调和振荡。

这三个控制部分共同作用于系统,使得控制器输出的值能够及时、准确地跟随系统的变化,达到对系统的精确控制。

PID 公式

u(t) = Kp * e(t) Ki * ∫e(t)dt Kd * de(t)/dt

其中,u(t)是控制器的输出值,e(t)是当前时刻的误差信号(设目标值为r(t),实际值为y(t),则e(t)=r(t)-y(t)),Kp、Ki和Kd分别是比例、积分和导数部分的控制参数。这里不对公式做深入解读,感兴趣的朋友们可去查阅相关资料。这里我们重点需了解 P 、I、D 三个参数各自的含义,后续主要通过调整这三个参数来达到目标效果。

轨迹被检测的原因

有些滑块验证存在反爬机制,会出现使用 Selenium 编写滑块移动轨迹后被识别为非人工操作,即使滑块正入缺口也会提示验证失败。为了让轨迹尽可能与人手拖动相似,我们需要注意以下几点:

代码实现

class PositionalPID: """位置式PID系统:位置式指的是将控制器输出与被控对象的位移(位置)进行比较来计算误差,并根据误差大小调整控制器输出的控制方法。在位置式PID系统中,目标是通过控制被控对象的位置来实现精确的控制""" def __init__(self, P, I, D): self.Kp = P self.Ki = I self.Kd = D self.SystemOutput = 0.0 self.ResultValueBack = 0.0 self.PidOutput = 0.0 self.PIDErrADD = 0.0 self.ErrBack = 0.0 def SetInertiaTime(self, InertiaTime, SampleTime): self.SystemOutput = (InertiaTime * self.ResultValueBack SampleTime * self.PidOutput) / ( SampleTime InertiaTime) self.ResultValueBack = self.SystemOutput def SetStepSignal(self, StepSignal): Err = StepSignal - self.SystemOutput KpWork = self.Kp * Err KiWork = self.Ki * self.PIDErrADD KdWork = self.Kd * (Err - self.ErrBack) self.PidOutput = KpWork KiWork KdWork self.PIDErrADD = Err self.ErrBack = Err def count_pid(P, I, D, li): PositionalPid = PositionalPID(P, I, D) PositionalXaxis = [0] PositionalYaxis = [0] # 100 次循环模拟滑块移动一段距离的过程,可调参 for i in range(1, 100): PositionalPid.SetStepSignal(li) PositionalPid.SetInertiaTime(3, 0.1) PositionalYaxis.append(PositionalPid.SystemOutput) PositionalXaxis.append(i) l = [] for i in range(len(PositionalYaxis) - 1): l.append(round(PositionalYaxis[i 1] - PositionalYaxis[i])) return l def get_pid_track(distance): ''' 可调参 ''' return count_pid(0.1, 0.1, 0.1, distance)

算法封装为 PositionalPID.class,可对 P、I、D 三个参数进行调参,如先控制 0.1,之后以试错法增加减少值大小以达到最佳效果。

def slide_verify(driver, expression, distance): """ :param driver: 驱动 :param expression: 滑块元素 :param distance: 滑块到达缺口的距离 :return: chrome Driver """ # 获得PID轨迹 track = get_pid_track(distance) webdriver.ActionChains(driver).click_and_hold(slider_element).perform() for x in track: if (x != 0): # 模拟抖动 offset_y = random.uniform(-2, 2) webdriver.ActionChains(driver).move_by_offset(xoffset=x, yoffset=offset_y).perform() time.sleep(0.5) webdriver.ActionChains(driver).release().perform()

这里通过传入滑块到达缺口的距离得到轨迹数组,同时模拟 Y 轴抖动,遍历数组拖动滑块完成验证。

最后

以上就是通过 PID 算法模拟手工拖动滑块的轨迹

感谢您的阅读,如果喜欢本文欢迎关注和转发,转载需注明出处,本头条号将持续分享IT技术知识。对于文章内容有其他想法或意见建议等,欢迎提出共同讨论共同进步。

查看全文
大家还看了
也许喜欢
更多游戏

Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved