@skrillex1224/playwright-toolkit 2.1.151 → 2.1.153
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/README.md +6 -0
- package/dist/browser.js +4 -4
- package/dist/browser.js.map +1 -1
- package/dist/index.cjs +141 -213
- package/dist/index.cjs.map +3 -3
- package/dist/index.js +141 -213
- package/dist/index.js.map +3 -3
- package/index.d.ts +8 -11
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -125,8 +125,8 @@ var ActorInfo = {
|
|
|
125
125
|
qbot: createActorInfo({
|
|
126
126
|
key: "qbot",
|
|
127
127
|
name: "\u641C\u72D7QBot",
|
|
128
|
-
domain: "
|
|
129
|
-
path: "/web
|
|
128
|
+
domain: "sogou.com",
|
|
129
|
+
path: "/web",
|
|
130
130
|
share: {
|
|
131
131
|
mode: "dom",
|
|
132
132
|
prefix: "",
|
|
@@ -136,8 +136,8 @@ var ActorInfo = {
|
|
|
136
136
|
douyin: createActorInfo({
|
|
137
137
|
key: "douyin",
|
|
138
138
|
name: "\u6296\u97F3AI\u641C",
|
|
139
|
-
domain: "
|
|
140
|
-
path: "/
|
|
139
|
+
domain: "so.douyin.com",
|
|
140
|
+
path: "/s",
|
|
141
141
|
share: {
|
|
142
142
|
mode: "response",
|
|
143
143
|
prefix: "",
|
|
@@ -297,18 +297,18 @@ var fallbackLog = {
|
|
|
297
297
|
error: (...args) => console.error(...args),
|
|
298
298
|
debug: (...args) => console.debug ? console.debug(...args) : console.log(...args)
|
|
299
299
|
};
|
|
300
|
-
var resolveLogMethod = (
|
|
301
|
-
if (
|
|
302
|
-
return
|
|
300
|
+
var resolveLogMethod = (logger11, name) => {
|
|
301
|
+
if (logger11 && typeof logger11[name] === "function") {
|
|
302
|
+
return logger11[name].bind(logger11);
|
|
303
303
|
}
|
|
304
|
-
if (name === "warning" &&
|
|
305
|
-
return
|
|
304
|
+
if (name === "warning" && logger11 && typeof logger11.warn === "function") {
|
|
305
|
+
return logger11.warn.bind(logger11);
|
|
306
306
|
}
|
|
307
307
|
return fallbackLog[name];
|
|
308
308
|
};
|
|
309
309
|
var defaultLogger = null;
|
|
310
|
-
var setDefaultLogger = (
|
|
311
|
-
defaultLogger =
|
|
310
|
+
var setDefaultLogger = (logger11) => {
|
|
311
|
+
defaultLogger = logger11;
|
|
312
312
|
};
|
|
313
313
|
var resolveLogger = (explicitLogger) => {
|
|
314
314
|
if (explicitLogger && typeof explicitLogger.info === "function") {
|
|
@@ -335,8 +335,8 @@ var colorize = (text, color) => {
|
|
|
335
335
|
var createBaseLogger = (prefix = "", explicitLogger) => {
|
|
336
336
|
const name = prefix ? String(prefix) : "";
|
|
337
337
|
const dispatch = (methodName, icon, message, color) => {
|
|
338
|
-
const
|
|
339
|
-
const logFn = resolveLogMethod(
|
|
338
|
+
const logger11 = resolveLogger(explicitLogger);
|
|
339
|
+
const logFn = resolveLogMethod(logger11, methodName);
|
|
340
340
|
const timestamp = colorize(`[${formatTimestamp()}]`, ANSI.gray);
|
|
341
341
|
const line = formatLine(name, icon, message);
|
|
342
342
|
const coloredLine = colorize(line, color);
|
|
@@ -622,8 +622,6 @@ var parseCookies = (cookieString, domain) => {
|
|
|
622
622
|
};
|
|
623
623
|
|
|
624
624
|
// src/utils.js
|
|
625
|
-
import delay from "delay";
|
|
626
|
-
var logger3 = createInternalLogger("Utils");
|
|
627
625
|
var Utils = {
|
|
628
626
|
/**
|
|
629
627
|
* 解析 Cookie 字符串为 Playwright 格式的 Cookie 数组
|
|
@@ -658,81 +656,11 @@ var Utils = {
|
|
|
658
656
|
unique.add(link);
|
|
659
657
|
}
|
|
660
658
|
return Array.from(unique);
|
|
661
|
-
},
|
|
662
|
-
/**
|
|
663
|
-
* 全页面滚动截图
|
|
664
|
-
* 自动检测页面所有可滚动元素,取最大高度,强制展开后截图
|
|
665
|
-
*
|
|
666
|
-
* @param {import('playwright').Page} page - Playwright page 对象
|
|
667
|
-
* @param {Object} [options] - 配置选项
|
|
668
|
-
* @param {number} [options.buffer] - 额外缓冲高度 (默认: 视口高度的一半)
|
|
669
|
-
* @param {boolean} [options.restore] - 截图后是否恢复页面高度和样式 (默认: false)
|
|
670
|
-
* @param {number} [options.maxHeight] - 最大截图高度 (默认: 8000px)
|
|
671
|
-
* @returns {Promise<string>} - base64 编码的 PNG 图片
|
|
672
|
-
*/
|
|
673
|
-
async fullPageScreenshot(page, options = {}) {
|
|
674
|
-
logger3.start("fullPageScreenshot", "detecting scrollable elements");
|
|
675
|
-
const originalViewport = page.viewportSize();
|
|
676
|
-
const defaultBuffer = Math.round((originalViewport?.height || 1080) / 2);
|
|
677
|
-
const buffer = options.buffer ?? defaultBuffer;
|
|
678
|
-
const restore = options.restore ?? false;
|
|
679
|
-
const maxHeight = options.maxHeight ?? 8e3;
|
|
680
|
-
try {
|
|
681
|
-
const maxScrollHeight = await page.evaluate(() => {
|
|
682
|
-
let maxHeight2 = document.body.scrollHeight;
|
|
683
|
-
document.querySelectorAll("*").forEach((el) => {
|
|
684
|
-
const style = window.getComputedStyle(el);
|
|
685
|
-
const overflowY = style.overflowY;
|
|
686
|
-
if ((overflowY === "auto" || overflowY === "scroll") && el.scrollHeight > el.clientHeight) {
|
|
687
|
-
if (el.scrollHeight > maxHeight2) {
|
|
688
|
-
maxHeight2 = el.scrollHeight;
|
|
689
|
-
}
|
|
690
|
-
el.dataset.pkOrigOverflow = el.style.overflow;
|
|
691
|
-
el.dataset.pkOrigHeight = el.style.height;
|
|
692
|
-
el.dataset.pkOrigMaxHeight = el.style.maxHeight;
|
|
693
|
-
el.classList.add("__pk_expanded__");
|
|
694
|
-
el.style.overflow = "visible";
|
|
695
|
-
el.style.height = "auto";
|
|
696
|
-
el.style.maxHeight = "none";
|
|
697
|
-
}
|
|
698
|
-
});
|
|
699
|
-
return maxHeight2;
|
|
700
|
-
});
|
|
701
|
-
const targetHeight = Math.min(maxScrollHeight + buffer, maxHeight);
|
|
702
|
-
await page.setViewportSize({
|
|
703
|
-
width: originalViewport?.width || 1280,
|
|
704
|
-
height: targetHeight
|
|
705
|
-
});
|
|
706
|
-
await delay(1e3);
|
|
707
|
-
const buffer_ = await page.screenshot({
|
|
708
|
-
fullPage: true,
|
|
709
|
-
type: "png"
|
|
710
|
-
});
|
|
711
|
-
logger3.success("fullPageScreenshot", `captured ${Math.round(buffer_.length / 1024)} KB`);
|
|
712
|
-
return buffer_.toString("base64");
|
|
713
|
-
} finally {
|
|
714
|
-
if (restore) {
|
|
715
|
-
await page.evaluate(() => {
|
|
716
|
-
document.querySelectorAll(".__pk_expanded__").forEach((el) => {
|
|
717
|
-
el.style.overflow = el.dataset.pkOrigOverflow || "";
|
|
718
|
-
el.style.height = el.dataset.pkOrigHeight || "";
|
|
719
|
-
el.style.maxHeight = el.dataset.pkOrigMaxHeight || "";
|
|
720
|
-
delete el.dataset.pkOrigOverflow;
|
|
721
|
-
delete el.dataset.pkOrigHeight;
|
|
722
|
-
delete el.dataset.pkOrigMaxHeight;
|
|
723
|
-
el.classList.remove("__pk_expanded__");
|
|
724
|
-
});
|
|
725
|
-
});
|
|
726
|
-
if (originalViewport) {
|
|
727
|
-
await page.setViewportSize(originalViewport);
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
659
|
}
|
|
732
660
|
};
|
|
733
661
|
|
|
734
662
|
// src/anti-cheat.js
|
|
735
|
-
var
|
|
663
|
+
var logger3 = createInternalLogger("AntiCheat");
|
|
736
664
|
var BASE_CONFIG = Object.freeze({
|
|
737
665
|
locale: "zh-CN",
|
|
738
666
|
acceptLanguage: "zh-CN,zh;q=0.9",
|
|
@@ -792,9 +720,9 @@ var AntiCheat = {
|
|
|
792
720
|
};
|
|
793
721
|
|
|
794
722
|
// src/humanize.js
|
|
795
|
-
import
|
|
723
|
+
import delay from "delay";
|
|
796
724
|
import { createCursor } from "ghost-cursor-playwright";
|
|
797
|
-
var
|
|
725
|
+
var logger4 = createInternalLogger("Humanize");
|
|
798
726
|
var $CursorWeakMap = /* @__PURE__ */ new WeakMap();
|
|
799
727
|
function $GetCursor(page) {
|
|
800
728
|
const cursor = $CursorWeakMap.get(page);
|
|
@@ -822,13 +750,13 @@ var Humanize = {
|
|
|
822
750
|
*/
|
|
823
751
|
async initializeCursor(page) {
|
|
824
752
|
if ($CursorWeakMap.has(page)) {
|
|
825
|
-
|
|
753
|
+
logger4.debug("initializeCursor: cursor already exists, skipping");
|
|
826
754
|
return;
|
|
827
755
|
}
|
|
828
|
-
|
|
756
|
+
logger4.start("initializeCursor", "creating cursor");
|
|
829
757
|
const cursor = await createCursor(page);
|
|
830
758
|
$CursorWeakMap.set(page, cursor);
|
|
831
|
-
|
|
759
|
+
logger4.success("initializeCursor", "cursor initialized");
|
|
832
760
|
},
|
|
833
761
|
/**
|
|
834
762
|
* 人类化鼠标移动 - 使用 ghost-cursor 移动到指定位置或元素
|
|
@@ -838,17 +766,17 @@ var Humanize = {
|
|
|
838
766
|
*/
|
|
839
767
|
async humanMove(page, target) {
|
|
840
768
|
const cursor = $GetCursor(page);
|
|
841
|
-
|
|
769
|
+
logger4.start("humanMove", `target=${typeof target === "string" ? target : "element/coords"}`);
|
|
842
770
|
try {
|
|
843
771
|
if (typeof target === "string") {
|
|
844
772
|
const element = await page.$(target);
|
|
845
773
|
if (!element) {
|
|
846
|
-
|
|
774
|
+
logger4.warn(`humanMove: \u5143\u7D20\u4E0D\u5B58\u5728 ${target}`);
|
|
847
775
|
return false;
|
|
848
776
|
}
|
|
849
777
|
const box = await element.boundingBox();
|
|
850
778
|
if (!box) {
|
|
851
|
-
|
|
779
|
+
logger4.warn(`humanMove: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E ${target}`);
|
|
852
780
|
return false;
|
|
853
781
|
}
|
|
854
782
|
const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.2;
|
|
@@ -864,10 +792,10 @@ var Humanize = {
|
|
|
864
792
|
await cursor.actions.move({ x, y });
|
|
865
793
|
}
|
|
866
794
|
}
|
|
867
|
-
|
|
795
|
+
logger4.success("humanMove");
|
|
868
796
|
return true;
|
|
869
797
|
} catch (error) {
|
|
870
|
-
|
|
798
|
+
logger4.fail("humanMove", error);
|
|
871
799
|
throw error;
|
|
872
800
|
}
|
|
873
801
|
},
|
|
@@ -891,12 +819,12 @@ var Humanize = {
|
|
|
891
819
|
maxDurationMs = maxSteps * 220 + 800
|
|
892
820
|
} = options;
|
|
893
821
|
const targetDesc = typeof target === "string" ? target : "ElementHandle";
|
|
894
|
-
|
|
822
|
+
logger4.start("humanScroll", `target=${targetDesc}`);
|
|
895
823
|
let element;
|
|
896
824
|
if (typeof target === "string") {
|
|
897
825
|
element = await page.$(target);
|
|
898
826
|
if (!element) {
|
|
899
|
-
|
|
827
|
+
logger4.warn(`humanScroll | \u5143\u7D20\u672A\u627E\u5230: ${target}`);
|
|
900
828
|
return { element: null, didScroll: false };
|
|
901
829
|
}
|
|
902
830
|
} else {
|
|
@@ -971,26 +899,26 @@ var Humanize = {
|
|
|
971
899
|
try {
|
|
972
900
|
for (let i = 0; i < maxSteps; i++) {
|
|
973
901
|
if (Date.now() - startTime > maxDurationMs) {
|
|
974
|
-
|
|
902
|
+
logger4.warn(`humanScroll | \u8D85\u65F6\u4FDD\u62A4\u89E6\u53D1 (${maxDurationMs}ms)`);
|
|
975
903
|
return { element, didScroll };
|
|
976
904
|
}
|
|
977
905
|
const status = await checkVisibility();
|
|
978
906
|
if (status.code === "VISIBLE") {
|
|
979
907
|
if (status.isFixed) {
|
|
980
|
-
|
|
908
|
+
logger4.info("humanScroll | fixed \u5BB9\u5668\u5185\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
|
|
981
909
|
} else {
|
|
982
|
-
|
|
910
|
+
logger4.debug("humanScroll | \u5143\u7D20\u53EF\u89C1\u4E14\u65E0\u906E\u6321");
|
|
983
911
|
}
|
|
984
|
-
|
|
912
|
+
logger4.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
|
|
985
913
|
return { element, didScroll };
|
|
986
914
|
}
|
|
987
|
-
|
|
915
|
+
logger4.debug(`humanScroll | \u6B65\u9AA4 ${i + 1}/${maxSteps}: ${status.reason} ${status.direction ? `(${status.direction})` : ""}`);
|
|
988
916
|
if (status.code === "OBSTRUCTED" && status.obstruction) {
|
|
989
|
-
|
|
917
|
+
logger4.debug(`humanScroll | \u88AB\u4EE5\u4E0B\u5143\u7D20\u906E\u6321 <${status.obstruction.tag} id="${status.obstruction.id}">`);
|
|
990
918
|
}
|
|
991
919
|
const scrollRect = await getScrollableRect();
|
|
992
920
|
if (!scrollRect && status.isFixed) {
|
|
993
|
-
|
|
921
|
+
logger4.warn("humanScroll | fixed \u5BB9\u5668\u5185\u4E14\u65E0\u53EF\u6EDA\u52A8\u7956\u5148\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
|
|
994
922
|
return { element, didScroll };
|
|
995
923
|
}
|
|
996
924
|
const stepMin = scrollRect ? Math.min(minStep, Math.max(60, scrollRect.height * 0.4)) : minStep;
|
|
@@ -1024,12 +952,12 @@ var Humanize = {
|
|
|
1024
952
|
}
|
|
1025
953
|
await page.mouse.wheel(0, deltaY);
|
|
1026
954
|
didScroll = true;
|
|
1027
|
-
await
|
|
955
|
+
await delay(this.jitterMs(20 + Math.random() * 40, 0.2));
|
|
1028
956
|
}
|
|
1029
|
-
|
|
957
|
+
logger4.warn(`humanScroll | \u5728 ${maxSteps} \u6B65\u540E\u65E0\u6CD5\u786E\u4FDD\u53EF\u89C1\u6027`);
|
|
1030
958
|
return { element, didScroll };
|
|
1031
959
|
} catch (error) {
|
|
1032
|
-
|
|
960
|
+
logger4.fail("humanScroll", error);
|
|
1033
961
|
throw error;
|
|
1034
962
|
}
|
|
1035
963
|
},
|
|
@@ -1047,23 +975,23 @@ var Humanize = {
|
|
|
1047
975
|
const cursor = $GetCursor(page);
|
|
1048
976
|
const { reactionDelay = 250, throwOnMissing = true, scrollIfNeeded = true, restore = false } = options;
|
|
1049
977
|
const targetDesc = target == null ? "Current Position" : typeof target === "string" ? target : "ElementHandle";
|
|
1050
|
-
|
|
978
|
+
logger4.start("humanClick", `target=${targetDesc}`);
|
|
1051
979
|
const restoreOnce = async () => {
|
|
1052
980
|
if (restoreOnce.restored) return;
|
|
1053
981
|
restoreOnce.restored = true;
|
|
1054
982
|
if (typeof restoreOnce.do !== "function") return;
|
|
1055
983
|
try {
|
|
1056
|
-
await
|
|
984
|
+
await delay(this.jitterMs(1e3));
|
|
1057
985
|
await restoreOnce.do();
|
|
1058
986
|
} catch (restoreError) {
|
|
1059
|
-
|
|
987
|
+
logger4.warn(`humanClick: \u6062\u590D\u6EDA\u52A8\u4F4D\u7F6E\u5931\u8D25: ${restoreError.message}`);
|
|
1060
988
|
}
|
|
1061
989
|
};
|
|
1062
990
|
try {
|
|
1063
991
|
if (target == null) {
|
|
1064
|
-
await
|
|
992
|
+
await delay(this.jitterMs(reactionDelay, 0.4));
|
|
1065
993
|
await cursor.actions.click();
|
|
1066
|
-
|
|
994
|
+
logger4.success("humanClick", "Clicked current position");
|
|
1067
995
|
return true;
|
|
1068
996
|
}
|
|
1069
997
|
let element;
|
|
@@ -1073,7 +1001,7 @@ var Humanize = {
|
|
|
1073
1001
|
if (throwOnMissing) {
|
|
1074
1002
|
throw new Error(`\u627E\u4E0D\u5230\u5143\u7D20 ${target}`);
|
|
1075
1003
|
}
|
|
1076
|
-
|
|
1004
|
+
logger4.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${target}`);
|
|
1077
1005
|
return false;
|
|
1078
1006
|
}
|
|
1079
1007
|
} else {
|
|
@@ -1089,20 +1017,20 @@ var Humanize = {
|
|
|
1089
1017
|
if (throwOnMissing) {
|
|
1090
1018
|
throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5143\u7D20\u4F4D\u7F6E");
|
|
1091
1019
|
}
|
|
1092
|
-
|
|
1020
|
+
logger4.warn("humanClick: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E\uFF0C\u8DF3\u8FC7\u70B9\u51FB");
|
|
1093
1021
|
return false;
|
|
1094
1022
|
}
|
|
1095
1023
|
const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.3;
|
|
1096
1024
|
const y = box.y + box.height / 2 + (Math.random() - 0.5) * box.height * 0.3;
|
|
1097
1025
|
await cursor.actions.move({ x, y });
|
|
1098
|
-
await
|
|
1026
|
+
await delay(this.jitterMs(reactionDelay, 0.4));
|
|
1099
1027
|
await cursor.actions.click();
|
|
1100
1028
|
await restoreOnce();
|
|
1101
|
-
|
|
1029
|
+
logger4.success("humanClick");
|
|
1102
1030
|
return true;
|
|
1103
1031
|
} catch (error) {
|
|
1104
1032
|
await restoreOnce();
|
|
1105
|
-
|
|
1033
|
+
logger4.fail("humanClick", error);
|
|
1106
1034
|
throw error;
|
|
1107
1035
|
}
|
|
1108
1036
|
},
|
|
@@ -1113,9 +1041,9 @@ var Humanize = {
|
|
|
1113
1041
|
*/
|
|
1114
1042
|
async randomSleep(baseMs, jitterPercent = 0.3) {
|
|
1115
1043
|
const ms = this.jitterMs(baseMs, jitterPercent);
|
|
1116
|
-
|
|
1117
|
-
await
|
|
1118
|
-
|
|
1044
|
+
logger4.start("randomSleep", `base=${baseMs}, actual=${ms}ms`);
|
|
1045
|
+
await delay(ms);
|
|
1046
|
+
logger4.success("randomSleep");
|
|
1119
1047
|
},
|
|
1120
1048
|
/**
|
|
1121
1049
|
* 模拟人类"注视"或"阅读"行为:鼠标在页面上随机微动
|
|
@@ -1125,16 +1053,16 @@ var Humanize = {
|
|
|
1125
1053
|
async simulateGaze(page, baseDurationMs = 2500) {
|
|
1126
1054
|
const cursor = $GetCursor(page);
|
|
1127
1055
|
const durationMs = this.jitterMs(baseDurationMs, 0.4);
|
|
1128
|
-
|
|
1056
|
+
logger4.start("simulateGaze", `duration=${durationMs}ms`);
|
|
1129
1057
|
const startTime = Date.now();
|
|
1130
1058
|
const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };
|
|
1131
1059
|
while (Date.now() - startTime < durationMs) {
|
|
1132
1060
|
const x = 100 + Math.random() * (viewportSize.width - 200);
|
|
1133
1061
|
const y = 100 + Math.random() * (viewportSize.height - 200);
|
|
1134
1062
|
await cursor.actions.move({ x, y });
|
|
1135
|
-
await
|
|
1063
|
+
await delay(this.jitterMs(600, 0.5));
|
|
1136
1064
|
}
|
|
1137
|
-
|
|
1065
|
+
logger4.success("simulateGaze");
|
|
1138
1066
|
},
|
|
1139
1067
|
/**
|
|
1140
1068
|
* 人类化输入 - 带节奏变化(快-慢-停顿-偶尔加速)
|
|
@@ -1147,7 +1075,7 @@ var Humanize = {
|
|
|
1147
1075
|
* @param {number} [options.pauseBase=800] - 停顿时长基础值 (ms),实际 ±50% 抖动
|
|
1148
1076
|
*/
|
|
1149
1077
|
async humanType(page, selector, text, options = {}) {
|
|
1150
|
-
|
|
1078
|
+
logger4.start("humanType", `selector=${selector}, textLen=${text.length}`);
|
|
1151
1079
|
const {
|
|
1152
1080
|
baseDelay = 180,
|
|
1153
1081
|
pauseProbability = 0.08,
|
|
@@ -1156,7 +1084,7 @@ var Humanize = {
|
|
|
1156
1084
|
try {
|
|
1157
1085
|
const locator = page.locator(selector);
|
|
1158
1086
|
await Humanize.humanClick(page, locator);
|
|
1159
|
-
await
|
|
1087
|
+
await delay(this.jitterMs(200, 0.4));
|
|
1160
1088
|
for (let i = 0; i < text.length; i++) {
|
|
1161
1089
|
const char = text[i];
|
|
1162
1090
|
let charDelay;
|
|
@@ -1168,16 +1096,16 @@ var Humanize = {
|
|
|
1168
1096
|
charDelay = this.jitterMs(baseDelay, 0.4);
|
|
1169
1097
|
}
|
|
1170
1098
|
await page.keyboard.type(char);
|
|
1171
|
-
await
|
|
1099
|
+
await delay(charDelay);
|
|
1172
1100
|
if (Math.random() < pauseProbability && i < text.length - 1) {
|
|
1173
1101
|
const pauseTime = this.jitterMs(pauseBase, 0.5);
|
|
1174
|
-
|
|
1175
|
-
await
|
|
1102
|
+
logger4.debug(`\u505C\u987F ${pauseTime}ms...`);
|
|
1103
|
+
await delay(pauseTime);
|
|
1176
1104
|
}
|
|
1177
1105
|
}
|
|
1178
|
-
|
|
1106
|
+
logger4.success("humanType");
|
|
1179
1107
|
} catch (error) {
|
|
1180
|
-
|
|
1108
|
+
logger4.fail("humanType", error);
|
|
1181
1109
|
throw error;
|
|
1182
1110
|
}
|
|
1183
1111
|
},
|
|
@@ -1187,22 +1115,22 @@ var Humanize = {
|
|
|
1187
1115
|
* @param {string} selector - 输入框选择器
|
|
1188
1116
|
*/
|
|
1189
1117
|
async humanClear(page, selector) {
|
|
1190
|
-
|
|
1118
|
+
logger4.start("humanClear", `selector=${selector}`);
|
|
1191
1119
|
try {
|
|
1192
1120
|
const locator = page.locator(selector);
|
|
1193
1121
|
await locator.click();
|
|
1194
|
-
await
|
|
1122
|
+
await delay(this.jitterMs(200, 0.4));
|
|
1195
1123
|
const currentValue = await locator.inputValue();
|
|
1196
1124
|
if (!currentValue || currentValue.length === 0) {
|
|
1197
|
-
|
|
1125
|
+
logger4.success("humanClear", "already empty");
|
|
1198
1126
|
return;
|
|
1199
1127
|
}
|
|
1200
1128
|
await page.keyboard.press("Meta+A");
|
|
1201
|
-
await
|
|
1129
|
+
await delay(this.jitterMs(100, 0.4));
|
|
1202
1130
|
await page.keyboard.press("Backspace");
|
|
1203
|
-
|
|
1131
|
+
logger4.success("humanClear");
|
|
1204
1132
|
} catch (error) {
|
|
1205
|
-
|
|
1133
|
+
logger4.fail("humanClear", error);
|
|
1206
1134
|
throw error;
|
|
1207
1135
|
}
|
|
1208
1136
|
},
|
|
@@ -1214,7 +1142,7 @@ var Humanize = {
|
|
|
1214
1142
|
async warmUpBrowsing(page, baseDuration = 3500) {
|
|
1215
1143
|
const cursor = $GetCursor(page);
|
|
1216
1144
|
const durationMs = this.jitterMs(baseDuration, 0.4);
|
|
1217
|
-
|
|
1145
|
+
logger4.start("warmUpBrowsing", `duration=${durationMs}ms`);
|
|
1218
1146
|
const startTime = Date.now();
|
|
1219
1147
|
const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };
|
|
1220
1148
|
try {
|
|
@@ -1224,18 +1152,18 @@ var Humanize = {
|
|
|
1224
1152
|
const x = 100 + Math.random() * (viewportSize.width - 200);
|
|
1225
1153
|
const y = 100 + Math.random() * (viewportSize.height - 200);
|
|
1226
1154
|
await cursor.actions.move({ x, y });
|
|
1227
|
-
await
|
|
1155
|
+
await delay(this.jitterMs(350, 0.4));
|
|
1228
1156
|
} else if (action < 0.7) {
|
|
1229
1157
|
const scrollY = (Math.random() - 0.5) * 200;
|
|
1230
1158
|
await page.mouse.wheel(0, scrollY);
|
|
1231
|
-
await
|
|
1159
|
+
await delay(this.jitterMs(500, 0.4));
|
|
1232
1160
|
} else {
|
|
1233
|
-
await
|
|
1161
|
+
await delay(this.jitterMs(800, 0.5));
|
|
1234
1162
|
}
|
|
1235
1163
|
}
|
|
1236
|
-
|
|
1164
|
+
logger4.success("warmUpBrowsing");
|
|
1237
1165
|
} catch (error) {
|
|
1238
|
-
|
|
1166
|
+
logger4.fail("warmUpBrowsing", error);
|
|
1239
1167
|
throw error;
|
|
1240
1168
|
}
|
|
1241
1169
|
},
|
|
@@ -1249,7 +1177,7 @@ var Humanize = {
|
|
|
1249
1177
|
async naturalScroll(page, direction = "down", distance = 300, baseSteps = 5) {
|
|
1250
1178
|
const steps = Math.max(3, baseSteps + Math.floor(Math.random() * 3) - 1);
|
|
1251
1179
|
const actualDistance = this.jitterMs(distance, 0.15);
|
|
1252
|
-
|
|
1180
|
+
logger4.start("naturalScroll", `dir=${direction}, dist=${actualDistance}, steps=${steps}`);
|
|
1253
1181
|
const sign = direction === "down" ? 1 : -1;
|
|
1254
1182
|
const stepDistance = actualDistance / steps;
|
|
1255
1183
|
try {
|
|
@@ -1259,11 +1187,11 @@ var Humanize = {
|
|
|
1259
1187
|
const scrollAmount = stepDistance * factor * sign * jitter;
|
|
1260
1188
|
await page.mouse.wheel(0, scrollAmount);
|
|
1261
1189
|
const baseDelay = 60 + i * 25;
|
|
1262
|
-
await
|
|
1190
|
+
await delay(this.jitterMs(baseDelay, 0.3));
|
|
1263
1191
|
}
|
|
1264
|
-
|
|
1192
|
+
logger4.success("naturalScroll");
|
|
1265
1193
|
} catch (error) {
|
|
1266
|
-
|
|
1194
|
+
logger4.fail("naturalScroll", error);
|
|
1267
1195
|
throw error;
|
|
1268
1196
|
}
|
|
1269
1197
|
}
|
|
@@ -1271,7 +1199,7 @@ var Humanize = {
|
|
|
1271
1199
|
|
|
1272
1200
|
// src/launch.js
|
|
1273
1201
|
import picomatch from "picomatch";
|
|
1274
|
-
var
|
|
1202
|
+
var logger5 = createInternalLogger("Launch");
|
|
1275
1203
|
var buildByPassDomainRule = (rawPattern) => {
|
|
1276
1204
|
const pattern = String(rawPattern || "").trim().toLowerCase();
|
|
1277
1205
|
if (!pattern) return null;
|
|
@@ -1335,15 +1263,15 @@ var Launch = {
|
|
|
1335
1263
|
}
|
|
1336
1264
|
const enableByPassLogger = Boolean(logOptions && logOptions.enable);
|
|
1337
1265
|
if (enableByPassLogger && launchProxy) {
|
|
1338
|
-
|
|
1266
|
+
logger5.info(
|
|
1339
1267
|
`[\u4EE3\u7406\u5DF2\u542F\u7528] \u4EE3\u7406\u670D\u52A1=${launchProxy.server} \u76F4\u8FDE\u57DF\u540D=${(byPassDomains || []).join(",")}`
|
|
1340
1268
|
);
|
|
1341
1269
|
} else if (enableByPassLogger && enableProxy && !launchProxy) {
|
|
1342
|
-
|
|
1270
|
+
logger5.info(
|
|
1343
1271
|
`[\u4EE3\u7406\u672A\u542F\u7528] enable_proxy=true \u4F46 proxy_url \u4E3A\u7A7A`
|
|
1344
1272
|
);
|
|
1345
1273
|
} else if (enableByPassLogger && !enableProxy && proxyUrl) {
|
|
1346
|
-
|
|
1274
|
+
logger5.info(
|
|
1347
1275
|
`[\u4EE3\u7406\u672A\u542F\u7528] enable_proxy=false \u4E14 proxy_url \u5DF2\u914D\u7F6E`
|
|
1348
1276
|
);
|
|
1349
1277
|
}
|
|
@@ -1365,7 +1293,7 @@ var Launch = {
|
|
|
1365
1293
|
}
|
|
1366
1294
|
const matchedRule = byPassRules.find((rule) => rule.test(hostname));
|
|
1367
1295
|
if (!matchedRule) return;
|
|
1368
|
-
|
|
1296
|
+
logger5.info(`[\u76F4\u8FDE\u547D\u4E2D] \u89C4\u5219=${matchedRule.pattern} \u57DF\u540D=${hostname} \u8D44\u6E90\u7C7B\u578B=${req.resourceType()} \u65B9\u6CD5=${req.method()} \u5730\u5740=${requestUrl}`);
|
|
1369
1297
|
};
|
|
1370
1298
|
page.on("request", requestHandler);
|
|
1371
1299
|
return recommendedGotoOptions;
|
|
@@ -1384,7 +1312,7 @@ var Launch = {
|
|
|
1384
1312
|
// src/live-view.js
|
|
1385
1313
|
import express from "express";
|
|
1386
1314
|
import { Actor } from "apify";
|
|
1387
|
-
var
|
|
1315
|
+
var logger6 = createInternalLogger("LiveView");
|
|
1388
1316
|
async function startLiveViewServer(liveViewKey) {
|
|
1389
1317
|
const app = express();
|
|
1390
1318
|
app.get("/", async (req, res) => {
|
|
@@ -1409,13 +1337,13 @@ async function startLiveViewServer(liveViewKey) {
|
|
|
1409
1337
|
</html>
|
|
1410
1338
|
`);
|
|
1411
1339
|
} catch (error) {
|
|
1412
|
-
|
|
1340
|
+
logger6.fail("Live View Server", error);
|
|
1413
1341
|
res.status(500).send(`\u65E0\u6CD5\u52A0\u8F7D\u5C4F\u5E55\u622A\u56FE: ${error.message}`);
|
|
1414
1342
|
}
|
|
1415
1343
|
});
|
|
1416
1344
|
const port = process.env.APIFY_CONTAINER_PORT || 4321;
|
|
1417
1345
|
app.listen(port, () => {
|
|
1418
|
-
|
|
1346
|
+
logger6.success("startLiveViewServer", `\u76D1\u542C\u7AEF\u53E3 ${port}`);
|
|
1419
1347
|
});
|
|
1420
1348
|
}
|
|
1421
1349
|
async function takeLiveScreenshot(liveViewKey, page, logMessage) {
|
|
@@ -1423,10 +1351,10 @@ async function takeLiveScreenshot(liveViewKey, page, logMessage) {
|
|
|
1423
1351
|
const buffer = await page.screenshot({ type: "png" });
|
|
1424
1352
|
await Actor.setValue(liveViewKey, buffer, { contentType: "image/png" });
|
|
1425
1353
|
if (logMessage) {
|
|
1426
|
-
|
|
1354
|
+
logger6.info(`(\u622A\u56FE): ${logMessage}`);
|
|
1427
1355
|
}
|
|
1428
1356
|
} catch (e) {
|
|
1429
|
-
|
|
1357
|
+
logger6.warn(`\u65E0\u6CD5\u6355\u83B7 Live View \u5C4F\u5E55\u622A\u56FE: ${e.message}`);
|
|
1430
1358
|
}
|
|
1431
1359
|
}
|
|
1432
1360
|
var useLiveView = (liveViewKey = PresetOfLiveViewKey) => {
|
|
@@ -1445,7 +1373,7 @@ var LiveView = {
|
|
|
1445
1373
|
|
|
1446
1374
|
// src/captcha-monitor.js
|
|
1447
1375
|
import { v4 as uuidv4 } from "uuid";
|
|
1448
|
-
var
|
|
1376
|
+
var logger7 = createInternalLogger("Captcha");
|
|
1449
1377
|
function useCaptchaMonitor(page, options) {
|
|
1450
1378
|
const { domSelector, urlPattern, onDetected } = options;
|
|
1451
1379
|
if (!domSelector && !urlPattern) {
|
|
@@ -1518,7 +1446,7 @@ function useCaptchaMonitor(page, options) {
|
|
|
1518
1446
|
};
|
|
1519
1447
|
})();
|
|
1520
1448
|
}, { selector: domSelector, callbackName: exposedFunctionName, cleanerName });
|
|
1521
|
-
|
|
1449
|
+
logger7.success("useCaptchaMonitor", `DOM \u76D1\u63A7\u5DF2\u542F\u7528: ${domSelector}`);
|
|
1522
1450
|
cleanupFns.push(async () => {
|
|
1523
1451
|
try {
|
|
1524
1452
|
await page.evaluate((name) => {
|
|
@@ -1541,14 +1469,14 @@ function useCaptchaMonitor(page, options) {
|
|
|
1541
1469
|
}
|
|
1542
1470
|
};
|
|
1543
1471
|
page.on("framenavigated", frameHandler);
|
|
1544
|
-
|
|
1472
|
+
logger7.success("useCaptchaMonitor", `URL \u76D1\u63A7\u5DF2\u542F\u7528: ${urlPattern}`);
|
|
1545
1473
|
cleanupFns.push(async () => {
|
|
1546
1474
|
page.off("framenavigated", frameHandler);
|
|
1547
1475
|
});
|
|
1548
1476
|
}
|
|
1549
1477
|
return {
|
|
1550
1478
|
stop: async () => {
|
|
1551
|
-
|
|
1479
|
+
logger7.info("useCaptchaMonitor", "\u6B63\u5728\u505C\u6B62\u76D1\u63A7...");
|
|
1552
1480
|
for (const fn of cleanupFns) {
|
|
1553
1481
|
await fn();
|
|
1554
1482
|
}
|
|
@@ -1563,7 +1491,7 @@ var Captcha = {
|
|
|
1563
1491
|
// src/sse.js
|
|
1564
1492
|
import https from "https";
|
|
1565
1493
|
import { URL as URL2 } from "url";
|
|
1566
|
-
var
|
|
1494
|
+
var logger8 = createInternalLogger("Sse");
|
|
1567
1495
|
var Sse = {
|
|
1568
1496
|
/**
|
|
1569
1497
|
* 解析 SSE 流文本
|
|
@@ -1582,11 +1510,11 @@ var Sse = {
|
|
|
1582
1510
|
events.push(JSON.parse(jsonContent));
|
|
1583
1511
|
}
|
|
1584
1512
|
} catch (e) {
|
|
1585
|
-
|
|
1513
|
+
logger8.debug("parseSseStream", `JSON \u89E3\u6790\u5931\u8D25: ${e.message}, line: ${line.substring(0, 100)}...`);
|
|
1586
1514
|
}
|
|
1587
1515
|
}
|
|
1588
1516
|
}
|
|
1589
|
-
|
|
1517
|
+
logger8.success("parseSseStream", `\u89E3\u6790\u5B8C\u6210, events \u6570\u91CF: ${events.length}`);
|
|
1590
1518
|
return events;
|
|
1591
1519
|
},
|
|
1592
1520
|
/**
|
|
@@ -1636,7 +1564,7 @@ var Sse = {
|
|
|
1636
1564
|
if (!autoUnroute) return;
|
|
1637
1565
|
if (unrouteRequested) return;
|
|
1638
1566
|
unrouteRequested = true;
|
|
1639
|
-
|
|
1567
|
+
logger8.info("[MITM] autoUnroute: \u53D6\u6D88\u540E\u7EED\u62E6\u622A");
|
|
1640
1568
|
page.unroute(urlPattern, routeHandler).catch(() => {
|
|
1641
1569
|
});
|
|
1642
1570
|
};
|
|
@@ -1656,19 +1584,19 @@ var Sse = {
|
|
|
1656
1584
|
};
|
|
1657
1585
|
const routeHandler = async (route) => {
|
|
1658
1586
|
if (firstMatchOnly && hasMatchedOnce) {
|
|
1659
|
-
|
|
1587
|
+
logger8.info(`[MITM] firstMatchOnly: \u653E\u884C\u540E\u7EED\u8BF7\u6C42: ${route.request().url()}`);
|
|
1660
1588
|
route.continue().catch(() => {
|
|
1661
1589
|
});
|
|
1662
1590
|
return;
|
|
1663
1591
|
}
|
|
1664
1592
|
if (firstMatchOnly && !hasMatchedOnce) {
|
|
1665
1593
|
hasMatchedOnce = true;
|
|
1666
|
-
|
|
1594
|
+
logger8.info("[MITM] firstMatchOnly: \u547D\u4E2D\u9996\u4E2A\u8BF7\u6C42\uFF0C\u53D6\u6D88\u540E\u7EED\u62E6\u622A");
|
|
1667
1595
|
page.unroute(urlPattern, routeHandler).catch(() => {
|
|
1668
1596
|
});
|
|
1669
1597
|
}
|
|
1670
1598
|
const request = route.request();
|
|
1671
|
-
|
|
1599
|
+
logger8.info(`[MITM] \u5DF2\u62E6\u622A\u8BF7\u6C42: ${request.url()}`);
|
|
1672
1600
|
try {
|
|
1673
1601
|
const headers = await request.allHeaders();
|
|
1674
1602
|
const postData = request.postData();
|
|
@@ -1693,7 +1621,7 @@ var Sse = {
|
|
|
1693
1621
|
clearTimeout(initialTimer);
|
|
1694
1622
|
initialTimer = null;
|
|
1695
1623
|
}
|
|
1696
|
-
|
|
1624
|
+
logger8.debug("[Intercept] \u5DF2\u63A5\u6536\u521D\u59CB\u6570\u636E");
|
|
1697
1625
|
}
|
|
1698
1626
|
chunks.push(chunk);
|
|
1699
1627
|
const textChunk = chunk.toString("utf-8");
|
|
@@ -1702,18 +1630,18 @@ var Sse = {
|
|
|
1702
1630
|
try {
|
|
1703
1631
|
onData(textChunk, safeResolve, accumulatedText);
|
|
1704
1632
|
} catch (e) {
|
|
1705
|
-
|
|
1633
|
+
logger8.fail(`onData \u9519\u8BEF`, e);
|
|
1706
1634
|
}
|
|
1707
1635
|
}
|
|
1708
1636
|
});
|
|
1709
1637
|
res.on("end", () => {
|
|
1710
|
-
|
|
1638
|
+
logger8.info("[MITM] \u4E0A\u6E38\u54CD\u5E94\u7ED3\u675F");
|
|
1711
1639
|
clearAllTimers();
|
|
1712
1640
|
if (onEnd) {
|
|
1713
1641
|
try {
|
|
1714
1642
|
onEnd(accumulatedText, safeResolve);
|
|
1715
1643
|
} catch (e) {
|
|
1716
|
-
|
|
1644
|
+
logger8.fail(`onEnd \u9519\u8BEF`, e);
|
|
1717
1645
|
}
|
|
1718
1646
|
} else if (!onData) {
|
|
1719
1647
|
safeResolve(accumulatedText);
|
|
@@ -1794,7 +1722,7 @@ var Sse = {
|
|
|
1794
1722
|
|
|
1795
1723
|
// src/mutation.js
|
|
1796
1724
|
import { v4 as uuidv42 } from "uuid";
|
|
1797
|
-
var
|
|
1725
|
+
var logger9 = createInternalLogger("Mutation");
|
|
1798
1726
|
var MUTATION_MONITOR_MODE = Object.freeze({
|
|
1799
1727
|
Added: "added",
|
|
1800
1728
|
Changed: "changed",
|
|
@@ -1827,14 +1755,14 @@ var Mutation = {
|
|
|
1827
1755
|
const stableTime = options.stableTime ?? 5 * 1e3;
|
|
1828
1756
|
const timeout = options.timeout ?? 120 * 1e3;
|
|
1829
1757
|
const onMutation = options.onMutation;
|
|
1830
|
-
|
|
1758
|
+
logger9.start("waitForStable", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, \u7A33\u5B9A\u65F6\u95F4=${stableTime}ms`);
|
|
1831
1759
|
if (initialTimeout > 0) {
|
|
1832
1760
|
const selectorQuery = selectorList.join(",");
|
|
1833
1761
|
try {
|
|
1834
1762
|
await page.waitForSelector(selectorQuery, { timeout: initialTimeout });
|
|
1835
|
-
|
|
1763
|
+
logger9.info(`waitForStable \u5DF2\u68C0\u6D4B\u5230\u5143\u7D20: ${selectorQuery}`);
|
|
1836
1764
|
} catch (e) {
|
|
1837
|
-
|
|
1765
|
+
logger9.warning(`waitForStable \u521D\u59CB\u7B49\u5F85\u8D85\u65F6 (${initialTimeout}ms): ${selectorQuery}`);
|
|
1838
1766
|
throw e;
|
|
1839
1767
|
}
|
|
1840
1768
|
}
|
|
@@ -1850,7 +1778,7 @@ var Mutation = {
|
|
|
1850
1778
|
return "__CONTINUE__";
|
|
1851
1779
|
}
|
|
1852
1780
|
});
|
|
1853
|
-
|
|
1781
|
+
logger9.info("waitForStable \u5DF2\u542F\u7528 onMutation \u56DE\u8C03");
|
|
1854
1782
|
} catch (e) {
|
|
1855
1783
|
}
|
|
1856
1784
|
}
|
|
@@ -1965,9 +1893,9 @@ var Mutation = {
|
|
|
1965
1893
|
{ selectorList, stableTime, timeout, callbackName, hasCallback: !!onMutation }
|
|
1966
1894
|
);
|
|
1967
1895
|
if (result.mutationCount === 0 && result.stableTime === 0) {
|
|
1968
|
-
|
|
1896
|
+
logger9.warning("waitForStable \u672A\u627E\u5230\u53EF\u76D1\u63A7\u7684\u5143\u7D20");
|
|
1969
1897
|
}
|
|
1970
|
-
|
|
1898
|
+
logger9.success("waitForStable", `DOM \u7A33\u5B9A, \u603B\u5171 ${result.mutationCount} \u6B21\u53D8\u5316${result.wasPaused ? ", \u66FE\u6682\u505C\u8BA1\u65F6" : ""}`);
|
|
1971
1899
|
return result;
|
|
1972
1900
|
},
|
|
1973
1901
|
/**
|
|
@@ -1987,7 +1915,7 @@ var Mutation = {
|
|
|
1987
1915
|
const onMutation = options.onMutation;
|
|
1988
1916
|
const rawMode = String(options.mode || MUTATION_MONITOR_MODE.Added).toLowerCase();
|
|
1989
1917
|
const mode = [MUTATION_MONITOR_MODE.Added, MUTATION_MONITOR_MODE.Changed, MUTATION_MONITOR_MODE.All].includes(rawMode) ? rawMode : MUTATION_MONITOR_MODE.Added;
|
|
1990
|
-
|
|
1918
|
+
logger9.start("useMonitor", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, mode=${mode}`);
|
|
1991
1919
|
const monitorKey = generateKey("pk_mon");
|
|
1992
1920
|
const callbackName = generateKey("pk_mon_cb");
|
|
1993
1921
|
const cleanerName = generateKey("pk_mon_clean");
|
|
@@ -2130,7 +2058,7 @@ var Mutation = {
|
|
|
2130
2058
|
return total;
|
|
2131
2059
|
};
|
|
2132
2060
|
}, { selectorList, monitorKey, callbackName, cleanerName, hasCallback: !!onMutation, mode });
|
|
2133
|
-
|
|
2061
|
+
logger9.success("useMonitor", "\u76D1\u63A7\u5668\u5DF2\u542F\u52A8");
|
|
2134
2062
|
return {
|
|
2135
2063
|
stop: async () => {
|
|
2136
2064
|
let totalMutations = 0;
|
|
@@ -2143,7 +2071,7 @@ var Mutation = {
|
|
|
2143
2071
|
}, cleanerName);
|
|
2144
2072
|
} catch (e) {
|
|
2145
2073
|
}
|
|
2146
|
-
|
|
2074
|
+
logger9.success("useMonitor.stop", `\u76D1\u63A7\u5DF2\u505C\u6B62, \u5171 ${totalMutations} \u6B21\u53D8\u5316`);
|
|
2147
2075
|
return { totalMutations };
|
|
2148
2076
|
}
|
|
2149
2077
|
};
|
|
@@ -3012,7 +2940,7 @@ var createTemplateLogger = (baseLogger = createBaseLogger()) => {
|
|
|
3012
2940
|
};
|
|
3013
2941
|
var getDefaultBaseLogger = () => createBaseLogger("");
|
|
3014
2942
|
var Logger = {
|
|
3015
|
-
setLogger: (
|
|
2943
|
+
setLogger: (logger11) => setDefaultLogger(logger11),
|
|
3016
2944
|
info: (message) => getDefaultBaseLogger().info(message),
|
|
3017
2945
|
success: (message) => getDefaultBaseLogger().success(message),
|
|
3018
2946
|
warning: (message) => getDefaultBaseLogger().warning(message),
|
|
@@ -3020,15 +2948,15 @@ var Logger = {
|
|
|
3020
2948
|
error: (message) => getDefaultBaseLogger().error(message),
|
|
3021
2949
|
debug: (message) => getDefaultBaseLogger().debug(message),
|
|
3022
2950
|
start: (message) => getDefaultBaseLogger().start(message),
|
|
3023
|
-
useTemplate: (
|
|
3024
|
-
if (
|
|
2951
|
+
useTemplate: (logger11) => {
|
|
2952
|
+
if (logger11) return createTemplateLogger(createBaseLogger("", logger11));
|
|
3025
2953
|
return createTemplateLogger();
|
|
3026
2954
|
}
|
|
3027
2955
|
};
|
|
3028
2956
|
|
|
3029
2957
|
// src/share.js
|
|
3030
|
-
import
|
|
3031
|
-
var
|
|
2958
|
+
import delay2 from "delay";
|
|
2959
|
+
var logger10 = createInternalLogger("Share");
|
|
3032
2960
|
var DEFAULT_TIMEOUT_MS = 50 * 1e3;
|
|
3033
2961
|
var DEFAULT_PAYLOAD_SNAPSHOT_MAX_LEN = 500;
|
|
3034
2962
|
var DEFAULT_POLL_INTERVAL_MS = 120;
|
|
@@ -3148,7 +3076,7 @@ var createDomShareMonitor = async (page, options = {}) => {
|
|
|
3148
3076
|
const onMatch = typeof options.onMatch === "function" ? options.onMatch : null;
|
|
3149
3077
|
const onTelemetry = typeof options.onTelemetry === "function" ? options.onTelemetry : null;
|
|
3150
3078
|
let matched = false;
|
|
3151
|
-
|
|
3079
|
+
logger10.info(`DOM \u76D1\u542C\u51C6\u5907\u6302\u8F7D: selectors=${toJsonInline(selectors, 120)}, mode=${mode}`);
|
|
3152
3080
|
const monitor = await Mutation.useMonitor(page, selectors, {
|
|
3153
3081
|
mode,
|
|
3154
3082
|
onMutation: (context = {}) => {
|
|
@@ -3166,12 +3094,12 @@ ${text}`;
|
|
|
3166
3094
|
});
|
|
3167
3095
|
}
|
|
3168
3096
|
if (mutationCount <= 5 || mutationCount % 50 === 0) {
|
|
3169
|
-
|
|
3097
|
+
logger10.info(`DOM \u53D8\u5316\u5DF2\u6355\u83B7: mutationCount=${mutationCount}, mutationNodes=${mutationNodes.length}`);
|
|
3170
3098
|
}
|
|
3171
3099
|
const [candidate] = Utils.parseLinks(rawDom, { prefix }) || [];
|
|
3172
3100
|
if (!candidate) return;
|
|
3173
3101
|
matched = true;
|
|
3174
|
-
|
|
3102
|
+
logger10.success("captureLink.domHit", `DOM \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: mutationCount=${mutationCount}, link=${candidate}`);
|
|
3175
3103
|
if (onMatch) {
|
|
3176
3104
|
onMatch({
|
|
3177
3105
|
link: candidate,
|
|
@@ -3187,7 +3115,7 @@ ${text}`;
|
|
|
3187
3115
|
return {
|
|
3188
3116
|
stop: async () => {
|
|
3189
3117
|
const result = await monitor.stop();
|
|
3190
|
-
|
|
3118
|
+
logger10.info(`DOM \u76D1\u542C\u5DF2\u505C\u6B62: totalMutations=${result?.totalMutations || 0}`);
|
|
3191
3119
|
return result;
|
|
3192
3120
|
}
|
|
3193
3121
|
};
|
|
@@ -3227,8 +3155,8 @@ var Share = {
|
|
|
3227
3155
|
if (share.mode === "response" && apiMatchers.length === 0) {
|
|
3228
3156
|
throw new Error("Share.captureLink requires share.xurl[0] api matcher when mode=response");
|
|
3229
3157
|
}
|
|
3230
|
-
|
|
3231
|
-
|
|
3158
|
+
logger10.start("captureLink", `mode=${share.mode}, timeoutMs=${timeoutMs}, prefix=${share.prefix}`);
|
|
3159
|
+
logger10.info(`captureLink \u914D\u7F6E: xurl=${toJsonInline(share.xurl)}, domMode=${domMode}, domSelectors=${toJsonInline(domSelectors, 120)}`);
|
|
3232
3160
|
const stats = {
|
|
3233
3161
|
actionTimedOut: false,
|
|
3234
3162
|
domMutationCount: 0,
|
|
@@ -3253,7 +3181,7 @@ var Share = {
|
|
|
3253
3181
|
link: validated,
|
|
3254
3182
|
payloadText: String(payloadText || "")
|
|
3255
3183
|
};
|
|
3256
|
-
|
|
3184
|
+
logger10.info(`\u5019\u9009\u94FE\u63A5\u5DF2\u786E\u8BA4: source=${source}, link=${validated}`);
|
|
3257
3185
|
return true;
|
|
3258
3186
|
};
|
|
3259
3187
|
const resolveResponseCandidate = (responseText) => {
|
|
@@ -3288,7 +3216,7 @@ var Share = {
|
|
|
3288
3216
|
try {
|
|
3289
3217
|
await monitor.stop();
|
|
3290
3218
|
} catch (error) {
|
|
3291
|
-
|
|
3219
|
+
logger10.warning(`\u505C\u6B62 DOM \u76D1\u542C\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
|
|
3292
3220
|
}
|
|
3293
3221
|
};
|
|
3294
3222
|
const onResponse = async (response) => {
|
|
@@ -3301,29 +3229,29 @@ var Share = {
|
|
|
3301
3229
|
stats.responseSampleUrls.push(url);
|
|
3302
3230
|
}
|
|
3303
3231
|
if (stats.responseObserved <= 5) {
|
|
3304
|
-
|
|
3232
|
+
logger10.info(`\u63A5\u53E3\u54CD\u5E94\u91C7\u6837(${stats.responseObserved}): ${url}`);
|
|
3305
3233
|
}
|
|
3306
3234
|
if (!apiMatchers.some((matcher) => url.includes(matcher))) return;
|
|
3307
3235
|
stats.responseMatched += 1;
|
|
3308
3236
|
stats.lastMatchedUrl = url;
|
|
3309
|
-
|
|
3237
|
+
logger10.info(`\u63A5\u53E3\u547D\u4E2D\u5339\u914D(${stats.responseMatched}): ${url}`);
|
|
3310
3238
|
const text = await response.text();
|
|
3311
3239
|
const hit = resolveResponseCandidate(text);
|
|
3312
3240
|
if (!hit?.link) {
|
|
3313
3241
|
if (stats.responseMatched <= 3) {
|
|
3314
|
-
|
|
3242
|
+
logger10.info(`\u63A5\u53E3\u89E3\u6790\u5B8C\u6210\u4F46\u672A\u63D0\u53D6\u5230\u5206\u4EAB\u94FE\u63A5: payloadSize=${text.length}`);
|
|
3315
3243
|
}
|
|
3316
3244
|
return;
|
|
3317
3245
|
}
|
|
3318
3246
|
stats.responseResolved += 1;
|
|
3319
|
-
|
|
3247
|
+
logger10.success("captureLink.responseHit", `\u63A5\u53E3\u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: url=${url}, link=${hit.link}`);
|
|
3320
3248
|
setCandidate("response", hit.link, hit.payloadText);
|
|
3321
3249
|
} catch (error) {
|
|
3322
|
-
|
|
3250
|
+
logger10.warning(`\u63A5\u53E3\u54CD\u5E94\u5904\u7406\u5F02\u5E38: ${error instanceof Error ? error.message : String(error)}`);
|
|
3323
3251
|
}
|
|
3324
3252
|
};
|
|
3325
3253
|
if (share.mode === "dom") {
|
|
3326
|
-
|
|
3254
|
+
logger10.info("\u5F53\u524D\u4E3A DOM \u6A21\u5F0F\uFF0C\u4EC5\u542F\u7528 DOM \u76D1\u542C");
|
|
3327
3255
|
domMonitor = await createDomShareMonitor(page, {
|
|
3328
3256
|
prefix: share.prefix,
|
|
3329
3257
|
selectors: domSelectors,
|
|
@@ -3338,14 +3266,14 @@ var Share = {
|
|
|
3338
3266
|
});
|
|
3339
3267
|
}
|
|
3340
3268
|
if (share.mode === "response") {
|
|
3341
|
-
|
|
3269
|
+
logger10.info(`\u5F53\u524D\u4E3A\u63A5\u53E3\u6A21\u5F0F\uFF0C\u6302\u8F7D response \u76D1\u542C: apiMatchers=${toJsonInline(apiMatchers, 160)}`);
|
|
3342
3270
|
page.on("response", onResponse);
|
|
3343
3271
|
}
|
|
3344
3272
|
const deadline = Date.now() + timeoutMs;
|
|
3345
3273
|
const getRemainingMs = () => Math.max(0, deadline - Date.now());
|
|
3346
3274
|
try {
|
|
3347
3275
|
const actionTimeout = getRemainingMs();
|
|
3348
|
-
|
|
3276
|
+
logger10.start("captureLink.performActions", `\u6267\u884C\u52A8\u4F5C\u9884\u7B97=${actionTimeout}ms`);
|
|
3349
3277
|
if (actionTimeout > 0) {
|
|
3350
3278
|
let timer = null;
|
|
3351
3279
|
let actionError = null;
|
|
@@ -3359,21 +3287,21 @@ var Share = {
|
|
|
3359
3287
|
const actionResult = await Promise.race([actionPromise, timeoutPromise]);
|
|
3360
3288
|
if (timer) clearTimeout(timer);
|
|
3361
3289
|
if (actionResult === "__ACTION_ERROR__") {
|
|
3362
|
-
|
|
3290
|
+
logger10.fail("captureLink.performActions", actionError);
|
|
3363
3291
|
throw actionError;
|
|
3364
3292
|
}
|
|
3365
3293
|
if (actionResult === "__ACTION_TIMEOUT__") {
|
|
3366
3294
|
stats.actionTimedOut = true;
|
|
3367
|
-
|
|
3295
|
+
logger10.warning(`performActions \u5DF2\u8D85\u65F6 (${actionTimeout}ms)\uFF0C\u52A8\u4F5C\u53EF\u80FD\u4ECD\u5728\u5F02\u6B65\u6267\u884C`);
|
|
3368
3296
|
} else {
|
|
3369
|
-
|
|
3297
|
+
logger10.success("captureLink.performActions", "\u6267\u884C\u52A8\u4F5C\u5B8C\u6210");
|
|
3370
3298
|
}
|
|
3371
3299
|
}
|
|
3372
3300
|
let nextProgressLogTs = Date.now() + 3e3;
|
|
3373
3301
|
while (true) {
|
|
3374
3302
|
const selected = share.mode === "dom" ? candidates.dom : candidates.response;
|
|
3375
3303
|
if (selected?.link) {
|
|
3376
|
-
|
|
3304
|
+
logger10.success("captureLink", `\u6355\u83B7\u6210\u529F: source=${share.mode}, link=${selected.link}`);
|
|
3377
3305
|
return {
|
|
3378
3306
|
link: selected.link,
|
|
3379
3307
|
payloadText: selected.payloadText,
|
|
@@ -3385,19 +3313,19 @@ var Share = {
|
|
|
3385
3313
|
if (remaining <= 0) break;
|
|
3386
3314
|
const now = Date.now();
|
|
3387
3315
|
if (now >= nextProgressLogTs) {
|
|
3388
|
-
|
|
3316
|
+
logger10.info(
|
|
3389
3317
|
`captureLink \u7B49\u5F85\u4E2D: remaining=${remaining}ms, domMutationCount=${stats.domMutationCount}, responseMatched=${stats.responseMatched}`
|
|
3390
3318
|
);
|
|
3391
3319
|
nextProgressLogTs = now + 5e3;
|
|
3392
3320
|
}
|
|
3393
|
-
await
|
|
3321
|
+
await delay2(Math.max(0, Math.min(DEFAULT_POLL_INTERVAL_MS, remaining)));
|
|
3394
3322
|
}
|
|
3395
3323
|
if (share.mode === "response" && stats.responseMatched === 0) {
|
|
3396
|
-
|
|
3324
|
+
logger10.warning(
|
|
3397
3325
|
`\u63A5\u53E3\u76D1\u542C\u672A\u547D\u4E2D: apiMatchers=${toJsonInline(apiMatchers, 220)}, \u54CD\u5E94\u6837\u672CURLs=${toJsonInline(stats.responseSampleUrls, 420)}`
|
|
3398
3326
|
);
|
|
3399
3327
|
}
|
|
3400
|
-
|
|
3328
|
+
logger10.warning(
|
|
3401
3329
|
`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"}`
|
|
3402
3330
|
);
|
|
3403
3331
|
return {
|
|
@@ -3409,7 +3337,7 @@ var Share = {
|
|
|
3409
3337
|
} finally {
|
|
3410
3338
|
if (share.mode === "response") {
|
|
3411
3339
|
page.off("response", onResponse);
|
|
3412
|
-
|
|
3340
|
+
logger10.info("response \u76D1\u542C\u5DF2\u5378\u8F7D");
|
|
3413
3341
|
}
|
|
3414
3342
|
await stopDomMonitor();
|
|
3415
3343
|
}
|
|
@@ -3456,7 +3384,7 @@ var Share = {
|
|
|
3456
3384
|
width: originalViewport?.width || 1280,
|
|
3457
3385
|
height: targetHeight
|
|
3458
3386
|
});
|
|
3459
|
-
await
|
|
3387
|
+
await delay2(1e3);
|
|
3460
3388
|
const buffer_ = await page.screenshot({
|
|
3461
3389
|
fullPage: true,
|
|
3462
3390
|
type: "png"
|