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

 背景:使用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()
    

轨迹如下如图

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这是一个经典的八皇后问题,可以使用回溯法进行求解。具体的做法是从第一行开始,按列枚举皇后的位置,并判断当前位置是否合法(即是否与前面的皇后在同一列、同一对角线上)。如果合法则继续往下一行放置皇后,否则回溯到上一行重新确定皇后的位置。 以下是一个Python代码实现: ```python # 判断皇后是否冲突 def conflict(state, nextX): nextY = len(state) for i in range(nextY): if abs(state[i]-nextX) in (0, nextY-i): return True return False # 生成所有合法的皇后位置 def queens(num=8, state=()): for pos in range(num): if not conflict(state, pos): if len(state) == num-1: yield (pos,) else: for result in queens(num, state+(pos,)): yield (pos,) + result # 统计指定列的皇后摆法数 def count_solutions(column): count = 0 for solution in queens(): if solution[0] == column: count += 1 return count # 测试程序,统计第一列的摆法数 print(count_solutions(0)) ``` 在上面的代码中,`queens`函数用来生成所有合法的皇后位置,它是一个递归函数,每次调用时会判断当前行上的每一个位置是否合法,如果合法则继续往下一行放置皇后,否则回溯到上一行重新确定皇后的位置。最终会生成一个元组,表示每个皇后在棋盘上的位置。 `conflict`函数用来判断当前位置是否合法,它会遍历之前放置的所有皇后,判断它们是否与当前皇后在同一列或同一对角线上。 `count_solutions`函数用来统计指定列的皇后摆法数,它会调用`queens`函数生成所有合法的皇后位置,并筛选出第一列为指定列的位置。 测试程序中统计了第一列的摆法数,输出结果为92。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值