DrissionPage鼠标操作:实现用户行为的高级技巧
2026-02-04 05:11:46作者:鲍丁臣Ursa
引言:告别机械点击,迈向智能交互
你是否还在为自动化脚本被网站反爬机制识别而烦恼?是否发现简单的元素点击已无法满足复杂场景需求?本文将系统讲解DrissionPage如何通过高级鼠标操作实现用户行为,帮助你构建更健壮、更可靠的Web自动化程序。读完本文,你将掌握从基础点击到复杂手势的全流程实现方法,学会处理动态元素交互、文件拖拽上传等实战难题,并通过行为模式优化大幅降低被识别风险。
DrissionPage鼠标操作核心架构
DrissionPage(版本4.1.1.2)通过模块化设计提供了两套互补的鼠标操作系统:Clicker类专注于元素点击的精准控制,Actions类则实现复杂的鼠标行为链。这种分层架构既保证了基础操作的便捷性,又为高级交互提供了灵活扩展能力。
classDiagram
class Clicker {
+left(by_js, timeout, wait_stop)
+right()
+middle(get_tab)
+at(offset_x, offset_y, button, count)
+multi(times)
+to_download(save_path, rename, suffix, new_tab, by_js, timeout)
+to_upload(file_paths, by_js)
+for_new_tab(by_js, timeout)
+for_url_change(text, exclude, by_js, timeout)
+for_title_change(text, exclude, by_js, timeout)
-_click(view_x, view_y, button, count)
}
class Actions {
+move_to(ele_or_loc, offset_x, offset_y, duration)
+move(offset_x, offset_y, duration)
+click(on_ele, times)
+r_click(on_ele, times)
+m_click(on_ele, times)
+hold(on_ele)
+release(on_ele)
+scroll(delta_y, delta_x, on_ele)
+key_down(key)
+key_up(key)
+type(keys, interval)
+drag_in(ele_or_loc, files, text, title, baseURL)
+wait(second, scope)
}
Clicker --> ChromiumElement : 操作目标
Actions --> ChromiumPage : 作用页面
Clicker <--|> Actions : 功能互补
基础鼠标操作:从精准点击开始
1. 多样化点击方法
DrissionPage提供了丰富的点击实现,可根据不同场景选择最适合的方式:
| 方法 | 用途 | 关键参数 | 适用场景 |
|---|---|---|---|
left() |
左键点击 | by_js: 是否用JS点击timeout: 等待超时wait_stop: 是否等待元素稳定 |
常规点击、防屏蔽点击 |
right() |
右键点击 | - | 打开上下文菜单 |
middle() |
中键点击 | get_tab: 是否返回新标签页 |
后台打开链接 |
at() |
指定位置点击 | offset_x/offset_y: 偏移坐标button: 鼠标键count: 点击次数 |
验证码点击、特定坐标交互 |
multi() |
多击 | times: 点击次数 |
双击选择、三连击操作 |
基础点击示例:
# 创建页面对象
page = ChromiumPage()
page.get('https://example.com')
# 获取目标元素
btn = page.ele('@text=提交')
# 基础左键点击
btn.click()
# 带延迟的右键点击
btn.clicker.right()
# 中键点击并获取新标签页
new_tab = btn.clicker.middle(get_tab=True)
# 双击元素
btn.clicker.multi(times=2)
# 在元素右下角偏移10px处点击
btn.clicker.at(offset_x=btn.rect.width-10, offset_y=btn.rect.height-10)
2. 智能等待机制
DrissionPage的点击操作内置了智能等待逻辑,解决90%以上的动态元素交互问题:
sequenceDiagram
participant 用户
participant Clicker
participant 元素
participant CDP
用户->>Clicker: 调用left()方法
Clicker->>元素: 检查是否有矩形区域(has_rect)
元素-->>Clicker: 返回坐标信息
Clicker->>元素: 等待元素停止移动(wait_stop)
Clicker->>元素: 检查是否启用(is_enabled)和可见(is_displayed)
Clicker->>元素: 滚动到可见区域(scroll.to_see)
Clicker->>CDP: 调用DOM.getNodeForLocation
CDP-->>Clicker: 返回元素ID验证结果
Clicker->>CDP: 发送Input.dispatchMouseEvent
CDP-->>Clicker: 执行点击操作
高级等待配置:
# 自定义超时和等待逻辑
btn.clicker.left(
by_js=False, # 优先尝试真实点击
timeout=3, # 最长等待3秒
wait_stop=True # 等待元素停止移动
)
# 处理可能被覆盖的元素
try:
btn.clicker.left(by_js=False)
except CanNotClickError:
# fallback到JS点击
btn.clicker.left(by_js=True)
高级鼠标行为:构建用户交互链
1. 鼠标轨迹实现
Actions类提供的鼠标移动方法能实现人类自然的鼠标轨迹,大幅降低被识别为机器人的风险:
# 创建动作链
actions = page.actions
# 移动到元素并点击
actions.move_to(btn, duration=0.8) # 0.8秒内自然移动到按钮
.click() # 点击
.perform() # 执行动作链
# 复杂轨迹示例:三角形路径移动
actions.move_to((100, 100), duration=0.5)
.move_to((300, 100), duration=0.3)
.move_to((200, 300), duration=0.4)
.move_to((100, 100), duration=0.6)
.perform()
DrissionPage采用贝塞尔曲线生成自然轨迹,可通过调整duration参数控制移动速度,使轨迹更接近人类行为特征。
2. 拖拽操作
实现文件拖拽上传或元素拖拽排序:
# 拖拽文件到上传区域
upload_area = page.ele('#upload-area')
# 本地文件拖拽
page.actions.drag_in(
upload_area,
files=['/path/to/file1.jpg', '/path/to/doc.pdf']
).perform()
# 文本拖拽
page.actions.drag_in(
upload_area,
text='https://example.com/data',
title='数据链接',
baseURL='https://example.com'
).perform()
# 元素拖拽排序
item = page.ele('.sortable-item', index=0)
target_pos = page.ele('.sortable-item', index=2).rect.midpoint
page.actions.hold(item) # 按住元素
.move_to(target_pos) # 移动到目标位置
.release() # 释放
.perform()
3. 键盘鼠标组合操作
实现用户的快捷键和组合操作:
# Ctrl+点击多选
page.actions.key_down('ctrl') # 按住Ctrl键
.click(ele1) # 点击第一个元素
.click(ele2) # 点击第二个元素
.key_up('ctrl') # 释放Ctrl键
.perform()
# 输入文本并按Enter
search_box = page.ele('#search')
page.actions.move_to(search_box)
.click()
.input('DrissionPage教程') # 输入文本
.key_down('enter')
.key_up('enter')
.perform()
# 复杂组合键:Ctrl+Shift+A
page.actions.key_down('ctrl')
.key_down('shift')
.key_down('a')
.key_up('a')
.key_up('shift')
.key_up('ctrl')
.perform()
用户行为实现策略
1. 行为模式优化
通过以下策略使自动化行为更接近用户:
mindmap
root(行为实现优化)
时间特征
随机延迟(0.3-1.2秒)
加速/减速移动
思考停顿
空间特征
非直线轨迹
微小抖动
自然偏移
交互特征
预点击悬停
偶发误操作
滚动浏览
环境适应
视口位置感知
元素状态判断
动态调整策略
行为优化代码示例:
import random
from DrissionPage import ChromiumPage
def human_click(ele, min_delay=0.3, max_delay=1.2):
"""实现人类点击行为"""
page = ele.page
# 随机延迟
sleep(random.uniform(min_delay, max_delay))
# 先悬停再点击
page.actions.move_to(ele, duration=random.uniform(0.2, 0.8))
.wait(random.uniform(0.1, 0.3)) # 悬停停顿
.click()
.perform()
# 随机微小移动
if random.random() < 0.3: # 30%概率产生后续小动作
page.actions.move(
offset_x=random.randint(-10, 10),
offset_y=random.randint(-10, 10),
duration=random.uniform(0.1, 0.3)
).perform()
# 使用人类行为点击
page = ChromiumPage()
page.get('https://example.com')
btn = page.ele('@text=提交')
human_click(btn)
2. 复杂场景解决方案
动态加载内容交互:
# 无限滚动加载并点击
def load_and_click():
page = ChromiumPage()
page.get('https://infinite-scroll.com')
last_height = page.run_js('return document.body.scrollHeight')
while True:
# 寻找目标元素
target = page.eles('.item', timeout=0)
if target:
# 使用人类点击模式
human_click(target[-1])
break
# 滚动到底部
page.scroll.to_bottom()
# 等待加载
page.wait(1)
# 检查是否到达页面底部
new_height = page.run_js('return document.body.scrollHeight')
if new_height == last_height:
break
last_height = new_height
文件下载与监控:
# 高级文件下载
download_btn = page.ele('@text=下载报告')
# 配置下载参数
mission = download_btn.clicker.to_download(
save_path='/data/reports', # 保存路径
rename='daily_report', # 文件名
suffix='.pdf', # 文件后缀
timeout=30 # 最长等待30秒
)
# 监控下载进度
if mission.wait():
print(f"文件下载完成: {mission.file_path}")
else:
print("下载失败或超时")
实战案例:构建自动化程序
案例1:电商平台商品抢购
from DrissionPage import ChromiumPage
import random
from time import sleep
def smart_shopping_bot():
# 初始化页面,配置指纹
page = ChromiumPage(
incognito=True,
headless=False,
user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36'
)
# 打开目标页面
page.get('https://example-mall.com/product/12345')
# 实现浏览行为
page.actions.move_to(page.ele('.product-image'), duration=1.2)
.scroll(delta_y=300, duration=0.8) # 向下滚动
.move_to(page.ele('.product-detail'), duration=0.6)
.scroll(delta_y=500, duration=1.0)
.perform()
# 选择规格
color = page.ele('@text=红色')
size = page.ele('@text=L')
# 人类式点击选择
human_click(color)
sleep(random.uniform(0.5, 1.2)) # 思考时间
human_click(size)
# 加入购物车
add_cart = page.ele('#add-to-cart')
human_click(add_cart)
# 等待弹窗并点击确认
confirm_btn = page.ele('@text=去结算', timeout=5)
if confirm_btn:
human_click(confirm_btn)
print("商品已加入购物车并跳转结算")
else:
print("加入购物车失败")
# 执行抢购
smart_shopping_bot()
案例2:复杂表单填写与提交
def fill_complex_form():
page = ChromiumPage()
page.get('https://complex-form.com/apply')
# 填写个人信息
page.ele('#name').input('张三')
page.ele('#id-card').input('110101199001011234')
# 选择出生日期(日期选择器交互)
date_picker = page.ele('#birth-date')
date_picker.click()
# 鼠标操作选择日期
page.actions.move_to(page.ele('.datepicker-year', text='1990'))
.click()
.move_to(page.ele('.datepicker-month', text='1'))
.click()
.move_to(page.ele('.datepicker-day', text='1'))
.click()
.perform()
# 上传身份证照片(拖拽上传)
upload_area = page.ele('#id-card-upload')
page.actions.drag_in(upload_area, files=['/path/to/id-front.jpg']).perform()
# 等待上传完成
page.wait.ele_not_exists('.uploading', timeout=10)
# 提交表单
submit_btn = page.ele('#submit-application')
submit_btn.clicker.for_url_change(timeout=10) # 点击并等待URL变化
print("表单提交成功,已跳转")
# 执行表单填写
fill_complex_form()
最佳实践与性能优化
1. 操作效率提升策略
| 优化方向 | 实现方法 | 性能提升 | 适用场景 |
|---|---|---|---|
| 减少CDP调用 | 批量执行操作 | 30-50% | 密集型点击操作 |
| 预获取元素 | 提前缓存元素引用 | 40-60% | 重复操作同一元素 |
| 关闭不必要监听 | 禁用未使用的事件监听 | 20-30% | 资源紧张环境 |
| 使用原生方法 | 优先使用内置方法而非JS | 15-25% | 简单交互操作 |
性能优化示例:
# 预获取元素并批量操作
def batch_operation():
page = ChromiumPage()
page.get('https://batch-operation.com')
# 预获取所有需要操作的元素
items = page.eles('.list-item')
print(f"找到{len(items)}个项目需要处理")
# 批量选择项目(避免重复查找元素)
for item in items[:5]: # 处理前5个项目
# 使用缓存的元素引用
item.clicker.at(offset_x=10, offset_y=10) # 点击复选框
page.wait(0.1) # 短暂延迟模拟真实操作
print("批量选择完成")
2. 常见问题解决方案
| 问题类型 | 表现特征 | 解决方案 | 代码示例 |
|---|---|---|---|
| 元素遮挡 | 点击无反应但不报异常 | 使用at()方法偏移点击 | ele.clicker.at(offset_x=5, offset_y=5) |
| 动态ID | 元素ID随机变化 | 使用文本或属性选择器 | page.ele('@class=btn-submit:text=提交') |
| 防机器人点击 | 点击后无响应 | 组合鼠标移动和点击 | actions.move_to(ele).wait(0.3).click().perform() |
| 弹出窗口拦截 | 新窗口无法打开 | 使用middle()方法或配置弹窗权限 | page.set.popup_blocker(False) |
复杂问题排查流程:
flowchart TD
A[操作失败] --> B{是否报异常?}
B -->|是| C[查看异常类型]
B -->|否| D[检查元素状态]
C --> E[NoRectError]
C --> F[CanNotClickError]
C --> G[TimeoutError]
E --> H[确保元素可见并刷新]
F --> I[尝试JS点击或偏移点击]
G --> J[增加超时时间或优化选择器]
D --> K[检查is_displayed()]
D --> L[检查is_enabled()]
D --> M[检查z-index层级]
K -->|否| N[滚动到可见区域]
L -->|否| O[查找可用状态元素]
M -->|低| P[使用JS点击或提升层级]
H --> Q[重试操作]
I --> Q
J --> Q
N --> Q
O --> Q
P --> Q
Q --> R[操作成功?]
R -->|是| S[继续流程]
R -->|否| T[记录错误并上报]
总结与展望
DrissionPage提供的鼠标操作API通过底层CDP通信和高级行为实现,实现了接近用户的交互能力。本文详细介绍了从基础点击到复杂手势的全系列操作方法,包括:
- 精准控制:多样化的点击方法和智能等待
登录后查看全文
热门项目推荐
相关项目推荐
Kimi-K2.5Kimi K2.5 是一款开源的原生多模态智能体模型,它在 Kimi-K2-Base 的基础上,通过对约 15 万亿混合视觉和文本 tokens 进行持续预训练构建而成。该模型将视觉与语言理解、高级智能体能力、即时模式与思考模式,以及对话式与智能体范式无缝融合。Python00
GLM-4.7-FlashGLM-4.7-Flash 是一款 30B-A3B MoE 模型。作为 30B 级别中的佼佼者,GLM-4.7-Flash 为追求性能与效率平衡的轻量化部署提供了全新选择。Jinja00
VLOOKVLOOK™ 是优雅好用的 Typora/Markdown 主题包和增强插件。 VLOOK™ is an elegant and practical THEME PACKAGE × ENHANCEMENT PLUGIN for Typora/Markdown.Less00
PaddleOCR-VL-1.5PaddleOCR-VL-1.5 是 PaddleOCR-VL 的新一代进阶模型,在 OmniDocBench v1.5 上实现了 94.5% 的全新 state-of-the-art 准确率。 为了严格评估模型在真实物理畸变下的鲁棒性——包括扫描伪影、倾斜、扭曲、屏幕拍摄和光照变化——我们提出了 Real5-OmniDocBench 基准测试集。实验结果表明,该增强模型在新构建的基准测试集上达到了 SOTA 性能。此外,我们通过整合印章识别和文本检测识别(text spotting)任务扩展了模型的能力,同时保持 0.9B 的超紧凑 VLM 规模,具备高效率特性。Python00
KuiklyUI基于KMP技术的高性能、全平台开发框架,具备统一代码库、极致易用性和动态灵活性。 Provide a high-performance, full-platform development framework with unified codebase, ultimate ease of use, and dynamic flexibility. 注意:本仓库为Github仓库镜像,PR或Issue请移步至Github发起,感谢支持!Kotlin07
compass-metrics-modelMetrics model project for the OSS CompassPython00
项目优选
收起
deepin linux kernel
C
27
11
OpenHarmony documentation | OpenHarmony开发者文档
Dockerfile
525
3.72 K
Ascend Extension for PyTorch
Python
329
391
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
877
578
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
335
162
暂无简介
Dart
764
189
Nop Platform 2.0是基于可逆计算理论实现的采用面向语言编程范式的新一代低代码开发平台,包含基于全新原理从零开始研发的GraphQL引擎、ORM引擎、工作流引擎、报表引擎、规则引擎、批处理引引擎等完整设计。nop-entropy是它的后端部分,采用java语言实现,可选择集成Spring框架或者Quarkus框架。中小企业可以免费商用
Java
12
1
🎉 (RuoYi)官方仓库 基于SpringBoot,Spring Security,JWT,Vue3 & Vite、Element Plus 的前后端分离权限管理系统
Vue
1.33 K
746
🔥LeetCode solutions in any programming language | 多种编程语言实现 LeetCode、《剑指 Offer(第 2 版)》、《程序员面试金典(第 6 版)》题解
Java
67
20
React Native鸿蒙化仓库
JavaScript
302
350