爬虫——根据两点坐标生成贝瑟尔曲线滑动路径

本文介绍了一种用于模拟手动操作的算法,GenerateCurve,通过贝塞尔曲线生成从两点到验证码点选区域的平滑轨迹,以避开网站的自动化检测。它适用于Selenium自动化测试中遇到的验证码挑战。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 背景:使用selenium自动化模拟点选验证码的时候,由于直接将鼠标移动到点选点,被对方网站识别为非人为操作轨迹,因此需要从 已知两点 生成类似手动移动的鼠标轨迹。

class GenerateCurve():
    '''根据两点坐标确定一条被瑟尔曲线'''

    def __init__(self, point0, point1, control_point=[], point_nums=random.randint(5, 15), debug=False):
        '''
        :param point0: 起点
        :param point1: 终点
        :param control_point: 控制点
        :param point_nums: 生成曲线坐标点的数量.数量越多图越凹凸不平,越少越平滑
        '''
        self.point0 = point0
        self.point1 = point1
        self.control_point = control_point
        self.point_nums = point_nums
        self.debug = debug

    def getBezierPoints(self):
        '''
        :return:
        '''
        if not self.point_nums:
            self.point_nums = random.randint(1, 6)
        pointList = []
        x1, y1 = int(self.point0[0]), int(self.point0[1])
        x2, y2 = int(self.point1[0]), int(self.point1[1])
        cx, cy = int(self.control_point[0]), int(self.control_point[1])
        for i in range(self.point_nums + 1):
            t = i / self.point_nums
            x = math.pow(1 - t, 2) * x1 + 2 * t * (1 - t) * cx + math.pow(t, 2) * x2
            y = math.pow(1 - t, 2) * y1 + 2 * t * (1 - t) * cy + math.pow(t, 2) * y2
            pointList.append([int(x), int(y)])
        return pointList

    def getControlPoint(self):
        '''
        :return: 控制点
        '''
        if self.control_point:
            return self.control_point

        x0, y0 = int(self.point0[0]), int(self.point0[1])
        x1, y1 = int(self.point1[0]), int(self.point1[1])

        abs_x = abs(x0 - x1) / 2  # 两点横坐标相减绝对值/2
        abs_y = abs(y0 - y1) / 2  # 两点横坐标相减绝对值/2
        # print(abs_y)
        ran_x = random.randint(0, int(abs_x))  # x取随机差值
        ran_y = random.randint(0, int(abs_y))  # y取随机差值

        # print(ran_x, ran_y)
        self.control_point.append((x0 + x1) / 2 + random.choice([-ran_x, +ran_x]))
        self.control_point.append((y0 + y1) / 2 + random.choice([-ran_y, +ran_y]))

    def showRoute(self, pointList):
        '''
        展示曲线走势
        :return:
        '''
        _xx = []
        _yy = []
        for p in pointList:
            _xx.append(p[0])
            _yy.append(p[1])
        plt.plot(_xx, _yy, 'b-')
        plt.show()


    def main(self):
        self.getControlPoint()
        print(self.control_point)
        pointList = self.getBezierPoints()
        if self.debug == True:
            self.showRoute(pointList)
        return pointList

if __name__ == "__main__":
    l = GenerateCurve([50, 268], [367, 485], [], debug=True)
    l.main()
    

轨迹如下如图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值