@skrillex1224/playwright-toolkit 2.1.276 → 2.1.278
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.js +22 -1
- package/dist/browser.js.map +3 -3
- package/dist/index.cjs +690 -125
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +690 -125
- package/dist/index.js.map +4 -4
- package/index.d.ts +12 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -40,9 +40,11 @@ __export(constants_exports, {
|
|
|
40
40
|
ActorInfo: () => ActorInfo,
|
|
41
41
|
Code: () => Code,
|
|
42
42
|
Device: () => Device,
|
|
43
|
+
Mode: () => Mode,
|
|
43
44
|
PresetOfLiveViewKey: () => PresetOfLiveViewKey,
|
|
44
45
|
Status: () => Status,
|
|
45
|
-
normalizeDevice: () => normalizeDevice
|
|
46
|
+
normalizeDevice: () => normalizeDevice,
|
|
47
|
+
normalizeMode: () => normalizeMode
|
|
46
48
|
});
|
|
47
49
|
var Code = {
|
|
48
50
|
Success: 0,
|
|
@@ -62,6 +64,10 @@ var Device = Object.freeze({
|
|
|
62
64
|
Desktop: "desktop",
|
|
63
65
|
Mobile: "mobile"
|
|
64
66
|
});
|
|
67
|
+
var Mode = Object.freeze({
|
|
68
|
+
Default: "default",
|
|
69
|
+
CloakBrowser: "cloakbrowser"
|
|
70
|
+
});
|
|
65
71
|
var normalizeDevice = (value, fallback = Device.Desktop) => {
|
|
66
72
|
const normalizedFallback = String(fallback || "").trim().toLowerCase() === Device.Mobile ? Device.Mobile : Device.Desktop;
|
|
67
73
|
const raw = String(value || "").trim().toLowerCase();
|
|
@@ -69,6 +75,13 @@ var normalizeDevice = (value, fallback = Device.Desktop) => {
|
|
|
69
75
|
if (raw === Device.Desktop) return Device.Desktop;
|
|
70
76
|
return normalizedFallback;
|
|
71
77
|
};
|
|
78
|
+
var normalizeMode = (value, fallback = Mode.Default) => {
|
|
79
|
+
const normalizedFallback = String(fallback || "").trim().toLowerCase() === Mode.CloakBrowser ? Mode.CloakBrowser : Mode.Default;
|
|
80
|
+
const raw = String(value || "").trim().toLowerCase();
|
|
81
|
+
if (raw === Mode.CloakBrowser) return Mode.CloakBrowser;
|
|
82
|
+
if (raw === Mode.Default) return Mode.Default;
|
|
83
|
+
return normalizedFallback;
|
|
84
|
+
};
|
|
72
85
|
var createActorInfo = (info) => {
|
|
73
86
|
const normalizeDomain = (value) => {
|
|
74
87
|
if (!value) return "";
|
|
@@ -2477,8 +2490,7 @@ var Utils = {
|
|
|
2477
2490
|
}
|
|
2478
2491
|
};
|
|
2479
2492
|
|
|
2480
|
-
// src/anti-cheat.js
|
|
2481
|
-
var logger5 = createInternalLogger("AntiCheat");
|
|
2493
|
+
// src/internals/anti-cheat/default.js
|
|
2482
2494
|
var BASE_CONFIG = Object.freeze({
|
|
2483
2495
|
locale: "zh-CN",
|
|
2484
2496
|
acceptLanguage: "zh-CN,zh;q=0.9",
|
|
@@ -2513,7 +2525,7 @@ function buildFingerprintOptions({ locale = BASE_CONFIG.locale, browserMajorVers
|
|
|
2513
2525
|
}
|
|
2514
2526
|
return options;
|
|
2515
2527
|
}
|
|
2516
|
-
var
|
|
2528
|
+
var DefaultAntiCheat = {
|
|
2517
2529
|
/**
|
|
2518
2530
|
* 获取统一的基础配置
|
|
2519
2531
|
*/
|
|
@@ -2550,6 +2562,44 @@ var AntiCheat = {
|
|
|
2550
2562
|
}
|
|
2551
2563
|
};
|
|
2552
2564
|
|
|
2565
|
+
// src/internals/anti-cheat/cloakbrowser.js
|
|
2566
|
+
var CloakBrowserAntiCheat = DefaultAntiCheat;
|
|
2567
|
+
|
|
2568
|
+
// src/internals/toolkit-mode.js
|
|
2569
|
+
var currentMode = Mode.Default;
|
|
2570
|
+
var getToolkitMode = () => currentMode;
|
|
2571
|
+
var setToolkitMode = (mode = Mode.Default) => {
|
|
2572
|
+
currentMode = normalizeMode(mode, Mode.Default);
|
|
2573
|
+
return currentMode;
|
|
2574
|
+
};
|
|
2575
|
+
|
|
2576
|
+
// src/anti-cheat.js
|
|
2577
|
+
var resolveAntiCheatDelegate = () => getToolkitMode() === Mode.CloakBrowser ? CloakBrowserAntiCheat : DefaultAntiCheat;
|
|
2578
|
+
var callAntiCheat = (method, ...args) => {
|
|
2579
|
+
const delegate = resolveAntiCheatDelegate();
|
|
2580
|
+
if (typeof delegate?.[method] !== "function") {
|
|
2581
|
+
throw new Error(`AntiCheat.${method} is not available in ${getToolkitMode()} mode`);
|
|
2582
|
+
}
|
|
2583
|
+
return delegate[method](...args);
|
|
2584
|
+
};
|
|
2585
|
+
var AntiCheat = {
|
|
2586
|
+
getBaseConfig() {
|
|
2587
|
+
return callAntiCheat("getBaseConfig");
|
|
2588
|
+
},
|
|
2589
|
+
getFingerprintGeneratorOptions(options = {}) {
|
|
2590
|
+
return callAntiCheat("getFingerprintGeneratorOptions", options);
|
|
2591
|
+
},
|
|
2592
|
+
getLaunchArgs(options = {}) {
|
|
2593
|
+
return callAntiCheat("getLaunchArgs", options);
|
|
2594
|
+
},
|
|
2595
|
+
getTlsFingerprintOptions(userAgent = "", acceptLanguage = "", options = {}) {
|
|
2596
|
+
return callAntiCheat("getTlsFingerprintOptions", userAgent, acceptLanguage, options);
|
|
2597
|
+
},
|
|
2598
|
+
applyLocaleHeaders(headers, acceptLanguage = "") {
|
|
2599
|
+
return callAntiCheat("applyLocaleHeaders", headers, acceptLanguage);
|
|
2600
|
+
}
|
|
2601
|
+
};
|
|
2602
|
+
|
|
2553
2603
|
// src/device-input.js
|
|
2554
2604
|
var resolveDeviceFromPage = (page) => normalizeDevice(page?.[PageRuntimeStateKey]?.device);
|
|
2555
2605
|
var assertPage = (page, method) => {
|
|
@@ -3103,7 +3153,7 @@ var DeviceView = {
|
|
|
3103
3153
|
// src/internals/humanize/desktop.js
|
|
3104
3154
|
var import_delay2 = __toESM(require("delay"), 1);
|
|
3105
3155
|
var import_ghost_cursor_playwright = require("ghost-cursor-playwright");
|
|
3106
|
-
var
|
|
3156
|
+
var logger5 = createInternalLogger("Humanize");
|
|
3107
3157
|
var $CursorWeakMap = /* @__PURE__ */ new WeakMap();
|
|
3108
3158
|
function $GetCursor(page) {
|
|
3109
3159
|
const cursor = $CursorWeakMap.get(page);
|
|
@@ -3131,13 +3181,13 @@ var Humanize = {
|
|
|
3131
3181
|
*/
|
|
3132
3182
|
async initializeCursor(page) {
|
|
3133
3183
|
if ($CursorWeakMap.has(page)) {
|
|
3134
|
-
|
|
3184
|
+
logger5.debug("initializeCursor: cursor already exists, skipping");
|
|
3135
3185
|
return;
|
|
3136
3186
|
}
|
|
3137
|
-
|
|
3187
|
+
logger5.start("initializeCursor", "creating cursor");
|
|
3138
3188
|
const cursor = await (0, import_ghost_cursor_playwright.createCursor)(page);
|
|
3139
3189
|
$CursorWeakMap.set(page, cursor);
|
|
3140
|
-
|
|
3190
|
+
logger5.success("initializeCursor", "cursor initialized");
|
|
3141
3191
|
},
|
|
3142
3192
|
/**
|
|
3143
3193
|
* 人类化鼠标移动 - 使用 ghost-cursor 移动到指定位置或元素
|
|
@@ -3147,17 +3197,17 @@ var Humanize = {
|
|
|
3147
3197
|
*/
|
|
3148
3198
|
async humanMove(page, target) {
|
|
3149
3199
|
const cursor = $GetCursor(page);
|
|
3150
|
-
|
|
3200
|
+
logger5.start("humanMove", `target=${typeof target === "string" ? target : "element/coords"}`);
|
|
3151
3201
|
try {
|
|
3152
3202
|
if (typeof target === "string") {
|
|
3153
3203
|
const element = await page.$(target);
|
|
3154
3204
|
if (!element) {
|
|
3155
|
-
|
|
3205
|
+
logger5.warn(`humanMove: \u5143\u7D20\u4E0D\u5B58\u5728 ${target}`);
|
|
3156
3206
|
return false;
|
|
3157
3207
|
}
|
|
3158
3208
|
const box = await element.boundingBox();
|
|
3159
3209
|
if (!box) {
|
|
3160
|
-
|
|
3210
|
+
logger5.warn(`humanMove: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E ${target}`);
|
|
3161
3211
|
return false;
|
|
3162
3212
|
}
|
|
3163
3213
|
const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.2;
|
|
@@ -3173,10 +3223,10 @@ var Humanize = {
|
|
|
3173
3223
|
await cursor.actions.move({ x, y });
|
|
3174
3224
|
}
|
|
3175
3225
|
}
|
|
3176
|
-
|
|
3226
|
+
logger5.success("humanMove");
|
|
3177
3227
|
return true;
|
|
3178
3228
|
} catch (error) {
|
|
3179
|
-
|
|
3229
|
+
logger5.fail("humanMove", error);
|
|
3180
3230
|
throw error;
|
|
3181
3231
|
}
|
|
3182
3232
|
},
|
|
@@ -3200,12 +3250,12 @@ var Humanize = {
|
|
|
3200
3250
|
maxDurationMs = maxSteps * 220 + 800
|
|
3201
3251
|
} = options;
|
|
3202
3252
|
const targetDesc = typeof target === "string" ? target : "ElementHandle";
|
|
3203
|
-
|
|
3253
|
+
logger5.start("humanScroll", `target=${targetDesc}`);
|
|
3204
3254
|
let element;
|
|
3205
3255
|
if (typeof target === "string") {
|
|
3206
3256
|
element = await page.$(target);
|
|
3207
3257
|
if (!element) {
|
|
3208
|
-
|
|
3258
|
+
logger5.warn(`humanScroll | \u5143\u7D20\u672A\u627E\u5230: ${target}`);
|
|
3209
3259
|
return { element: null, didScroll: false };
|
|
3210
3260
|
}
|
|
3211
3261
|
} else {
|
|
@@ -3280,26 +3330,26 @@ var Humanize = {
|
|
|
3280
3330
|
try {
|
|
3281
3331
|
for (let i = 0; i < maxSteps; i++) {
|
|
3282
3332
|
if (Date.now() - startTime > maxDurationMs) {
|
|
3283
|
-
|
|
3333
|
+
logger5.warn(`humanScroll | \u8D85\u65F6\u4FDD\u62A4\u89E6\u53D1 (${maxDurationMs}ms)`);
|
|
3284
3334
|
return { element, didScroll };
|
|
3285
3335
|
}
|
|
3286
3336
|
const status = await checkVisibility();
|
|
3287
3337
|
if (status.code === "VISIBLE") {
|
|
3288
3338
|
if (status.isFixed) {
|
|
3289
|
-
|
|
3339
|
+
logger5.info("humanScroll | fixed \u5BB9\u5668\u5185\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
|
|
3290
3340
|
} else {
|
|
3291
|
-
|
|
3341
|
+
logger5.debug("humanScroll | \u5143\u7D20\u53EF\u89C1\u4E14\u65E0\u906E\u6321");
|
|
3292
3342
|
}
|
|
3293
|
-
|
|
3343
|
+
logger5.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
|
|
3294
3344
|
return { element, didScroll };
|
|
3295
3345
|
}
|
|
3296
|
-
|
|
3346
|
+
logger5.debug(`humanScroll | \u6B65\u9AA4 ${i + 1}/${maxSteps}: ${status.reason} ${status.direction ? `(${status.direction})` : ""}`);
|
|
3297
3347
|
if (status.code === "OBSTRUCTED" && status.obstruction) {
|
|
3298
|
-
|
|
3348
|
+
logger5.debug(`humanScroll | \u88AB\u4EE5\u4E0B\u5143\u7D20\u906E\u6321 <${status.obstruction.tag} id="${status.obstruction.id}">`);
|
|
3299
3349
|
}
|
|
3300
3350
|
const scrollRect = await getScrollableRect2();
|
|
3301
3351
|
if (!scrollRect && status.isFixed) {
|
|
3302
|
-
|
|
3352
|
+
logger5.warn("humanScroll | fixed \u5BB9\u5668\u5185\u4E14\u65E0\u53EF\u6EDA\u52A8\u7956\u5148\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
|
|
3303
3353
|
return { element, didScroll };
|
|
3304
3354
|
}
|
|
3305
3355
|
const stepMin = scrollRect ? Math.min(minStep, Math.max(60, scrollRect.height * 0.4)) : minStep;
|
|
@@ -3335,10 +3385,10 @@ var Humanize = {
|
|
|
3335
3385
|
didScroll = true;
|
|
3336
3386
|
await (0, import_delay2.default)(this.jitterMs(20 + Math.random() * 40, 0.2));
|
|
3337
3387
|
}
|
|
3338
|
-
|
|
3388
|
+
logger5.warn(`humanScroll | \u5728 ${maxSteps} \u6B65\u540E\u65E0\u6CD5\u786E\u4FDD\u53EF\u89C1\u6027`);
|
|
3339
3389
|
return { element, didScroll };
|
|
3340
3390
|
} catch (error) {
|
|
3341
|
-
|
|
3391
|
+
logger5.fail("humanScroll", error);
|
|
3342
3392
|
throw error;
|
|
3343
3393
|
}
|
|
3344
3394
|
},
|
|
@@ -3356,7 +3406,7 @@ var Humanize = {
|
|
|
3356
3406
|
const cursor = $GetCursor(page);
|
|
3357
3407
|
const { reactionDelay = 250, throwOnMissing = true, scrollIfNeeded = true, restore = false } = options;
|
|
3358
3408
|
const targetDesc = target == null ? "Current Position" : typeof target === "string" ? target : "ElementHandle";
|
|
3359
|
-
|
|
3409
|
+
logger5.start("humanClick", `target=${targetDesc}`);
|
|
3360
3410
|
const restoreOnce = async () => {
|
|
3361
3411
|
if (restoreOnce.restored) return;
|
|
3362
3412
|
restoreOnce.restored = true;
|
|
@@ -3365,14 +3415,14 @@ var Humanize = {
|
|
|
3365
3415
|
await (0, import_delay2.default)(this.jitterMs(1e3));
|
|
3366
3416
|
await restoreOnce.do();
|
|
3367
3417
|
} catch (restoreError) {
|
|
3368
|
-
|
|
3418
|
+
logger5.warn(`humanClick: \u6062\u590D\u6EDA\u52A8\u4F4D\u7F6E\u5931\u8D25: ${restoreError.message}`);
|
|
3369
3419
|
}
|
|
3370
3420
|
};
|
|
3371
3421
|
try {
|
|
3372
3422
|
if (target == null) {
|
|
3373
3423
|
await (0, import_delay2.default)(this.jitterMs(reactionDelay, 0.4));
|
|
3374
3424
|
await cursor.actions.click();
|
|
3375
|
-
|
|
3425
|
+
logger5.success("humanClick", "Clicked current position");
|
|
3376
3426
|
return true;
|
|
3377
3427
|
}
|
|
3378
3428
|
let element;
|
|
@@ -3382,7 +3432,7 @@ var Humanize = {
|
|
|
3382
3432
|
if (throwOnMissing) {
|
|
3383
3433
|
throw new Error(`\u627E\u4E0D\u5230\u5143\u7D20 ${target}`);
|
|
3384
3434
|
}
|
|
3385
|
-
|
|
3435
|
+
logger5.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${target}`);
|
|
3386
3436
|
return false;
|
|
3387
3437
|
}
|
|
3388
3438
|
} else {
|
|
@@ -3398,7 +3448,7 @@ var Humanize = {
|
|
|
3398
3448
|
if (throwOnMissing) {
|
|
3399
3449
|
throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5143\u7D20\u4F4D\u7F6E");
|
|
3400
3450
|
}
|
|
3401
|
-
|
|
3451
|
+
logger5.warn("humanClick: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E\uFF0C\u8DF3\u8FC7\u70B9\u51FB");
|
|
3402
3452
|
return false;
|
|
3403
3453
|
}
|
|
3404
3454
|
const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.3;
|
|
@@ -3407,11 +3457,11 @@ var Humanize = {
|
|
|
3407
3457
|
await (0, import_delay2.default)(this.jitterMs(reactionDelay, 0.4));
|
|
3408
3458
|
await cursor.actions.click();
|
|
3409
3459
|
await restoreOnce();
|
|
3410
|
-
|
|
3460
|
+
logger5.success("humanClick");
|
|
3411
3461
|
return true;
|
|
3412
3462
|
} catch (error) {
|
|
3413
3463
|
await restoreOnce();
|
|
3414
|
-
|
|
3464
|
+
logger5.fail("humanClick", error);
|
|
3415
3465
|
throw error;
|
|
3416
3466
|
}
|
|
3417
3467
|
},
|
|
@@ -3422,9 +3472,9 @@ var Humanize = {
|
|
|
3422
3472
|
*/
|
|
3423
3473
|
async randomSleep(baseMs, jitterPercent = 0.3) {
|
|
3424
3474
|
const ms = this.jitterMs(baseMs, jitterPercent);
|
|
3425
|
-
|
|
3475
|
+
logger5.start("randomSleep", `base=${baseMs}, actual=${ms}ms`);
|
|
3426
3476
|
await (0, import_delay2.default)(ms);
|
|
3427
|
-
|
|
3477
|
+
logger5.success("randomSleep");
|
|
3428
3478
|
},
|
|
3429
3479
|
/**
|
|
3430
3480
|
* 模拟人类"注视"或"阅读"行为:鼠标在页面上随机微动
|
|
@@ -3434,7 +3484,7 @@ var Humanize = {
|
|
|
3434
3484
|
async simulateGaze(page, baseDurationMs = 2500) {
|
|
3435
3485
|
const cursor = $GetCursor(page);
|
|
3436
3486
|
const durationMs = this.jitterMs(baseDurationMs, 0.4);
|
|
3437
|
-
|
|
3487
|
+
logger5.start("simulateGaze", `duration=${durationMs}ms`);
|
|
3438
3488
|
const startTime = Date.now();
|
|
3439
3489
|
const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };
|
|
3440
3490
|
while (Date.now() - startTime < durationMs) {
|
|
@@ -3443,7 +3493,7 @@ var Humanize = {
|
|
|
3443
3493
|
await cursor.actions.move({ x, y });
|
|
3444
3494
|
await (0, import_delay2.default)(this.jitterMs(600, 0.5));
|
|
3445
3495
|
}
|
|
3446
|
-
|
|
3496
|
+
logger5.success("simulateGaze");
|
|
3447
3497
|
},
|
|
3448
3498
|
/**
|
|
3449
3499
|
* 人类化输入 - 带节奏变化(快-慢-停顿-偶尔加速)
|
|
@@ -3456,7 +3506,7 @@ var Humanize = {
|
|
|
3456
3506
|
* @param {number} [options.pauseBase=800] - 停顿时长基础值 (ms),实际 ±50% 抖动
|
|
3457
3507
|
*/
|
|
3458
3508
|
async humanType(page, selector, text, options = {}) {
|
|
3459
|
-
|
|
3509
|
+
logger5.start("humanType", `selector=${selector}, textLen=${text.length}`);
|
|
3460
3510
|
const {
|
|
3461
3511
|
baseDelay = 180,
|
|
3462
3512
|
pauseProbability = 0.08,
|
|
@@ -3480,13 +3530,13 @@ var Humanize = {
|
|
|
3480
3530
|
await (0, import_delay2.default)(charDelay);
|
|
3481
3531
|
if (Math.random() < pauseProbability && i < text.length - 1) {
|
|
3482
3532
|
const pauseTime = this.jitterMs(pauseBase, 0.5);
|
|
3483
|
-
|
|
3533
|
+
logger5.debug(`\u505C\u987F ${pauseTime}ms...`);
|
|
3484
3534
|
await (0, import_delay2.default)(pauseTime);
|
|
3485
3535
|
}
|
|
3486
3536
|
}
|
|
3487
|
-
|
|
3537
|
+
logger5.success("humanType");
|
|
3488
3538
|
} catch (error) {
|
|
3489
|
-
|
|
3539
|
+
logger5.fail("humanType", error);
|
|
3490
3540
|
throw error;
|
|
3491
3541
|
}
|
|
3492
3542
|
},
|
|
@@ -3510,7 +3560,7 @@ var Humanize = {
|
|
|
3510
3560
|
keyboardOptions = {}
|
|
3511
3561
|
} = pressOptions || {};
|
|
3512
3562
|
const targetDesc = hasTarget ? typeof targetOrKey === "string" ? targetOrKey : "ElementHandle" : "current focus";
|
|
3513
|
-
|
|
3563
|
+
logger5.start("humanPress", `key=${key}, target=${targetDesc}`);
|
|
3514
3564
|
try {
|
|
3515
3565
|
if (hasTarget) {
|
|
3516
3566
|
await this.humanClick(page, targetOrKey, { reactionDelay: focusDelay, scrollIfNeeded, throwOnMissing });
|
|
@@ -3520,10 +3570,10 @@ var Humanize = {
|
|
|
3520
3570
|
...keyboardOptions,
|
|
3521
3571
|
delay: this.jitterMs(holdDelay, 0.5)
|
|
3522
3572
|
});
|
|
3523
|
-
|
|
3573
|
+
logger5.success("humanPress");
|
|
3524
3574
|
return true;
|
|
3525
3575
|
} catch (error) {
|
|
3526
|
-
|
|
3576
|
+
logger5.fail("humanPress", error);
|
|
3527
3577
|
throw error;
|
|
3528
3578
|
}
|
|
3529
3579
|
},
|
|
@@ -3533,22 +3583,22 @@ var Humanize = {
|
|
|
3533
3583
|
* @param {string} selector - 输入框选择器
|
|
3534
3584
|
*/
|
|
3535
3585
|
async humanClear(page, selector) {
|
|
3536
|
-
|
|
3586
|
+
logger5.start("humanClear", `selector=${selector}`);
|
|
3537
3587
|
try {
|
|
3538
3588
|
const locator = page.locator(selector);
|
|
3539
3589
|
await locator.click();
|
|
3540
3590
|
await (0, import_delay2.default)(this.jitterMs(200, 0.4));
|
|
3541
3591
|
const currentValue = await locator.inputValue();
|
|
3542
3592
|
if (!currentValue || currentValue.length === 0) {
|
|
3543
|
-
|
|
3593
|
+
logger5.success("humanClear", "already empty");
|
|
3544
3594
|
return;
|
|
3545
3595
|
}
|
|
3546
3596
|
await page.keyboard.press("Meta+A");
|
|
3547
3597
|
await (0, import_delay2.default)(this.jitterMs(100, 0.4));
|
|
3548
3598
|
await page.keyboard.press("Backspace");
|
|
3549
|
-
|
|
3599
|
+
logger5.success("humanClear");
|
|
3550
3600
|
} catch (error) {
|
|
3551
|
-
|
|
3601
|
+
logger5.fail("humanClear", error);
|
|
3552
3602
|
throw error;
|
|
3553
3603
|
}
|
|
3554
3604
|
},
|
|
@@ -3560,7 +3610,7 @@ var Humanize = {
|
|
|
3560
3610
|
async warmUpBrowsing(page, baseDuration = 3500) {
|
|
3561
3611
|
const cursor = $GetCursor(page);
|
|
3562
3612
|
const durationMs = this.jitterMs(baseDuration, 0.4);
|
|
3563
|
-
|
|
3613
|
+
logger5.start("warmUpBrowsing", `duration=${durationMs}ms`);
|
|
3564
3614
|
const startTime = Date.now();
|
|
3565
3615
|
const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };
|
|
3566
3616
|
try {
|
|
@@ -3579,9 +3629,9 @@ var Humanize = {
|
|
|
3579
3629
|
await (0, import_delay2.default)(this.jitterMs(800, 0.5));
|
|
3580
3630
|
}
|
|
3581
3631
|
}
|
|
3582
|
-
|
|
3632
|
+
logger5.success("warmUpBrowsing");
|
|
3583
3633
|
} catch (error) {
|
|
3584
|
-
|
|
3634
|
+
logger5.fail("warmUpBrowsing", error);
|
|
3585
3635
|
throw error;
|
|
3586
3636
|
}
|
|
3587
3637
|
},
|
|
@@ -3595,7 +3645,7 @@ var Humanize = {
|
|
|
3595
3645
|
async naturalScroll(page, direction = "down", distance = 300, baseSteps = 5) {
|
|
3596
3646
|
const steps = Math.max(3, baseSteps + Math.floor(Math.random() * 3) - 1);
|
|
3597
3647
|
const actualDistance = this.jitterMs(distance, 0.15);
|
|
3598
|
-
|
|
3648
|
+
logger5.start("naturalScroll", `dir=${direction}, dist=${actualDistance}, steps=${steps}`);
|
|
3599
3649
|
const sign = direction === "down" ? 1 : -1;
|
|
3600
3650
|
const stepDistance = actualDistance / steps;
|
|
3601
3651
|
try {
|
|
@@ -3607,9 +3657,9 @@ var Humanize = {
|
|
|
3607
3657
|
const baseDelay = 60 + i * 25;
|
|
3608
3658
|
await (0, import_delay2.default)(this.jitterMs(baseDelay, 0.3));
|
|
3609
3659
|
}
|
|
3610
|
-
|
|
3660
|
+
logger5.success("naturalScroll");
|
|
3611
3661
|
} catch (error) {
|
|
3612
|
-
|
|
3662
|
+
logger5.fail("naturalScroll", error);
|
|
3613
3663
|
throw error;
|
|
3614
3664
|
}
|
|
3615
3665
|
}
|
|
@@ -3638,7 +3688,7 @@ var resolveElement = async (page, target, { throwOnMissing = true } = {}) => {
|
|
|
3638
3688
|
var waitJitter = (base, jitterPercent = 0.3) => (0, import_delay3.default)(jitterMs(base, jitterPercent));
|
|
3639
3689
|
|
|
3640
3690
|
// src/internals/humanize/mobile.js
|
|
3641
|
-
var
|
|
3691
|
+
var logger6 = createInternalLogger("Humanize.Mobile");
|
|
3642
3692
|
var initializedPages = /* @__PURE__ */ new WeakSet();
|
|
3643
3693
|
var DEFAULT_TAP_TIMEOUT_MS = 2500;
|
|
3644
3694
|
var DEFAULT_MOUSE_TAP_FALLBACK_TIMEOUT_MS = 1200;
|
|
@@ -4095,7 +4145,7 @@ var dispatchTouchSwipe = async (page, deltaY, options = {}) => {
|
|
|
4095
4145
|
}
|
|
4096
4146
|
return true;
|
|
4097
4147
|
} catch (error) {
|
|
4098
|
-
|
|
4148
|
+
logger6.debug(`touch swipe fallback: ${error?.message || error}`);
|
|
4099
4149
|
try {
|
|
4100
4150
|
await page.evaluate((amount) => window.scrollBy(0, amount), deltaY);
|
|
4101
4151
|
await waitJitter(120, 0.35);
|
|
@@ -4129,7 +4179,7 @@ var tapPoint = async (page, point, options = {}) => {
|
|
|
4129
4179
|
);
|
|
4130
4180
|
return { method: "touchscreen" };
|
|
4131
4181
|
} catch (error) {
|
|
4132
|
-
|
|
4182
|
+
logger6.warn(`tapPoint | touchscreen.tap \u5931\u8D25\u6216\u8D85\u65F6\uFF0C\u5C1D\u8BD5\u9F20\u6807\u515C\u5E95: ${error?.message || error}`);
|
|
4133
4183
|
if (!allowMouseFallback) throw error;
|
|
4134
4184
|
}
|
|
4135
4185
|
}
|
|
@@ -4145,10 +4195,10 @@ var MobileHumanize = {
|
|
|
4145
4195
|
async initializeCursor(page) {
|
|
4146
4196
|
if (initializedPages.has(page)) return;
|
|
4147
4197
|
initializedPages.add(page);
|
|
4148
|
-
|
|
4198
|
+
logger6.debug("initializeCursor: mobile mode uses touch gestures, cursor init skipped");
|
|
4149
4199
|
},
|
|
4150
4200
|
async humanMove(page, target) {
|
|
4151
|
-
|
|
4201
|
+
logger6.debug(`humanMove: mobile no-op target=${typeof target === "string" ? target : "element/coords"}`);
|
|
4152
4202
|
if (typeof target === "string" || target && typeof target.boundingBox === "function") {
|
|
4153
4203
|
const element = await resolveElement(page, target, { throwOnMissing: false });
|
|
4154
4204
|
if (!element) {
|
|
@@ -4167,10 +4217,10 @@ var MobileHumanize = {
|
|
|
4167
4217
|
throwOnMissing = false
|
|
4168
4218
|
} = options;
|
|
4169
4219
|
const targetDesc = describeTarget(target);
|
|
4170
|
-
|
|
4220
|
+
logger6.start("humanScroll", `target=${targetDesc}`);
|
|
4171
4221
|
const element = await resolveElement(page, target, { throwOnMissing });
|
|
4172
4222
|
if (!element) {
|
|
4173
|
-
|
|
4223
|
+
logger6.warn(`humanScroll | \u5143\u7D20\u672A\u627E\u5230: ${targetDesc}`);
|
|
4174
4224
|
return { element: null, didScroll: false, restore: null };
|
|
4175
4225
|
}
|
|
4176
4226
|
const startTime = Date.now();
|
|
@@ -4179,42 +4229,42 @@ var MobileHumanize = {
|
|
|
4179
4229
|
const status = await checkElementVisibility(element);
|
|
4180
4230
|
if (status.code === "VISIBLE") {
|
|
4181
4231
|
if (status.isFixed) {
|
|
4182
|
-
|
|
4232
|
+
logger6.info("humanScroll | fixed/sticky \u5BB9\u5668\u5185\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
|
|
4183
4233
|
} else {
|
|
4184
|
-
|
|
4234
|
+
logger6.debug("humanScroll | \u5143\u7D20\u53EF\u89C1\u4E14\u65E0\u906E\u6321");
|
|
4185
4235
|
}
|
|
4186
|
-
|
|
4236
|
+
logger6.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
|
|
4187
4237
|
return { element, didScroll, restore: null };
|
|
4188
4238
|
}
|
|
4189
4239
|
if (status.code === "ZERO_DIMENSIONS" || status.code === "NOT_INTERACTABLE") {
|
|
4190
|
-
|
|
4240
|
+
logger6.warn(`humanScroll | \u5143\u7D20\u4E0D\u53EF\u6EDA\u52A8\u81F3\u53EF\u70B9\u51FB\u72B6\u6001: ${status.reason || status.code}`);
|
|
4191
4241
|
return { element, didScroll, restore: null };
|
|
4192
4242
|
}
|
|
4193
4243
|
const scrollRect = await getScrollableRect(element);
|
|
4194
4244
|
if (!scrollRect && status.isFixed && status.code === "OUT_OF_VIEWPORT") {
|
|
4195
|
-
|
|
4245
|
+
logger6.warn(`humanScroll | fixed/sticky \u76EE\u6807\u4E0D\u5728\u89C6\u53E3\u5185\uFF0C\u9875\u9762\u6EDA\u52A8\u65E0\u6CD5\u6539\u53D8\u5176\u4F4D\u7F6E (direction=${status.direction || "unknown"})`);
|
|
4196
4246
|
return { element, didScroll, restore: null, unscrollable: true };
|
|
4197
4247
|
}
|
|
4198
4248
|
if (!scrollRect && status.isFixed && status.code === "OBSTRUCTED") {
|
|
4199
|
-
|
|
4249
|
+
logger6.warn(`humanScroll | fixed/sticky \u76EE\u6807\u88AB\u906E\u6321\uFF0C\u6EDA\u52A8\u65E0\u6CD5\u89E3\u9664 (${status.obstruction?.tag || "unknown"})`);
|
|
4200
4250
|
return { element, didScroll, restore: null, unscrollable: true };
|
|
4201
4251
|
}
|
|
4202
4252
|
if (scrollRect && status.code === "OBSTRUCTED" && status.obstruction?.isFixed) {
|
|
4203
4253
|
const moved = await scrollAwayFromObstruction(element, status);
|
|
4204
4254
|
if (moved.moved) {
|
|
4205
|
-
|
|
4255
|
+
logger6.debug(`humanScroll | sticky/fixed \u906E\u6321\u8865\u507F\u6EDA\u52A8 top=${Math.round(moved.scrollTop || 0)}`);
|
|
4206
4256
|
await waitJitter(90, 0.3);
|
|
4207
4257
|
didScroll = true;
|
|
4208
4258
|
continue;
|
|
4209
4259
|
}
|
|
4210
4260
|
}
|
|
4211
4261
|
if (Date.now() - startTime > maxDurationMs) {
|
|
4212
|
-
|
|
4262
|
+
logger6.warn(`humanScroll | mobile timeout (${maxDurationMs}ms, status=${status.code}, direction=${status.direction || "unknown"}, fixed=${Boolean(status.isFixed)})`);
|
|
4213
4263
|
return { element, didScroll, restore: null };
|
|
4214
4264
|
}
|
|
4215
4265
|
const stepMin = scrollRect ? Math.min(minStep, Math.max(60, scrollRect.height * 0.4)) : minStep;
|
|
4216
4266
|
const stepMax = scrollRect ? Math.min(maxStep, Math.max(stepMin + 40, scrollRect.height * 0.8)) : maxStep;
|
|
4217
|
-
|
|
4267
|
+
logger6.debug(`humanScroll | \u6B65\u9AA4 ${i + 1}/${maxSteps}: ${status.reason || status.code} ${status.direction ? `(${status.direction})` : ""}`);
|
|
4218
4268
|
const distance = stepMin + Math.random() * Math.max(1, stepMax - stepMin);
|
|
4219
4269
|
let deltaY = status.direction === "up" ? -distance : distance;
|
|
4220
4270
|
if (status.code === "OBSTRUCTED") {
|
|
@@ -4255,7 +4305,7 @@ var MobileHumanize = {
|
|
|
4255
4305
|
const afterWindowState = await page.evaluate(() => ({ x: window.scrollX, y: window.scrollY }));
|
|
4256
4306
|
if (Math.abs(afterWindowState.x - beforeWindowState.x) > 2 || Math.abs(afterWindowState.y - beforeWindowState.y) > 2) {
|
|
4257
4307
|
await page.evaluate((state) => window.scrollTo(state.x, state.y), beforeWindowState);
|
|
4258
|
-
|
|
4308
|
+
logger6.debug(`humanScroll | \u7A97\u53E3\u6EDA\u52A8\u56DE\u6536 from=${Math.round(afterWindowState.y)} to=${Math.round(beforeWindowState.y)}`);
|
|
4259
4309
|
}
|
|
4260
4310
|
}
|
|
4261
4311
|
let afterElementSnapshot = null;
|
|
@@ -4269,7 +4319,7 @@ var MobileHumanize = {
|
|
|
4269
4319
|
const afterSnapshot = await readAfterElementSnapshot();
|
|
4270
4320
|
if (isTargetImmobileAfterScroll(beforeElementSnapshot, afterSnapshot)) {
|
|
4271
4321
|
await restoreWindowFromSnapshot(page, beforeElementSnapshot, afterSnapshot);
|
|
4272
|
-
|
|
4322
|
+
logger6.warn(`humanScroll | \u76EE\u6807\u4E0D\u968F\u9875\u9762\u6EDA\u52A8\u79FB\u52A8\uFF0C\u9875\u9762\u6EDA\u52A8\u65E0\u6CD5\u6539\u53D8\u5176\u4F4D\u7F6E (status=${status.code}, direction=${status.direction || "unknown"})`);
|
|
4273
4323
|
return { element, didScroll, restore: null, unscrollable: true };
|
|
4274
4324
|
}
|
|
4275
4325
|
}
|
|
@@ -4301,12 +4351,12 @@ var MobileHumanize = {
|
|
|
4301
4351
|
const moved = beforeState.kind !== afterState.kind || Math.abs(topDelta) > 2 || Math.abs(leftDelta) > 2;
|
|
4302
4352
|
if (!moved) {
|
|
4303
4353
|
const fallback = await scrollScrollableAncestor(element, deltaY);
|
|
4304
|
-
|
|
4354
|
+
logger6.debug(`humanScroll | \u5BB9\u5668\u89E6\u6478\u65E0\u6548\uFF0C\u76F4\u63A5\u6EDA\u52A8 fallback=${fallback.scroller ? "ancestor" : "window"} top=${Math.round(fallback.scrollTop || 0)}`);
|
|
4305
4355
|
} else if (beforeState.kind === afterState.kind && Math.abs(expectedDelta) > 24 && Math.sign(topDelta || expectedDelta) === Math.sign(expectedDelta) && Math.abs(topDelta) < Math.min(Math.abs(expectedDelta) * 0.45, 96)) {
|
|
4306
4356
|
const residualDelta = expectedDelta - topDelta;
|
|
4307
4357
|
if (Math.sign(residualDelta) === Math.sign(expectedDelta) && Math.abs(residualDelta) > 24) {
|
|
4308
4358
|
const fallback = await scrollScrollableAncestor(element, residualDelta);
|
|
4309
|
-
|
|
4359
|
+
logger6.debug(`humanScroll | \u5BB9\u5668\u89E6\u6478\u8DDD\u79BB\u4E0D\u8DB3\uFF0C\u8865\u507F\u6EDA\u52A8 fallback=${fallback.scroller ? "ancestor" : "window"} top=${Math.round(fallback.scrollTop || 0)}`);
|
|
4310
4360
|
}
|
|
4311
4361
|
}
|
|
4312
4362
|
}
|
|
@@ -4314,7 +4364,7 @@ var MobileHumanize = {
|
|
|
4314
4364
|
const afterSnapshot = await getElementViewportSnapshot(element).catch(() => null);
|
|
4315
4365
|
if (isTargetImmobileAfterScroll(beforeElementSnapshot, afterSnapshot)) {
|
|
4316
4366
|
await restoreWindowFromSnapshot(page, beforeElementSnapshot, afterSnapshot);
|
|
4317
|
-
|
|
4367
|
+
logger6.warn(`humanScroll | \u76EE\u6807\u4E0D\u968F\u6EDA\u52A8\u5BB9\u5668\u79FB\u52A8\uFF0C\u6EDA\u52A8\u65E0\u6CD5\u6539\u53D8\u5176\u4F4D\u7F6E (status=${status.code}, direction=${status.direction || "unknown"})`);
|
|
4318
4368
|
return { element, didScroll, restore: null, unscrollable: true };
|
|
4319
4369
|
}
|
|
4320
4370
|
}
|
|
@@ -4325,14 +4375,14 @@ var MobileHumanize = {
|
|
|
4325
4375
|
await waitJitter(80, 0.3);
|
|
4326
4376
|
const finalStatus = await checkElementVisibility(element);
|
|
4327
4377
|
if (finalStatus.code === "VISIBLE") {
|
|
4328
|
-
|
|
4329
|
-
|
|
4378
|
+
logger6.info("humanScroll | \u539F\u751F scrollIntoViewIfNeeded \u515C\u5E95\u6210\u529F");
|
|
4379
|
+
logger6.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
|
|
4330
4380
|
return { element, didScroll: true, restore: null };
|
|
4331
4381
|
}
|
|
4332
4382
|
} catch (fallbackError) {
|
|
4333
|
-
|
|
4383
|
+
logger6.debug(`humanScroll | native fallback failed: ${fallbackError?.message || fallbackError}`);
|
|
4334
4384
|
}
|
|
4335
|
-
|
|
4385
|
+
logger6.warn(`humanScroll | \u5728 ${maxSteps} \u6B65\u540E\u65E0\u6CD5\u786E\u4FDD\u53EF\u89C1\u6027`);
|
|
4336
4386
|
return { element, didScroll, restore: null };
|
|
4337
4387
|
},
|
|
4338
4388
|
async humanClick(page, target, options = {}) {
|
|
@@ -4347,7 +4397,7 @@ var MobileHumanize = {
|
|
|
4347
4397
|
fallbackDomClickOnTapError = true
|
|
4348
4398
|
} = options;
|
|
4349
4399
|
const targetDesc = describeTarget(target);
|
|
4350
|
-
|
|
4400
|
+
logger6.start("humanClick", `target=${targetDesc}`);
|
|
4351
4401
|
try {
|
|
4352
4402
|
if (target == null) {
|
|
4353
4403
|
const viewport = resolveViewport(page);
|
|
@@ -4359,12 +4409,12 @@ var MobileHumanize = {
|
|
|
4359
4409
|
timeoutMs: tapTimeoutMs,
|
|
4360
4410
|
mouseFallbackTimeoutMs
|
|
4361
4411
|
});
|
|
4362
|
-
|
|
4412
|
+
logger6.success("humanClick", "Tapped current position");
|
|
4363
4413
|
return true;
|
|
4364
4414
|
}
|
|
4365
4415
|
const element = await resolveElement(page, target, { throwOnMissing });
|
|
4366
4416
|
if (!element) {
|
|
4367
|
-
|
|
4417
|
+
logger6.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${targetDesc}`);
|
|
4368
4418
|
return false;
|
|
4369
4419
|
}
|
|
4370
4420
|
const scrollResult = scrollIfNeeded ? await MobileHumanize.humanScroll(page, element, { throwOnMissing }) : null;
|
|
@@ -4388,19 +4438,19 @@ var MobileHumanize = {
|
|
|
4388
4438
|
).catch(() => null);
|
|
4389
4439
|
}
|
|
4390
4440
|
if (fallback?.activated) {
|
|
4391
|
-
|
|
4441
|
+
logger6.warn(`humanClick: \u4E0D\u53EF\u6EDA\u52A8\u76EE\u6807\u4E0D\u53EF\u7269\u7406\u70B9\u51FB\uFF0C\u5DF2\u7528 ${fallback.method} \u6FC0\u6D3B`);
|
|
4392
4442
|
return true;
|
|
4393
4443
|
}
|
|
4394
4444
|
}
|
|
4395
4445
|
const message = `\u5143\u7D20\u4E0D\u53EF\u70B9\u51FB: ${status.reason || status.code}`;
|
|
4396
4446
|
if (throwOnMissing) throw new Error(message);
|
|
4397
|
-
|
|
4447
|
+
logger6.warn(`humanClick: ${message}\uFF0C\u8DF3\u8FC7\u70B9\u51FB`);
|
|
4398
4448
|
return false;
|
|
4399
4449
|
}
|
|
4400
4450
|
const box = await element.boundingBox();
|
|
4401
4451
|
if (!box) {
|
|
4402
4452
|
if (throwOnMissing) throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5143\u7D20\u4F4D\u7F6E");
|
|
4403
|
-
|
|
4453
|
+
logger6.warn("humanClick: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E\uFF0C\u8DF3\u8FC7\u70B9\u51FB");
|
|
4404
4454
|
return false;
|
|
4405
4455
|
}
|
|
4406
4456
|
await waitJitter(reactionDelay, 0.45);
|
|
@@ -4421,13 +4471,13 @@ var MobileHumanize = {
|
|
|
4421
4471
|
"activation fallback"
|
|
4422
4472
|
).catch(() => null);
|
|
4423
4473
|
if (!fallback?.activated) throw tapError;
|
|
4424
|
-
|
|
4474
|
+
logger6.warn(`humanClick: tap \u5931\u8D25\u540E\u5DF2\u7528 ${fallback.method} \u515C\u5E95: ${tapError?.message || tapError}`);
|
|
4425
4475
|
}
|
|
4426
4476
|
await waitJitter(120, 0.35);
|
|
4427
|
-
|
|
4477
|
+
logger6.success("humanClick");
|
|
4428
4478
|
return true;
|
|
4429
4479
|
} catch (error) {
|
|
4430
|
-
|
|
4480
|
+
logger6.fail("humanClick", error);
|
|
4431
4481
|
throw error;
|
|
4432
4482
|
}
|
|
4433
4483
|
},
|
|
@@ -4480,7 +4530,7 @@ var MobileHumanize = {
|
|
|
4480
4530
|
keyboardOptions = {}
|
|
4481
4531
|
} = pressOptions || {};
|
|
4482
4532
|
const targetDesc = hasTarget ? describeTarget(targetOrKey) : "current focus";
|
|
4483
|
-
|
|
4533
|
+
logger6.start("humanPress", `key=${key}, target=${targetDesc}`);
|
|
4484
4534
|
try {
|
|
4485
4535
|
if (hasTarget) {
|
|
4486
4536
|
await MobileHumanize.humanClick(page, targetOrKey, {
|
|
@@ -4494,10 +4544,10 @@ var MobileHumanize = {
|
|
|
4494
4544
|
...keyboardOptions,
|
|
4495
4545
|
delay: jitterMs(holdDelay, 0.5)
|
|
4496
4546
|
});
|
|
4497
|
-
|
|
4547
|
+
logger6.success("humanPress");
|
|
4498
4548
|
return true;
|
|
4499
4549
|
} catch (error) {
|
|
4500
|
-
|
|
4550
|
+
logger6.fail("humanPress", error);
|
|
4501
4551
|
throw error;
|
|
4502
4552
|
}
|
|
4503
4553
|
},
|
|
@@ -4564,7 +4614,7 @@ var MobileHumanize = {
|
|
|
4564
4614
|
}
|
|
4565
4615
|
};
|
|
4566
4616
|
|
|
4567
|
-
// src/humanize.js
|
|
4617
|
+
// src/internals/humanize/default.js
|
|
4568
4618
|
var resolveDeviceFromPage2 = (page) => normalizeDevice(page?.[PageRuntimeStateKey]?.device);
|
|
4569
4619
|
var resolveDelegate = (page) => {
|
|
4570
4620
|
return resolveDeviceFromPage2(page) === Device.Mobile ? MobileHumanize : Humanize;
|
|
@@ -4573,7 +4623,7 @@ var callDelegate = (method, page, args) => {
|
|
|
4573
4623
|
const delegate = resolveDelegate(page);
|
|
4574
4624
|
return delegate[method](page, ...args);
|
|
4575
4625
|
};
|
|
4576
|
-
var
|
|
4626
|
+
var DefaultHumanize = {
|
|
4577
4627
|
jitterMs(base, jitterPercent = 0.3) {
|
|
4578
4628
|
return Humanize.jitterMs(base, jitterPercent);
|
|
4579
4629
|
},
|
|
@@ -4619,7 +4669,509 @@ var Humanize2 = {
|
|
|
4619
4669
|
}
|
|
4620
4670
|
};
|
|
4621
4671
|
|
|
4622
|
-
// src/
|
|
4672
|
+
// src/internals/humanize/cloakbrowser.js
|
|
4673
|
+
var import_delay4 = __toESM(require("delay"), 1);
|
|
4674
|
+
var logger7 = createInternalLogger("Humanize.CloakBrowser");
|
|
4675
|
+
var humanizedPages = /* @__PURE__ */ new WeakSet();
|
|
4676
|
+
var cachedCloakHumanModulePromise = null;
|
|
4677
|
+
var isPageLike2 = (value) => value && typeof value === "object" && typeof value.evaluate === "function";
|
|
4678
|
+
var isPoint2 = (value) => value && typeof value === "object" && Number.isFinite(Number(value.x)) && Number.isFinite(Number(value.y));
|
|
4679
|
+
var resolveDeviceFromPage3 = (page) => normalizeDevice(page?.[PageRuntimeStateKey]?.device);
|
|
4680
|
+
var isMobilePage = (page) => resolveDeviceFromPage3(page) === Device.Mobile;
|
|
4681
|
+
var loadCloakHumanModule = async () => {
|
|
4682
|
+
if (!cachedCloakHumanModulePromise) {
|
|
4683
|
+
cachedCloakHumanModulePromise = import("cloakbrowser/human").catch((error) => {
|
|
4684
|
+
cachedCloakHumanModulePromise = null;
|
|
4685
|
+
throw new Error("cloakbrowser/human \u6A21\u5757\u52A0\u8F7D\u5931\u8D25\uFF0C\u8BF7\u786E\u8BA4\u5F53\u524D\u8FD0\u884C\u73AF\u5883\u5DF2\u5B89\u88C5 cloakbrowser\u3002", {
|
|
4686
|
+
cause: error
|
|
4687
|
+
});
|
|
4688
|
+
});
|
|
4689
|
+
}
|
|
4690
|
+
return cachedCloakHumanModulePromise;
|
|
4691
|
+
};
|
|
4692
|
+
var buildTypingHumanConfig = (options = {}) => {
|
|
4693
|
+
const humanConfig = {};
|
|
4694
|
+
if (Number.isFinite(Number(options.baseDelay))) {
|
|
4695
|
+
humanConfig.typing_delay = Number(options.baseDelay);
|
|
4696
|
+
}
|
|
4697
|
+
if (Number.isFinite(Number(options.pauseProbability))) {
|
|
4698
|
+
humanConfig.typing_pause_chance = Number(options.pauseProbability);
|
|
4699
|
+
}
|
|
4700
|
+
if (Number.isFinite(Number(options.pauseBase))) {
|
|
4701
|
+
const basePause = Math.max(40, Number(options.pauseBase));
|
|
4702
|
+
humanConfig.typing_pause_range = [
|
|
4703
|
+
Math.round(basePause * 0.5),
|
|
4704
|
+
Math.round(basePause * 1.5)
|
|
4705
|
+
];
|
|
4706
|
+
}
|
|
4707
|
+
return Object.keys(humanConfig).length > 0 ? humanConfig : null;
|
|
4708
|
+
};
|
|
4709
|
+
var buildActionOptions = (options = {}) => {
|
|
4710
|
+
const actionOptions = {};
|
|
4711
|
+
if (options && options.timeout != null) {
|
|
4712
|
+
actionOptions.timeout = options.timeout;
|
|
4713
|
+
}
|
|
4714
|
+
if (options && options.force != null) {
|
|
4715
|
+
actionOptions.force = options.force;
|
|
4716
|
+
}
|
|
4717
|
+
const humanConfig = buildTypingHumanConfig(options);
|
|
4718
|
+
if (humanConfig) {
|
|
4719
|
+
actionOptions.human_config = humanConfig;
|
|
4720
|
+
}
|
|
4721
|
+
return actionOptions;
|
|
4722
|
+
};
|
|
4723
|
+
var getErrorMessage = (error) => {
|
|
4724
|
+
if (typeof error === "string") return error;
|
|
4725
|
+
if (error && typeof error.message === "string") return error.message;
|
|
4726
|
+
return String(error ?? "");
|
|
4727
|
+
};
|
|
4728
|
+
var isPointerEventsCoveredError = (error) => {
|
|
4729
|
+
const message = getErrorMessage(error).toLowerCase();
|
|
4730
|
+
return message.includes("pointer_events") && (message.includes("covered by") || message.includes("receiving events"));
|
|
4731
|
+
};
|
|
4732
|
+
var withPointerEventsForceFallback = async (label, options, operation) => {
|
|
4733
|
+
try {
|
|
4734
|
+
return await operation(options);
|
|
4735
|
+
} catch (error) {
|
|
4736
|
+
if (options?.force || !isPointerEventsCoveredError(error)) {
|
|
4737
|
+
throw error;
|
|
4738
|
+
}
|
|
4739
|
+
logger7.warn(`${label}: cloakbrowser pointer_events check failed, retrying with force=true (${getErrorMessage(error)})`);
|
|
4740
|
+
return await operation({
|
|
4741
|
+
...options || {},
|
|
4742
|
+
force: true
|
|
4743
|
+
});
|
|
4744
|
+
}
|
|
4745
|
+
};
|
|
4746
|
+
var ensureDesktopHumanized = async (page) => {
|
|
4747
|
+
if (!page || typeof page !== "object") {
|
|
4748
|
+
throw new Error("Humanize requires a Playwright page");
|
|
4749
|
+
}
|
|
4750
|
+
const humanModule = await loadCloakHumanModule();
|
|
4751
|
+
if (page._original && page._humanCursor) {
|
|
4752
|
+
humanizedPages.add(page);
|
|
4753
|
+
return humanModule;
|
|
4754
|
+
}
|
|
4755
|
+
if (humanizedPages.has(page)) {
|
|
4756
|
+
return humanModule;
|
|
4757
|
+
}
|
|
4758
|
+
const config = page._humanCfg || humanModule.resolveConfig?.("default") || humanModule.resolveConfig?.();
|
|
4759
|
+
const cursor = page._humanCursor || { x: 0, y: 0, initialized: false };
|
|
4760
|
+
humanModule.patchPage(page, config, cursor);
|
|
4761
|
+
humanizedPages.add(page);
|
|
4762
|
+
return humanModule;
|
|
4763
|
+
};
|
|
4764
|
+
var patchHandle = async (page, handle) => {
|
|
4765
|
+
if (!handle || typeof handle !== "object") return handle;
|
|
4766
|
+
const humanModule = await ensureDesktopHumanized(page);
|
|
4767
|
+
humanModule.patchSingleElementHandle(
|
|
4768
|
+
handle,
|
|
4769
|
+
page,
|
|
4770
|
+
page._humanCfg,
|
|
4771
|
+
page._humanCursor,
|
|
4772
|
+
page._humanRaw,
|
|
4773
|
+
page._humanRawKb,
|
|
4774
|
+
page._humanOriginals,
|
|
4775
|
+
page._stealth
|
|
4776
|
+
);
|
|
4777
|
+
return handle;
|
|
4778
|
+
};
|
|
4779
|
+
var resolvePatchedTarget = async (page, target, { throwOnMissing = true } = {}) => {
|
|
4780
|
+
if (target == null) {
|
|
4781
|
+
return { target: null, dispose: null };
|
|
4782
|
+
}
|
|
4783
|
+
if (typeof target === "string") {
|
|
4784
|
+
const handle = await page.$(target);
|
|
4785
|
+
if (!handle) {
|
|
4786
|
+
if (throwOnMissing) {
|
|
4787
|
+
throw new Error(`\u627E\u4E0D\u5230\u5143\u7D20 ${String(target)}`);
|
|
4788
|
+
}
|
|
4789
|
+
return { target: null, dispose: null };
|
|
4790
|
+
}
|
|
4791
|
+
return { target: handle, dispose: null };
|
|
4792
|
+
}
|
|
4793
|
+
if (typeof target.elementHandle === "function") {
|
|
4794
|
+
const handle = await target.elementHandle();
|
|
4795
|
+
if (!handle) {
|
|
4796
|
+
if (throwOnMissing) {
|
|
4797
|
+
throw new Error("\u627E\u4E0D\u5230 locator \u5BF9\u5E94\u7684\u5143\u7D20");
|
|
4798
|
+
}
|
|
4799
|
+
return { target: null, dispose: null };
|
|
4800
|
+
}
|
|
4801
|
+
await patchHandle(page, handle);
|
|
4802
|
+
return {
|
|
4803
|
+
target: handle,
|
|
4804
|
+
dispose: async () => {
|
|
4805
|
+
await handle.dispose().catch(() => {
|
|
4806
|
+
});
|
|
4807
|
+
}
|
|
4808
|
+
};
|
|
4809
|
+
}
|
|
4810
|
+
await patchHandle(page, target);
|
|
4811
|
+
return { target, dispose: null };
|
|
4812
|
+
};
|
|
4813
|
+
var jitterSleep = async (baseMs, jitterPercent = 0.3) => {
|
|
4814
|
+
await (0, import_delay4.default)(jitterMs(baseMs, jitterPercent));
|
|
4815
|
+
};
|
|
4816
|
+
var humanMoveToPoint = async (page, point) => {
|
|
4817
|
+
await ensureDesktopHumanized(page);
|
|
4818
|
+
await page.mouse.move(Number(point.x), Number(point.y));
|
|
4819
|
+
return true;
|
|
4820
|
+
};
|
|
4821
|
+
var doDesktopHumanClick = async (page, target, options = {}) => {
|
|
4822
|
+
await ensureDesktopHumanized(page);
|
|
4823
|
+
return await withPointerEventsForceFallback("humanClick", options, async (effectiveOptions = {}) => {
|
|
4824
|
+
if (target == null) {
|
|
4825
|
+
const cursor = page._humanCursor || { x: 0, y: 0 };
|
|
4826
|
+
await page.mouse.click(cursor.x || 0, cursor.y || 0);
|
|
4827
|
+
return true;
|
|
4828
|
+
}
|
|
4829
|
+
if (isPoint2(target)) {
|
|
4830
|
+
return humanMoveToPoint(page, target).then(async () => {
|
|
4831
|
+
await page.mouse.click(Number(target.x), Number(target.y));
|
|
4832
|
+
return true;
|
|
4833
|
+
});
|
|
4834
|
+
}
|
|
4835
|
+
const throwOnMissing = effectiveOptions.throwOnMissing !== false;
|
|
4836
|
+
if (typeof target === "string") {
|
|
4837
|
+
if (!throwOnMissing) {
|
|
4838
|
+
const existingHandle = await page.$(target);
|
|
4839
|
+
if (!existingHandle) {
|
|
4840
|
+
return false;
|
|
4841
|
+
}
|
|
4842
|
+
await existingHandle.click(buildActionOptions(effectiveOptions));
|
|
4843
|
+
return true;
|
|
4844
|
+
}
|
|
4845
|
+
await page.click(target, buildActionOptions(effectiveOptions));
|
|
4846
|
+
return true;
|
|
4847
|
+
}
|
|
4848
|
+
const { target: resolvedTarget, dispose } = await resolvePatchedTarget(page, target, { throwOnMissing });
|
|
4849
|
+
try {
|
|
4850
|
+
if (!resolvedTarget) {
|
|
4851
|
+
return false;
|
|
4852
|
+
}
|
|
4853
|
+
if (typeof resolvedTarget.click === "function") {
|
|
4854
|
+
await resolvedTarget.click(buildActionOptions(effectiveOptions));
|
|
4855
|
+
return true;
|
|
4856
|
+
}
|
|
4857
|
+
const box = await resolvedTarget.boundingBox?.();
|
|
4858
|
+
if (!box) {
|
|
4859
|
+
if (throwOnMissing) {
|
|
4860
|
+
throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5143\u7D20\u4F4D\u7F6E");
|
|
4861
|
+
}
|
|
4862
|
+
return false;
|
|
4863
|
+
}
|
|
4864
|
+
await page.mouse.click(box.x + box.width / 2, box.y + box.height / 2);
|
|
4865
|
+
return true;
|
|
4866
|
+
} finally {
|
|
4867
|
+
if (typeof dispose === "function") {
|
|
4868
|
+
await dispose();
|
|
4869
|
+
}
|
|
4870
|
+
}
|
|
4871
|
+
});
|
|
4872
|
+
};
|
|
4873
|
+
var CloakBrowserHumanize = {
|
|
4874
|
+
jitterMs(base, jitterPercent = 0.3) {
|
|
4875
|
+
return jitterMs(base, jitterPercent);
|
|
4876
|
+
},
|
|
4877
|
+
async initializeCursor(page) {
|
|
4878
|
+
if (isMobilePage(page)) {
|
|
4879
|
+
return MobileHumanize.initializeCursor(page);
|
|
4880
|
+
}
|
|
4881
|
+
await ensureDesktopHumanized(page);
|
|
4882
|
+
logger7.debug("initializeCursor: cloakbrowser human layer ready");
|
|
4883
|
+
},
|
|
4884
|
+
async humanMove(page, target) {
|
|
4885
|
+
if (isMobilePage(page)) {
|
|
4886
|
+
return await MobileHumanize.humanMove(page, target);
|
|
4887
|
+
}
|
|
4888
|
+
await ensureDesktopHumanized(page);
|
|
4889
|
+
if (isPoint2(target)) {
|
|
4890
|
+
return await humanMoveToPoint(page, target);
|
|
4891
|
+
}
|
|
4892
|
+
const { target: resolvedTarget, dispose } = await resolvePatchedTarget(page, target, { throwOnMissing: false });
|
|
4893
|
+
try {
|
|
4894
|
+
if (!resolvedTarget) {
|
|
4895
|
+
return false;
|
|
4896
|
+
}
|
|
4897
|
+
if (typeof resolvedTarget.hover === "function") {
|
|
4898
|
+
await resolvedTarget.hover();
|
|
4899
|
+
return true;
|
|
4900
|
+
}
|
|
4901
|
+
const box = await resolvedTarget.boundingBox?.();
|
|
4902
|
+
if (!box) {
|
|
4903
|
+
return false;
|
|
4904
|
+
}
|
|
4905
|
+
await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2);
|
|
4906
|
+
return true;
|
|
4907
|
+
} finally {
|
|
4908
|
+
if (typeof dispose === "function") {
|
|
4909
|
+
await dispose();
|
|
4910
|
+
}
|
|
4911
|
+
}
|
|
4912
|
+
},
|
|
4913
|
+
async humanScroll(page, target, options = {}) {
|
|
4914
|
+
if (isMobilePage(page)) {
|
|
4915
|
+
return await MobileHumanize.humanScroll(page, target, options);
|
|
4916
|
+
}
|
|
4917
|
+
const humanModule = await ensureDesktopHumanized(page);
|
|
4918
|
+
if (typeof target === "string") {
|
|
4919
|
+
const { x = 0, y = 0 } = page._humanCursor || {};
|
|
4920
|
+
try {
|
|
4921
|
+
const result = await humanModule.scrollToElement(
|
|
4922
|
+
page,
|
|
4923
|
+
page._humanRaw,
|
|
4924
|
+
target,
|
|
4925
|
+
x,
|
|
4926
|
+
y,
|
|
4927
|
+
page._humanCfg,
|
|
4928
|
+
options.timeout
|
|
4929
|
+
);
|
|
4930
|
+
if (page._humanCursor) {
|
|
4931
|
+
page._humanCursor.x = result.cursorX;
|
|
4932
|
+
page._humanCursor.y = result.cursorY;
|
|
4933
|
+
}
|
|
4934
|
+
return {
|
|
4935
|
+
element: await page.$(target),
|
|
4936
|
+
didScroll: Boolean(result.didScroll),
|
|
4937
|
+
restore: null
|
|
4938
|
+
};
|
|
4939
|
+
} catch (error) {
|
|
4940
|
+
logger7.warn(`humanScroll: cloakbrowser \u6EDA\u52A8\u5931\u8D25\uFF0C\u8DF3\u8FC7 (${error?.message || error})`);
|
|
4941
|
+
return { element: null, didScroll: false, restore: null };
|
|
4942
|
+
}
|
|
4943
|
+
}
|
|
4944
|
+
const { target: resolvedTarget, dispose } = await resolvePatchedTarget(page, target, { throwOnMissing: false });
|
|
4945
|
+
try {
|
|
4946
|
+
if (!resolvedTarget) {
|
|
4947
|
+
return { element: null, didScroll: false, restore: null };
|
|
4948
|
+
}
|
|
4949
|
+
const before = await page.evaluate(() => ({ x: window.scrollX, y: window.scrollY }));
|
|
4950
|
+
await resolvedTarget.scrollIntoViewIfNeeded?.();
|
|
4951
|
+
const after = await page.evaluate(() => ({ x: window.scrollX, y: window.scrollY }));
|
|
4952
|
+
return {
|
|
4953
|
+
element: resolvedTarget,
|
|
4954
|
+
didScroll: before.x !== after.x || before.y !== after.y,
|
|
4955
|
+
restore: null
|
|
4956
|
+
};
|
|
4957
|
+
} finally {
|
|
4958
|
+
if (typeof dispose === "function") {
|
|
4959
|
+
await dispose();
|
|
4960
|
+
}
|
|
4961
|
+
}
|
|
4962
|
+
},
|
|
4963
|
+
async humanClick(page, target, options = {}) {
|
|
4964
|
+
if (isMobilePage(page)) {
|
|
4965
|
+
return await MobileHumanize.humanClick(page, target, options);
|
|
4966
|
+
}
|
|
4967
|
+
return await doDesktopHumanClick(page, target, options);
|
|
4968
|
+
},
|
|
4969
|
+
async randomSleep(pageOrBaseMs, maybeBaseMs, maybeJitterPercent) {
|
|
4970
|
+
if (isPageLike2(pageOrBaseMs)) {
|
|
4971
|
+
if (isMobilePage(pageOrBaseMs)) {
|
|
4972
|
+
return await MobileHumanize.randomSleep(maybeBaseMs, maybeJitterPercent);
|
|
4973
|
+
}
|
|
4974
|
+
await jitterSleep(maybeBaseMs, maybeJitterPercent ?? 0.3);
|
|
4975
|
+
return;
|
|
4976
|
+
}
|
|
4977
|
+
await jitterSleep(pageOrBaseMs, maybeBaseMs ?? 0.3);
|
|
4978
|
+
},
|
|
4979
|
+
async simulateGaze(page, baseDurationMs = 2500) {
|
|
4980
|
+
if (isMobilePage(page)) {
|
|
4981
|
+
return await MobileHumanize.simulateGaze(page, baseDurationMs);
|
|
4982
|
+
}
|
|
4983
|
+
await ensureDesktopHumanized(page);
|
|
4984
|
+
const durationMs = jitterMs(baseDurationMs, 0.4);
|
|
4985
|
+
const startTime = Date.now();
|
|
4986
|
+
const viewportSize = page.viewportSize() || { width: 1365, height: 900 };
|
|
4987
|
+
while (Date.now() - startTime < durationMs) {
|
|
4988
|
+
await page.mouse.move(
|
|
4989
|
+
100 + Math.random() * Math.max(120, viewportSize.width - 200),
|
|
4990
|
+
100 + Math.random() * Math.max(120, viewportSize.height - 200)
|
|
4991
|
+
);
|
|
4992
|
+
await jitterSleep(600, 0.5);
|
|
4993
|
+
}
|
|
4994
|
+
},
|
|
4995
|
+
async humanType(page, selector, text, options = {}) {
|
|
4996
|
+
if (isMobilePage(page)) {
|
|
4997
|
+
return await MobileHumanize.humanType(page, selector, text, options);
|
|
4998
|
+
}
|
|
4999
|
+
await ensureDesktopHumanized(page);
|
|
5000
|
+
await withPointerEventsForceFallback("humanType", options, async (effectiveOptions = {}) => {
|
|
5001
|
+
const actionOptions = buildActionOptions(effectiveOptions);
|
|
5002
|
+
if (typeof selector === "string") {
|
|
5003
|
+
await page.type(selector, text, actionOptions);
|
|
5004
|
+
return;
|
|
5005
|
+
}
|
|
5006
|
+
const { target: resolvedTarget, dispose } = await resolvePatchedTarget(page, selector, { throwOnMissing: true });
|
|
5007
|
+
try {
|
|
5008
|
+
if (!resolvedTarget || typeof resolvedTarget.type !== "function") {
|
|
5009
|
+
throw new Error("\u76EE\u6807\u5143\u7D20\u4E0D\u652F\u6301 type()");
|
|
5010
|
+
}
|
|
5011
|
+
await resolvedTarget.type(text, actionOptions);
|
|
5012
|
+
} finally {
|
|
5013
|
+
if (typeof dispose === "function") {
|
|
5014
|
+
await dispose();
|
|
5015
|
+
}
|
|
5016
|
+
}
|
|
5017
|
+
});
|
|
5018
|
+
},
|
|
5019
|
+
async humanPress(page, targetOrKey, maybeKey, options = {}) {
|
|
5020
|
+
if (isMobilePage(page)) {
|
|
5021
|
+
return await MobileHumanize.humanPress(page, targetOrKey, maybeKey, options);
|
|
5022
|
+
}
|
|
5023
|
+
await ensureDesktopHumanized(page);
|
|
5024
|
+
const hasTarget = typeof maybeKey === "string";
|
|
5025
|
+
const key = hasTarget ? maybeKey : targetOrKey;
|
|
5026
|
+
const pressOptions = hasTarget ? options : maybeKey || options;
|
|
5027
|
+
if (!hasTarget) {
|
|
5028
|
+
await jitterSleep(pressOptions.reactionDelay ?? 180, 0.45);
|
|
5029
|
+
await page.keyboard.press(key, {
|
|
5030
|
+
...pressOptions.keyboardOptions || {},
|
|
5031
|
+
delay: jitterMs(pressOptions.holdDelay ?? 45, 0.5)
|
|
5032
|
+
});
|
|
5033
|
+
return true;
|
|
5034
|
+
}
|
|
5035
|
+
return await withPointerEventsForceFallback("humanPress", pressOptions, async (effectiveOptions = {}) => {
|
|
5036
|
+
if (typeof targetOrKey === "string") {
|
|
5037
|
+
await page.press(targetOrKey, key, buildActionOptions(effectiveOptions));
|
|
5038
|
+
return true;
|
|
5039
|
+
}
|
|
5040
|
+
const { target: resolvedTarget, dispose } = await resolvePatchedTarget(page, targetOrKey, {
|
|
5041
|
+
throwOnMissing: effectiveOptions.throwOnMissing !== false
|
|
5042
|
+
});
|
|
5043
|
+
try {
|
|
5044
|
+
if (!resolvedTarget) {
|
|
5045
|
+
return false;
|
|
5046
|
+
}
|
|
5047
|
+
if (typeof resolvedTarget.press === "function") {
|
|
5048
|
+
await resolvedTarget.press(key, buildActionOptions(effectiveOptions));
|
|
5049
|
+
return true;
|
|
5050
|
+
}
|
|
5051
|
+
await doDesktopHumanClick(page, targetOrKey, {
|
|
5052
|
+
...effectiveOptions,
|
|
5053
|
+
reactionDelay: effectiveOptions.focusDelay ?? 180
|
|
5054
|
+
});
|
|
5055
|
+
await jitterSleep(effectiveOptions.reactionDelay ?? 180, 0.45);
|
|
5056
|
+
await page.keyboard.press(key, {
|
|
5057
|
+
...effectiveOptions.keyboardOptions || {},
|
|
5058
|
+
delay: jitterMs(effectiveOptions.holdDelay ?? 45, 0.5)
|
|
5059
|
+
});
|
|
5060
|
+
return true;
|
|
5061
|
+
} finally {
|
|
5062
|
+
if (typeof dispose === "function") {
|
|
5063
|
+
await dispose();
|
|
5064
|
+
}
|
|
5065
|
+
}
|
|
5066
|
+
});
|
|
5067
|
+
},
|
|
5068
|
+
async humanClear(page, selector) {
|
|
5069
|
+
if (isMobilePage(page)) {
|
|
5070
|
+
return await MobileHumanize.humanClear(page, selector);
|
|
5071
|
+
}
|
|
5072
|
+
await ensureDesktopHumanized(page);
|
|
5073
|
+
if (typeof page.clear === "function") {
|
|
5074
|
+
await page.clear(selector);
|
|
5075
|
+
return;
|
|
5076
|
+
}
|
|
5077
|
+
await page.fill(selector, "");
|
|
5078
|
+
},
|
|
5079
|
+
async warmUpBrowsing(page, baseDuration = 3500) {
|
|
5080
|
+
if (isMobilePage(page)) {
|
|
5081
|
+
return await MobileHumanize.warmUpBrowsing(page, baseDuration);
|
|
5082
|
+
}
|
|
5083
|
+
await ensureDesktopHumanized(page);
|
|
5084
|
+
const durationMs = jitterMs(baseDuration, 0.4);
|
|
5085
|
+
const startTime = Date.now();
|
|
5086
|
+
const viewportSize = page.viewportSize() || { width: 1365, height: 900 };
|
|
5087
|
+
while (Date.now() - startTime < durationMs) {
|
|
5088
|
+
const action = Math.random();
|
|
5089
|
+
if (action < 0.4) {
|
|
5090
|
+
await page.mouse.move(
|
|
5091
|
+
100 + Math.random() * Math.max(120, viewportSize.width - 200),
|
|
5092
|
+
100 + Math.random() * Math.max(120, viewportSize.height - 200)
|
|
5093
|
+
);
|
|
5094
|
+
await jitterSleep(350, 0.4);
|
|
5095
|
+
continue;
|
|
5096
|
+
}
|
|
5097
|
+
if (action < 0.7) {
|
|
5098
|
+
await page.mouse.wheel(0, (Math.random() - 0.5) * 220);
|
|
5099
|
+
await jitterSleep(500, 0.4);
|
|
5100
|
+
continue;
|
|
5101
|
+
}
|
|
5102
|
+
await jitterSleep(800, 0.5);
|
|
5103
|
+
}
|
|
5104
|
+
},
|
|
5105
|
+
async naturalScroll(page, direction = "down", distance = 300, baseSteps = 5) {
|
|
5106
|
+
if (isMobilePage(page)) {
|
|
5107
|
+
return await MobileHumanize.naturalScroll(page, direction, distance, baseSteps);
|
|
5108
|
+
}
|
|
5109
|
+
await ensureDesktopHumanized(page);
|
|
5110
|
+
const steps = Math.max(3, baseSteps + Math.floor(Math.random() * 3) - 1);
|
|
5111
|
+
const actualDistance = jitterMs(distance, 0.15);
|
|
5112
|
+
const sign = direction === "down" ? 1 : -1;
|
|
5113
|
+
const stepDistance = actualDistance / steps;
|
|
5114
|
+
for (let index = 0; index < steps; index += 1) {
|
|
5115
|
+
const factor = 1 - index / steps * 0.5;
|
|
5116
|
+
const jitter = 0.9 + Math.random() * 0.2;
|
|
5117
|
+
await page.mouse.wheel(0, stepDistance * factor * sign * jitter);
|
|
5118
|
+
await jitterSleep(60 + index * 25, 0.3);
|
|
5119
|
+
}
|
|
5120
|
+
}
|
|
5121
|
+
};
|
|
5122
|
+
|
|
5123
|
+
// src/humanize.js
|
|
5124
|
+
var resolveHumanizeDelegate = () => getToolkitMode() === Mode.CloakBrowser ? CloakBrowserHumanize : DefaultHumanize;
|
|
5125
|
+
var callHumanize = (method, ...args) => {
|
|
5126
|
+
const delegate = resolveHumanizeDelegate();
|
|
5127
|
+
if (typeof delegate?.[method] !== "function") {
|
|
5128
|
+
throw new Error(`Humanize.${method} is not available in ${getToolkitMode()} mode`);
|
|
5129
|
+
}
|
|
5130
|
+
return delegate[method](...args);
|
|
5131
|
+
};
|
|
5132
|
+
var Humanize2 = {
|
|
5133
|
+
jitterMs(base, jitterPercent = 0.3) {
|
|
5134
|
+
return callHumanize("jitterMs", base, jitterPercent);
|
|
5135
|
+
},
|
|
5136
|
+
initializeCursor(page) {
|
|
5137
|
+
return callHumanize("initializeCursor", page);
|
|
5138
|
+
},
|
|
5139
|
+
humanMove(page, target) {
|
|
5140
|
+
return callHumanize("humanMove", page, target);
|
|
5141
|
+
},
|
|
5142
|
+
humanScroll(page, target, options = {}) {
|
|
5143
|
+
return callHumanize("humanScroll", page, target, options);
|
|
5144
|
+
},
|
|
5145
|
+
humanClick(page, target, options = {}) {
|
|
5146
|
+
return callHumanize("humanClick", page, target, options);
|
|
5147
|
+
},
|
|
5148
|
+
randomSleep(pageOrBaseMs, maybeBaseMs, maybeJitterPercent) {
|
|
5149
|
+
return callHumanize("randomSleep", pageOrBaseMs, maybeBaseMs, maybeJitterPercent);
|
|
5150
|
+
},
|
|
5151
|
+
simulateGaze(page, baseDurationMs = 2500) {
|
|
5152
|
+
return callHumanize("simulateGaze", page, baseDurationMs);
|
|
5153
|
+
},
|
|
5154
|
+
humanType(page, selector, text, options = {}) {
|
|
5155
|
+
return callHumanize("humanType", page, selector, text, options);
|
|
5156
|
+
},
|
|
5157
|
+
humanPress(page, targetOrKey, maybeKey, options = {}) {
|
|
5158
|
+
if (typeof maybeKey === "string") {
|
|
5159
|
+
return callHumanize("humanPress", page, targetOrKey, maybeKey, options);
|
|
5160
|
+
}
|
|
5161
|
+
return callHumanize("humanPress", page, targetOrKey, maybeKey || options);
|
|
5162
|
+
},
|
|
5163
|
+
humanClear(page, selector) {
|
|
5164
|
+
return callHumanize("humanClear", page, selector);
|
|
5165
|
+
},
|
|
5166
|
+
warmUpBrowsing(page, baseDuration = 3500) {
|
|
5167
|
+
return callHumanize("warmUpBrowsing", page, baseDuration);
|
|
5168
|
+
},
|
|
5169
|
+
naturalScroll(page, direction = "down", distance = 300, baseSteps = 5) {
|
|
5170
|
+
return callHumanize("naturalScroll", page, direction, distance, baseSteps);
|
|
5171
|
+
}
|
|
5172
|
+
};
|
|
5173
|
+
|
|
5174
|
+
// src/internals/launch/default.js
|
|
4623
5175
|
var import_node_child_process = require("node:child_process");
|
|
4624
5176
|
var import_fingerprint_generator = require("fingerprint-generator");
|
|
4625
5177
|
var import_fingerprint_injector = require("fingerprint-injector");
|
|
@@ -4704,7 +5256,7 @@ var ByPass = {
|
|
|
4704
5256
|
resolveRouteByProxy
|
|
4705
5257
|
};
|
|
4706
5258
|
|
|
4707
|
-
// src/launch.js
|
|
5259
|
+
// src/internals/launch/default.js
|
|
4708
5260
|
var logger8 = createInternalLogger("Launch");
|
|
4709
5261
|
var REQUEST_HOOK_FLAG = Symbol("playwright-toolkit-request-hook");
|
|
4710
5262
|
var injectedContexts = /* @__PURE__ */ new WeakSet();
|
|
@@ -4771,7 +5323,7 @@ var resolveCoreDevice = (core = {}) => {
|
|
|
4771
5323
|
};
|
|
4772
5324
|
var buildFingerprintGenerator = ({ locale, browserMajorVersion, device }) => {
|
|
4773
5325
|
return new import_fingerprint_generator.FingerprintGenerator(
|
|
4774
|
-
|
|
5326
|
+
DefaultAntiCheat.getFingerprintGeneratorOptions({
|
|
4775
5327
|
locale,
|
|
4776
5328
|
browserMajorVersion,
|
|
4777
5329
|
device
|
|
@@ -4815,7 +5367,7 @@ var buildReplayableBrowserProfile = (runtimeState, launcher) => {
|
|
|
4815
5367
|
}
|
|
4816
5368
|
let nextState = RuntimeEnv.rememberState(runtimeState);
|
|
4817
5369
|
let browserProfileCore = RuntimeEnv.getBrowserProfileCore(nextState);
|
|
4818
|
-
const timezoneId = String(browserProfileCore?.timezone_id || "").trim() ||
|
|
5370
|
+
const timezoneId = String(browserProfileCore?.timezone_id || "").trim() || DefaultAntiCheat.getBaseConfig().timezoneId;
|
|
4819
5371
|
const locale = DEFAULT_LOCALE;
|
|
4820
5372
|
const currentBrowserMajorVersion = detectBrowserMajorVersion(launcher);
|
|
4821
5373
|
const storedBrowserMajorVersion = Number(browserProfileCore?.browser_major_version || 0);
|
|
@@ -4924,7 +5476,7 @@ var buildReplayBrowserPoolOptions = (browserProfileCore) => {
|
|
|
4924
5476
|
]
|
|
4925
5477
|
};
|
|
4926
5478
|
};
|
|
4927
|
-
var
|
|
5479
|
+
var DefaultLaunch = {
|
|
4928
5480
|
getPlaywrightCrawlerOptions(options = {}) {
|
|
4929
5481
|
const normalizedOptions = Array.isArray(options) ? { customArgs: options } : options || {};
|
|
4930
5482
|
const {
|
|
@@ -4952,7 +5504,7 @@ var Launch = {
|
|
|
4952
5504
|
const launchLocale = String(replayContext.browserProfileCore?.locale || DEFAULT_LOCALE).trim() || DEFAULT_LOCALE;
|
|
4953
5505
|
const launchOptions = {
|
|
4954
5506
|
args: [
|
|
4955
|
-
...
|
|
5507
|
+
...DefaultAntiCheat.getLaunchArgs({ locale: launchLocale }),
|
|
4956
5508
|
...customArgs
|
|
4957
5509
|
],
|
|
4958
5510
|
ignoreDefaultArgs: ["--enable-automation"]
|
|
@@ -5020,7 +5572,7 @@ var Launch = {
|
|
|
5020
5572
|
browserPoolOptions: replayBrowserPoolOptions || {
|
|
5021
5573
|
useFingerprints: true,
|
|
5022
5574
|
fingerprintOptions: {
|
|
5023
|
-
fingerprintGeneratorOptions:
|
|
5575
|
+
fingerprintGeneratorOptions: DefaultAntiCheat.getFingerprintGeneratorOptions({
|
|
5024
5576
|
locale: launchLocale,
|
|
5025
5577
|
device
|
|
5026
5578
|
})
|
|
@@ -5028,7 +5580,7 @@ var Launch = {
|
|
|
5028
5580
|
prePageCreateHooks: [
|
|
5029
5581
|
(_pageId, browserController, pageOptions = {}) => {
|
|
5030
5582
|
const fingerprintWithHeaders = browserController?.launchContext?.fingerprint;
|
|
5031
|
-
const timezoneId =
|
|
5583
|
+
const timezoneId = DefaultAntiCheat.getBaseConfig().timezoneId;
|
|
5032
5584
|
applyFingerprintPageOptions(pageOptions, {
|
|
5033
5585
|
fingerprintWithHeaders,
|
|
5034
5586
|
locale: launchLocale,
|
|
@@ -5055,7 +5607,7 @@ var Launch = {
|
|
|
5055
5607
|
}
|
|
5056
5608
|
};
|
|
5057
5609
|
|
|
5058
|
-
// src/cloakbrowser.js
|
|
5610
|
+
// src/internals/launch/cloakbrowser.js
|
|
5059
5611
|
var import_node_child_process2 = require("node:child_process");
|
|
5060
5612
|
var import_node_util = require("node:util");
|
|
5061
5613
|
var logger9 = createInternalLogger("CloakBrowser");
|
|
@@ -5197,7 +5749,7 @@ var forceTerminateBrowsersByFingerprintArg = async (fingerprintArg) => {
|
|
|
5197
5749
|
logger9.info(`\u5F3A\u5236\u5173\u95ED CloakBrowser \u8FDB\u7A0B\u5931\u8D25\uFF08\u5FFD\u7565\uFF09: ${error?.message || String(error)}`);
|
|
5198
5750
|
});
|
|
5199
5751
|
};
|
|
5200
|
-
var
|
|
5752
|
+
var CloakBrowserLaunch = {
|
|
5201
5753
|
resolveProxyConfiguration(proxyConfiguration = {}) {
|
|
5202
5754
|
return resolveCloakBrowserProxy(proxyConfiguration);
|
|
5203
5755
|
},
|
|
@@ -5207,6 +5759,10 @@ var CloakBrowser = {
|
|
|
5207
5759
|
createStableGotoHook(recommendedGotoOptions = DEFAULT_CLOAK_GOTO_OPTIONS) {
|
|
5208
5760
|
return createStableGotoHook(recommendedGotoOptions);
|
|
5209
5761
|
},
|
|
5762
|
+
async getPlaywrightCrawlerOptions(options = {}) {
|
|
5763
|
+
const { crawlerOptions } = await CloakBrowserLaunch.createPlaywrightCrawlerRuntime(options);
|
|
5764
|
+
return crawlerOptions;
|
|
5765
|
+
},
|
|
5210
5766
|
async buildLaunchOptions(options = {}) {
|
|
5211
5767
|
return await buildCloakLaunchOptions(options);
|
|
5212
5768
|
},
|
|
@@ -5284,26 +5840,35 @@ var CloakBrowser = {
|
|
|
5284
5840
|
};
|
|
5285
5841
|
}
|
|
5286
5842
|
};
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
}
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
}
|
|
5843
|
+
|
|
5844
|
+
// src/launch.js
|
|
5845
|
+
var resolveLaunchDelegate = () => getToolkitMode() === Mode.CloakBrowser ? CloakBrowserLaunch : DefaultLaunch;
|
|
5846
|
+
var callLaunch = (method, ...args) => {
|
|
5847
|
+
const delegate = resolveLaunchDelegate();
|
|
5848
|
+
if (typeof delegate?.[method] !== "function") {
|
|
5849
|
+
throw new Error(`Launch.${method} is not available in ${getToolkitMode()} mode`);
|
|
5850
|
+
}
|
|
5851
|
+
return delegate[method](...args);
|
|
5852
|
+
};
|
|
5853
|
+
var Launch = {
|
|
5854
|
+
getPlaywrightCrawlerOptions(options = {}) {
|
|
5855
|
+
return callLaunch("getPlaywrightCrawlerOptions", options);
|
|
5856
|
+
},
|
|
5857
|
+
resolveProxyConfiguration(proxyConfiguration = {}) {
|
|
5858
|
+
return callLaunch("resolveProxyConfiguration", proxyConfiguration);
|
|
5859
|
+
},
|
|
5860
|
+
extractFingerprintArg(launchOptions = {}) {
|
|
5861
|
+
return callLaunch("extractFingerprintArg", launchOptions);
|
|
5862
|
+
},
|
|
5863
|
+
createStableGotoHook(recommendedGotoOptions = {}) {
|
|
5864
|
+
return callLaunch("createStableGotoHook", recommendedGotoOptions);
|
|
5865
|
+
},
|
|
5866
|
+
buildLaunchOptions(options = {}) {
|
|
5867
|
+
return callLaunch("buildLaunchOptions", options);
|
|
5868
|
+
},
|
|
5869
|
+
createPlaywrightCrawlerRuntime(options = {}) {
|
|
5870
|
+
return callLaunch("createPlaywrightCrawlerRuntime", options);
|
|
5871
|
+
}
|
|
5307
5872
|
};
|
|
5308
5873
|
|
|
5309
5874
|
// src/live-view.js
|
|
@@ -7673,7 +8238,7 @@ var Logger = {
|
|
|
7673
8238
|
};
|
|
7674
8239
|
|
|
7675
8240
|
// src/share.js
|
|
7676
|
-
var
|
|
8241
|
+
var import_delay5 = __toESM(require("delay"), 1);
|
|
7677
8242
|
|
|
7678
8243
|
// src/internals/watermarkify.js
|
|
7679
8244
|
var DEFAULT_TIMEZONE_OFFSET = 8;
|
|
@@ -9744,7 +10309,7 @@ var Share = {
|
|
|
9744
10309
|
);
|
|
9745
10310
|
nextProgressLogTs = now + 5e3;
|
|
9746
10311
|
}
|
|
9747
|
-
await (0,
|
|
10312
|
+
await (0, import_delay5.default)(Math.max(0, Math.min(DEFAULT_POLL_INTERVAL_MS, remaining)));
|
|
9748
10313
|
}
|
|
9749
10314
|
if (!timeoutDisabled && share.mode === "response" && stats.responseMatched === 0) {
|
|
9750
10315
|
logger16.warning(
|
|
@@ -9810,14 +10375,14 @@ var Share = {
|
|
|
9810
10375
|
// entrys/node.js
|
|
9811
10376
|
Logger.setLogger(import_crawlee.log);
|
|
9812
10377
|
var usePlaywrightToolKit = (mode = "default") => {
|
|
9813
|
-
|
|
10378
|
+
setToolkitMode(mode);
|
|
9814
10379
|
const toolkit = {
|
|
9815
10380
|
ApifyKit,
|
|
9816
10381
|
AntiCheat,
|
|
9817
10382
|
DeviceInput,
|
|
9818
10383
|
DeviceView,
|
|
9819
10384
|
Humanize: Humanize2,
|
|
9820
|
-
Launch
|
|
10385
|
+
Launch,
|
|
9821
10386
|
LiveView,
|
|
9822
10387
|
Constants: constants_exports,
|
|
9823
10388
|
Utils,
|