鱼C论坛

 找回密码
 立即注册
查看: 2502|回复: 7

[已解决]滑块验证码,会自动往回拉 求助各位大神

[复制链接]
发表于 2020-12-2 22:21:51 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
def get_track(distance):  # 人为滑动是先慢 中快 后慢
    """
    根据偏移量获取移动轨迹
    :param distance: 偏移量
    :return: 移动轨迹列表
    """
    track = []
    current = 0  # 当前位移
    mid = distance * 4 / 5  # 设定一个阈值进行改变加速度
    t = 1  # 计算间隔
    v = 0  # 初速度
    while current < distance:
        if current < mid:
            a = 1  # 加速度为正1
        else:
            a = -2  # 加速度为负2
        v0 = v  # 初速度v0
        v = v0 + a * t  # 当前速度v = v0 + at
        # 移动距离x = v0t + 1/2 * a * t^2
        move = v0 * t + 1 / 2 * a * t * t
        current += move  # 当前位移
        track.append(round(move))  # 加入轨迹
    track.append(distance-sum(track))
    return track
browser = webdriver.Chrome()
action = ActionChains(browser)
#.....
#.....
dic = get_track(220)
for track in dic:
    action.move_by_offset(xoffset=track, yoffset=0).perform()
    time.sleep(1)
action.release().perform()


用selenium进行滑块验证的时候 每当action执行一次move操作 滑块先往右移动一段距离之后自动往回拉一段距离 滑块整个过程就在左右左右移动
最佳答案
2020-12-3 01:43:44
这里去掉perform()就行了
action.move_by_offset(xoffset=track, yoffset=0)

或者循环中新建ActionChains对象
for track in dic:
    action.move_by_offset(xoffset=track, yoffset=0).perform()
    action = ActionChains(browser)
    time.sleep(1)
action.release().perform()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-12-2 22:54:55 | 显示全部楼层
move是小数,round是四舍五入,所以sum(track)的值其实比distance总距离大,因此是负数,track列表就添加一个负数元素,所以就是最后向左移一点。 Screenshot 2020-12-02 225052.jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-2 23:06:36 | 显示全部楼层
suchocolate 发表于 2020-12-2 22:54
move是小数,round是四舍五入,所以sum(track)的值其实比distance总距离大,因此是负数,track列表就添加一 ...

其实最后 是负是为了回调 模拟人拉验证码过头往回来 现在问题是 每次往左拉一次 滑块就会自己往右拉一次 不仅仅是最后
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-12-3 01:43:44 | 显示全部楼层    本楼为最佳答案   
这里去掉perform()就行了
action.move_by_offset(xoffset=track, yoffset=0)

或者循环中新建ActionChains对象
for track in dic:
    action.move_by_offset(xoffset=track, yoffset=0).perform()
    action = ActionChains(browser)
    time.sleep(1)
action.release().perform()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 2 反对 0

使用道具 举报

 楼主| 发表于 2020-12-3 10:54:46 | 显示全部楼层
厉害了 还真的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-3 10:58:51 | 显示全部楼层
YunGuo 发表于 2020-12-3 01:43
这里去掉perform()就行了
action.move_by_offset(xoffset=track, yoffset=0)

想知道为什么
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-12-3 17:40:57 | 显示全部楼层

其实吧对于你这个问题刚开始我也不懂,但谁让我是一个乐于探究的人呢,于是就用你的代码去测试你说的这个问题,发现确实是会来回移动,后来百度了一下,说是ActionChains对象会自动累加位移,需要在循环中新建对象,这个测试了是没有问题,可以正常移动。

但是!我看了源代码后,发现move_by_offset方法好像本身就是用来移动鼠标的,既然如此,为什么还要加个perform?想到就做,最后删掉perform后,一样可以正常移动。

perform方法会执行ActionChains对象中的所有动作链,最大的问题就是在move_by_offset后面加了perform方法(个人理解)。

move_by_offset是将鼠标从上一次鼠标位置移到当前位置(这个方法本身就是根据坐标移动鼠标用的),当循环调用ActionChains对象并再执行动作链,ActionChains对象中还保留着前面位移的动作链,鼠标就会先回到上一次的位置,然后再移到当前位置,就是重复执行了一次上一次位移坐标(你看到的结果就是会左右来回移动)。

把循环中的执行动作链perform方法去掉就是为了不执行ActionChains对象中所有的动作链。你去百度也能找到答案,但几乎所有能找到的答案都是告诉你,在位移后面新建ActionChains对象清除前面的动作链,避免重复累加,就能正常移动。

最后吐槽一下,好多人使用move_by_offset方法移动鼠标都会在后面加一个perform(几乎百分之九十以上),这让我有点想不通。。。为什么要多此一举,这个方法本身就是移动鼠标的,当你加个执行动作链,就会导致重复执行动作,最后还要在后面重建ActionChains对象,才能正常移动,这不是自找麻烦么。
emmm~我只想说,你们随意~

当然,以上只是个人见解~
另外,我也不是大佬~如果有说错的,可以指出来。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-7 17:05:11 | 显示全部楼层
YunGuo 发表于 2020-12-3 17:40
其实吧对于你这个问题刚开始我也不懂,但谁让我是一个乐于探究的人呢,于是就用你的代码去测试你说的这个 ...

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-17 05:48

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表