@skrillex1224/playwright-toolkit 2.1.275 → 2.1.277
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 +700 -138
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +700 -138
- package/dist/index.js.map +4 -4
- package/index.d.ts +14 -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,480 @@ 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 ensureDesktopHumanized = async (page) => {
|
|
4724
|
+
if (!page || typeof page !== "object") {
|
|
4725
|
+
throw new Error("Humanize requires a Playwright page");
|
|
4726
|
+
}
|
|
4727
|
+
const humanModule = await loadCloakHumanModule();
|
|
4728
|
+
if (page._original && page._humanCursor) {
|
|
4729
|
+
humanizedPages.add(page);
|
|
4730
|
+
return humanModule;
|
|
4731
|
+
}
|
|
4732
|
+
if (humanizedPages.has(page)) {
|
|
4733
|
+
return humanModule;
|
|
4734
|
+
}
|
|
4735
|
+
const config = page._humanCfg || humanModule.resolveConfig?.("default") || humanModule.resolveConfig?.();
|
|
4736
|
+
const cursor = page._humanCursor || { x: 0, y: 0, initialized: false };
|
|
4737
|
+
humanModule.patchPage(page, config, cursor);
|
|
4738
|
+
humanizedPages.add(page);
|
|
4739
|
+
return humanModule;
|
|
4740
|
+
};
|
|
4741
|
+
var patchHandle = async (page, handle) => {
|
|
4742
|
+
if (!handle || typeof handle !== "object") return handle;
|
|
4743
|
+
const humanModule = await ensureDesktopHumanized(page);
|
|
4744
|
+
humanModule.patchSingleElementHandle(
|
|
4745
|
+
handle,
|
|
4746
|
+
page,
|
|
4747
|
+
page._humanCfg,
|
|
4748
|
+
page._humanCursor,
|
|
4749
|
+
page._humanRaw,
|
|
4750
|
+
page._humanRawKb,
|
|
4751
|
+
page._humanOriginals,
|
|
4752
|
+
page._stealth
|
|
4753
|
+
);
|
|
4754
|
+
return handle;
|
|
4755
|
+
};
|
|
4756
|
+
var resolvePatchedTarget = async (page, target, { throwOnMissing = true } = {}) => {
|
|
4757
|
+
if (target == null) {
|
|
4758
|
+
return { target: null, dispose: null };
|
|
4759
|
+
}
|
|
4760
|
+
if (typeof target === "string") {
|
|
4761
|
+
const handle = await page.$(target);
|
|
4762
|
+
if (!handle) {
|
|
4763
|
+
if (throwOnMissing) {
|
|
4764
|
+
throw new Error(`\u627E\u4E0D\u5230\u5143\u7D20 ${String(target)}`);
|
|
4765
|
+
}
|
|
4766
|
+
return { target: null, dispose: null };
|
|
4767
|
+
}
|
|
4768
|
+
return { target: handle, dispose: null };
|
|
4769
|
+
}
|
|
4770
|
+
if (typeof target.elementHandle === "function") {
|
|
4771
|
+
const handle = await target.elementHandle();
|
|
4772
|
+
if (!handle) {
|
|
4773
|
+
if (throwOnMissing) {
|
|
4774
|
+
throw new Error("\u627E\u4E0D\u5230 locator \u5BF9\u5E94\u7684\u5143\u7D20");
|
|
4775
|
+
}
|
|
4776
|
+
return { target: null, dispose: null };
|
|
4777
|
+
}
|
|
4778
|
+
await patchHandle(page, handle);
|
|
4779
|
+
return {
|
|
4780
|
+
target: handle,
|
|
4781
|
+
dispose: async () => {
|
|
4782
|
+
await handle.dispose().catch(() => {
|
|
4783
|
+
});
|
|
4784
|
+
}
|
|
4785
|
+
};
|
|
4786
|
+
}
|
|
4787
|
+
await patchHandle(page, target);
|
|
4788
|
+
return { target, dispose: null };
|
|
4789
|
+
};
|
|
4790
|
+
var jitterSleep = async (baseMs, jitterPercent = 0.3) => {
|
|
4791
|
+
await (0, import_delay4.default)(jitterMs(baseMs, jitterPercent));
|
|
4792
|
+
};
|
|
4793
|
+
var humanMoveToPoint = async (page, point) => {
|
|
4794
|
+
await ensureDesktopHumanized(page);
|
|
4795
|
+
await page.mouse.move(Number(point.x), Number(point.y));
|
|
4796
|
+
return true;
|
|
4797
|
+
};
|
|
4798
|
+
var doDesktopHumanClick = async (page, target, options = {}) => {
|
|
4799
|
+
await ensureDesktopHumanized(page);
|
|
4800
|
+
if (target == null) {
|
|
4801
|
+
const cursor = page._humanCursor || { x: 0, y: 0 };
|
|
4802
|
+
await page.mouse.click(cursor.x || 0, cursor.y || 0);
|
|
4803
|
+
return true;
|
|
4804
|
+
}
|
|
4805
|
+
if (isPoint2(target)) {
|
|
4806
|
+
return humanMoveToPoint(page, target).then(async () => {
|
|
4807
|
+
await page.mouse.click(Number(target.x), Number(target.y));
|
|
4808
|
+
return true;
|
|
4809
|
+
});
|
|
4810
|
+
}
|
|
4811
|
+
const throwOnMissing = options.throwOnMissing !== false;
|
|
4812
|
+
if (typeof target === "string") {
|
|
4813
|
+
if (!throwOnMissing) {
|
|
4814
|
+
const existingHandle = await page.$(target);
|
|
4815
|
+
if (!existingHandle) {
|
|
4816
|
+
return false;
|
|
4817
|
+
}
|
|
4818
|
+
await existingHandle.click(buildActionOptions(options));
|
|
4819
|
+
return true;
|
|
4820
|
+
}
|
|
4821
|
+
await page.click(target, buildActionOptions(options));
|
|
4822
|
+
return true;
|
|
4823
|
+
}
|
|
4824
|
+
const { target: resolvedTarget, dispose } = await resolvePatchedTarget(page, target, { throwOnMissing });
|
|
4825
|
+
try {
|
|
4826
|
+
if (!resolvedTarget) {
|
|
4827
|
+
return false;
|
|
4828
|
+
}
|
|
4829
|
+
if (typeof resolvedTarget.click === "function") {
|
|
4830
|
+
await resolvedTarget.click(buildActionOptions(options));
|
|
4831
|
+
return true;
|
|
4832
|
+
}
|
|
4833
|
+
const box = await resolvedTarget.boundingBox?.();
|
|
4834
|
+
if (!box) {
|
|
4835
|
+
if (throwOnMissing) {
|
|
4836
|
+
throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5143\u7D20\u4F4D\u7F6E");
|
|
4837
|
+
}
|
|
4838
|
+
return false;
|
|
4839
|
+
}
|
|
4840
|
+
await page.mouse.click(box.x + box.width / 2, box.y + box.height / 2);
|
|
4841
|
+
return true;
|
|
4842
|
+
} finally {
|
|
4843
|
+
if (typeof dispose === "function") {
|
|
4844
|
+
await dispose();
|
|
4845
|
+
}
|
|
4846
|
+
}
|
|
4847
|
+
};
|
|
4848
|
+
var CloakBrowserHumanize = {
|
|
4849
|
+
jitterMs(base, jitterPercent = 0.3) {
|
|
4850
|
+
return jitterMs(base, jitterPercent);
|
|
4851
|
+
},
|
|
4852
|
+
async initializeCursor(page) {
|
|
4853
|
+
if (isMobilePage(page)) {
|
|
4854
|
+
return MobileHumanize.initializeCursor(page);
|
|
4855
|
+
}
|
|
4856
|
+
await ensureDesktopHumanized(page);
|
|
4857
|
+
logger7.debug("initializeCursor: cloakbrowser human layer ready");
|
|
4858
|
+
},
|
|
4859
|
+
async humanMove(page, target) {
|
|
4860
|
+
if (isMobilePage(page)) {
|
|
4861
|
+
return await MobileHumanize.humanMove(page, target);
|
|
4862
|
+
}
|
|
4863
|
+
await ensureDesktopHumanized(page);
|
|
4864
|
+
if (isPoint2(target)) {
|
|
4865
|
+
return await humanMoveToPoint(page, target);
|
|
4866
|
+
}
|
|
4867
|
+
const { target: resolvedTarget, dispose } = await resolvePatchedTarget(page, target, { throwOnMissing: false });
|
|
4868
|
+
try {
|
|
4869
|
+
if (!resolvedTarget) {
|
|
4870
|
+
return false;
|
|
4871
|
+
}
|
|
4872
|
+
if (typeof resolvedTarget.hover === "function") {
|
|
4873
|
+
await resolvedTarget.hover();
|
|
4874
|
+
return true;
|
|
4875
|
+
}
|
|
4876
|
+
const box = await resolvedTarget.boundingBox?.();
|
|
4877
|
+
if (!box) {
|
|
4878
|
+
return false;
|
|
4879
|
+
}
|
|
4880
|
+
await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2);
|
|
4881
|
+
return true;
|
|
4882
|
+
} finally {
|
|
4883
|
+
if (typeof dispose === "function") {
|
|
4884
|
+
await dispose();
|
|
4885
|
+
}
|
|
4886
|
+
}
|
|
4887
|
+
},
|
|
4888
|
+
async humanScroll(page, target, options = {}) {
|
|
4889
|
+
if (isMobilePage(page)) {
|
|
4890
|
+
return await MobileHumanize.humanScroll(page, target, options);
|
|
4891
|
+
}
|
|
4892
|
+
const humanModule = await ensureDesktopHumanized(page);
|
|
4893
|
+
if (typeof target === "string") {
|
|
4894
|
+
const { x = 0, y = 0 } = page._humanCursor || {};
|
|
4895
|
+
try {
|
|
4896
|
+
const result = await humanModule.scrollToElement(
|
|
4897
|
+
page,
|
|
4898
|
+
page._humanRaw,
|
|
4899
|
+
target,
|
|
4900
|
+
x,
|
|
4901
|
+
y,
|
|
4902
|
+
page._humanCfg,
|
|
4903
|
+
options.timeout
|
|
4904
|
+
);
|
|
4905
|
+
if (page._humanCursor) {
|
|
4906
|
+
page._humanCursor.x = result.cursorX;
|
|
4907
|
+
page._humanCursor.y = result.cursorY;
|
|
4908
|
+
}
|
|
4909
|
+
return {
|
|
4910
|
+
element: await page.$(target),
|
|
4911
|
+
didScroll: Boolean(result.didScroll),
|
|
4912
|
+
restore: null
|
|
4913
|
+
};
|
|
4914
|
+
} catch (error) {
|
|
4915
|
+
logger7.warn(`humanScroll: cloakbrowser \u6EDA\u52A8\u5931\u8D25\uFF0C\u8DF3\u8FC7 (${error?.message || error})`);
|
|
4916
|
+
return { element: null, didScroll: false, restore: null };
|
|
4917
|
+
}
|
|
4918
|
+
}
|
|
4919
|
+
const { target: resolvedTarget, dispose } = await resolvePatchedTarget(page, target, { throwOnMissing: false });
|
|
4920
|
+
try {
|
|
4921
|
+
if (!resolvedTarget) {
|
|
4922
|
+
return { element: null, didScroll: false, restore: null };
|
|
4923
|
+
}
|
|
4924
|
+
const before = await page.evaluate(() => ({ x: window.scrollX, y: window.scrollY }));
|
|
4925
|
+
await resolvedTarget.scrollIntoViewIfNeeded?.();
|
|
4926
|
+
const after = await page.evaluate(() => ({ x: window.scrollX, y: window.scrollY }));
|
|
4927
|
+
return {
|
|
4928
|
+
element: resolvedTarget,
|
|
4929
|
+
didScroll: before.x !== after.x || before.y !== after.y,
|
|
4930
|
+
restore: null
|
|
4931
|
+
};
|
|
4932
|
+
} finally {
|
|
4933
|
+
if (typeof dispose === "function") {
|
|
4934
|
+
await dispose();
|
|
4935
|
+
}
|
|
4936
|
+
}
|
|
4937
|
+
},
|
|
4938
|
+
async humanClick(page, target, options = {}) {
|
|
4939
|
+
if (isMobilePage(page)) {
|
|
4940
|
+
return await MobileHumanize.humanClick(page, target, options);
|
|
4941
|
+
}
|
|
4942
|
+
return await doDesktopHumanClick(page, target, options);
|
|
4943
|
+
},
|
|
4944
|
+
async randomSleep(pageOrBaseMs, maybeBaseMs, maybeJitterPercent) {
|
|
4945
|
+
if (isPageLike2(pageOrBaseMs)) {
|
|
4946
|
+
if (isMobilePage(pageOrBaseMs)) {
|
|
4947
|
+
return await MobileHumanize.randomSleep(maybeBaseMs, maybeJitterPercent);
|
|
4948
|
+
}
|
|
4949
|
+
await jitterSleep(maybeBaseMs, maybeJitterPercent ?? 0.3);
|
|
4950
|
+
return;
|
|
4951
|
+
}
|
|
4952
|
+
await jitterSleep(pageOrBaseMs, maybeBaseMs ?? 0.3);
|
|
4953
|
+
},
|
|
4954
|
+
async simulateGaze(page, baseDurationMs = 2500) {
|
|
4955
|
+
if (isMobilePage(page)) {
|
|
4956
|
+
return await MobileHumanize.simulateGaze(page, baseDurationMs);
|
|
4957
|
+
}
|
|
4958
|
+
await ensureDesktopHumanized(page);
|
|
4959
|
+
const durationMs = jitterMs(baseDurationMs, 0.4);
|
|
4960
|
+
const startTime = Date.now();
|
|
4961
|
+
const viewportSize = page.viewportSize() || { width: 1365, height: 900 };
|
|
4962
|
+
while (Date.now() - startTime < durationMs) {
|
|
4963
|
+
await page.mouse.move(
|
|
4964
|
+
100 + Math.random() * Math.max(120, viewportSize.width - 200),
|
|
4965
|
+
100 + Math.random() * Math.max(120, viewportSize.height - 200)
|
|
4966
|
+
);
|
|
4967
|
+
await jitterSleep(600, 0.5);
|
|
4968
|
+
}
|
|
4969
|
+
},
|
|
4970
|
+
async humanType(page, selector, text, options = {}) {
|
|
4971
|
+
if (isMobilePage(page)) {
|
|
4972
|
+
return await MobileHumanize.humanType(page, selector, text, options);
|
|
4973
|
+
}
|
|
4974
|
+
await ensureDesktopHumanized(page);
|
|
4975
|
+
const actionOptions = buildActionOptions(options);
|
|
4976
|
+
if (typeof selector === "string") {
|
|
4977
|
+
await page.type(selector, text, actionOptions);
|
|
4978
|
+
return;
|
|
4979
|
+
}
|
|
4980
|
+
const { target: resolvedTarget, dispose } = await resolvePatchedTarget(page, selector, { throwOnMissing: true });
|
|
4981
|
+
try {
|
|
4982
|
+
if (!resolvedTarget || typeof resolvedTarget.type !== "function") {
|
|
4983
|
+
throw new Error("\u76EE\u6807\u5143\u7D20\u4E0D\u652F\u6301 type()");
|
|
4984
|
+
}
|
|
4985
|
+
await resolvedTarget.type(text, actionOptions);
|
|
4986
|
+
} finally {
|
|
4987
|
+
if (typeof dispose === "function") {
|
|
4988
|
+
await dispose();
|
|
4989
|
+
}
|
|
4990
|
+
}
|
|
4991
|
+
},
|
|
4992
|
+
async humanPress(page, targetOrKey, maybeKey, options = {}) {
|
|
4993
|
+
if (isMobilePage(page)) {
|
|
4994
|
+
return await MobileHumanize.humanPress(page, targetOrKey, maybeKey, options);
|
|
4995
|
+
}
|
|
4996
|
+
await ensureDesktopHumanized(page);
|
|
4997
|
+
const hasTarget = typeof maybeKey === "string";
|
|
4998
|
+
const key = hasTarget ? maybeKey : targetOrKey;
|
|
4999
|
+
const pressOptions = hasTarget ? options : maybeKey || options;
|
|
5000
|
+
if (!hasTarget) {
|
|
5001
|
+
await jitterSleep(pressOptions.reactionDelay ?? 180, 0.45);
|
|
5002
|
+
await page.keyboard.press(key, {
|
|
5003
|
+
...pressOptions.keyboardOptions || {},
|
|
5004
|
+
delay: jitterMs(pressOptions.holdDelay ?? 45, 0.5)
|
|
5005
|
+
});
|
|
5006
|
+
return true;
|
|
5007
|
+
}
|
|
5008
|
+
if (typeof targetOrKey === "string") {
|
|
5009
|
+
await page.press(targetOrKey, key, buildActionOptions(pressOptions));
|
|
5010
|
+
return true;
|
|
5011
|
+
}
|
|
5012
|
+
const { target: resolvedTarget, dispose } = await resolvePatchedTarget(page, targetOrKey, {
|
|
5013
|
+
throwOnMissing: pressOptions.throwOnMissing !== false
|
|
5014
|
+
});
|
|
5015
|
+
try {
|
|
5016
|
+
if (!resolvedTarget) {
|
|
5017
|
+
return false;
|
|
5018
|
+
}
|
|
5019
|
+
if (typeof resolvedTarget.press === "function") {
|
|
5020
|
+
await resolvedTarget.press(key, buildActionOptions(pressOptions));
|
|
5021
|
+
return true;
|
|
5022
|
+
}
|
|
5023
|
+
await doDesktopHumanClick(page, targetOrKey, {
|
|
5024
|
+
...pressOptions,
|
|
5025
|
+
reactionDelay: pressOptions.focusDelay ?? 180
|
|
5026
|
+
});
|
|
5027
|
+
await jitterSleep(pressOptions.reactionDelay ?? 180, 0.45);
|
|
5028
|
+
await page.keyboard.press(key, {
|
|
5029
|
+
...pressOptions.keyboardOptions || {},
|
|
5030
|
+
delay: jitterMs(pressOptions.holdDelay ?? 45, 0.5)
|
|
5031
|
+
});
|
|
5032
|
+
return true;
|
|
5033
|
+
} finally {
|
|
5034
|
+
if (typeof dispose === "function") {
|
|
5035
|
+
await dispose();
|
|
5036
|
+
}
|
|
5037
|
+
}
|
|
5038
|
+
},
|
|
5039
|
+
async humanClear(page, selector) {
|
|
5040
|
+
if (isMobilePage(page)) {
|
|
5041
|
+
return await MobileHumanize.humanClear(page, selector);
|
|
5042
|
+
}
|
|
5043
|
+
await ensureDesktopHumanized(page);
|
|
5044
|
+
if (typeof page.clear === "function") {
|
|
5045
|
+
await page.clear(selector);
|
|
5046
|
+
return;
|
|
5047
|
+
}
|
|
5048
|
+
await page.fill(selector, "");
|
|
5049
|
+
},
|
|
5050
|
+
async warmUpBrowsing(page, baseDuration = 3500) {
|
|
5051
|
+
if (isMobilePage(page)) {
|
|
5052
|
+
return await MobileHumanize.warmUpBrowsing(page, baseDuration);
|
|
5053
|
+
}
|
|
5054
|
+
await ensureDesktopHumanized(page);
|
|
5055
|
+
const durationMs = jitterMs(baseDuration, 0.4);
|
|
5056
|
+
const startTime = Date.now();
|
|
5057
|
+
const viewportSize = page.viewportSize() || { width: 1365, height: 900 };
|
|
5058
|
+
while (Date.now() - startTime < durationMs) {
|
|
5059
|
+
const action = Math.random();
|
|
5060
|
+
if (action < 0.4) {
|
|
5061
|
+
await page.mouse.move(
|
|
5062
|
+
100 + Math.random() * Math.max(120, viewportSize.width - 200),
|
|
5063
|
+
100 + Math.random() * Math.max(120, viewportSize.height - 200)
|
|
5064
|
+
);
|
|
5065
|
+
await jitterSleep(350, 0.4);
|
|
5066
|
+
continue;
|
|
5067
|
+
}
|
|
5068
|
+
if (action < 0.7) {
|
|
5069
|
+
await page.mouse.wheel(0, (Math.random() - 0.5) * 220);
|
|
5070
|
+
await jitterSleep(500, 0.4);
|
|
5071
|
+
continue;
|
|
5072
|
+
}
|
|
5073
|
+
await jitterSleep(800, 0.5);
|
|
5074
|
+
}
|
|
5075
|
+
},
|
|
5076
|
+
async naturalScroll(page, direction = "down", distance = 300, baseSteps = 5) {
|
|
5077
|
+
if (isMobilePage(page)) {
|
|
5078
|
+
return await MobileHumanize.naturalScroll(page, direction, distance, baseSteps);
|
|
5079
|
+
}
|
|
5080
|
+
await ensureDesktopHumanized(page);
|
|
5081
|
+
const steps = Math.max(3, baseSteps + Math.floor(Math.random() * 3) - 1);
|
|
5082
|
+
const actualDistance = jitterMs(distance, 0.15);
|
|
5083
|
+
const sign = direction === "down" ? 1 : -1;
|
|
5084
|
+
const stepDistance = actualDistance / steps;
|
|
5085
|
+
for (let index = 0; index < steps; index += 1) {
|
|
5086
|
+
const factor = 1 - index / steps * 0.5;
|
|
5087
|
+
const jitter = 0.9 + Math.random() * 0.2;
|
|
5088
|
+
await page.mouse.wheel(0, stepDistance * factor * sign * jitter);
|
|
5089
|
+
await jitterSleep(60 + index * 25, 0.3);
|
|
5090
|
+
}
|
|
5091
|
+
}
|
|
5092
|
+
};
|
|
5093
|
+
|
|
5094
|
+
// src/humanize.js
|
|
5095
|
+
var resolveHumanizeDelegate = () => getToolkitMode() === Mode.CloakBrowser ? CloakBrowserHumanize : DefaultHumanize;
|
|
5096
|
+
var callHumanize = (method, ...args) => {
|
|
5097
|
+
const delegate = resolveHumanizeDelegate();
|
|
5098
|
+
if (typeof delegate?.[method] !== "function") {
|
|
5099
|
+
throw new Error(`Humanize.${method} is not available in ${getToolkitMode()} mode`);
|
|
5100
|
+
}
|
|
5101
|
+
return delegate[method](...args);
|
|
5102
|
+
};
|
|
5103
|
+
var Humanize2 = {
|
|
5104
|
+
jitterMs(base, jitterPercent = 0.3) {
|
|
5105
|
+
return callHumanize("jitterMs", base, jitterPercent);
|
|
5106
|
+
},
|
|
5107
|
+
initializeCursor(page) {
|
|
5108
|
+
return callHumanize("initializeCursor", page);
|
|
5109
|
+
},
|
|
5110
|
+
humanMove(page, target) {
|
|
5111
|
+
return callHumanize("humanMove", page, target);
|
|
5112
|
+
},
|
|
5113
|
+
humanScroll(page, target, options = {}) {
|
|
5114
|
+
return callHumanize("humanScroll", page, target, options);
|
|
5115
|
+
},
|
|
5116
|
+
humanClick(page, target, options = {}) {
|
|
5117
|
+
return callHumanize("humanClick", page, target, options);
|
|
5118
|
+
},
|
|
5119
|
+
randomSleep(pageOrBaseMs, maybeBaseMs, maybeJitterPercent) {
|
|
5120
|
+
return callHumanize("randomSleep", pageOrBaseMs, maybeBaseMs, maybeJitterPercent);
|
|
5121
|
+
},
|
|
5122
|
+
simulateGaze(page, baseDurationMs = 2500) {
|
|
5123
|
+
return callHumanize("simulateGaze", page, baseDurationMs);
|
|
5124
|
+
},
|
|
5125
|
+
humanType(page, selector, text, options = {}) {
|
|
5126
|
+
return callHumanize("humanType", page, selector, text, options);
|
|
5127
|
+
},
|
|
5128
|
+
humanPress(page, targetOrKey, maybeKey, options = {}) {
|
|
5129
|
+
if (typeof maybeKey === "string") {
|
|
5130
|
+
return callHumanize("humanPress", page, targetOrKey, maybeKey, options);
|
|
5131
|
+
}
|
|
5132
|
+
return callHumanize("humanPress", page, targetOrKey, maybeKey || options);
|
|
5133
|
+
},
|
|
5134
|
+
humanClear(page, selector) {
|
|
5135
|
+
return callHumanize("humanClear", page, selector);
|
|
5136
|
+
},
|
|
5137
|
+
warmUpBrowsing(page, baseDuration = 3500) {
|
|
5138
|
+
return callHumanize("warmUpBrowsing", page, baseDuration);
|
|
5139
|
+
},
|
|
5140
|
+
naturalScroll(page, direction = "down", distance = 300, baseSteps = 5) {
|
|
5141
|
+
return callHumanize("naturalScroll", page, direction, distance, baseSteps);
|
|
5142
|
+
}
|
|
5143
|
+
};
|
|
5144
|
+
|
|
5145
|
+
// src/internals/launch/default.js
|
|
4623
5146
|
var import_node_child_process = require("node:child_process");
|
|
4624
5147
|
var import_fingerprint_generator = require("fingerprint-generator");
|
|
4625
5148
|
var import_fingerprint_injector = require("fingerprint-injector");
|
|
@@ -4704,7 +5227,7 @@ var ByPass = {
|
|
|
4704
5227
|
resolveRouteByProxy
|
|
4705
5228
|
};
|
|
4706
5229
|
|
|
4707
|
-
// src/launch.js
|
|
5230
|
+
// src/internals/launch/default.js
|
|
4708
5231
|
var logger8 = createInternalLogger("Launch");
|
|
4709
5232
|
var REQUEST_HOOK_FLAG = Symbol("playwright-toolkit-request-hook");
|
|
4710
5233
|
var injectedContexts = /* @__PURE__ */ new WeakSet();
|
|
@@ -4771,7 +5294,7 @@ var resolveCoreDevice = (core = {}) => {
|
|
|
4771
5294
|
};
|
|
4772
5295
|
var buildFingerprintGenerator = ({ locale, browserMajorVersion, device }) => {
|
|
4773
5296
|
return new import_fingerprint_generator.FingerprintGenerator(
|
|
4774
|
-
|
|
5297
|
+
DefaultAntiCheat.getFingerprintGeneratorOptions({
|
|
4775
5298
|
locale,
|
|
4776
5299
|
browserMajorVersion,
|
|
4777
5300
|
device
|
|
@@ -4815,7 +5338,7 @@ var buildReplayableBrowserProfile = (runtimeState, launcher) => {
|
|
|
4815
5338
|
}
|
|
4816
5339
|
let nextState = RuntimeEnv.rememberState(runtimeState);
|
|
4817
5340
|
let browserProfileCore = RuntimeEnv.getBrowserProfileCore(nextState);
|
|
4818
|
-
const timezoneId = String(browserProfileCore?.timezone_id || "").trim() ||
|
|
5341
|
+
const timezoneId = String(browserProfileCore?.timezone_id || "").trim() || DefaultAntiCheat.getBaseConfig().timezoneId;
|
|
4819
5342
|
const locale = DEFAULT_LOCALE;
|
|
4820
5343
|
const currentBrowserMajorVersion = detectBrowserMajorVersion(launcher);
|
|
4821
5344
|
const storedBrowserMajorVersion = Number(browserProfileCore?.browser_major_version || 0);
|
|
@@ -4924,7 +5447,7 @@ var buildReplayBrowserPoolOptions = (browserProfileCore) => {
|
|
|
4924
5447
|
]
|
|
4925
5448
|
};
|
|
4926
5449
|
};
|
|
4927
|
-
var
|
|
5450
|
+
var DefaultLaunch = {
|
|
4928
5451
|
getPlaywrightCrawlerOptions(options = {}) {
|
|
4929
5452
|
const normalizedOptions = Array.isArray(options) ? { customArgs: options } : options || {};
|
|
4930
5453
|
const {
|
|
@@ -4952,7 +5475,7 @@ var Launch = {
|
|
|
4952
5475
|
const launchLocale = String(replayContext.browserProfileCore?.locale || DEFAULT_LOCALE).trim() || DEFAULT_LOCALE;
|
|
4953
5476
|
const launchOptions = {
|
|
4954
5477
|
args: [
|
|
4955
|
-
...
|
|
5478
|
+
...DefaultAntiCheat.getLaunchArgs({ locale: launchLocale }),
|
|
4956
5479
|
...customArgs
|
|
4957
5480
|
],
|
|
4958
5481
|
ignoreDefaultArgs: ["--enable-automation"]
|
|
@@ -5020,7 +5543,7 @@ var Launch = {
|
|
|
5020
5543
|
browserPoolOptions: replayBrowserPoolOptions || {
|
|
5021
5544
|
useFingerprints: true,
|
|
5022
5545
|
fingerprintOptions: {
|
|
5023
|
-
fingerprintGeneratorOptions:
|
|
5546
|
+
fingerprintGeneratorOptions: DefaultAntiCheat.getFingerprintGeneratorOptions({
|
|
5024
5547
|
locale: launchLocale,
|
|
5025
5548
|
device
|
|
5026
5549
|
})
|
|
@@ -5028,7 +5551,7 @@ var Launch = {
|
|
|
5028
5551
|
prePageCreateHooks: [
|
|
5029
5552
|
(_pageId, browserController, pageOptions = {}) => {
|
|
5030
5553
|
const fingerprintWithHeaders = browserController?.launchContext?.fingerprint;
|
|
5031
|
-
const timezoneId =
|
|
5554
|
+
const timezoneId = DefaultAntiCheat.getBaseConfig().timezoneId;
|
|
5032
5555
|
applyFingerprintPageOptions(pageOptions, {
|
|
5033
5556
|
fingerprintWithHeaders,
|
|
5034
5557
|
locale: launchLocale,
|
|
@@ -5055,7 +5578,7 @@ var Launch = {
|
|
|
5055
5578
|
}
|
|
5056
5579
|
};
|
|
5057
5580
|
|
|
5058
|
-
// src/cloakbrowser.js
|
|
5581
|
+
// src/internals/launch/cloakbrowser.js
|
|
5059
5582
|
var import_node_child_process2 = require("node:child_process");
|
|
5060
5583
|
var import_node_util = require("node:util");
|
|
5061
5584
|
var logger9 = createInternalLogger("CloakBrowser");
|
|
@@ -5197,7 +5720,7 @@ var forceTerminateBrowsersByFingerprintArg = async (fingerprintArg) => {
|
|
|
5197
5720
|
logger9.info(`\u5F3A\u5236\u5173\u95ED CloakBrowser \u8FDB\u7A0B\u5931\u8D25\uFF08\u5FFD\u7565\uFF09: ${error?.message || String(error)}`);
|
|
5198
5721
|
});
|
|
5199
5722
|
};
|
|
5200
|
-
var
|
|
5723
|
+
var CloakBrowserLaunch = {
|
|
5201
5724
|
resolveProxyConfiguration(proxyConfiguration = {}) {
|
|
5202
5725
|
return resolveCloakBrowserProxy(proxyConfiguration);
|
|
5203
5726
|
},
|
|
@@ -5207,6 +5730,10 @@ var CloakBrowser = {
|
|
|
5207
5730
|
createStableGotoHook(recommendedGotoOptions = DEFAULT_CLOAK_GOTO_OPTIONS) {
|
|
5208
5731
|
return createStableGotoHook(recommendedGotoOptions);
|
|
5209
5732
|
},
|
|
5733
|
+
async getPlaywrightCrawlerOptions(options = {}) {
|
|
5734
|
+
const { crawlerOptions } = await CloakBrowserLaunch.createPlaywrightCrawlerRuntime(options);
|
|
5735
|
+
return crawlerOptions;
|
|
5736
|
+
},
|
|
5210
5737
|
async buildLaunchOptions(options = {}) {
|
|
5211
5738
|
return await buildCloakLaunchOptions(options);
|
|
5212
5739
|
},
|
|
@@ -5284,26 +5811,35 @@ var CloakBrowser = {
|
|
|
5284
5811
|
};
|
|
5285
5812
|
}
|
|
5286
5813
|
};
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
}
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
}
|
|
5814
|
+
|
|
5815
|
+
// src/launch.js
|
|
5816
|
+
var resolveLaunchDelegate = () => getToolkitMode() === Mode.CloakBrowser ? CloakBrowserLaunch : DefaultLaunch;
|
|
5817
|
+
var callLaunch = (method, ...args) => {
|
|
5818
|
+
const delegate = resolveLaunchDelegate();
|
|
5819
|
+
if (typeof delegate?.[method] !== "function") {
|
|
5820
|
+
throw new Error(`Launch.${method} is not available in ${getToolkitMode()} mode`);
|
|
5821
|
+
}
|
|
5822
|
+
return delegate[method](...args);
|
|
5823
|
+
};
|
|
5824
|
+
var Launch = {
|
|
5825
|
+
getPlaywrightCrawlerOptions(options = {}) {
|
|
5826
|
+
return callLaunch("getPlaywrightCrawlerOptions", options);
|
|
5827
|
+
},
|
|
5828
|
+
resolveProxyConfiguration(proxyConfiguration = {}) {
|
|
5829
|
+
return callLaunch("resolveProxyConfiguration", proxyConfiguration);
|
|
5830
|
+
},
|
|
5831
|
+
extractFingerprintArg(launchOptions = {}) {
|
|
5832
|
+
return callLaunch("extractFingerprintArg", launchOptions);
|
|
5833
|
+
},
|
|
5834
|
+
createStableGotoHook(recommendedGotoOptions = {}) {
|
|
5835
|
+
return callLaunch("createStableGotoHook", recommendedGotoOptions);
|
|
5836
|
+
},
|
|
5837
|
+
buildLaunchOptions(options = {}) {
|
|
5838
|
+
return callLaunch("buildLaunchOptions", options);
|
|
5839
|
+
},
|
|
5840
|
+
createPlaywrightCrawlerRuntime(options = {}) {
|
|
5841
|
+
return callLaunch("createPlaywrightCrawlerRuntime", options);
|
|
5842
|
+
}
|
|
5307
5843
|
};
|
|
5308
5844
|
|
|
5309
5845
|
// src/live-view.js
|
|
@@ -7673,7 +8209,7 @@ var Logger = {
|
|
|
7673
8209
|
};
|
|
7674
8210
|
|
|
7675
8211
|
// src/share.js
|
|
7676
|
-
var
|
|
8212
|
+
var import_delay5 = __toESM(require("delay"), 1);
|
|
7677
8213
|
|
|
7678
8214
|
// src/internals/watermarkify.js
|
|
7679
8215
|
var DEFAULT_TIMEZONE_OFFSET = 8;
|
|
@@ -8169,7 +8705,10 @@ var buildWatermarkifyRenderHtml = ({ imageSrc, overlaySvg, width, height, imageH
|
|
|
8169
8705
|
</html>
|
|
8170
8706
|
`;
|
|
8171
8707
|
};
|
|
8172
|
-
var
|
|
8708
|
+
var normalizeWatermarkifyRenderMode = (value) => {
|
|
8709
|
+
return String(value || "default").trim().toLowerCase() === "cloakbrowser" ? "cloakbrowser" : "default";
|
|
8710
|
+
};
|
|
8711
|
+
var composeScreenshotBufferWithBrowser = async (page, buffer, overlaySvg, imageInfo = {}, options = {}) => {
|
|
8173
8712
|
if (!page || typeof page.context !== "function") {
|
|
8174
8713
|
logger14.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u8DF3\u8FC7: \u7F3A\u5C11\u53EF\u7528 page");
|
|
8175
8714
|
return buffer;
|
|
@@ -8193,15 +8732,35 @@ var composeScreenshotBufferWithBrowser = async (page, buffer, overlaySvg, imageI
|
|
|
8193
8732
|
height: viewportHeight
|
|
8194
8733
|
}).catch(() => {
|
|
8195
8734
|
});
|
|
8196
|
-
|
|
8197
|
-
|
|
8198
|
-
|
|
8199
|
-
|
|
8200
|
-
|
|
8201
|
-
|
|
8202
|
-
|
|
8203
|
-
|
|
8204
|
-
|
|
8735
|
+
const renderMode = normalizeWatermarkifyRenderMode(options.mode);
|
|
8736
|
+
if (renderMode === "cloakbrowser") {
|
|
8737
|
+
const renderHtml = buildWatermarkifyRenderHtml({
|
|
8738
|
+
imageSrc: `data:${imageInfo.mimeType || "image/png"};base64,${buffer.toString("base64")}`,
|
|
8739
|
+
overlaySvg,
|
|
8740
|
+
width: safeWidth,
|
|
8741
|
+
height: safeHeight,
|
|
8742
|
+
imageHeight: safeImageHeight
|
|
8743
|
+
});
|
|
8744
|
+
await renderPage.goto("about:blank", {
|
|
8745
|
+
waitUntil: "commit"
|
|
8746
|
+
}).catch(() => {
|
|
8747
|
+
});
|
|
8748
|
+
await renderPage.evaluate((html) => {
|
|
8749
|
+
document.open();
|
|
8750
|
+
document.write(html);
|
|
8751
|
+
document.close();
|
|
8752
|
+
}, renderHtml);
|
|
8753
|
+
} else {
|
|
8754
|
+
await renderPage.setContent(buildWatermarkifyRenderHtml({
|
|
8755
|
+
imageSrc: `data:${imageInfo.mimeType || "image/png"};base64,${buffer.toString("base64")}`,
|
|
8756
|
+
overlaySvg,
|
|
8757
|
+
width: safeWidth,
|
|
8758
|
+
height: safeHeight,
|
|
8759
|
+
imageHeight: safeImageHeight
|
|
8760
|
+
}), {
|
|
8761
|
+
waitUntil: "load"
|
|
8762
|
+
});
|
|
8763
|
+
}
|
|
8205
8764
|
await renderPage.waitForFunction(() => {
|
|
8206
8765
|
const image = document.getElementById("pk-base-image");
|
|
8207
8766
|
return image instanceof HTMLImageElement && image.complete && image.naturalWidth > 0 && image.naturalHeight > 0;
|
|
@@ -9136,7 +9695,7 @@ var buildWatermarkifySvg = (meta, imageWidth, imageHeight) => {
|
|
|
9136
9695
|
</svg>
|
|
9137
9696
|
`;
|
|
9138
9697
|
};
|
|
9139
|
-
var watermarkifyScreenshotBuffer = async (buffer, meta, page = null) => {
|
|
9698
|
+
var watermarkifyScreenshotBuffer = async (buffer, meta, page = null, options = {}) => {
|
|
9140
9699
|
const hasWatermark = meta?.watermark?.enabled !== false && normalizeText(meta?.watermarkText);
|
|
9141
9700
|
const hasStrip = meta?.strip?.enabled !== false && Array.isArray(meta?.stripSegments) && meta.stripSegments.length > 0;
|
|
9142
9701
|
if (!Buffer.isBuffer(buffer) || !meta || !hasWatermark && !hasStrip) {
|
|
@@ -9157,7 +9716,7 @@ var watermarkifyScreenshotBuffer = async (buffer, meta, page = null) => {
|
|
|
9157
9716
|
if (!overlaySvg) {
|
|
9158
9717
|
return buffer;
|
|
9159
9718
|
}
|
|
9160
|
-
return await composeScreenshotBufferWithBrowser(page, buffer, overlaySvg, outputImageInfo);
|
|
9719
|
+
return await composeScreenshotBufferWithBrowser(page, buffer, overlaySvg, outputImageInfo, options);
|
|
9161
9720
|
};
|
|
9162
9721
|
|
|
9163
9722
|
// src/internals/compression.js
|
|
@@ -9721,7 +10280,7 @@ var Share = {
|
|
|
9721
10280
|
);
|
|
9722
10281
|
nextProgressLogTs = now + 5e3;
|
|
9723
10282
|
}
|
|
9724
|
-
await (0,
|
|
10283
|
+
await (0, import_delay5.default)(Math.max(0, Math.min(DEFAULT_POLL_INTERVAL_MS, remaining)));
|
|
9725
10284
|
}
|
|
9726
10285
|
if (!timeoutDisabled && share.mode === "response" && stats.responseMatched === 0) {
|
|
9727
10286
|
logger16.warning(
|
|
@@ -9755,6 +10314,7 @@ var Share = {
|
|
|
9755
10314
|
* @param {number} [options.maxBytes] 默认 5MiB,返回 base64 超过后会压缩
|
|
9756
10315
|
* @param {'jpeg'|'jpg'} [options.type] 压缩输出格式,默认 jpeg
|
|
9757
10316
|
* @param {boolean|Object} [options.compression] 传 false 可关闭压缩
|
|
10317
|
+
* @param {'default'|'cloakbrowser'} [options.mode] 截图水印合成模式,默认 default
|
|
9758
10318
|
* @returns {Promise<string>} base64 image
|
|
9759
10319
|
*/
|
|
9760
10320
|
async captureScreen(page, options = {}) {
|
|
@@ -9775,7 +10335,9 @@ var Share = {
|
|
|
9775
10335
|
...screenshotWatermarkify,
|
|
9776
10336
|
capturedAt
|
|
9777
10337
|
});
|
|
9778
|
-
outputBuffer = await watermarkifyScreenshotBuffer(rawBuffer, watermarkifyMeta, page
|
|
10338
|
+
outputBuffer = await watermarkifyScreenshotBuffer(rawBuffer, watermarkifyMeta, page, {
|
|
10339
|
+
mode: options.mode === "cloakbrowser" ? "cloakbrowser" : "default"
|
|
10340
|
+
});
|
|
9779
10341
|
}
|
|
9780
10342
|
return await compressImageBufferToBase64(outputBuffer, compression);
|
|
9781
10343
|
}
|
|
@@ -9784,14 +10346,14 @@ var Share = {
|
|
|
9784
10346
|
// entrys/node.js
|
|
9785
10347
|
Logger.setLogger(import_crawlee.log);
|
|
9786
10348
|
var usePlaywrightToolKit = (mode = "default") => {
|
|
9787
|
-
|
|
10349
|
+
setToolkitMode(mode);
|
|
9788
10350
|
const toolkit = {
|
|
9789
10351
|
ApifyKit,
|
|
9790
10352
|
AntiCheat,
|
|
9791
10353
|
DeviceInput,
|
|
9792
10354
|
DeviceView,
|
|
9793
10355
|
Humanize: Humanize2,
|
|
9794
|
-
Launch
|
|
10356
|
+
Launch,
|
|
9795
10357
|
LiveView,
|
|
9796
10358
|
Constants: constants_exports,
|
|
9797
10359
|
Utils,
|