Selenium Python如何模拟平滑鼠标移动避免被网站检测为爬虫
Selenium模拟自然鼠标移动规避坐标检测方案
核心问题说明
原生Selenium的click()和ActionChains.move_to_element()都是瞬间完成坐标跳转,没有移动过程,很容易被网站通过监听mousemove事件识别为爬虫。
方案1:自定义贝塞尔曲线轨迹移动
通过贝塞尔曲线生成符合人类操作习惯的移动路径,拆分多步小位移逐步移动,每步添加随机延迟。
代码实现示例
import random import time from selenium.webdriver.common.action_chains import ActionChains def human_mouse_move(driver, target_element, offset_range=5): # 获取当前鼠标起始位置,可替换为js获取实际当前坐标 current_x = random.randint(0, 100) current_y = random.randint(0, 100) # 获取目标元素坐标和宽高 target_rect = target_element.rect # 目标点加随机偏移,避免每次精准点击中心 target_x = target_rect['x'] + target_rect['width']/2 + random.randint(-offset_range, offset_range) target_y = target_rect['y'] + target_rect['height']/2 + random.randint(-offset_range, offset_range) # 生成贝塞尔曲线随机控制点 cp_x = current_x + (target_x - current_x) * random.uniform(0.2, 0.8) cp_y = current_y + (target_y - current_y) * random.uniform(0.2, 0.8) + random.randint(-30, 30) # 拆分随机移动步长 steps = random.randint(30, 60) for i in range(steps+1): t = i / steps # 二阶贝塞尔曲线公式计算当前移动坐标 move_x = (1-t)**2 * current_x + 2*(1-t)*t * cp_x + t**2 * target_x move_y = (1-t)**2 * current_y + 2*(1-t)*t * cp_y + t**2 * target_y # 执行单步偏移 ActionChains(driver).move_by_offset(int(move_x - current_x), int(move_y - current_y)).perform() current_x, current_y = int(move_x), int(move_y) # 随机延迟,模拟前快后慢的人类移动特征 time.sleep(random.uniform(0.005, 0.02) * (1 + t)) # 点击前模拟确认目标的停顿 time.sleep(random.uniform(0.1, 0.3)) target_element.click() # 调用示例 findtop = driver.find_element_by_class_name('topbutton') human_mouse_move(driver, findtop) time.sleep(3) findbottom = driver.find_element_by_class_name('bottomButton') human_mouse_move(driver, findbottom)
方案2:使用PyAutoGUI实现系统级鼠标移动
适合本地运行的爬虫场景,PyAutoGUI直接控制操作系统鼠标,移动轨迹完全和真人操作一致,不会被Selenium驱动特征暴露。
代码实现示例
import pyautogui import random from selenium import webdriver # 需先确认浏览器窗口在屏幕中的坐标偏移,计算元素实际屏幕坐标 def system_mouse_move(target_x, target_y): # 自带缓动效果,直接模拟自然移动 pyautogui.moveTo(target_x, target_y, duration=random.uniform(0.3, 0.8), tween=pyautogui.easeOutQuad) pyautogui.click() # 调用示例 findtop = driver.find_element_by_class_name('topbutton') top_rect = findtop.rect # 80为浏览器顶部导航栏高度,可根据实际情况调整 system_mouse_move(top_rect['x'] + 10, top_rect['y'] + 80 + 10)
优化注意事项
- 避免固定移动速度、固定步长,加入随机波动
- 点击位置不要每次都落在元素正中心,增加±5px的随机偏移
- 可以在移动过程中随机插入1-2次100ms以内的小停顿,模拟人手移动的抖动
- 配合undetected-chromedriver使用,可覆盖更多Selenium原生特征检测
内容的提问来源于stack exchange,提问作者Emoyaki
相关产品推荐
相关产品推荐

