@skrillex1224/playwright-toolkit 2.1.159 → 2.1.161
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/index.cjs +241 -143
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +241 -143
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -335,18 +335,18 @@ var fallbackLog = {
|
|
|
335
335
|
error: (...args) => console.error(...args),
|
|
336
336
|
debug: (...args) => console.debug ? console.debug(...args) : console.log(...args)
|
|
337
337
|
};
|
|
338
|
-
var resolveLogMethod = (
|
|
339
|
-
if (
|
|
340
|
-
return
|
|
338
|
+
var resolveLogMethod = (logger13, name) => {
|
|
339
|
+
if (logger13 && typeof logger13[name] === "function") {
|
|
340
|
+
return logger13[name].bind(logger13);
|
|
341
341
|
}
|
|
342
|
-
if (name === "warning" &&
|
|
343
|
-
return
|
|
342
|
+
if (name === "warning" && logger13 && typeof logger13.warn === "function") {
|
|
343
|
+
return logger13.warn.bind(logger13);
|
|
344
344
|
}
|
|
345
345
|
return fallbackLog[name];
|
|
346
346
|
};
|
|
347
347
|
var defaultLogger = null;
|
|
348
|
-
var setDefaultLogger = (
|
|
349
|
-
defaultLogger =
|
|
348
|
+
var setDefaultLogger = (logger13) => {
|
|
349
|
+
defaultLogger = logger13;
|
|
350
350
|
};
|
|
351
351
|
var resolveLogger = (explicitLogger) => {
|
|
352
352
|
if (explicitLogger && typeof explicitLogger.info === "function") {
|
|
@@ -373,8 +373,8 @@ var colorize = (text, color) => {
|
|
|
373
373
|
var createBaseLogger = (prefix = "", explicitLogger) => {
|
|
374
374
|
const name = prefix ? String(prefix) : "";
|
|
375
375
|
const dispatch = (methodName, icon, message, color) => {
|
|
376
|
-
const
|
|
377
|
-
const logFn = resolveLogMethod(
|
|
376
|
+
const logger13 = resolveLogger(explicitLogger);
|
|
377
|
+
const logFn = resolveLogMethod(logger13, methodName);
|
|
378
378
|
const timestamp = colorize(`[${formatTimestamp()}]`, ANSI.gray);
|
|
379
379
|
const line = formatLine(name, icon, message);
|
|
380
380
|
const coloredLine = colorize(line, color);
|
|
@@ -420,6 +420,99 @@ function createInternalLogger(moduleName, explicitLogger) {
|
|
|
420
420
|
};
|
|
421
421
|
}
|
|
422
422
|
|
|
423
|
+
// src/internals/screenshot.js
|
|
424
|
+
var logger = createInternalLogger("Screenshot");
|
|
425
|
+
var DEFAULT_TIMEOUT_MS = 5e3;
|
|
426
|
+
var FORCED_FULLPAGE_TYPE = "jpeg";
|
|
427
|
+
var FORCED_FULLPAGE_QUALITY = 50;
|
|
428
|
+
var SUPPORTED_TYPES = /* @__PURE__ */ new Set(["png", "jpeg", "webp"]);
|
|
429
|
+
var toPositiveNumber = (value, fallback = 0) => {
|
|
430
|
+
const n = Number(value);
|
|
431
|
+
if (!Number.isFinite(n) || n <= 0) return fallback;
|
|
432
|
+
return n;
|
|
433
|
+
};
|
|
434
|
+
var normalizeType = (value) => {
|
|
435
|
+
const raw = String(value || "png").trim().toLowerCase();
|
|
436
|
+
if (!SUPPORTED_TYPES.has(raw)) return "png";
|
|
437
|
+
return raw;
|
|
438
|
+
};
|
|
439
|
+
var normalizeQuality = (value, type) => {
|
|
440
|
+
if (type !== "jpeg" && type !== "webp") return void 0;
|
|
441
|
+
const n = Number(value);
|
|
442
|
+
if (!Number.isFinite(n)) return void 0;
|
|
443
|
+
const rounded = Math.round(n);
|
|
444
|
+
if (rounded < 0 || rounded > 100) return void 0;
|
|
445
|
+
return rounded;
|
|
446
|
+
};
|
|
447
|
+
var buildFullPageClip = (metrics, viewport, maxClipHeight) => {
|
|
448
|
+
const contentSize = metrics && typeof metrics === "object" ? metrics.contentSize || null : null;
|
|
449
|
+
const width = Math.max(1, Math.ceil(contentSize?.width || viewport.width || 1));
|
|
450
|
+
let height = Math.max(1, Math.ceil(contentSize?.height || viewport.height || 1));
|
|
451
|
+
if (maxClipHeight > 0) {
|
|
452
|
+
height = Math.min(height, maxClipHeight);
|
|
453
|
+
}
|
|
454
|
+
return {
|
|
455
|
+
x: 0,
|
|
456
|
+
y: 0,
|
|
457
|
+
width,
|
|
458
|
+
height,
|
|
459
|
+
scale: 1
|
|
460
|
+
};
|
|
461
|
+
};
|
|
462
|
+
var capturePageScreenshot = async (page, options = {}) => {
|
|
463
|
+
const fullPage = Boolean(options.fullPage);
|
|
464
|
+
const type = fullPage ? FORCED_FULLPAGE_TYPE : normalizeType(options.type);
|
|
465
|
+
const quality = fullPage ? FORCED_FULLPAGE_QUALITY : normalizeQuality(options.quality, type);
|
|
466
|
+
const timeout = toPositiveNumber(options.timeout, DEFAULT_TIMEOUT_MS);
|
|
467
|
+
const maxClipHeight = Math.round(toPositiveNumber(options.maxClipHeight, 0));
|
|
468
|
+
const fallbackOptions = {
|
|
469
|
+
type: type === "webp" ? "png" : type,
|
|
470
|
+
fullPage
|
|
471
|
+
};
|
|
472
|
+
if (quality !== void 0 && fallbackOptions.type === "jpeg") {
|
|
473
|
+
fallbackOptions.quality = quality;
|
|
474
|
+
}
|
|
475
|
+
if (timeout > 0) {
|
|
476
|
+
fallbackOptions.timeout = timeout;
|
|
477
|
+
}
|
|
478
|
+
try {
|
|
479
|
+
const context = page && typeof page.context === "function" ? page.context() : null;
|
|
480
|
+
if (!context || typeof context.newCDPSession !== "function") {
|
|
481
|
+
throw new Error("CDP session is not available");
|
|
482
|
+
}
|
|
483
|
+
const session = await context.newCDPSession(page);
|
|
484
|
+
try {
|
|
485
|
+
const metrics = await session.send("Page.getLayoutMetrics");
|
|
486
|
+
const viewport = page.viewportSize() || { width: 1280, height: 720 };
|
|
487
|
+
const captureParams = {
|
|
488
|
+
format: type,
|
|
489
|
+
fromSurface: true,
|
|
490
|
+
captureBeyondViewport: fullPage,
|
|
491
|
+
optimizeForSpeed: true
|
|
492
|
+
};
|
|
493
|
+
if (quality !== void 0) {
|
|
494
|
+
captureParams.quality = quality;
|
|
495
|
+
}
|
|
496
|
+
if (fullPage) {
|
|
497
|
+
captureParams.clip = buildFullPageClip(metrics, viewport, maxClipHeight);
|
|
498
|
+
}
|
|
499
|
+
const result = await session.send("Page.captureScreenshot", captureParams);
|
|
500
|
+
if (!result || typeof result.data !== "string" || !result.data) {
|
|
501
|
+
throw new Error("CDP returned empty screenshot data");
|
|
502
|
+
}
|
|
503
|
+
return Buffer.from(result.data, "base64");
|
|
504
|
+
} finally {
|
|
505
|
+
if (typeof session.detach === "function") {
|
|
506
|
+
await session.detach().catch(() => {
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
} catch (error) {
|
|
511
|
+
logger.warning(`CDP \u622A\u56FE\u5931\u8D25\uFF0C\u56DE\u9000 page.screenshot: ${error?.message || error}`);
|
|
512
|
+
return await page.screenshot(fallbackOptions);
|
|
513
|
+
}
|
|
514
|
+
};
|
|
515
|
+
|
|
423
516
|
// src/errors.js
|
|
424
517
|
var errors_exports = {};
|
|
425
518
|
__export(errors_exports, {
|
|
@@ -493,7 +586,7 @@ var getTrafficSnapshot = () => {
|
|
|
493
586
|
};
|
|
494
587
|
|
|
495
588
|
// src/apify-kit.js
|
|
496
|
-
var
|
|
589
|
+
var logger2 = createInternalLogger("ApifyKit");
|
|
497
590
|
async function createApifyKit() {
|
|
498
591
|
let apify = null;
|
|
499
592
|
try {
|
|
@@ -521,29 +614,29 @@ async function createApifyKit() {
|
|
|
521
614
|
const { times: retryTimes = 0, mode: retryMode = "direct", before: beforeRetry } = retry;
|
|
522
615
|
const executeAction = async (attemptNumber) => {
|
|
523
616
|
const attemptLabel = attemptNumber > 0 ? ` (\u91CD\u8BD5 #${attemptNumber})` : "";
|
|
524
|
-
|
|
617
|
+
logger2.start(`[Step] ${step}${attemptLabel}`);
|
|
525
618
|
try {
|
|
526
619
|
const result = await actionFn();
|
|
527
|
-
|
|
620
|
+
logger2.success(`[Step] ${step}${attemptLabel}`);
|
|
528
621
|
return { success: true, result };
|
|
529
622
|
} catch (error) {
|
|
530
|
-
|
|
623
|
+
logger2.fail(`[Step] ${step}${attemptLabel}`, error);
|
|
531
624
|
return { success: false, error };
|
|
532
625
|
}
|
|
533
626
|
};
|
|
534
627
|
const prepareForRetry = async (attemptNumber) => {
|
|
535
628
|
if (typeof beforeRetry === "function") {
|
|
536
|
-
|
|
629
|
+
logger2.start(`[RetryStep] \u6267\u884C\u81EA\u5B9A\u4E49 before \u94A9\u5B50 (\u7B2C ${attemptNumber} \u6B21\u91CD\u8BD5)`);
|
|
537
630
|
await beforeRetry(page, attemptNumber);
|
|
538
|
-
|
|
631
|
+
logger2.success(`[RetryStep] before \u94A9\u5B50\u5B8C\u6210`);
|
|
539
632
|
} else if (retryMode === "refresh") {
|
|
540
|
-
|
|
633
|
+
logger2.start(`[RetryStep] \u5237\u65B0\u9875\u9762 (\u7B2C ${attemptNumber} \u6B21\u91CD\u8BD5)`);
|
|
541
634
|
await page.reload({ waitUntil: "domcontentloaded" });
|
|
542
|
-
|
|
635
|
+
logger2.success(`[RetryStep] \u9875\u9762\u5237\u65B0\u5B8C\u6210`);
|
|
543
636
|
} else {
|
|
544
|
-
|
|
637
|
+
logger2.start(`[RetryStep] \u7B49\u5F85 3 \u79D2 (\u7B2C ${attemptNumber} \u6B21\u91CD\u8BD5)`);
|
|
545
638
|
await new Promise((resolve) => setTimeout(resolve, 3e3));
|
|
546
|
-
|
|
639
|
+
logger2.success(`[RetryStep] \u7B49\u5F85\u5B8C\u6210`);
|
|
547
640
|
}
|
|
548
641
|
};
|
|
549
642
|
let lastResult = await executeAction(0);
|
|
@@ -551,11 +644,11 @@ async function createApifyKit() {
|
|
|
551
644
|
return lastResult.result;
|
|
552
645
|
}
|
|
553
646
|
for (let attempt = 1; attempt <= retryTimes; attempt++) {
|
|
554
|
-
|
|
647
|
+
logger2.start(`[RetryStep] \u51C6\u5907\u7B2C ${attempt}/${retryTimes} \u6B21\u91CD\u8BD5: ${step}`);
|
|
555
648
|
try {
|
|
556
649
|
await prepareForRetry(attempt);
|
|
557
650
|
} catch (prepareError) {
|
|
558
|
-
|
|
651
|
+
logger2.warn(`[RetryStep] \u91CD\u8BD5\u51C6\u5907\u5931\u8D25: ${prepareError.message}`);
|
|
559
652
|
continue;
|
|
560
653
|
}
|
|
561
654
|
lastResult = await executeAction(attempt);
|
|
@@ -568,11 +661,15 @@ async function createApifyKit() {
|
|
|
568
661
|
let base64 = "\u622A\u56FE\u5931\u8D25";
|
|
569
662
|
try {
|
|
570
663
|
if (page) {
|
|
571
|
-
const buffer = await page
|
|
664
|
+
const buffer = await capturePageScreenshot(page, {
|
|
665
|
+
fullPage: true,
|
|
666
|
+
type: "jpeg",
|
|
667
|
+
quality: 60
|
|
668
|
+
});
|
|
572
669
|
base64 = `data:image/jpeg;base64,${buffer.toString("base64")}`;
|
|
573
670
|
}
|
|
574
671
|
} catch (snapErr) {
|
|
575
|
-
|
|
672
|
+
logger2.warn(`\u622A\u56FE\u751F\u6210\u5931\u8D25: ${snapErr.message}`);
|
|
576
673
|
}
|
|
577
674
|
await this.pushFailed(finalError, {
|
|
578
675
|
step,
|
|
@@ -615,7 +712,7 @@ async function createApifyKit() {
|
|
|
615
712
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
616
713
|
data
|
|
617
714
|
});
|
|
618
|
-
|
|
715
|
+
logger2.success("pushSuccess", "Data pushed");
|
|
619
716
|
},
|
|
620
717
|
/**
|
|
621
718
|
* 推送失败数据的通用方法(私有方法,仅供runStep内部使用)
|
|
@@ -639,7 +736,7 @@ async function createApifyKit() {
|
|
|
639
736
|
context,
|
|
640
737
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
641
738
|
});
|
|
642
|
-
|
|
739
|
+
logger2.success("pushFailed", "Error data pushed");
|
|
643
740
|
}
|
|
644
741
|
};
|
|
645
742
|
}
|
|
@@ -655,7 +752,7 @@ var ApifyKit = {
|
|
|
655
752
|
};
|
|
656
753
|
|
|
657
754
|
// src/internals/utils.js
|
|
658
|
-
var
|
|
755
|
+
var logger3 = createInternalLogger("InternalUtils");
|
|
659
756
|
var parseCookies = (cookieString, domain) => {
|
|
660
757
|
const cookies = [];
|
|
661
758
|
const pairs = cookieString.split(";").map((c) => c.trim());
|
|
@@ -673,7 +770,7 @@ var parseCookies = (cookieString, domain) => {
|
|
|
673
770
|
cookies.push(cookie);
|
|
674
771
|
}
|
|
675
772
|
}
|
|
676
|
-
|
|
773
|
+
logger3.success("parseCookies", `parsed ${cookies.length} cookies`);
|
|
677
774
|
return cookies;
|
|
678
775
|
};
|
|
679
776
|
|
|
@@ -716,7 +813,7 @@ var Utils = {
|
|
|
716
813
|
};
|
|
717
814
|
|
|
718
815
|
// src/anti-cheat.js
|
|
719
|
-
var
|
|
816
|
+
var logger4 = createInternalLogger("AntiCheat");
|
|
720
817
|
var BASE_CONFIG = Object.freeze({
|
|
721
818
|
locale: "zh-CN",
|
|
722
819
|
acceptLanguage: "zh-CN,zh;q=0.9",
|
|
@@ -778,7 +875,7 @@ var AntiCheat = {
|
|
|
778
875
|
// src/humanize.js
|
|
779
876
|
var import_delay = __toESM(require("delay"), 1);
|
|
780
877
|
var import_ghost_cursor_playwright = require("ghost-cursor-playwright");
|
|
781
|
-
var
|
|
878
|
+
var logger5 = createInternalLogger("Humanize");
|
|
782
879
|
var $CursorWeakMap = /* @__PURE__ */ new WeakMap();
|
|
783
880
|
function $GetCursor(page) {
|
|
784
881
|
const cursor = $CursorWeakMap.get(page);
|
|
@@ -806,13 +903,13 @@ var Humanize = {
|
|
|
806
903
|
*/
|
|
807
904
|
async initializeCursor(page) {
|
|
808
905
|
if ($CursorWeakMap.has(page)) {
|
|
809
|
-
|
|
906
|
+
logger5.debug("initializeCursor: cursor already exists, skipping");
|
|
810
907
|
return;
|
|
811
908
|
}
|
|
812
|
-
|
|
909
|
+
logger5.start("initializeCursor", "creating cursor");
|
|
813
910
|
const cursor = await (0, import_ghost_cursor_playwright.createCursor)(page);
|
|
814
911
|
$CursorWeakMap.set(page, cursor);
|
|
815
|
-
|
|
912
|
+
logger5.success("initializeCursor", "cursor initialized");
|
|
816
913
|
},
|
|
817
914
|
/**
|
|
818
915
|
* 人类化鼠标移动 - 使用 ghost-cursor 移动到指定位置或元素
|
|
@@ -822,17 +919,17 @@ var Humanize = {
|
|
|
822
919
|
*/
|
|
823
920
|
async humanMove(page, target) {
|
|
824
921
|
const cursor = $GetCursor(page);
|
|
825
|
-
|
|
922
|
+
logger5.start("humanMove", `target=${typeof target === "string" ? target : "element/coords"}`);
|
|
826
923
|
try {
|
|
827
924
|
if (typeof target === "string") {
|
|
828
925
|
const element = await page.$(target);
|
|
829
926
|
if (!element) {
|
|
830
|
-
|
|
927
|
+
logger5.warn(`humanMove: \u5143\u7D20\u4E0D\u5B58\u5728 ${target}`);
|
|
831
928
|
return false;
|
|
832
929
|
}
|
|
833
930
|
const box = await element.boundingBox();
|
|
834
931
|
if (!box) {
|
|
835
|
-
|
|
932
|
+
logger5.warn(`humanMove: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E ${target}`);
|
|
836
933
|
return false;
|
|
837
934
|
}
|
|
838
935
|
const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.2;
|
|
@@ -848,10 +945,10 @@ var Humanize = {
|
|
|
848
945
|
await cursor.actions.move({ x, y });
|
|
849
946
|
}
|
|
850
947
|
}
|
|
851
|
-
|
|
948
|
+
logger5.success("humanMove");
|
|
852
949
|
return true;
|
|
853
950
|
} catch (error) {
|
|
854
|
-
|
|
951
|
+
logger5.fail("humanMove", error);
|
|
855
952
|
throw error;
|
|
856
953
|
}
|
|
857
954
|
},
|
|
@@ -875,12 +972,12 @@ var Humanize = {
|
|
|
875
972
|
maxDurationMs = maxSteps * 220 + 800
|
|
876
973
|
} = options;
|
|
877
974
|
const targetDesc = typeof target === "string" ? target : "ElementHandle";
|
|
878
|
-
|
|
975
|
+
logger5.start("humanScroll", `target=${targetDesc}`);
|
|
879
976
|
let element;
|
|
880
977
|
if (typeof target === "string") {
|
|
881
978
|
element = await page.$(target);
|
|
882
979
|
if (!element) {
|
|
883
|
-
|
|
980
|
+
logger5.warn(`humanScroll | \u5143\u7D20\u672A\u627E\u5230: ${target}`);
|
|
884
981
|
return { element: null, didScroll: false };
|
|
885
982
|
}
|
|
886
983
|
} else {
|
|
@@ -955,26 +1052,26 @@ var Humanize = {
|
|
|
955
1052
|
try {
|
|
956
1053
|
for (let i = 0; i < maxSteps; i++) {
|
|
957
1054
|
if (Date.now() - startTime > maxDurationMs) {
|
|
958
|
-
|
|
1055
|
+
logger5.warn(`humanScroll | \u8D85\u65F6\u4FDD\u62A4\u89E6\u53D1 (${maxDurationMs}ms)`);
|
|
959
1056
|
return { element, didScroll };
|
|
960
1057
|
}
|
|
961
1058
|
const status = await checkVisibility();
|
|
962
1059
|
if (status.code === "VISIBLE") {
|
|
963
1060
|
if (status.isFixed) {
|
|
964
|
-
|
|
1061
|
+
logger5.info("humanScroll | fixed \u5BB9\u5668\u5185\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
|
|
965
1062
|
} else {
|
|
966
|
-
|
|
1063
|
+
logger5.debug("humanScroll | \u5143\u7D20\u53EF\u89C1\u4E14\u65E0\u906E\u6321");
|
|
967
1064
|
}
|
|
968
|
-
|
|
1065
|
+
logger5.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
|
|
969
1066
|
return { element, didScroll };
|
|
970
1067
|
}
|
|
971
|
-
|
|
1068
|
+
logger5.debug(`humanScroll | \u6B65\u9AA4 ${i + 1}/${maxSteps}: ${status.reason} ${status.direction ? `(${status.direction})` : ""}`);
|
|
972
1069
|
if (status.code === "OBSTRUCTED" && status.obstruction) {
|
|
973
|
-
|
|
1070
|
+
logger5.debug(`humanScroll | \u88AB\u4EE5\u4E0B\u5143\u7D20\u906E\u6321 <${status.obstruction.tag} id="${status.obstruction.id}">`);
|
|
974
1071
|
}
|
|
975
1072
|
const scrollRect = await getScrollableRect();
|
|
976
1073
|
if (!scrollRect && status.isFixed) {
|
|
977
|
-
|
|
1074
|
+
logger5.warn("humanScroll | fixed \u5BB9\u5668\u5185\u4E14\u65E0\u53EF\u6EDA\u52A8\u7956\u5148\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
|
|
978
1075
|
return { element, didScroll };
|
|
979
1076
|
}
|
|
980
1077
|
const stepMin = scrollRect ? Math.min(minStep, Math.max(60, scrollRect.height * 0.4)) : minStep;
|
|
@@ -1010,10 +1107,10 @@ var Humanize = {
|
|
|
1010
1107
|
didScroll = true;
|
|
1011
1108
|
await (0, import_delay.default)(this.jitterMs(20 + Math.random() * 40, 0.2));
|
|
1012
1109
|
}
|
|
1013
|
-
|
|
1110
|
+
logger5.warn(`humanScroll | \u5728 ${maxSteps} \u6B65\u540E\u65E0\u6CD5\u786E\u4FDD\u53EF\u89C1\u6027`);
|
|
1014
1111
|
return { element, didScroll };
|
|
1015
1112
|
} catch (error) {
|
|
1016
|
-
|
|
1113
|
+
logger5.fail("humanScroll", error);
|
|
1017
1114
|
throw error;
|
|
1018
1115
|
}
|
|
1019
1116
|
},
|
|
@@ -1031,7 +1128,7 @@ var Humanize = {
|
|
|
1031
1128
|
const cursor = $GetCursor(page);
|
|
1032
1129
|
const { reactionDelay = 250, throwOnMissing = true, scrollIfNeeded = true, restore = false } = options;
|
|
1033
1130
|
const targetDesc = target == null ? "Current Position" : typeof target === "string" ? target : "ElementHandle";
|
|
1034
|
-
|
|
1131
|
+
logger5.start("humanClick", `target=${targetDesc}`);
|
|
1035
1132
|
const restoreOnce = async () => {
|
|
1036
1133
|
if (restoreOnce.restored) return;
|
|
1037
1134
|
restoreOnce.restored = true;
|
|
@@ -1040,14 +1137,14 @@ var Humanize = {
|
|
|
1040
1137
|
await (0, import_delay.default)(this.jitterMs(1e3));
|
|
1041
1138
|
await restoreOnce.do();
|
|
1042
1139
|
} catch (restoreError) {
|
|
1043
|
-
|
|
1140
|
+
logger5.warn(`humanClick: \u6062\u590D\u6EDA\u52A8\u4F4D\u7F6E\u5931\u8D25: ${restoreError.message}`);
|
|
1044
1141
|
}
|
|
1045
1142
|
};
|
|
1046
1143
|
try {
|
|
1047
1144
|
if (target == null) {
|
|
1048
1145
|
await (0, import_delay.default)(this.jitterMs(reactionDelay, 0.4));
|
|
1049
1146
|
await cursor.actions.click();
|
|
1050
|
-
|
|
1147
|
+
logger5.success("humanClick", "Clicked current position");
|
|
1051
1148
|
return true;
|
|
1052
1149
|
}
|
|
1053
1150
|
let element;
|
|
@@ -1057,7 +1154,7 @@ var Humanize = {
|
|
|
1057
1154
|
if (throwOnMissing) {
|
|
1058
1155
|
throw new Error(`\u627E\u4E0D\u5230\u5143\u7D20 ${target}`);
|
|
1059
1156
|
}
|
|
1060
|
-
|
|
1157
|
+
logger5.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${target}`);
|
|
1061
1158
|
return false;
|
|
1062
1159
|
}
|
|
1063
1160
|
} else {
|
|
@@ -1073,7 +1170,7 @@ var Humanize = {
|
|
|
1073
1170
|
if (throwOnMissing) {
|
|
1074
1171
|
throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5143\u7D20\u4F4D\u7F6E");
|
|
1075
1172
|
}
|
|
1076
|
-
|
|
1173
|
+
logger5.warn("humanClick: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E\uFF0C\u8DF3\u8FC7\u70B9\u51FB");
|
|
1077
1174
|
return false;
|
|
1078
1175
|
}
|
|
1079
1176
|
const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.3;
|
|
@@ -1082,11 +1179,11 @@ var Humanize = {
|
|
|
1082
1179
|
await (0, import_delay.default)(this.jitterMs(reactionDelay, 0.4));
|
|
1083
1180
|
await cursor.actions.click();
|
|
1084
1181
|
await restoreOnce();
|
|
1085
|
-
|
|
1182
|
+
logger5.success("humanClick");
|
|
1086
1183
|
return true;
|
|
1087
1184
|
} catch (error) {
|
|
1088
1185
|
await restoreOnce();
|
|
1089
|
-
|
|
1186
|
+
logger5.fail("humanClick", error);
|
|
1090
1187
|
throw error;
|
|
1091
1188
|
}
|
|
1092
1189
|
},
|
|
@@ -1097,9 +1194,9 @@ var Humanize = {
|
|
|
1097
1194
|
*/
|
|
1098
1195
|
async randomSleep(baseMs, jitterPercent = 0.3) {
|
|
1099
1196
|
const ms = this.jitterMs(baseMs, jitterPercent);
|
|
1100
|
-
|
|
1197
|
+
logger5.start("randomSleep", `base=${baseMs}, actual=${ms}ms`);
|
|
1101
1198
|
await (0, import_delay.default)(ms);
|
|
1102
|
-
|
|
1199
|
+
logger5.success("randomSleep");
|
|
1103
1200
|
},
|
|
1104
1201
|
/**
|
|
1105
1202
|
* 模拟人类"注视"或"阅读"行为:鼠标在页面上随机微动
|
|
@@ -1109,7 +1206,7 @@ var Humanize = {
|
|
|
1109
1206
|
async simulateGaze(page, baseDurationMs = 2500) {
|
|
1110
1207
|
const cursor = $GetCursor(page);
|
|
1111
1208
|
const durationMs = this.jitterMs(baseDurationMs, 0.4);
|
|
1112
|
-
|
|
1209
|
+
logger5.start("simulateGaze", `duration=${durationMs}ms`);
|
|
1113
1210
|
const startTime = Date.now();
|
|
1114
1211
|
const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };
|
|
1115
1212
|
while (Date.now() - startTime < durationMs) {
|
|
@@ -1118,7 +1215,7 @@ var Humanize = {
|
|
|
1118
1215
|
await cursor.actions.move({ x, y });
|
|
1119
1216
|
await (0, import_delay.default)(this.jitterMs(600, 0.5));
|
|
1120
1217
|
}
|
|
1121
|
-
|
|
1218
|
+
logger5.success("simulateGaze");
|
|
1122
1219
|
},
|
|
1123
1220
|
/**
|
|
1124
1221
|
* 人类化输入 - 带节奏变化(快-慢-停顿-偶尔加速)
|
|
@@ -1131,7 +1228,7 @@ var Humanize = {
|
|
|
1131
1228
|
* @param {number} [options.pauseBase=800] - 停顿时长基础值 (ms),实际 ±50% 抖动
|
|
1132
1229
|
*/
|
|
1133
1230
|
async humanType(page, selector, text, options = {}) {
|
|
1134
|
-
|
|
1231
|
+
logger5.start("humanType", `selector=${selector}, textLen=${text.length}`);
|
|
1135
1232
|
const {
|
|
1136
1233
|
baseDelay = 180,
|
|
1137
1234
|
pauseProbability = 0.08,
|
|
@@ -1155,13 +1252,13 @@ var Humanize = {
|
|
|
1155
1252
|
await (0, import_delay.default)(charDelay);
|
|
1156
1253
|
if (Math.random() < pauseProbability && i < text.length - 1) {
|
|
1157
1254
|
const pauseTime = this.jitterMs(pauseBase, 0.5);
|
|
1158
|
-
|
|
1255
|
+
logger5.debug(`\u505C\u987F ${pauseTime}ms...`);
|
|
1159
1256
|
await (0, import_delay.default)(pauseTime);
|
|
1160
1257
|
}
|
|
1161
1258
|
}
|
|
1162
|
-
|
|
1259
|
+
logger5.success("humanType");
|
|
1163
1260
|
} catch (error) {
|
|
1164
|
-
|
|
1261
|
+
logger5.fail("humanType", error);
|
|
1165
1262
|
throw error;
|
|
1166
1263
|
}
|
|
1167
1264
|
},
|
|
@@ -1171,22 +1268,22 @@ var Humanize = {
|
|
|
1171
1268
|
* @param {string} selector - 输入框选择器
|
|
1172
1269
|
*/
|
|
1173
1270
|
async humanClear(page, selector) {
|
|
1174
|
-
|
|
1271
|
+
logger5.start("humanClear", `selector=${selector}`);
|
|
1175
1272
|
try {
|
|
1176
1273
|
const locator = page.locator(selector);
|
|
1177
1274
|
await locator.click();
|
|
1178
1275
|
await (0, import_delay.default)(this.jitterMs(200, 0.4));
|
|
1179
1276
|
const currentValue = await locator.inputValue();
|
|
1180
1277
|
if (!currentValue || currentValue.length === 0) {
|
|
1181
|
-
|
|
1278
|
+
logger5.success("humanClear", "already empty");
|
|
1182
1279
|
return;
|
|
1183
1280
|
}
|
|
1184
1281
|
await page.keyboard.press("Meta+A");
|
|
1185
1282
|
await (0, import_delay.default)(this.jitterMs(100, 0.4));
|
|
1186
1283
|
await page.keyboard.press("Backspace");
|
|
1187
|
-
|
|
1284
|
+
logger5.success("humanClear");
|
|
1188
1285
|
} catch (error) {
|
|
1189
|
-
|
|
1286
|
+
logger5.fail("humanClear", error);
|
|
1190
1287
|
throw error;
|
|
1191
1288
|
}
|
|
1192
1289
|
},
|
|
@@ -1198,7 +1295,7 @@ var Humanize = {
|
|
|
1198
1295
|
async warmUpBrowsing(page, baseDuration = 3500) {
|
|
1199
1296
|
const cursor = $GetCursor(page);
|
|
1200
1297
|
const durationMs = this.jitterMs(baseDuration, 0.4);
|
|
1201
|
-
|
|
1298
|
+
logger5.start("warmUpBrowsing", `duration=${durationMs}ms`);
|
|
1202
1299
|
const startTime = Date.now();
|
|
1203
1300
|
const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };
|
|
1204
1301
|
try {
|
|
@@ -1217,9 +1314,9 @@ var Humanize = {
|
|
|
1217
1314
|
await (0, import_delay.default)(this.jitterMs(800, 0.5));
|
|
1218
1315
|
}
|
|
1219
1316
|
}
|
|
1220
|
-
|
|
1317
|
+
logger5.success("warmUpBrowsing");
|
|
1221
1318
|
} catch (error) {
|
|
1222
|
-
|
|
1319
|
+
logger5.fail("warmUpBrowsing", error);
|
|
1223
1320
|
throw error;
|
|
1224
1321
|
}
|
|
1225
1322
|
},
|
|
@@ -1233,7 +1330,7 @@ var Humanize = {
|
|
|
1233
1330
|
async naturalScroll(page, direction = "down", distance = 300, baseSteps = 5) {
|
|
1234
1331
|
const steps = Math.max(3, baseSteps + Math.floor(Math.random() * 3) - 1);
|
|
1235
1332
|
const actualDistance = this.jitterMs(distance, 0.15);
|
|
1236
|
-
|
|
1333
|
+
logger5.start("naturalScroll", `dir=${direction}, dist=${actualDistance}, steps=${steps}`);
|
|
1237
1334
|
const sign = direction === "down" ? 1 : -1;
|
|
1238
1335
|
const stepDistance = actualDistance / steps;
|
|
1239
1336
|
try {
|
|
@@ -1245,9 +1342,9 @@ var Humanize = {
|
|
|
1245
1342
|
const baseDelay = 60 + i * 25;
|
|
1246
1343
|
await (0, import_delay.default)(this.jitterMs(baseDelay, 0.3));
|
|
1247
1344
|
}
|
|
1248
|
-
|
|
1345
|
+
logger5.success("naturalScroll");
|
|
1249
1346
|
} catch (error) {
|
|
1250
|
-
|
|
1347
|
+
logger5.fail("naturalScroll", error);
|
|
1251
1348
|
throw error;
|
|
1252
1349
|
}
|
|
1253
1350
|
}
|
|
@@ -1315,7 +1412,7 @@ var resolveRouteByProxy = ({
|
|
|
1315
1412
|
};
|
|
1316
1413
|
|
|
1317
1414
|
// src/traffic-meter.js
|
|
1318
|
-
var
|
|
1415
|
+
var logger6 = createInternalLogger("TrafficMeter");
|
|
1319
1416
|
var encoder = new TextEncoder();
|
|
1320
1417
|
var toSafeNumber = (value) => {
|
|
1321
1418
|
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) return 0;
|
|
@@ -1485,7 +1582,7 @@ var createTrafficMeter = ({
|
|
|
1485
1582
|
session.on("Network.webSocketFrameSent", recordWebSocketFrameSent);
|
|
1486
1583
|
session.on("Network.webSocketFrameReceived", recordWebSocketFrameReceived);
|
|
1487
1584
|
} catch (error) {
|
|
1488
|
-
|
|
1585
|
+
logger6.warn(`CDP \u76D1\u542C\u6CE8\u518C\u5931\u8D25: ${error?.message || error}`);
|
|
1489
1586
|
}
|
|
1490
1587
|
};
|
|
1491
1588
|
const snapshot = () => {
|
|
@@ -1521,7 +1618,7 @@ var createTrafficMeter = ({
|
|
|
1521
1618
|
};
|
|
1522
1619
|
|
|
1523
1620
|
// src/launch.js
|
|
1524
|
-
var
|
|
1621
|
+
var logger7 = createInternalLogger("Launch");
|
|
1525
1622
|
var resolveProxyLaunchOptions = (proxyConfiguration = {}) => {
|
|
1526
1623
|
const config = proxyConfiguration && typeof proxyConfiguration === "object" && !Array.isArray(proxyConfiguration) ? proxyConfiguration : {};
|
|
1527
1624
|
const proxyUrl = String(config.proxy_url || "").trim();
|
|
@@ -1573,15 +1670,15 @@ var Launch = {
|
|
|
1573
1670
|
}
|
|
1574
1671
|
const enableByPassLogger = Boolean(logOptions && logOptions.enable);
|
|
1575
1672
|
if (enableByPassLogger && launchProxy) {
|
|
1576
|
-
|
|
1673
|
+
logger7.info(
|
|
1577
1674
|
`[\u4EE3\u7406\u5DF2\u542F\u7528] \u4EE3\u7406\u670D\u52A1=${launchProxy.server} \u76F4\u8FDE\u57DF\u540D=${(byPassDomains || []).join(",")}`
|
|
1578
1675
|
);
|
|
1579
1676
|
} else if (enableByPassLogger && enableProxy && !launchProxy) {
|
|
1580
|
-
|
|
1677
|
+
logger7.info(
|
|
1581
1678
|
`[\u4EE3\u7406\u672A\u542F\u7528] enable_proxy=true \u4F46 proxy_url \u4E3A\u7A7A`
|
|
1582
1679
|
);
|
|
1583
1680
|
} else if (enableByPassLogger && !enableProxy && proxyUrl) {
|
|
1584
|
-
|
|
1681
|
+
logger7.info(
|
|
1585
1682
|
`[\u4EE3\u7406\u672A\u542F\u7528] enable_proxy=false \u4E14 proxy_url \u5DF2\u914D\u7F6E`
|
|
1586
1683
|
);
|
|
1587
1684
|
}
|
|
@@ -1599,7 +1696,7 @@ var Launch = {
|
|
|
1599
1696
|
const requestUrl = req.url();
|
|
1600
1697
|
const matched = findMatchedByPassRule(byPassRules, requestUrl);
|
|
1601
1698
|
if (!matched || !matched.rule) return;
|
|
1602
|
-
|
|
1699
|
+
logger7.info(`[\u76F4\u8FDE\u547D\u4E2D] \u89C4\u5219=${matched.rule.pattern} \u57DF\u540D=${matched.hostname} \u8D44\u6E90\u7C7B\u578B=${req.resourceType()} \u65B9\u6CD5=${req.method()} \u5730\u5740=${requestUrl}`);
|
|
1603
1700
|
};
|
|
1604
1701
|
page.on("request", requestHandler);
|
|
1605
1702
|
return recommendedGotoOptions;
|
|
@@ -1618,7 +1715,7 @@ var Launch = {
|
|
|
1618
1715
|
// src/live-view.js
|
|
1619
1716
|
var import_express = __toESM(require("express"), 1);
|
|
1620
1717
|
var import_apify = require("apify");
|
|
1621
|
-
var
|
|
1718
|
+
var logger8 = createInternalLogger("LiveView");
|
|
1622
1719
|
async function startLiveViewServer(liveViewKey) {
|
|
1623
1720
|
const app = (0, import_express.default)();
|
|
1624
1721
|
app.get("/", async (req, res) => {
|
|
@@ -1643,24 +1740,24 @@ async function startLiveViewServer(liveViewKey) {
|
|
|
1643
1740
|
</html>
|
|
1644
1741
|
`);
|
|
1645
1742
|
} catch (error) {
|
|
1646
|
-
|
|
1743
|
+
logger8.fail("Live View Server", error);
|
|
1647
1744
|
res.status(500).send(`\u65E0\u6CD5\u52A0\u8F7D\u5C4F\u5E55\u622A\u56FE: ${error.message}`);
|
|
1648
1745
|
}
|
|
1649
1746
|
});
|
|
1650
1747
|
const port = process.env.APIFY_CONTAINER_PORT || 4321;
|
|
1651
1748
|
app.listen(port, () => {
|
|
1652
|
-
|
|
1749
|
+
logger8.success("startLiveViewServer", `\u76D1\u542C\u7AEF\u53E3 ${port}`);
|
|
1653
1750
|
});
|
|
1654
1751
|
}
|
|
1655
1752
|
async function takeLiveScreenshot(liveViewKey, page, logMessage) {
|
|
1656
1753
|
try {
|
|
1657
|
-
const buffer = await page
|
|
1754
|
+
const buffer = await capturePageScreenshot(page, { type: "png" });
|
|
1658
1755
|
await import_apify.Actor.setValue(liveViewKey, buffer, { contentType: "image/png" });
|
|
1659
1756
|
if (logMessage) {
|
|
1660
|
-
|
|
1757
|
+
logger8.info(`(\u622A\u56FE): ${logMessage}`);
|
|
1661
1758
|
}
|
|
1662
1759
|
} catch (e) {
|
|
1663
|
-
|
|
1760
|
+
logger8.warn(`\u65E0\u6CD5\u6355\u83B7 Live View \u5C4F\u5E55\u622A\u56FE: ${e.message}`);
|
|
1664
1761
|
}
|
|
1665
1762
|
}
|
|
1666
1763
|
var useLiveView = (liveViewKey = PresetOfLiveViewKey) => {
|
|
@@ -1679,7 +1776,7 @@ var LiveView = {
|
|
|
1679
1776
|
|
|
1680
1777
|
// src/captcha-monitor.js
|
|
1681
1778
|
var import_uuid = require("uuid");
|
|
1682
|
-
var
|
|
1779
|
+
var logger9 = createInternalLogger("Captcha");
|
|
1683
1780
|
function useCaptchaMonitor(page, options) {
|
|
1684
1781
|
const { domSelector, urlPattern, onDetected } = options;
|
|
1685
1782
|
if (!domSelector && !urlPattern) {
|
|
@@ -1752,7 +1849,7 @@ function useCaptchaMonitor(page, options) {
|
|
|
1752
1849
|
};
|
|
1753
1850
|
})();
|
|
1754
1851
|
}, { selector: domSelector, callbackName: exposedFunctionName, cleanerName });
|
|
1755
|
-
|
|
1852
|
+
logger9.success("useCaptchaMonitor", `DOM \u76D1\u63A7\u5DF2\u542F\u7528: ${domSelector}`);
|
|
1756
1853
|
cleanupFns.push(async () => {
|
|
1757
1854
|
try {
|
|
1758
1855
|
await page.evaluate((name) => {
|
|
@@ -1775,14 +1872,14 @@ function useCaptchaMonitor(page, options) {
|
|
|
1775
1872
|
}
|
|
1776
1873
|
};
|
|
1777
1874
|
page.on("framenavigated", frameHandler);
|
|
1778
|
-
|
|
1875
|
+
logger9.success("useCaptchaMonitor", `URL \u76D1\u63A7\u5DF2\u542F\u7528: ${urlPattern}`);
|
|
1779
1876
|
cleanupFns.push(async () => {
|
|
1780
1877
|
page.off("framenavigated", frameHandler);
|
|
1781
1878
|
});
|
|
1782
1879
|
}
|
|
1783
1880
|
return {
|
|
1784
1881
|
stop: async () => {
|
|
1785
|
-
|
|
1882
|
+
logger9.info("useCaptchaMonitor", "\u6B63\u5728\u505C\u6B62\u76D1\u63A7...");
|
|
1786
1883
|
for (const fn of cleanupFns) {
|
|
1787
1884
|
await fn();
|
|
1788
1885
|
}
|
|
@@ -1797,7 +1894,7 @@ var Captcha = {
|
|
|
1797
1894
|
// src/sse.js
|
|
1798
1895
|
var import_https = __toESM(require("https"), 1);
|
|
1799
1896
|
var import_url = require("url");
|
|
1800
|
-
var
|
|
1897
|
+
var logger10 = createInternalLogger("Sse");
|
|
1801
1898
|
var Sse = {
|
|
1802
1899
|
/**
|
|
1803
1900
|
* 解析 SSE 流文本
|
|
@@ -1816,11 +1913,11 @@ var Sse = {
|
|
|
1816
1913
|
events.push(JSON.parse(jsonContent));
|
|
1817
1914
|
}
|
|
1818
1915
|
} catch (e) {
|
|
1819
|
-
|
|
1916
|
+
logger10.debug("parseSseStream", `JSON \u89E3\u6790\u5931\u8D25: ${e.message}, line: ${line.substring(0, 100)}...`);
|
|
1820
1917
|
}
|
|
1821
1918
|
}
|
|
1822
1919
|
}
|
|
1823
|
-
|
|
1920
|
+
logger10.success("parseSseStream", `\u89E3\u6790\u5B8C\u6210, events \u6570\u91CF: ${events.length}`);
|
|
1824
1921
|
return events;
|
|
1825
1922
|
},
|
|
1826
1923
|
/**
|
|
@@ -1870,7 +1967,7 @@ var Sse = {
|
|
|
1870
1967
|
if (!autoUnroute) return;
|
|
1871
1968
|
if (unrouteRequested) return;
|
|
1872
1969
|
unrouteRequested = true;
|
|
1873
|
-
|
|
1970
|
+
logger10.info("[MITM] autoUnroute: \u53D6\u6D88\u540E\u7EED\u62E6\u622A");
|
|
1874
1971
|
page.unroute(urlPattern, routeHandler).catch(() => {
|
|
1875
1972
|
});
|
|
1876
1973
|
};
|
|
@@ -1890,19 +1987,19 @@ var Sse = {
|
|
|
1890
1987
|
};
|
|
1891
1988
|
const routeHandler = async (route) => {
|
|
1892
1989
|
if (firstMatchOnly && hasMatchedOnce) {
|
|
1893
|
-
|
|
1990
|
+
logger10.info(`[MITM] firstMatchOnly: \u653E\u884C\u540E\u7EED\u8BF7\u6C42: ${route.request().url()}`);
|
|
1894
1991
|
route.continue().catch(() => {
|
|
1895
1992
|
});
|
|
1896
1993
|
return;
|
|
1897
1994
|
}
|
|
1898
1995
|
if (firstMatchOnly && !hasMatchedOnce) {
|
|
1899
1996
|
hasMatchedOnce = true;
|
|
1900
|
-
|
|
1997
|
+
logger10.info("[MITM] firstMatchOnly: \u547D\u4E2D\u9996\u4E2A\u8BF7\u6C42\uFF0C\u53D6\u6D88\u540E\u7EED\u62E6\u622A");
|
|
1901
1998
|
page.unroute(urlPattern, routeHandler).catch(() => {
|
|
1902
1999
|
});
|
|
1903
2000
|
}
|
|
1904
2001
|
const request = route.request();
|
|
1905
|
-
|
|
2002
|
+
logger10.info(`[MITM] \u5DF2\u62E6\u622A\u8BF7\u6C42: ${request.url()}`);
|
|
1906
2003
|
try {
|
|
1907
2004
|
const headers = await request.allHeaders();
|
|
1908
2005
|
const postData = request.postData();
|
|
@@ -1927,7 +2024,7 @@ var Sse = {
|
|
|
1927
2024
|
clearTimeout(initialTimer);
|
|
1928
2025
|
initialTimer = null;
|
|
1929
2026
|
}
|
|
1930
|
-
|
|
2027
|
+
logger10.debug("[Intercept] \u5DF2\u63A5\u6536\u521D\u59CB\u6570\u636E");
|
|
1931
2028
|
}
|
|
1932
2029
|
chunks.push(chunk);
|
|
1933
2030
|
const textChunk = chunk.toString("utf-8");
|
|
@@ -1936,18 +2033,18 @@ var Sse = {
|
|
|
1936
2033
|
try {
|
|
1937
2034
|
onData(textChunk, safeResolve, accumulatedText);
|
|
1938
2035
|
} catch (e) {
|
|
1939
|
-
|
|
2036
|
+
logger10.fail(`onData \u9519\u8BEF`, e);
|
|
1940
2037
|
}
|
|
1941
2038
|
}
|
|
1942
2039
|
});
|
|
1943
2040
|
res.on("end", () => {
|
|
1944
|
-
|
|
2041
|
+
logger10.info("[MITM] \u4E0A\u6E38\u54CD\u5E94\u7ED3\u675F");
|
|
1945
2042
|
clearAllTimers();
|
|
1946
2043
|
if (onEnd) {
|
|
1947
2044
|
try {
|
|
1948
2045
|
onEnd(accumulatedText, safeResolve);
|
|
1949
2046
|
} catch (e) {
|
|
1950
|
-
|
|
2047
|
+
logger10.fail(`onEnd \u9519\u8BEF`, e);
|
|
1951
2048
|
}
|
|
1952
2049
|
} else if (!onData) {
|
|
1953
2050
|
safeResolve(accumulatedText);
|
|
@@ -2028,7 +2125,7 @@ var Sse = {
|
|
|
2028
2125
|
|
|
2029
2126
|
// src/mutation.js
|
|
2030
2127
|
var import_uuid2 = require("uuid");
|
|
2031
|
-
var
|
|
2128
|
+
var logger11 = createInternalLogger("Mutation");
|
|
2032
2129
|
var MUTATION_MONITOR_MODE = Object.freeze({
|
|
2033
2130
|
Added: "added",
|
|
2034
2131
|
Changed: "changed",
|
|
@@ -2061,14 +2158,14 @@ var Mutation = {
|
|
|
2061
2158
|
const stableTime = options.stableTime ?? 5 * 1e3;
|
|
2062
2159
|
const timeout = options.timeout ?? 120 * 1e3;
|
|
2063
2160
|
const onMutation = options.onMutation;
|
|
2064
|
-
|
|
2161
|
+
logger11.start("waitForStable", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, \u7A33\u5B9A\u65F6\u95F4=${stableTime}ms`);
|
|
2065
2162
|
if (initialTimeout > 0) {
|
|
2066
2163
|
const selectorQuery = selectorList.join(",");
|
|
2067
2164
|
try {
|
|
2068
2165
|
await page.waitForSelector(selectorQuery, { timeout: initialTimeout });
|
|
2069
|
-
|
|
2166
|
+
logger11.info(`waitForStable \u5DF2\u68C0\u6D4B\u5230\u5143\u7D20: ${selectorQuery}`);
|
|
2070
2167
|
} catch (e) {
|
|
2071
|
-
|
|
2168
|
+
logger11.warning(`waitForStable \u521D\u59CB\u7B49\u5F85\u8D85\u65F6 (${initialTimeout}ms): ${selectorQuery}`);
|
|
2072
2169
|
throw e;
|
|
2073
2170
|
}
|
|
2074
2171
|
}
|
|
@@ -2084,7 +2181,7 @@ var Mutation = {
|
|
|
2084
2181
|
return "__CONTINUE__";
|
|
2085
2182
|
}
|
|
2086
2183
|
});
|
|
2087
|
-
|
|
2184
|
+
logger11.info("waitForStable \u5DF2\u542F\u7528 onMutation \u56DE\u8C03");
|
|
2088
2185
|
} catch (e) {
|
|
2089
2186
|
}
|
|
2090
2187
|
}
|
|
@@ -2199,9 +2296,9 @@ var Mutation = {
|
|
|
2199
2296
|
{ selectorList, stableTime, timeout, callbackName, hasCallback: !!onMutation }
|
|
2200
2297
|
);
|
|
2201
2298
|
if (result.mutationCount === 0 && result.stableTime === 0) {
|
|
2202
|
-
|
|
2299
|
+
logger11.warning("waitForStable \u672A\u627E\u5230\u53EF\u76D1\u63A7\u7684\u5143\u7D20");
|
|
2203
2300
|
}
|
|
2204
|
-
|
|
2301
|
+
logger11.success("waitForStable", `DOM \u7A33\u5B9A, \u603B\u5171 ${result.mutationCount} \u6B21\u53D8\u5316${result.wasPaused ? ", \u66FE\u6682\u505C\u8BA1\u65F6" : ""}`);
|
|
2205
2302
|
return result;
|
|
2206
2303
|
},
|
|
2207
2304
|
/**
|
|
@@ -2221,7 +2318,7 @@ var Mutation = {
|
|
|
2221
2318
|
const onMutation = options.onMutation;
|
|
2222
2319
|
const rawMode = String(options.mode || MUTATION_MONITOR_MODE.Added).toLowerCase();
|
|
2223
2320
|
const mode = [MUTATION_MONITOR_MODE.Added, MUTATION_MONITOR_MODE.Changed, MUTATION_MONITOR_MODE.All].includes(rawMode) ? rawMode : MUTATION_MONITOR_MODE.Added;
|
|
2224
|
-
|
|
2321
|
+
logger11.start("useMonitor", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, mode=${mode}`);
|
|
2225
2322
|
const monitorKey = generateKey("pk_mon");
|
|
2226
2323
|
const callbackName = generateKey("pk_mon_cb");
|
|
2227
2324
|
const cleanerName = generateKey("pk_mon_clean");
|
|
@@ -2364,7 +2461,7 @@ var Mutation = {
|
|
|
2364
2461
|
return total;
|
|
2365
2462
|
};
|
|
2366
2463
|
}, { selectorList, monitorKey, callbackName, cleanerName, hasCallback: !!onMutation, mode });
|
|
2367
|
-
|
|
2464
|
+
logger11.success("useMonitor", "\u76D1\u63A7\u5668\u5DF2\u542F\u52A8");
|
|
2368
2465
|
return {
|
|
2369
2466
|
stop: async () => {
|
|
2370
2467
|
let totalMutations = 0;
|
|
@@ -2377,7 +2474,7 @@ var Mutation = {
|
|
|
2377
2474
|
}, cleanerName);
|
|
2378
2475
|
} catch (e) {
|
|
2379
2476
|
}
|
|
2380
|
-
|
|
2477
|
+
logger11.success("useMonitor.stop", `\u76D1\u63A7\u5DF2\u505C\u6B62, \u5171 ${totalMutations} \u6B21\u53D8\u5316`);
|
|
2381
2478
|
return { totalMutations };
|
|
2382
2479
|
}
|
|
2383
2480
|
};
|
|
@@ -3246,7 +3343,7 @@ var createTemplateLogger = (baseLogger = createBaseLogger()) => {
|
|
|
3246
3343
|
};
|
|
3247
3344
|
var getDefaultBaseLogger = () => createBaseLogger("");
|
|
3248
3345
|
var Logger = {
|
|
3249
|
-
setLogger: (
|
|
3346
|
+
setLogger: (logger13) => setDefaultLogger(logger13),
|
|
3250
3347
|
info: (message) => getDefaultBaseLogger().info(message),
|
|
3251
3348
|
success: (message) => getDefaultBaseLogger().success(message),
|
|
3252
3349
|
warning: (message) => getDefaultBaseLogger().warning(message),
|
|
@@ -3254,16 +3351,16 @@ var Logger = {
|
|
|
3254
3351
|
error: (message) => getDefaultBaseLogger().error(message),
|
|
3255
3352
|
debug: (message) => getDefaultBaseLogger().debug(message),
|
|
3256
3353
|
start: (message) => getDefaultBaseLogger().start(message),
|
|
3257
|
-
useTemplate: (
|
|
3258
|
-
if (
|
|
3354
|
+
useTemplate: (logger13) => {
|
|
3355
|
+
if (logger13) return createTemplateLogger(createBaseLogger("", logger13));
|
|
3259
3356
|
return createTemplateLogger();
|
|
3260
3357
|
}
|
|
3261
3358
|
};
|
|
3262
3359
|
|
|
3263
3360
|
// src/share.js
|
|
3264
3361
|
var import_delay2 = __toESM(require("delay"), 1);
|
|
3265
|
-
var
|
|
3266
|
-
var
|
|
3362
|
+
var logger12 = createInternalLogger("Share");
|
|
3363
|
+
var DEFAULT_TIMEOUT_MS2 = 50 * 1e3;
|
|
3267
3364
|
var DEFAULT_PAYLOAD_SNAPSHOT_MAX_LEN = 500;
|
|
3268
3365
|
var DEFAULT_POLL_INTERVAL_MS = 120;
|
|
3269
3366
|
var normalizePrefix = (value) => value == null ? void 0 : String(value).trim();
|
|
@@ -3382,7 +3479,7 @@ var createDomShareMonitor = async (page, options = {}) => {
|
|
|
3382
3479
|
const onMatch = typeof options.onMatch === "function" ? options.onMatch : null;
|
|
3383
3480
|
const onTelemetry = typeof options.onTelemetry === "function" ? options.onTelemetry : null;
|
|
3384
3481
|
let matched = false;
|
|
3385
|
-
|
|
3482
|
+
logger12.info(`DOM \u76D1\u542C\u51C6\u5907\u6302\u8F7D: selectors=${toJsonInline(selectors, 120)}, mode=${mode}`);
|
|
3386
3483
|
const monitor = await Mutation.useMonitor(page, selectors, {
|
|
3387
3484
|
mode,
|
|
3388
3485
|
onMutation: (context = {}) => {
|
|
@@ -3400,12 +3497,12 @@ ${text}`;
|
|
|
3400
3497
|
});
|
|
3401
3498
|
}
|
|
3402
3499
|
if (mutationCount <= 5 || mutationCount % 50 === 0) {
|
|
3403
|
-
|
|
3500
|
+
logger12.info(`DOM \u53D8\u5316\u5DF2\u6355\u83B7: mutationCount=${mutationCount}, mutationNodes=${mutationNodes.length}`);
|
|
3404
3501
|
}
|
|
3405
3502
|
const [candidate] = Utils.parseLinks(rawDom, { prefix }) || [];
|
|
3406
3503
|
if (!candidate) return;
|
|
3407
3504
|
matched = true;
|
|
3408
|
-
|
|
3505
|
+
logger12.success("captureLink.domHit", `DOM \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: mutationCount=${mutationCount}, link=${candidate}`);
|
|
3409
3506
|
if (onMatch) {
|
|
3410
3507
|
onMatch({
|
|
3411
3508
|
link: candidate,
|
|
@@ -3421,7 +3518,7 @@ ${text}`;
|
|
|
3421
3518
|
return {
|
|
3422
3519
|
stop: async () => {
|
|
3423
3520
|
const result = await monitor.stop();
|
|
3424
|
-
|
|
3521
|
+
logger12.info(`DOM \u76D1\u542C\u5DF2\u505C\u6B62: totalMutations=${result?.totalMutations || 0}`);
|
|
3425
3522
|
return result;
|
|
3426
3523
|
}
|
|
3427
3524
|
};
|
|
@@ -3444,7 +3541,7 @@ var Share = {
|
|
|
3444
3541
|
*/
|
|
3445
3542
|
async captureLink(page, options = {}) {
|
|
3446
3543
|
const share = normalizeShare(options.share);
|
|
3447
|
-
const timeoutMs = Math.max(0, Number(options.timeoutMs ??
|
|
3544
|
+
const timeoutMs = Math.max(0, Number(options.timeoutMs ?? DEFAULT_TIMEOUT_MS2) || 0);
|
|
3448
3545
|
const payloadSnapshotMaxLen = options.payloadSnapshotMaxLen ?? DEFAULT_PAYLOAD_SNAPSHOT_MAX_LEN;
|
|
3449
3546
|
const domSelectors = options.domSelectors ?? "html";
|
|
3450
3547
|
const domMode = options.domMode ?? Mutation.Mode.All;
|
|
@@ -3461,8 +3558,8 @@ var Share = {
|
|
|
3461
3558
|
if (share.mode === "response" && apiMatchers.length === 0) {
|
|
3462
3559
|
throw new Error("Share.captureLink requires share.xurl[0] api matcher when mode=response");
|
|
3463
3560
|
}
|
|
3464
|
-
|
|
3465
|
-
|
|
3561
|
+
logger12.start("captureLink", `mode=${share.mode}, timeoutMs=${timeoutMs}, prefix=${share.prefix}`);
|
|
3562
|
+
logger12.info(`captureLink \u914D\u7F6E: xurl=${toJsonInline(share.xurl)}, domMode=${domMode}, domSelectors=${toJsonInline(domSelectors, 120)}`);
|
|
3466
3563
|
const stats = {
|
|
3467
3564
|
actionTimedOut: false,
|
|
3468
3565
|
domMutationCount: 0,
|
|
@@ -3487,7 +3584,7 @@ var Share = {
|
|
|
3487
3584
|
link: validated,
|
|
3488
3585
|
payloadText: String(payloadText || "")
|
|
3489
3586
|
};
|
|
3490
|
-
|
|
3587
|
+
logger12.info(`\u5019\u9009\u94FE\u63A5\u5DF2\u786E\u8BA4: source=${source}, link=${validated}`);
|
|
3491
3588
|
return true;
|
|
3492
3589
|
};
|
|
3493
3590
|
const resolveResponseCandidate = (responseText) => {
|
|
@@ -3522,7 +3619,7 @@ var Share = {
|
|
|
3522
3619
|
try {
|
|
3523
3620
|
await monitor.stop();
|
|
3524
3621
|
} catch (error) {
|
|
3525
|
-
|
|
3622
|
+
logger12.warning(`\u505C\u6B62 DOM \u76D1\u542C\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
|
|
3526
3623
|
}
|
|
3527
3624
|
};
|
|
3528
3625
|
const onResponse = async (response) => {
|
|
@@ -3535,29 +3632,29 @@ var Share = {
|
|
|
3535
3632
|
stats.responseSampleUrls.push(url);
|
|
3536
3633
|
}
|
|
3537
3634
|
if (stats.responseObserved <= 5) {
|
|
3538
|
-
|
|
3635
|
+
logger12.info(`\u63A5\u53E3\u54CD\u5E94\u91C7\u6837(${stats.responseObserved}): ${url}`);
|
|
3539
3636
|
}
|
|
3540
3637
|
if (!apiMatchers.some((matcher) => url.includes(matcher))) return;
|
|
3541
3638
|
stats.responseMatched += 1;
|
|
3542
3639
|
stats.lastMatchedUrl = url;
|
|
3543
|
-
|
|
3640
|
+
logger12.info(`\u63A5\u53E3\u547D\u4E2D\u5339\u914D(${stats.responseMatched}): ${url}`);
|
|
3544
3641
|
const text = await response.text();
|
|
3545
3642
|
const hit = resolveResponseCandidate(text);
|
|
3546
3643
|
if (!hit?.link) {
|
|
3547
3644
|
if (stats.responseMatched <= 3) {
|
|
3548
|
-
|
|
3645
|
+
logger12.info(`\u63A5\u53E3\u89E3\u6790\u5B8C\u6210\u4F46\u672A\u63D0\u53D6\u5230\u5206\u4EAB\u94FE\u63A5: payloadSize=${text.length}`);
|
|
3549
3646
|
}
|
|
3550
3647
|
return;
|
|
3551
3648
|
}
|
|
3552
3649
|
stats.responseResolved += 1;
|
|
3553
|
-
|
|
3650
|
+
logger12.success("captureLink.responseHit", `\u63A5\u53E3\u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: url=${url}, link=${hit.link}`);
|
|
3554
3651
|
setCandidate("response", hit.link, hit.payloadText);
|
|
3555
3652
|
} catch (error) {
|
|
3556
|
-
|
|
3653
|
+
logger12.warning(`\u63A5\u53E3\u54CD\u5E94\u5904\u7406\u5F02\u5E38: ${error instanceof Error ? error.message : String(error)}`);
|
|
3557
3654
|
}
|
|
3558
3655
|
};
|
|
3559
3656
|
if (share.mode === "dom") {
|
|
3560
|
-
|
|
3657
|
+
logger12.info("\u5F53\u524D\u4E3A DOM \u6A21\u5F0F\uFF0C\u4EC5\u542F\u7528 DOM \u76D1\u542C");
|
|
3561
3658
|
domMonitor = await createDomShareMonitor(page, {
|
|
3562
3659
|
prefix: share.prefix,
|
|
3563
3660
|
selectors: domSelectors,
|
|
@@ -3572,14 +3669,14 @@ var Share = {
|
|
|
3572
3669
|
});
|
|
3573
3670
|
}
|
|
3574
3671
|
if (share.mode === "response") {
|
|
3575
|
-
|
|
3672
|
+
logger12.info(`\u5F53\u524D\u4E3A\u63A5\u53E3\u6A21\u5F0F\uFF0C\u6302\u8F7D response \u76D1\u542C: apiMatchers=${toJsonInline(apiMatchers, 160)}`);
|
|
3576
3673
|
page.on("response", onResponse);
|
|
3577
3674
|
}
|
|
3578
3675
|
const deadline = Date.now() + timeoutMs;
|
|
3579
3676
|
const getRemainingMs = () => Math.max(0, deadline - Date.now());
|
|
3580
3677
|
try {
|
|
3581
3678
|
const actionTimeout = getRemainingMs();
|
|
3582
|
-
|
|
3679
|
+
logger12.start("captureLink.performActions", `\u6267\u884C\u52A8\u4F5C\u9884\u7B97=${actionTimeout}ms`);
|
|
3583
3680
|
if (actionTimeout > 0) {
|
|
3584
3681
|
let timer = null;
|
|
3585
3682
|
let actionError = null;
|
|
@@ -3593,21 +3690,21 @@ var Share = {
|
|
|
3593
3690
|
const actionResult = await Promise.race([actionPromise, timeoutPromise]);
|
|
3594
3691
|
if (timer) clearTimeout(timer);
|
|
3595
3692
|
if (actionResult === "__ACTION_ERROR__") {
|
|
3596
|
-
|
|
3693
|
+
logger12.fail("captureLink.performActions", actionError);
|
|
3597
3694
|
throw actionError;
|
|
3598
3695
|
}
|
|
3599
3696
|
if (actionResult === "__ACTION_TIMEOUT__") {
|
|
3600
3697
|
stats.actionTimedOut = true;
|
|
3601
|
-
|
|
3698
|
+
logger12.warning(`performActions \u5DF2\u8D85\u65F6 (${actionTimeout}ms)\uFF0C\u52A8\u4F5C\u53EF\u80FD\u4ECD\u5728\u5F02\u6B65\u6267\u884C`);
|
|
3602
3699
|
} else {
|
|
3603
|
-
|
|
3700
|
+
logger12.success("captureLink.performActions", "\u6267\u884C\u52A8\u4F5C\u5B8C\u6210");
|
|
3604
3701
|
}
|
|
3605
3702
|
}
|
|
3606
3703
|
let nextProgressLogTs = Date.now() + 3e3;
|
|
3607
3704
|
while (true) {
|
|
3608
3705
|
const selected = share.mode === "dom" ? candidates.dom : candidates.response;
|
|
3609
3706
|
if (selected?.link) {
|
|
3610
|
-
|
|
3707
|
+
logger12.success("captureLink", `\u6355\u83B7\u6210\u529F: source=${share.mode}, link=${selected.link}`);
|
|
3611
3708
|
return {
|
|
3612
3709
|
link: selected.link,
|
|
3613
3710
|
payloadText: selected.payloadText,
|
|
@@ -3619,7 +3716,7 @@ var Share = {
|
|
|
3619
3716
|
if (remaining <= 0) break;
|
|
3620
3717
|
const now = Date.now();
|
|
3621
3718
|
if (now >= nextProgressLogTs) {
|
|
3622
|
-
|
|
3719
|
+
logger12.info(
|
|
3623
3720
|
`captureLink \u7B49\u5F85\u4E2D: remaining=${remaining}ms, domMutationCount=${stats.domMutationCount}, responseMatched=${stats.responseMatched}`
|
|
3624
3721
|
);
|
|
3625
3722
|
nextProgressLogTs = now + 5e3;
|
|
@@ -3627,11 +3724,11 @@ var Share = {
|
|
|
3627
3724
|
await (0, import_delay2.default)(Math.max(0, Math.min(DEFAULT_POLL_INTERVAL_MS, remaining)));
|
|
3628
3725
|
}
|
|
3629
3726
|
if (share.mode === "response" && stats.responseMatched === 0) {
|
|
3630
|
-
|
|
3727
|
+
logger12.warning(
|
|
3631
3728
|
`\u63A5\u53E3\u76D1\u542C\u672A\u547D\u4E2D: apiMatchers=${toJsonInline(apiMatchers, 220)}, \u54CD\u5E94\u6837\u672CURLs=${toJsonInline(stats.responseSampleUrls, 420)}`
|
|
3632
3729
|
);
|
|
3633
3730
|
}
|
|
3634
|
-
|
|
3731
|
+
logger12.warning(
|
|
3635
3732
|
`captureLink \u8D85\u65F6\u672A\u62FF\u5230\u94FE\u63A5: mode=${share.mode}, actionTimedOut=${stats.actionTimedOut}, domMutationCount=${stats.domMutationCount}, responseObserved=${stats.responseObserved}, responseMatched=${stats.responseMatched}, lastMatchedUrl=${stats.lastMatchedUrl || "none"}`
|
|
3636
3733
|
);
|
|
3637
3734
|
return {
|
|
@@ -3643,7 +3740,7 @@ var Share = {
|
|
|
3643
3740
|
} finally {
|
|
3644
3741
|
if (share.mode === "response") {
|
|
3645
3742
|
page.off("response", onResponse);
|
|
3646
|
-
|
|
3743
|
+
logger12.info("response \u76D1\u542C\u5DF2\u5378\u8F7D");
|
|
3647
3744
|
}
|
|
3648
3745
|
await stopDomMonitor();
|
|
3649
3746
|
}
|
|
@@ -3691,9 +3788,10 @@ var Share = {
|
|
|
3691
3788
|
height: targetHeight
|
|
3692
3789
|
});
|
|
3693
3790
|
await (0, import_delay2.default)(1e3);
|
|
3694
|
-
const buffer_ = await page
|
|
3791
|
+
const buffer_ = await capturePageScreenshot(page, {
|
|
3695
3792
|
fullPage: true,
|
|
3696
|
-
type: "png"
|
|
3793
|
+
type: "png",
|
|
3794
|
+
maxClipHeight: targetHeight
|
|
3697
3795
|
});
|
|
3698
3796
|
return buffer_.toString("base64");
|
|
3699
3797
|
} finally {
|