@skrillex1224/playwright-toolkit 2.1.54 → 2.1.56
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 +19 -99
- package/dist/browser.js.map +4 -4
- package/dist/index.cjs +124 -107
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +124 -107
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -72,18 +72,18 @@ var fallbackLog = {
|
|
|
72
72
|
error: (...args) => console.error(...args),
|
|
73
73
|
debug: (...args) => console.debug ? console.debug(...args) : console.log(...args)
|
|
74
74
|
};
|
|
75
|
-
var resolveLogMethod = (
|
|
76
|
-
if (
|
|
77
|
-
return
|
|
75
|
+
var resolveLogMethod = (logger11, name) => {
|
|
76
|
+
if (logger11 && typeof logger11[name] === "function") {
|
|
77
|
+
return logger11[name].bind(logger11);
|
|
78
78
|
}
|
|
79
|
-
if (name === "warning" &&
|
|
80
|
-
return
|
|
79
|
+
if (name === "warning" && logger11 && typeof logger11.warn === "function") {
|
|
80
|
+
return logger11.warn.bind(logger11);
|
|
81
81
|
}
|
|
82
82
|
return fallbackLog[name];
|
|
83
83
|
};
|
|
84
84
|
var defaultLogger = null;
|
|
85
|
-
var setDefaultLogger = (
|
|
86
|
-
defaultLogger =
|
|
85
|
+
var setDefaultLogger = (logger11) => {
|
|
86
|
+
defaultLogger = logger11;
|
|
87
87
|
};
|
|
88
88
|
var resolveLogger = (explicitLogger) => {
|
|
89
89
|
if (explicitLogger && typeof explicitLogger.info === "function") {
|
|
@@ -110,8 +110,8 @@ var colorize = (text, color) => {
|
|
|
110
110
|
var createBaseLogger = (prefix = "", explicitLogger) => {
|
|
111
111
|
const name = prefix ? String(prefix) : "";
|
|
112
112
|
const dispatch = (methodName, icon, message, color) => {
|
|
113
|
-
const
|
|
114
|
-
const logFn = resolveLogMethod(
|
|
113
|
+
const logger11 = resolveLogger(explicitLogger);
|
|
114
|
+
const logFn = resolveLogMethod(logger11, methodName);
|
|
115
115
|
logFn(colorize(formatLine(name, icon, message), color));
|
|
116
116
|
};
|
|
117
117
|
return {
|
|
@@ -361,9 +361,32 @@ var ApifyKit = {
|
|
|
361
361
|
useApifyKit
|
|
362
362
|
};
|
|
363
363
|
|
|
364
|
+
// src/internals/utils.js
|
|
365
|
+
var logger2 = createInternalLogger("InternalUtils");
|
|
366
|
+
var parseCookies = (cookieString, domain) => {
|
|
367
|
+
const cookies = [];
|
|
368
|
+
const pairs = cookieString.split(";").map((c) => c.trim());
|
|
369
|
+
for (const pair of pairs) {
|
|
370
|
+
const [name, ...valueParts] = pair.split("=");
|
|
371
|
+
if (name && valueParts.length > 0) {
|
|
372
|
+
const cookie = {
|
|
373
|
+
name: name.trim(),
|
|
374
|
+
value: valueParts.join("=").trim(),
|
|
375
|
+
path: "/"
|
|
376
|
+
};
|
|
377
|
+
if (domain) {
|
|
378
|
+
cookie.domain = domain;
|
|
379
|
+
}
|
|
380
|
+
cookies.push(cookie);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
logger2.success("parseCookies", `parsed ${cookies.length} cookies`);
|
|
384
|
+
return cookies;
|
|
385
|
+
};
|
|
386
|
+
|
|
364
387
|
// src/utils.js
|
|
365
388
|
var import_delay = __toESM(require("delay"), 1);
|
|
366
|
-
var
|
|
389
|
+
var logger3 = createInternalLogger("Utils");
|
|
367
390
|
var Utils = {
|
|
368
391
|
/**
|
|
369
392
|
* 解析 Cookie 字符串为 Playwright 格式的 Cookie 数组
|
|
@@ -372,24 +395,7 @@ var Utils = {
|
|
|
372
395
|
* @returns {Array} Cookie 数组
|
|
373
396
|
*/
|
|
374
397
|
parseCookies(cookieString, domain) {
|
|
375
|
-
|
|
376
|
-
const pairs = cookieString.split(";").map((c) => c.trim());
|
|
377
|
-
for (const pair of pairs) {
|
|
378
|
-
const [name, ...valueParts] = pair.split("=");
|
|
379
|
-
if (name && valueParts.length > 0) {
|
|
380
|
-
const cookie = {
|
|
381
|
-
name: name.trim(),
|
|
382
|
-
value: valueParts.join("=").trim(),
|
|
383
|
-
path: "/"
|
|
384
|
-
};
|
|
385
|
-
if (domain) {
|
|
386
|
-
cookie.domain = domain;
|
|
387
|
-
}
|
|
388
|
-
cookies.push(cookie);
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
logger2.success("parseCookies", `parsed ${cookies.length} cookies`);
|
|
392
|
-
return cookies;
|
|
398
|
+
return parseCookies(cookieString, domain);
|
|
393
399
|
},
|
|
394
400
|
/**
|
|
395
401
|
* 全页面滚动截图
|
|
@@ -403,7 +409,7 @@ var Utils = {
|
|
|
403
409
|
* @returns {Promise<string>} - base64 编码的 PNG 图片
|
|
404
410
|
*/
|
|
405
411
|
async fullPageScreenshot(page, options = {}) {
|
|
406
|
-
|
|
412
|
+
logger3.start("fullPageScreenshot", "detecting scrollable elements");
|
|
407
413
|
const originalViewport = page.viewportSize();
|
|
408
414
|
const defaultBuffer = Math.round((originalViewport?.height || 1080) / 2);
|
|
409
415
|
const buffer = options.buffer ?? defaultBuffer;
|
|
@@ -440,7 +446,7 @@ var Utils = {
|
|
|
440
446
|
fullPage: true,
|
|
441
447
|
type: "png"
|
|
442
448
|
});
|
|
443
|
-
|
|
449
|
+
logger3.success("fullPageScreenshot", `captured ${Math.round(buffer_.length / 1024)} KB`);
|
|
444
450
|
return buffer_.toString("base64");
|
|
445
451
|
} finally {
|
|
446
452
|
if (restore) {
|
|
@@ -464,7 +470,7 @@ var Utils = {
|
|
|
464
470
|
};
|
|
465
471
|
|
|
466
472
|
// src/anti-cheat.js
|
|
467
|
-
var
|
|
473
|
+
var logger4 = createInternalLogger("AntiCheat");
|
|
468
474
|
var BASE_CONFIG = Object.freeze({
|
|
469
475
|
locale: "zh-CN",
|
|
470
476
|
acceptLanguage: "zh-CN,zh;q=0.9",
|
|
@@ -526,7 +532,7 @@ var AntiCheat = {
|
|
|
526
532
|
// src/humanize.js
|
|
527
533
|
var import_delay2 = __toESM(require("delay"), 1);
|
|
528
534
|
var import_ghost_cursor_playwright = require("ghost-cursor-playwright");
|
|
529
|
-
var
|
|
535
|
+
var logger5 = createInternalLogger("Humanize");
|
|
530
536
|
var $CursorWeakMap = /* @__PURE__ */ new WeakMap();
|
|
531
537
|
function $GetCursor(page) {
|
|
532
538
|
const cursor = $CursorWeakMap.get(page);
|
|
@@ -554,13 +560,13 @@ var Humanize = {
|
|
|
554
560
|
*/
|
|
555
561
|
async initializeCursor(page) {
|
|
556
562
|
if ($CursorWeakMap.has(page)) {
|
|
557
|
-
|
|
563
|
+
logger5.debug("initializeCursor: cursor already exists, skipping");
|
|
558
564
|
return;
|
|
559
565
|
}
|
|
560
|
-
|
|
566
|
+
logger5.start("initializeCursor", "creating cursor");
|
|
561
567
|
const cursor = await (0, import_ghost_cursor_playwright.createCursor)(page);
|
|
562
568
|
$CursorWeakMap.set(page, cursor);
|
|
563
|
-
|
|
569
|
+
logger5.success("initializeCursor", "cursor initialized");
|
|
564
570
|
},
|
|
565
571
|
/**
|
|
566
572
|
* 人类化鼠标移动 - 使用 ghost-cursor 移动到指定位置或元素
|
|
@@ -570,17 +576,17 @@ var Humanize = {
|
|
|
570
576
|
*/
|
|
571
577
|
async humanMove(page, target) {
|
|
572
578
|
const cursor = $GetCursor(page);
|
|
573
|
-
|
|
579
|
+
logger5.start("humanMove", `target=${typeof target === "string" ? target : "element/coords"}`);
|
|
574
580
|
try {
|
|
575
581
|
if (typeof target === "string") {
|
|
576
582
|
const element = await page.$(target);
|
|
577
583
|
if (!element) {
|
|
578
|
-
|
|
584
|
+
logger5.warn(`humanMove: \u5143\u7D20\u4E0D\u5B58\u5728 ${target}`);
|
|
579
585
|
return false;
|
|
580
586
|
}
|
|
581
587
|
const box = await element.boundingBox();
|
|
582
588
|
if (!box) {
|
|
583
|
-
|
|
589
|
+
logger5.warn(`humanMove: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E ${target}`);
|
|
584
590
|
return false;
|
|
585
591
|
}
|
|
586
592
|
const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.2;
|
|
@@ -596,10 +602,10 @@ var Humanize = {
|
|
|
596
602
|
await cursor.actions.move({ x, y });
|
|
597
603
|
}
|
|
598
604
|
}
|
|
599
|
-
|
|
605
|
+
logger5.success("humanMove");
|
|
600
606
|
return true;
|
|
601
607
|
} catch (error) {
|
|
602
|
-
|
|
608
|
+
logger5.fail("humanMove", error);
|
|
603
609
|
throw error;
|
|
604
610
|
}
|
|
605
611
|
},
|
|
@@ -617,12 +623,12 @@ var Humanize = {
|
|
|
617
623
|
async humanScroll(page, target, options = {}) {
|
|
618
624
|
const { maxSteps = 30, minStep = 150, maxStep = 400 } = options;
|
|
619
625
|
const targetDesc = typeof target === "string" ? target : "ElementHandle";
|
|
620
|
-
|
|
626
|
+
logger5.debug(`humanScroll | \u76EE\u6807=${targetDesc}`);
|
|
621
627
|
let element;
|
|
622
628
|
if (typeof target === "string") {
|
|
623
629
|
element = await page.$(target);
|
|
624
630
|
if (!element) {
|
|
625
|
-
|
|
631
|
+
logger5.warn(`humanScroll | \u5143\u7D20\u672A\u627E\u5230: ${target}`);
|
|
626
632
|
return { element: null, didScroll: false };
|
|
627
633
|
}
|
|
628
634
|
} else {
|
|
@@ -666,12 +672,12 @@ var Humanize = {
|
|
|
666
672
|
for (let i = 0; i < maxSteps; i++) {
|
|
667
673
|
const status = await checkVisibility();
|
|
668
674
|
if (status.code === "VISIBLE") {
|
|
669
|
-
|
|
675
|
+
logger5.debug("humanScroll | \u5143\u7D20\u53EF\u89C1\u4E14\u65E0\u906E\u6321");
|
|
670
676
|
return { element, didScroll };
|
|
671
677
|
}
|
|
672
|
-
|
|
678
|
+
logger5.debug(`humanScroll | \u6B65\u9AA4 ${i + 1}/${maxSteps}: ${status.reason} ${status.direction ? `(${status.direction})` : ""}`);
|
|
673
679
|
if (status.code === "OBSTRUCTED" && status.obstruction) {
|
|
674
|
-
|
|
680
|
+
logger5.debug(`humanScroll | \u88AB\u4EE5\u4E0B\u5143\u7D20\u906E\u6321 <${status.obstruction.tag} id="${status.obstruction.id}">`);
|
|
675
681
|
}
|
|
676
682
|
let deltaY = 0;
|
|
677
683
|
if (status.code === "OUT_OF_VIEWPORT") {
|
|
@@ -699,10 +705,10 @@ var Humanize = {
|
|
|
699
705
|
didScroll = true;
|
|
700
706
|
await (0, import_delay2.default)(this.jitterMs(100 + Math.random() * 150, 0.2));
|
|
701
707
|
}
|
|
702
|
-
|
|
708
|
+
logger5.warn(`humanScroll | \u5728 ${maxSteps} \u6B65\u540E\u65E0\u6CD5\u786E\u4FDD\u53EF\u89C1\u6027`);
|
|
703
709
|
return { element, didScroll };
|
|
704
710
|
} catch (error) {
|
|
705
|
-
|
|
711
|
+
logger5.fail("humanScroll", error);
|
|
706
712
|
throw error;
|
|
707
713
|
}
|
|
708
714
|
},
|
|
@@ -720,7 +726,7 @@ var Humanize = {
|
|
|
720
726
|
const cursor = $GetCursor(page);
|
|
721
727
|
const { reactionDelay = 250, throwOnMissing = true, scrollIfNeeded = true, restore = false } = options;
|
|
722
728
|
const targetDesc = target == null ? "Current Position" : typeof target === "string" ? target : "ElementHandle";
|
|
723
|
-
|
|
729
|
+
logger5.start("humanClick", `target=${targetDesc}`);
|
|
724
730
|
const restoreOnce = async () => {
|
|
725
731
|
if (restoreOnce.restored) return;
|
|
726
732
|
restoreOnce.restored = true;
|
|
@@ -729,14 +735,14 @@ var Humanize = {
|
|
|
729
735
|
await (0, import_delay2.default)(this.jitterMs(1e3));
|
|
730
736
|
await restoreOnce.do();
|
|
731
737
|
} catch (restoreError) {
|
|
732
|
-
|
|
738
|
+
logger5.warn(`humanClick: \u6062\u590D\u6EDA\u52A8\u4F4D\u7F6E\u5931\u8D25: ${restoreError.message}`);
|
|
733
739
|
}
|
|
734
740
|
};
|
|
735
741
|
try {
|
|
736
742
|
if (target == null) {
|
|
737
743
|
await (0, import_delay2.default)(this.jitterMs(reactionDelay, 0.4));
|
|
738
744
|
await cursor.actions.click();
|
|
739
|
-
|
|
745
|
+
logger5.success("humanClick", "Clicked current position");
|
|
740
746
|
return true;
|
|
741
747
|
}
|
|
742
748
|
let element;
|
|
@@ -746,7 +752,7 @@ var Humanize = {
|
|
|
746
752
|
if (throwOnMissing) {
|
|
747
753
|
throw new Error(`\u627E\u4E0D\u5230\u5143\u7D20 ${target}`);
|
|
748
754
|
}
|
|
749
|
-
|
|
755
|
+
logger5.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${target}`);
|
|
750
756
|
return false;
|
|
751
757
|
}
|
|
752
758
|
} else {
|
|
@@ -762,7 +768,7 @@ var Humanize = {
|
|
|
762
768
|
if (throwOnMissing) {
|
|
763
769
|
throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5143\u7D20\u4F4D\u7F6E");
|
|
764
770
|
}
|
|
765
|
-
|
|
771
|
+
logger5.warn("humanClick: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E\uFF0C\u8DF3\u8FC7\u70B9\u51FB");
|
|
766
772
|
return false;
|
|
767
773
|
}
|
|
768
774
|
const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.3;
|
|
@@ -771,11 +777,11 @@ var Humanize = {
|
|
|
771
777
|
await (0, import_delay2.default)(this.jitterMs(reactionDelay, 0.4));
|
|
772
778
|
await cursor.actions.click();
|
|
773
779
|
await restoreOnce();
|
|
774
|
-
|
|
780
|
+
logger5.success("humanClick");
|
|
775
781
|
return true;
|
|
776
782
|
} catch (error) {
|
|
777
783
|
await restoreOnce();
|
|
778
|
-
|
|
784
|
+
logger5.fail("humanClick", error);
|
|
779
785
|
throw error;
|
|
780
786
|
}
|
|
781
787
|
},
|
|
@@ -786,9 +792,9 @@ var Humanize = {
|
|
|
786
792
|
*/
|
|
787
793
|
async randomSleep(baseMs, jitterPercent = 0.3) {
|
|
788
794
|
const ms = this.jitterMs(baseMs, jitterPercent);
|
|
789
|
-
|
|
795
|
+
logger5.start("randomSleep", `base=${baseMs}, actual=${ms}ms`);
|
|
790
796
|
await (0, import_delay2.default)(ms);
|
|
791
|
-
|
|
797
|
+
logger5.success("randomSleep");
|
|
792
798
|
},
|
|
793
799
|
/**
|
|
794
800
|
* 模拟人类"注视"或"阅读"行为:鼠标在页面上随机微动
|
|
@@ -798,7 +804,7 @@ var Humanize = {
|
|
|
798
804
|
async simulateGaze(page, baseDurationMs = 2500) {
|
|
799
805
|
const cursor = $GetCursor(page);
|
|
800
806
|
const durationMs = this.jitterMs(baseDurationMs, 0.4);
|
|
801
|
-
|
|
807
|
+
logger5.start("simulateGaze", `duration=${durationMs}ms`);
|
|
802
808
|
const startTime = Date.now();
|
|
803
809
|
const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };
|
|
804
810
|
while (Date.now() - startTime < durationMs) {
|
|
@@ -807,7 +813,7 @@ var Humanize = {
|
|
|
807
813
|
await cursor.actions.move({ x, y });
|
|
808
814
|
await (0, import_delay2.default)(this.jitterMs(600, 0.5));
|
|
809
815
|
}
|
|
810
|
-
|
|
816
|
+
logger5.success("simulateGaze");
|
|
811
817
|
},
|
|
812
818
|
/**
|
|
813
819
|
* 人类化输入 - 带节奏变化(快-慢-停顿-偶尔加速)
|
|
@@ -820,7 +826,7 @@ var Humanize = {
|
|
|
820
826
|
* @param {number} [options.pauseBase=800] - 停顿时长基础值 (ms),实际 ±50% 抖动
|
|
821
827
|
*/
|
|
822
828
|
async humanType(page, selector, text, options = {}) {
|
|
823
|
-
|
|
829
|
+
logger5.start("humanType", `selector=${selector}, textLen=${text.length}`);
|
|
824
830
|
const {
|
|
825
831
|
baseDelay = 180,
|
|
826
832
|
pauseProbability = 0.08,
|
|
@@ -844,13 +850,13 @@ var Humanize = {
|
|
|
844
850
|
await (0, import_delay2.default)(charDelay);
|
|
845
851
|
if (Math.random() < pauseProbability && i < text.length - 1) {
|
|
846
852
|
const pauseTime = this.jitterMs(pauseBase, 0.5);
|
|
847
|
-
|
|
853
|
+
logger5.debug(`\u505C\u987F ${pauseTime}ms...`);
|
|
848
854
|
await (0, import_delay2.default)(pauseTime);
|
|
849
855
|
}
|
|
850
856
|
}
|
|
851
|
-
|
|
857
|
+
logger5.success("humanType");
|
|
852
858
|
} catch (error) {
|
|
853
|
-
|
|
859
|
+
logger5.fail("humanType", error);
|
|
854
860
|
throw error;
|
|
855
861
|
}
|
|
856
862
|
},
|
|
@@ -860,22 +866,22 @@ var Humanize = {
|
|
|
860
866
|
* @param {string} selector - 输入框选择器
|
|
861
867
|
*/
|
|
862
868
|
async humanClear(page, selector) {
|
|
863
|
-
|
|
869
|
+
logger5.start("humanClear", `selector=${selector}`);
|
|
864
870
|
try {
|
|
865
871
|
const locator = page.locator(selector);
|
|
866
872
|
await locator.click();
|
|
867
873
|
await (0, import_delay2.default)(this.jitterMs(200, 0.4));
|
|
868
874
|
const currentValue = await locator.inputValue();
|
|
869
875
|
if (!currentValue || currentValue.length === 0) {
|
|
870
|
-
|
|
876
|
+
logger5.success("humanClear", "already empty");
|
|
871
877
|
return;
|
|
872
878
|
}
|
|
873
879
|
await page.keyboard.press("Meta+A");
|
|
874
880
|
await (0, import_delay2.default)(this.jitterMs(100, 0.4));
|
|
875
881
|
await page.keyboard.press("Backspace");
|
|
876
|
-
|
|
882
|
+
logger5.success("humanClear");
|
|
877
883
|
} catch (error) {
|
|
878
|
-
|
|
884
|
+
logger5.fail("humanClear", error);
|
|
879
885
|
throw error;
|
|
880
886
|
}
|
|
881
887
|
},
|
|
@@ -887,7 +893,7 @@ var Humanize = {
|
|
|
887
893
|
async warmUpBrowsing(page, baseDuration = 3500) {
|
|
888
894
|
const cursor = $GetCursor(page);
|
|
889
895
|
const durationMs = this.jitterMs(baseDuration, 0.4);
|
|
890
|
-
|
|
896
|
+
logger5.start("warmUpBrowsing", `duration=${durationMs}ms`);
|
|
891
897
|
const startTime = Date.now();
|
|
892
898
|
const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };
|
|
893
899
|
try {
|
|
@@ -906,9 +912,9 @@ var Humanize = {
|
|
|
906
912
|
await (0, import_delay2.default)(this.jitterMs(800, 0.5));
|
|
907
913
|
}
|
|
908
914
|
}
|
|
909
|
-
|
|
915
|
+
logger5.success("warmUpBrowsing");
|
|
910
916
|
} catch (error) {
|
|
911
|
-
|
|
917
|
+
logger5.fail("warmUpBrowsing", error);
|
|
912
918
|
throw error;
|
|
913
919
|
}
|
|
914
920
|
},
|
|
@@ -922,7 +928,7 @@ var Humanize = {
|
|
|
922
928
|
async naturalScroll(page, direction = "down", distance = 300, baseSteps = 5) {
|
|
923
929
|
const steps = Math.max(3, baseSteps + Math.floor(Math.random() * 3) - 1);
|
|
924
930
|
const actualDistance = this.jitterMs(distance, 0.15);
|
|
925
|
-
|
|
931
|
+
logger5.start("naturalScroll", `dir=${direction}, dist=${actualDistance}, steps=${steps}`);
|
|
926
932
|
const sign = direction === "down" ? 1 : -1;
|
|
927
933
|
const stepDistance = actualDistance / steps;
|
|
928
934
|
try {
|
|
@@ -934,9 +940,9 @@ var Humanize = {
|
|
|
934
940
|
const baseDelay = 60 + i * 25;
|
|
935
941
|
await (0, import_delay2.default)(this.jitterMs(baseDelay, 0.3));
|
|
936
942
|
}
|
|
937
|
-
|
|
943
|
+
logger5.success("naturalScroll");
|
|
938
944
|
} catch (error) {
|
|
939
|
-
|
|
945
|
+
logger5.fail("naturalScroll", error);
|
|
940
946
|
throw error;
|
|
941
947
|
}
|
|
942
948
|
}
|
|
@@ -965,7 +971,7 @@ var Launch = {
|
|
|
965
971
|
// src/live-view.js
|
|
966
972
|
var import_express = __toESM(require("express"), 1);
|
|
967
973
|
var import_apify = require("apify");
|
|
968
|
-
var
|
|
974
|
+
var logger6 = createInternalLogger("LiveView");
|
|
969
975
|
async function startLiveViewServer(liveViewKey) {
|
|
970
976
|
const app = (0, import_express.default)();
|
|
971
977
|
app.get("/", async (req, res) => {
|
|
@@ -990,13 +996,13 @@ async function startLiveViewServer(liveViewKey) {
|
|
|
990
996
|
</html>
|
|
991
997
|
`);
|
|
992
998
|
} catch (error) {
|
|
993
|
-
|
|
999
|
+
logger6.fail("Live View Server", error);
|
|
994
1000
|
res.status(500).send(`\u65E0\u6CD5\u52A0\u8F7D\u5C4F\u5E55\u622A\u56FE: ${error.message}`);
|
|
995
1001
|
}
|
|
996
1002
|
});
|
|
997
1003
|
const port = process.env.APIFY_CONTAINER_PORT || 4321;
|
|
998
1004
|
app.listen(port, () => {
|
|
999
|
-
|
|
1005
|
+
logger6.success("startLiveViewServer", `\u76D1\u542C\u7AEF\u53E3 ${port}`);
|
|
1000
1006
|
});
|
|
1001
1007
|
}
|
|
1002
1008
|
async function takeLiveScreenshot(liveViewKey, page, logMessage) {
|
|
@@ -1004,10 +1010,10 @@ async function takeLiveScreenshot(liveViewKey, page, logMessage) {
|
|
|
1004
1010
|
const buffer = await page.screenshot({ type: "png" });
|
|
1005
1011
|
await import_apify.Actor.setValue(liveViewKey, buffer, { contentType: "image/png" });
|
|
1006
1012
|
if (logMessage) {
|
|
1007
|
-
|
|
1013
|
+
logger6.info(`(\u622A\u56FE): ${logMessage}`);
|
|
1008
1014
|
}
|
|
1009
1015
|
} catch (e) {
|
|
1010
|
-
|
|
1016
|
+
logger6.warn(`\u65E0\u6CD5\u6355\u83B7 Live View \u5C4F\u5E55\u622A\u56FE: ${e.message}`);
|
|
1011
1017
|
}
|
|
1012
1018
|
}
|
|
1013
1019
|
var useLiveView = (liveViewKey = PresetOfLiveViewKey) => {
|
|
@@ -1026,7 +1032,7 @@ var LiveView = {
|
|
|
1026
1032
|
|
|
1027
1033
|
// src/captcha-monitor.js
|
|
1028
1034
|
var import_uuid = require("uuid");
|
|
1029
|
-
var
|
|
1035
|
+
var logger7 = createInternalLogger("Captcha");
|
|
1030
1036
|
function useCaptchaMonitor(page, options) {
|
|
1031
1037
|
const { domSelector, urlPattern, onDetected } = options;
|
|
1032
1038
|
if (!domSelector && !urlPattern) {
|
|
@@ -1098,7 +1104,7 @@ function useCaptchaMonitor(page, options) {
|
|
|
1098
1104
|
};
|
|
1099
1105
|
})();
|
|
1100
1106
|
}, { selector: domSelector, callbackName: exposedFunctionName, cleanerName });
|
|
1101
|
-
|
|
1107
|
+
logger7.success("useCaptchaMonitor", `DOM \u76D1\u63A7\u5DF2\u542F\u7528: ${domSelector}`);
|
|
1102
1108
|
cleanupFns.push(async () => {
|
|
1103
1109
|
try {
|
|
1104
1110
|
await page.evaluate((name) => {
|
|
@@ -1121,14 +1127,14 @@ function useCaptchaMonitor(page, options) {
|
|
|
1121
1127
|
}
|
|
1122
1128
|
};
|
|
1123
1129
|
page.on("framenavigated", frameHandler);
|
|
1124
|
-
|
|
1130
|
+
logger7.success("useCaptchaMonitor", `URL \u76D1\u63A7\u5DF2\u542F\u7528: ${urlPattern}`);
|
|
1125
1131
|
cleanupFns.push(async () => {
|
|
1126
1132
|
page.off("framenavigated", frameHandler);
|
|
1127
1133
|
});
|
|
1128
1134
|
}
|
|
1129
1135
|
return {
|
|
1130
1136
|
stop: async () => {
|
|
1131
|
-
|
|
1137
|
+
logger7.info("useCaptchaMonitor", "\u6B63\u5728\u505C\u6B62\u76D1\u63A7...");
|
|
1132
1138
|
for (const fn of cleanupFns) {
|
|
1133
1139
|
await fn();
|
|
1134
1140
|
}
|
|
@@ -1143,7 +1149,7 @@ var Captcha = {
|
|
|
1143
1149
|
// src/sse.js
|
|
1144
1150
|
var import_https = __toESM(require("https"), 1);
|
|
1145
1151
|
var import_url = require("url");
|
|
1146
|
-
var
|
|
1152
|
+
var logger8 = createInternalLogger("Sse");
|
|
1147
1153
|
var Sse = {
|
|
1148
1154
|
/**
|
|
1149
1155
|
* 解析 SSE 流文本
|
|
@@ -1162,11 +1168,11 @@ var Sse = {
|
|
|
1162
1168
|
events.push(JSON.parse(jsonContent));
|
|
1163
1169
|
}
|
|
1164
1170
|
} catch (e) {
|
|
1165
|
-
|
|
1171
|
+
logger8.debug("parseSseStream", `JSON \u89E3\u6790\u5931\u8D25: ${e.message}, line: ${line.substring(0, 100)}...`);
|
|
1166
1172
|
}
|
|
1167
1173
|
}
|
|
1168
1174
|
}
|
|
1169
|
-
|
|
1175
|
+
logger8.success("parseSseStream", `\u89E3\u6790\u5B8C\u6210, events \u6570\u91CF: ${events.length}`);
|
|
1170
1176
|
return events;
|
|
1171
1177
|
},
|
|
1172
1178
|
/**
|
|
@@ -1201,7 +1207,7 @@ var Sse = {
|
|
|
1201
1207
|
const workPromise = new Promise((resolve, reject) => {
|
|
1202
1208
|
page.route(urlPattern, async (route) => {
|
|
1203
1209
|
const request = route.request();
|
|
1204
|
-
|
|
1210
|
+
logger8.info(`[MITM] \u5DF2\u62E6\u622A\u8BF7\u6C42: ${request.url()}`);
|
|
1205
1211
|
try {
|
|
1206
1212
|
const headers = await request.allHeaders();
|
|
1207
1213
|
const postData = request.postData();
|
|
@@ -1226,7 +1232,7 @@ var Sse = {
|
|
|
1226
1232
|
clearTimeout(initialTimer);
|
|
1227
1233
|
initialTimer = null;
|
|
1228
1234
|
}
|
|
1229
|
-
|
|
1235
|
+
logger8.debug("[Intercept] \u5DF2\u63A5\u6536\u521D\u59CB\u6570\u636E");
|
|
1230
1236
|
}
|
|
1231
1237
|
chunks.push(chunk);
|
|
1232
1238
|
const textChunk = chunk.toString("utf-8");
|
|
@@ -1235,18 +1241,18 @@ var Sse = {
|
|
|
1235
1241
|
try {
|
|
1236
1242
|
onData(textChunk, resolve, accumulatedText);
|
|
1237
1243
|
} catch (e) {
|
|
1238
|
-
|
|
1244
|
+
logger8.fail(`onData \u9519\u8BEF`, e);
|
|
1239
1245
|
}
|
|
1240
1246
|
}
|
|
1241
1247
|
});
|
|
1242
1248
|
res.on("end", () => {
|
|
1243
|
-
|
|
1249
|
+
logger8.info("[MITM] \u4E0A\u6E38\u54CD\u5E94\u7ED3\u675F");
|
|
1244
1250
|
clearAllTimers();
|
|
1245
1251
|
if (onEnd) {
|
|
1246
1252
|
try {
|
|
1247
1253
|
onEnd(accumulatedText, resolve);
|
|
1248
1254
|
} catch (e) {
|
|
1249
|
-
|
|
1255
|
+
logger8.fail(`onEnd \u9519\u8BEF`, e);
|
|
1250
1256
|
}
|
|
1251
1257
|
} else if (!onData) {
|
|
1252
1258
|
resolve(accumulatedText);
|
|
@@ -1328,9 +1334,20 @@ var Sse = {
|
|
|
1328
1334
|
var import_got_scraping = require("got-scraping");
|
|
1329
1335
|
var import_http = require("http");
|
|
1330
1336
|
var import_https2 = require("https");
|
|
1331
|
-
var
|
|
1332
|
-
var SHARED_HTTP_AGENT = new import_http.Agent({
|
|
1333
|
-
|
|
1337
|
+
var logger9 = createInternalLogger("Interception");
|
|
1338
|
+
var SHARED_HTTP_AGENT = new import_http.Agent({
|
|
1339
|
+
keepAlive: true,
|
|
1340
|
+
keepAliveMsecs: 15e3,
|
|
1341
|
+
maxSockets: 30,
|
|
1342
|
+
maxFreeSockets: 10
|
|
1343
|
+
});
|
|
1344
|
+
var SHARED_HTTPS_AGENT = new import_https2.Agent({
|
|
1345
|
+
keepAlive: true,
|
|
1346
|
+
keepAliveMsecs: 15e3,
|
|
1347
|
+
maxSockets: 30,
|
|
1348
|
+
maxFreeSockets: 10,
|
|
1349
|
+
rejectUnauthorized: false
|
|
1350
|
+
});
|
|
1334
1351
|
var DirectConfig = {
|
|
1335
1352
|
/** 直连请求超时时间(秒) */
|
|
1336
1353
|
directTimeout: 12,
|
|
@@ -1459,7 +1476,7 @@ var Interception = {
|
|
|
1459
1476
|
if (mergedBlockingConfig.blockFont) enabledCategories.push("\u5B57\u4F53");
|
|
1460
1477
|
if (mergedBlockingConfig.blockCss) enabledCategories.push("CSS");
|
|
1461
1478
|
if (mergedBlockingConfig.blockOther) enabledCategories.push("\u5176\u4ED6");
|
|
1462
|
-
|
|
1479
|
+
logger9.start("setup", hasDirectDomains ? `\u76F4\u8FDE\u57DF\u540D: [${directDomains.length} \u4E2A] | \u5C4F\u853D: [${enabledCategories.join(", ")}]` : `\u4EC5\u8D44\u6E90\u5C4F\u853D\u6A21\u5F0F | \u5C4F\u853D: [${enabledCategories.join(", ")}]`);
|
|
1463
1480
|
await page.route("**/*", async (route) => {
|
|
1464
1481
|
let handled = false;
|
|
1465
1482
|
try {
|
|
@@ -1522,7 +1539,7 @@ var Interception = {
|
|
|
1522
1539
|
delete resHeaders["transfer-encoding"];
|
|
1523
1540
|
delete resHeaders["connection"];
|
|
1524
1541
|
delete resHeaders["keep-alive"];
|
|
1525
|
-
isSilent ?
|
|
1542
|
+
isSilent ? logger9.debug(`\u76F4\u8FDE\u6210\u529F: ${urlPath}`) : logger9.info(`\u76F4\u8FDE\u6210\u529F: ${urlPath}`);
|
|
1526
1543
|
await safeFulfill(route, {
|
|
1527
1544
|
status: response.statusCode,
|
|
1528
1545
|
headers: resHeaders,
|
|
@@ -1534,7 +1551,7 @@ var Interception = {
|
|
|
1534
1551
|
const isTimeout = e.code === "ETIMEDOUT" || e.message.toLowerCase().includes("timeout");
|
|
1535
1552
|
const action = fallbackToProxy ? "\u56DE\u9000\u4EE3\u7406" : "\u5DF2\u653E\u5F03";
|
|
1536
1553
|
const reason = isTimeout ? `\u8D85\u65F6(${DirectConfig.directTimeout}s)` : `\u5F02\u5E38: ${e.message}`;
|
|
1537
|
-
|
|
1554
|
+
logger9.warn(`\u76F4\u8FDE${reason}\uFF0C${action}: ${urlPath}`);
|
|
1538
1555
|
if (fallbackToProxy) {
|
|
1539
1556
|
await safeContinue(route);
|
|
1540
1557
|
} else {
|
|
@@ -1547,7 +1564,7 @@ var Interception = {
|
|
|
1547
1564
|
await safeContinue(route);
|
|
1548
1565
|
handled = true;
|
|
1549
1566
|
} catch (err) {
|
|
1550
|
-
|
|
1567
|
+
logger9.warn(`\u8DEF\u7531\u5904\u7406\u5F02\u5E38: ${err.message}`);
|
|
1551
1568
|
if (!handled) {
|
|
1552
1569
|
try {
|
|
1553
1570
|
await route.continue();
|
|
@@ -2284,7 +2301,7 @@ var createTemplateLogger = (baseLogger = createBaseLogger()) => {
|
|
|
2284
2301
|
};
|
|
2285
2302
|
var getDefaultBaseLogger = () => createBaseLogger("");
|
|
2286
2303
|
var Logger = {
|
|
2287
|
-
setLogger: (
|
|
2304
|
+
setLogger: (logger11) => setDefaultLogger(logger11),
|
|
2288
2305
|
info: (message) => getDefaultBaseLogger().info(message),
|
|
2289
2306
|
success: (message) => getDefaultBaseLogger().success(message),
|
|
2290
2307
|
warning: (message) => getDefaultBaseLogger().warning(message),
|
|
@@ -2292,14 +2309,14 @@ var Logger = {
|
|
|
2292
2309
|
error: (message) => getDefaultBaseLogger().error(message),
|
|
2293
2310
|
debug: (message) => getDefaultBaseLogger().debug(message),
|
|
2294
2311
|
start: (message) => getDefaultBaseLogger().start(message),
|
|
2295
|
-
useTemplate: (
|
|
2296
|
-
if (
|
|
2312
|
+
useTemplate: (logger11) => {
|
|
2313
|
+
if (logger11) return createTemplateLogger(createBaseLogger("", logger11));
|
|
2297
2314
|
return createTemplateLogger();
|
|
2298
2315
|
}
|
|
2299
2316
|
};
|
|
2300
2317
|
|
|
2301
2318
|
// src/mutation.js
|
|
2302
|
-
var
|
|
2319
|
+
var logger10 = createInternalLogger("Mutation");
|
|
2303
2320
|
function generateKey(prefix) {
|
|
2304
2321
|
return `__${prefix}_${(0, import_uuid2.v4)().replace(/-/g, "_")}`;
|
|
2305
2322
|
}
|
|
@@ -2324,7 +2341,7 @@ var Mutation = {
|
|
|
2324
2341
|
const stableTime = options.stableTime ?? 5e3;
|
|
2325
2342
|
const timeout = options.timeout ?? 6e4;
|
|
2326
2343
|
const onMutation = options.onMutation;
|
|
2327
|
-
|
|
2344
|
+
logger10.start("waitForStable", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, \u7A33\u5B9A\u65F6\u95F4=${stableTime}ms`);
|
|
2328
2345
|
const callbackName = generateKey("pk_mut_cb");
|
|
2329
2346
|
if (onMutation) {
|
|
2330
2347
|
try {
|
|
@@ -2337,7 +2354,7 @@ var Mutation = {
|
|
|
2337
2354
|
return "__CONTINUE__";
|
|
2338
2355
|
}
|
|
2339
2356
|
});
|
|
2340
|
-
|
|
2357
|
+
logger10.info("waitForStable \u5DF2\u542F\u7528 onMutation \u56DE\u8C03");
|
|
2341
2358
|
} catch (e) {
|
|
2342
2359
|
}
|
|
2343
2360
|
}
|
|
@@ -2443,9 +2460,9 @@ var Mutation = {
|
|
|
2443
2460
|
{ selectorList, stableTime, timeout, callbackName, hasCallback: !!onMutation }
|
|
2444
2461
|
);
|
|
2445
2462
|
if (result.mutationCount === 0 && result.stableTime === 0) {
|
|
2446
|
-
|
|
2463
|
+
logger10.warning("waitForStable \u672A\u627E\u5230\u53EF\u76D1\u63A7\u7684\u5143\u7D20");
|
|
2447
2464
|
}
|
|
2448
|
-
|
|
2465
|
+
logger10.success("waitForStable", `DOM \u7A33\u5B9A, \u603B\u5171 ${result.mutationCount} \u6B21\u53D8\u5316${result.wasPaused ? ", \u66FE\u6682\u505C\u8BA1\u65F6" : ""}`);
|
|
2449
2466
|
return result;
|
|
2450
2467
|
},
|
|
2451
2468
|
/**
|
|
@@ -2460,7 +2477,7 @@ var Mutation = {
|
|
|
2460
2477
|
async useMonitor(page, selectors, options = {}) {
|
|
2461
2478
|
const selectorList = Array.isArray(selectors) ? selectors : [selectors];
|
|
2462
2479
|
const onMutation = options.onMutation;
|
|
2463
|
-
|
|
2480
|
+
logger10.start("useMonitor", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668`);
|
|
2464
2481
|
const monitorKey = generateKey("pk_mon");
|
|
2465
2482
|
const callbackName = generateKey("pk_mon_cb");
|
|
2466
2483
|
const cleanerName = generateKey("pk_mon_clean");
|
|
@@ -2510,7 +2527,7 @@ var Mutation = {
|
|
|
2510
2527
|
return total;
|
|
2511
2528
|
};
|
|
2512
2529
|
}, { selectorList, monitorKey, callbackName, cleanerName, hasCallback: !!onMutation });
|
|
2513
|
-
|
|
2530
|
+
logger10.success("useMonitor", "\u76D1\u63A7\u5668\u5DF2\u542F\u52A8");
|
|
2514
2531
|
return {
|
|
2515
2532
|
stop: async () => {
|
|
2516
2533
|
let totalMutations = 0;
|
|
@@ -2523,7 +2540,7 @@ var Mutation = {
|
|
|
2523
2540
|
}, cleanerName);
|
|
2524
2541
|
} catch (e) {
|
|
2525
2542
|
}
|
|
2526
|
-
|
|
2543
|
+
logger10.success("useMonitor.stop", `\u76D1\u63A7\u5DF2\u505C\u6B62, \u5171 ${totalMutations} \u6B21\u53D8\u5316`);
|
|
2527
2544
|
return { totalMutations };
|
|
2528
2545
|
}
|
|
2529
2546
|
};
|