/**
-
进入淘宝模拟滑动验证码。
-
@returns true - 成功; false - 失败;
*/
function humanLikeSwipe(startX, startY, endX, endY) {
var distance = endX - startX;
var steps = Math.floor(distance / 5) + 10; // 根据距离动态调整步数
var points = [];// 生成模拟人类行为的不规则轨迹
var cx = (startX + endX) / 2;
var cy = startY - 50;for (var i = 0; i <= steps; i++) {
var t = i / steps;
var x = Math.pow(1 - t, 2) * startX + 2 * t * (1 - t) * cx + Math.pow(t, 2) * endX;
var y = Math.pow(1 - t, 2) * startY + 2 * t * (1 - t) * cy + Math.pow(t, 2) * endY;
points.push([x, y]);
}// 添加随机抖动
for (var i = 1; i < points.length - 1; i++) {
points[i][0] += random(-3, 3);
points[i][1] += random(-2, 2);
}// 添加随机延迟点
var insertIndex = Math.floor(steps * 0.6);
points.splice(insertIndex, 0, [points[insertIndex][0], points[insertIndex][1]]);// 执行手势
//log(points);
gesture(500, points);
} 这个成功率不高,是否可以现改进一下
function humanLikeSwipe(startX, startY, endX, endY) {
// 先在起点按住模拟人类准备动作
press(startX, startY, 300 + Math.random() * 200);
var distance = Math.abs(endX - startX);
var duration = 800 + Math.random() * 400; // 总时长800-1200ms更符合人类操作
var steps = Math.max(15, Math.floor(distance / 4)); // 最低15步保证流畅性
// 生成贝塞尔曲线轨迹(二阶)
var controlX = (startX + endX) / 2 + (Math.random() - 0.5) * 100;
var controlY = startY + (Math.random() - 0.5) * 30;
var points = [];
for (var i = 0; i <= steps; i++) {
var t = i / steps;
// 应用速度曲线:开始慢->中间快->结束慢
var easedT = t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
var x = Math.pow(1 - easedT, 2) * startX +
2 * easedT * (1 - easedT) * controlX +
Math.pow(easedT, 2) * endX;
var y = Math.pow(1 - easedT, 2) * startY +
2 * easedT * (1 - easedT) * controlY +
Math.pow(easedT, 2) * endY;
// 添加动态抖动:开始和结束时抖动小,中间抖动大
var jitter = (1 - Math.abs(2 * t - 1)) * 8;
x += (Math.random() - 0.5) * jitter;
y += (Math.random() - 0.5) * (jitter * 0.5);
points.push([x, y]);
}
// 修正:正确传递坐标点(必须展开数组)
var args = [duration];
for (var i = 0; i < points.length; i++) {
args.push(points[i]);
}
// 添加起始点延迟避免被检测
sleep(100 + Math.random() * 50);
return gesture.apply(null, args);
} , press 和 gresture配合起来,滑不动是怎么回事
回答
文档地址 https://docs.hamibot.com/
你的滑动验证码模拟函数有几个关键问题需要改进。主要问题在于gesture()函数的参数传递方式不符合Hamibot API规范,以及人类行为模拟不够自然。以下是优化后的版本:
function humanLikeSwipe(startX, startY, endX, endY) {
// 先在起点按住模拟人类准备动作
press(startX, startY, 300 + Math.random() * 200);
var distance = Math.abs(endX - startX);
var duration = 800 + Math.random() * 400; // 总时长800-1200ms更符合人类操作
var steps = Math.max(15, Math.floor(distance / 4)); // 最低15步保证流畅性
// 生成贝塞尔曲线轨迹(二阶)
var controlX = (startX + endX) / 2 + (Math.random() - 0.5) * 100;
var controlY = startY + (Math.random() - 0.5) * 30;
var points = [];
for (var i = 0; i <= steps; i++) {
var t = i / steps;
// 应用速度曲线:开始慢->中间快->结束慢
var easedT = t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
var x = Math.pow(1 - easedT, 2) * startX +
2 * easedT * (1 - easedT) * controlX +
Math.pow(easedT, 2) * endX;
var y = Math.pow(1 - easedT, 2) * startY +
2 * easedT * (1 - easedT) * controlY +
Math.pow(easedT, 2) * endY;
// 添加动态抖动:开始和结束时抖动小,中间抖动大
var jitter = (1 - Math.abs(2 * t - 1)) * 8;
x += (Math.random() - 0.5) * jitter;
y += (Math.random() - 0.5) * (jitter * 0.5);
points.push([x, y]);
}
// 修正:正确传递坐标点(必须展开数组)
var args = [duration];
for (var i = 0; i < points.length; i++) {
args.push(points[i]);
}
// 添加起始点延迟避免被检测
sleep(100 + Math.random() * 50);
return gesture.apply(null, args);
}
关键改进点:
-
API调用修正:原代码直接传入数组
gesture(500, points)不符合规范。Hamibot的gesture()要求每个坐标点作为独立参数,必须使用apply方法展开数组。 -
预按压动作:添加了
press()模拟人类在滑动前的准备动作(300-500ms),这是人类操作的典型特征。 -
速度曲线优化:采用缓动函数(easedT)模拟人类滑动的"慢-快-慢"特性,而非匀速滑动。
-
动态抖动机制:抖动幅度根据滑动进度动态变化(两端小,中间大),更符合人体运动特征。
-
参数随机化:总时长、控制点位置等关键参数加入随机性,避免模式化。
-
步数下限:确保最低15步,防止短距离滑动过于僵硬。
-
起始延迟:滑动开始前增加随机延迟,模拟人类反应时间。
使用示例:
// 淘宝滑块典型坐标(需根据实际屏幕调整)
var result = humanLikeSwipe(200, 1000, 800, 1000);
if(result) {
toast("滑块验证成功");
} else {
toast("滑块验证失败,尝试重试");
}
注意:验证码系统会持续更新检测策略,建议定期微调参数(特别是持续时间和抖动幅度)。如果仍遇到问题,可以尝试在滑动过程中随机添加1-2个短暂停顿点(通过插入重复坐标点并延长总时长)。
补充回答 1
文档地址 https://docs.hamibot.com/
你遇到的问题很典型:press 和 gesture 配合使用导致滑动失效。这是因为这两个函数的操作逻辑存在冲突:
问题核心原因
press是完整操作:press(x, y, duration)会执行"按下→保持→释放"的完整操作(类似点击)gesture需要独立触摸会话:滑动必须是"按下→移动→释放"的连续过程,不能在已有触摸操作后继续
当先执行 press 时:
- 系统已完成触摸释放
- 后续
gesture无法在已释放状态下开始滑动 - 导致滑动操作被系统忽略
正确解决方案(无需 Root)
function humanLikeSwipe(startX, startY, endX, endY) {
var distance = Math.abs(endX - startX);
var duration = 800 + Math.random() * 400;
var steps = Math.max(15, Math.floor(distance / 4));
// 生成贝塞尔曲线轨迹
var controlX = (startX + endX) / 2 + (Math.random() - 0.5) * 100;
var controlY = startY + (Math.random() - 0.5) * 30;
var points = [];
for (var i = 0; i <= steps; i++) {
var t = i / steps;
var easedT = t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
var x = Math.pow(1 - easedT, 2) * startX +
2 * easedT * (1 - easedT) * controlX +
Math.pow(easedT, 2) * endX;
var y = Math.pow(1 - easedT, 2) * startY +
2 * easedT * (1 - easedT) * controlY +
Math.pow(easedT, 2) * endY;
var jitter = (1 - Math.abs(2 * t - 1)) * 8;
x += (Math.random() - 0.5) * jitter;
y += (Math.random() - 0.5) * (jitter * 0.5);
points.push([x, y]);
}
// 关键修正:移除前置 press,直接使用 gesture 模拟完整滑动
var args = [duration];
for (var i = 0; i < points.length; i++) {
args.push(points[i]);
}
// 添加初始延迟模拟人类反应
sleep(150 + Math.random() * 100);
return gesture.apply(null, args);
}
为什么这样修改有效
- 单一触摸会话:
gesture本身会处理"按下→移动→释放"全过程 - 避免操作冲突:不再有前置触摸操作干扰滑动开始状态
- 自然延迟:
sleep()模拟人类反应时间,而非用press模拟准备动作
高级替代方案(需要 Root)
如果上述方案仍不理想,可以使用 RootAutomator 实现更精准控制:
function humanLikeSwipeRoot(startX, startY, endX, endY) {
var ra = new RootAutomator();
// 按下但不释放
ra.press(startX, startY, 150 + Math.random() * 100);
// 生成路径点(同前)
var points = /* 生成同上 */;
// 滑动过程中
for (var i = 1; i < points.length; i++) {
ra.swipe(
points[i-1][0], points[i-1][1],
points[i][0], points[i][1],
30 + Math.random() * 20
);
// 关键:滑动间隔随机化
sleep(20 + Math.random() * 15);
}
// 最终释放
ra.exit();
return true;
}
使用提示
- 淘宝验证码建议将
steps提高到 20+ - 滑动总时长建议 1000-1500ms(太短易被识别为机器)
- 在滑动中随机插入 1-2 个 100-300ms 的停顿点:
// 在 points 数组中随机位置插入停顿 var pauseIndex = Math.floor(steps * (0.3 + Math.random() * 0.4)); points.splice(pauseIndex, 0, [points[pauseIndex][0], points[pauseIndex][1]]); - 始终在脚本开头添加
auto.waitFor();确保无障碍服务就绪
记住:滑动验证码的核心是模拟"非匀速+随机停顿+自然抖动",而非单纯追求速度。移除前置 press 是解决你当前问题的关键。