@skrillex1224/playwright-toolkit 2.1.152 → 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/dist/browser.js +4 -4
- package/dist/browser.js.map +1 -1
- package/dist/index.cjs +146 -238
- package/dist/index.cjs.map +3 -3
- package/dist/index.js +146 -238
- package/dist/index.js.map +3 -3
- package/index.d.ts +2 -22
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -152,8 +152,8 @@ var ActorInfo = {
|
|
|
152
152
|
qbot: createActorInfo({
|
|
153
153
|
key: "qbot",
|
|
154
154
|
name: "\u641C\u72D7QBot",
|
|
155
|
-
domain: "
|
|
156
|
-
path: "/web
|
|
155
|
+
domain: "sogou.com",
|
|
156
|
+
path: "/web",
|
|
157
157
|
share: {
|
|
158
158
|
mode: "dom",
|
|
159
159
|
prefix: "",
|
|
@@ -163,8 +163,8 @@ var ActorInfo = {
|
|
|
163
163
|
douyin: createActorInfo({
|
|
164
164
|
key: "douyin",
|
|
165
165
|
name: "\u6296\u97F3AI\u641C",
|
|
166
|
-
domain: "
|
|
167
|
-
path: "/
|
|
166
|
+
domain: "so.douyin.com",
|
|
167
|
+
path: "/s",
|
|
168
168
|
share: {
|
|
169
169
|
mode: "response",
|
|
170
170
|
prefix: "",
|
|
@@ -324,18 +324,18 @@ var fallbackLog = {
|
|
|
324
324
|
error: (...args) => console.error(...args),
|
|
325
325
|
debug: (...args) => console.debug ? console.debug(...args) : console.log(...args)
|
|
326
326
|
};
|
|
327
|
-
var resolveLogMethod = (
|
|
328
|
-
if (
|
|
329
|
-
return
|
|
327
|
+
var resolveLogMethod = (logger11, name) => {
|
|
328
|
+
if (logger11 && typeof logger11[name] === "function") {
|
|
329
|
+
return logger11[name].bind(logger11);
|
|
330
330
|
}
|
|
331
|
-
if (name === "warning" &&
|
|
332
|
-
return
|
|
331
|
+
if (name === "warning" && logger11 && typeof logger11.warn === "function") {
|
|
332
|
+
return logger11.warn.bind(logger11);
|
|
333
333
|
}
|
|
334
334
|
return fallbackLog[name];
|
|
335
335
|
};
|
|
336
336
|
var defaultLogger = null;
|
|
337
|
-
var setDefaultLogger = (
|
|
338
|
-
defaultLogger =
|
|
337
|
+
var setDefaultLogger = (logger11) => {
|
|
338
|
+
defaultLogger = logger11;
|
|
339
339
|
};
|
|
340
340
|
var resolveLogger = (explicitLogger) => {
|
|
341
341
|
if (explicitLogger && typeof explicitLogger.info === "function") {
|
|
@@ -362,8 +362,8 @@ var colorize = (text, color) => {
|
|
|
362
362
|
var createBaseLogger = (prefix = "", explicitLogger) => {
|
|
363
363
|
const name = prefix ? String(prefix) : "";
|
|
364
364
|
const dispatch = (methodName, icon, message, color) => {
|
|
365
|
-
const
|
|
366
|
-
const logFn = resolveLogMethod(
|
|
365
|
+
const logger11 = resolveLogger(explicitLogger);
|
|
366
|
+
const logFn = resolveLogMethod(logger11, methodName);
|
|
367
367
|
const timestamp = colorize(`[${formatTimestamp()}]`, ANSI.gray);
|
|
368
368
|
const line = formatLine(name, icon, message);
|
|
369
369
|
const coloredLine = colorize(line, color);
|
|
@@ -649,8 +649,6 @@ var parseCookies = (cookieString, domain) => {
|
|
|
649
649
|
};
|
|
650
650
|
|
|
651
651
|
// src/utils.js
|
|
652
|
-
var import_delay = __toESM(require("delay"), 1);
|
|
653
|
-
var logger3 = createInternalLogger("Utils");
|
|
654
652
|
var Utils = {
|
|
655
653
|
/**
|
|
656
654
|
* 解析 Cookie 字符串为 Playwright 格式的 Cookie 数组
|
|
@@ -685,81 +683,11 @@ var Utils = {
|
|
|
685
683
|
unique.add(link);
|
|
686
684
|
}
|
|
687
685
|
return Array.from(unique);
|
|
688
|
-
},
|
|
689
|
-
/**
|
|
690
|
-
* 全页面滚动截图
|
|
691
|
-
* 自动检测页面所有可滚动元素,取最大高度,强制展开后截图
|
|
692
|
-
*
|
|
693
|
-
* @param {import('playwright').Page} page - Playwright page 对象
|
|
694
|
-
* @param {Object} [options] - 配置选项
|
|
695
|
-
* @param {number} [options.buffer] - 额外缓冲高度 (默认: 视口高度的一半)
|
|
696
|
-
* @param {boolean} [options.restore] - 截图后是否恢复页面高度和样式 (默认: false)
|
|
697
|
-
* @param {number} [options.maxHeight] - 最大截图高度 (默认: 8000px)
|
|
698
|
-
* @returns {Promise<string>} - base64 编码的 PNG 图片
|
|
699
|
-
*/
|
|
700
|
-
async fullPageScreenshot(page, options = {}) {
|
|
701
|
-
logger3.start("fullPageScreenshot", "detecting scrollable elements");
|
|
702
|
-
const originalViewport = page.viewportSize();
|
|
703
|
-
const defaultBuffer = Math.round((originalViewport?.height || 1080) / 2);
|
|
704
|
-
const buffer = options.buffer ?? defaultBuffer;
|
|
705
|
-
const restore = options.restore ?? false;
|
|
706
|
-
const maxHeight = options.maxHeight ?? 8e3;
|
|
707
|
-
try {
|
|
708
|
-
const maxScrollHeight = await page.evaluate(() => {
|
|
709
|
-
let maxHeight2 = document.body.scrollHeight;
|
|
710
|
-
document.querySelectorAll("*").forEach((el) => {
|
|
711
|
-
const style = window.getComputedStyle(el);
|
|
712
|
-
const overflowY = style.overflowY;
|
|
713
|
-
if ((overflowY === "auto" || overflowY === "scroll") && el.scrollHeight > el.clientHeight) {
|
|
714
|
-
if (el.scrollHeight > maxHeight2) {
|
|
715
|
-
maxHeight2 = el.scrollHeight;
|
|
716
|
-
}
|
|
717
|
-
el.dataset.pkOrigOverflow = el.style.overflow;
|
|
718
|
-
el.dataset.pkOrigHeight = el.style.height;
|
|
719
|
-
el.dataset.pkOrigMaxHeight = el.style.maxHeight;
|
|
720
|
-
el.classList.add("__pk_expanded__");
|
|
721
|
-
el.style.overflow = "visible";
|
|
722
|
-
el.style.height = "auto";
|
|
723
|
-
el.style.maxHeight = "none";
|
|
724
|
-
}
|
|
725
|
-
});
|
|
726
|
-
return maxHeight2;
|
|
727
|
-
});
|
|
728
|
-
const targetHeight = Math.min(maxScrollHeight + buffer, maxHeight);
|
|
729
|
-
await page.setViewportSize({
|
|
730
|
-
width: originalViewport?.width || 1280,
|
|
731
|
-
height: targetHeight
|
|
732
|
-
});
|
|
733
|
-
await (0, import_delay.default)(1e3);
|
|
734
|
-
const buffer_ = await page.screenshot({
|
|
735
|
-
fullPage: true,
|
|
736
|
-
type: "png"
|
|
737
|
-
});
|
|
738
|
-
logger3.success("fullPageScreenshot", `captured ${Math.round(buffer_.length / 1024)} KB`);
|
|
739
|
-
return buffer_.toString("base64");
|
|
740
|
-
} finally {
|
|
741
|
-
if (restore) {
|
|
742
|
-
await page.evaluate(() => {
|
|
743
|
-
document.querySelectorAll(".__pk_expanded__").forEach((el) => {
|
|
744
|
-
el.style.overflow = el.dataset.pkOrigOverflow || "";
|
|
745
|
-
el.style.height = el.dataset.pkOrigHeight || "";
|
|
746
|
-
el.style.maxHeight = el.dataset.pkOrigMaxHeight || "";
|
|
747
|
-
delete el.dataset.pkOrigOverflow;
|
|
748
|
-
delete el.dataset.pkOrigHeight;
|
|
749
|
-
delete el.dataset.pkOrigMaxHeight;
|
|
750
|
-
el.classList.remove("__pk_expanded__");
|
|
751
|
-
});
|
|
752
|
-
});
|
|
753
|
-
if (originalViewport) {
|
|
754
|
-
await page.setViewportSize(originalViewport);
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
686
|
}
|
|
759
687
|
};
|
|
760
688
|
|
|
761
689
|
// src/anti-cheat.js
|
|
762
|
-
var
|
|
690
|
+
var logger3 = createInternalLogger("AntiCheat");
|
|
763
691
|
var BASE_CONFIG = Object.freeze({
|
|
764
692
|
locale: "zh-CN",
|
|
765
693
|
acceptLanguage: "zh-CN,zh;q=0.9",
|
|
@@ -819,9 +747,9 @@ var AntiCheat = {
|
|
|
819
747
|
};
|
|
820
748
|
|
|
821
749
|
// src/humanize.js
|
|
822
|
-
var
|
|
750
|
+
var import_delay = __toESM(require("delay"), 1);
|
|
823
751
|
var import_ghost_cursor_playwright = require("ghost-cursor-playwright");
|
|
824
|
-
var
|
|
752
|
+
var logger4 = createInternalLogger("Humanize");
|
|
825
753
|
var $CursorWeakMap = /* @__PURE__ */ new WeakMap();
|
|
826
754
|
function $GetCursor(page) {
|
|
827
755
|
const cursor = $CursorWeakMap.get(page);
|
|
@@ -849,13 +777,13 @@ var Humanize = {
|
|
|
849
777
|
*/
|
|
850
778
|
async initializeCursor(page) {
|
|
851
779
|
if ($CursorWeakMap.has(page)) {
|
|
852
|
-
|
|
780
|
+
logger4.debug("initializeCursor: cursor already exists, skipping");
|
|
853
781
|
return;
|
|
854
782
|
}
|
|
855
|
-
|
|
783
|
+
logger4.start("initializeCursor", "creating cursor");
|
|
856
784
|
const cursor = await (0, import_ghost_cursor_playwright.createCursor)(page);
|
|
857
785
|
$CursorWeakMap.set(page, cursor);
|
|
858
|
-
|
|
786
|
+
logger4.success("initializeCursor", "cursor initialized");
|
|
859
787
|
},
|
|
860
788
|
/**
|
|
861
789
|
* 人类化鼠标移动 - 使用 ghost-cursor 移动到指定位置或元素
|
|
@@ -865,17 +793,17 @@ var Humanize = {
|
|
|
865
793
|
*/
|
|
866
794
|
async humanMove(page, target) {
|
|
867
795
|
const cursor = $GetCursor(page);
|
|
868
|
-
|
|
796
|
+
logger4.start("humanMove", `target=${typeof target === "string" ? target : "element/coords"}`);
|
|
869
797
|
try {
|
|
870
798
|
if (typeof target === "string") {
|
|
871
799
|
const element = await page.$(target);
|
|
872
800
|
if (!element) {
|
|
873
|
-
|
|
801
|
+
logger4.warn(`humanMove: \u5143\u7D20\u4E0D\u5B58\u5728 ${target}`);
|
|
874
802
|
return false;
|
|
875
803
|
}
|
|
876
804
|
const box = await element.boundingBox();
|
|
877
805
|
if (!box) {
|
|
878
|
-
|
|
806
|
+
logger4.warn(`humanMove: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E ${target}`);
|
|
879
807
|
return false;
|
|
880
808
|
}
|
|
881
809
|
const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.2;
|
|
@@ -891,10 +819,10 @@ var Humanize = {
|
|
|
891
819
|
await cursor.actions.move({ x, y });
|
|
892
820
|
}
|
|
893
821
|
}
|
|
894
|
-
|
|
822
|
+
logger4.success("humanMove");
|
|
895
823
|
return true;
|
|
896
824
|
} catch (error) {
|
|
897
|
-
|
|
825
|
+
logger4.fail("humanMove", error);
|
|
898
826
|
throw error;
|
|
899
827
|
}
|
|
900
828
|
},
|
|
@@ -918,12 +846,12 @@ var Humanize = {
|
|
|
918
846
|
maxDurationMs = maxSteps * 220 + 800
|
|
919
847
|
} = options;
|
|
920
848
|
const targetDesc = typeof target === "string" ? target : "ElementHandle";
|
|
921
|
-
|
|
849
|
+
logger4.start("humanScroll", `target=${targetDesc}`);
|
|
922
850
|
let element;
|
|
923
851
|
if (typeof target === "string") {
|
|
924
852
|
element = await page.$(target);
|
|
925
853
|
if (!element) {
|
|
926
|
-
|
|
854
|
+
logger4.warn(`humanScroll | \u5143\u7D20\u672A\u627E\u5230: ${target}`);
|
|
927
855
|
return { element: null, didScroll: false };
|
|
928
856
|
}
|
|
929
857
|
} else {
|
|
@@ -998,26 +926,26 @@ var Humanize = {
|
|
|
998
926
|
try {
|
|
999
927
|
for (let i = 0; i < maxSteps; i++) {
|
|
1000
928
|
if (Date.now() - startTime > maxDurationMs) {
|
|
1001
|
-
|
|
929
|
+
logger4.warn(`humanScroll | \u8D85\u65F6\u4FDD\u62A4\u89E6\u53D1 (${maxDurationMs}ms)`);
|
|
1002
930
|
return { element, didScroll };
|
|
1003
931
|
}
|
|
1004
932
|
const status = await checkVisibility();
|
|
1005
933
|
if (status.code === "VISIBLE") {
|
|
1006
934
|
if (status.isFixed) {
|
|
1007
|
-
|
|
935
|
+
logger4.info("humanScroll | fixed \u5BB9\u5668\u5185\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
|
|
1008
936
|
} else {
|
|
1009
|
-
|
|
937
|
+
logger4.debug("humanScroll | \u5143\u7D20\u53EF\u89C1\u4E14\u65E0\u906E\u6321");
|
|
1010
938
|
}
|
|
1011
|
-
|
|
939
|
+
logger4.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
|
|
1012
940
|
return { element, didScroll };
|
|
1013
941
|
}
|
|
1014
|
-
|
|
942
|
+
logger4.debug(`humanScroll | \u6B65\u9AA4 ${i + 1}/${maxSteps}: ${status.reason} ${status.direction ? `(${status.direction})` : ""}`);
|
|
1015
943
|
if (status.code === "OBSTRUCTED" && status.obstruction) {
|
|
1016
|
-
|
|
944
|
+
logger4.debug(`humanScroll | \u88AB\u4EE5\u4E0B\u5143\u7D20\u906E\u6321 <${status.obstruction.tag} id="${status.obstruction.id}">`);
|
|
1017
945
|
}
|
|
1018
946
|
const scrollRect = await getScrollableRect();
|
|
1019
947
|
if (!scrollRect && status.isFixed) {
|
|
1020
|
-
|
|
948
|
+
logger4.warn("humanScroll | fixed \u5BB9\u5668\u5185\u4E14\u65E0\u53EF\u6EDA\u52A8\u7956\u5148\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
|
|
1021
949
|
return { element, didScroll };
|
|
1022
950
|
}
|
|
1023
951
|
const stepMin = scrollRect ? Math.min(minStep, Math.max(60, scrollRect.height * 0.4)) : minStep;
|
|
@@ -1051,12 +979,12 @@ var Humanize = {
|
|
|
1051
979
|
}
|
|
1052
980
|
await page.mouse.wheel(0, deltaY);
|
|
1053
981
|
didScroll = true;
|
|
1054
|
-
await (0,
|
|
982
|
+
await (0, import_delay.default)(this.jitterMs(20 + Math.random() * 40, 0.2));
|
|
1055
983
|
}
|
|
1056
|
-
|
|
984
|
+
logger4.warn(`humanScroll | \u5728 ${maxSteps} \u6B65\u540E\u65E0\u6CD5\u786E\u4FDD\u53EF\u89C1\u6027`);
|
|
1057
985
|
return { element, didScroll };
|
|
1058
986
|
} catch (error) {
|
|
1059
|
-
|
|
987
|
+
logger4.fail("humanScroll", error);
|
|
1060
988
|
throw error;
|
|
1061
989
|
}
|
|
1062
990
|
},
|
|
@@ -1074,23 +1002,23 @@ var Humanize = {
|
|
|
1074
1002
|
const cursor = $GetCursor(page);
|
|
1075
1003
|
const { reactionDelay = 250, throwOnMissing = true, scrollIfNeeded = true, restore = false } = options;
|
|
1076
1004
|
const targetDesc = target == null ? "Current Position" : typeof target === "string" ? target : "ElementHandle";
|
|
1077
|
-
|
|
1005
|
+
logger4.start("humanClick", `target=${targetDesc}`);
|
|
1078
1006
|
const restoreOnce = async () => {
|
|
1079
1007
|
if (restoreOnce.restored) return;
|
|
1080
1008
|
restoreOnce.restored = true;
|
|
1081
1009
|
if (typeof restoreOnce.do !== "function") return;
|
|
1082
1010
|
try {
|
|
1083
|
-
await (0,
|
|
1011
|
+
await (0, import_delay.default)(this.jitterMs(1e3));
|
|
1084
1012
|
await restoreOnce.do();
|
|
1085
1013
|
} catch (restoreError) {
|
|
1086
|
-
|
|
1014
|
+
logger4.warn(`humanClick: \u6062\u590D\u6EDA\u52A8\u4F4D\u7F6E\u5931\u8D25: ${restoreError.message}`);
|
|
1087
1015
|
}
|
|
1088
1016
|
};
|
|
1089
1017
|
try {
|
|
1090
1018
|
if (target == null) {
|
|
1091
|
-
await (0,
|
|
1019
|
+
await (0, import_delay.default)(this.jitterMs(reactionDelay, 0.4));
|
|
1092
1020
|
await cursor.actions.click();
|
|
1093
|
-
|
|
1021
|
+
logger4.success("humanClick", "Clicked current position");
|
|
1094
1022
|
return true;
|
|
1095
1023
|
}
|
|
1096
1024
|
let element;
|
|
@@ -1100,7 +1028,7 @@ var Humanize = {
|
|
|
1100
1028
|
if (throwOnMissing) {
|
|
1101
1029
|
throw new Error(`\u627E\u4E0D\u5230\u5143\u7D20 ${target}`);
|
|
1102
1030
|
}
|
|
1103
|
-
|
|
1031
|
+
logger4.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${target}`);
|
|
1104
1032
|
return false;
|
|
1105
1033
|
}
|
|
1106
1034
|
} else {
|
|
@@ -1116,20 +1044,20 @@ var Humanize = {
|
|
|
1116
1044
|
if (throwOnMissing) {
|
|
1117
1045
|
throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5143\u7D20\u4F4D\u7F6E");
|
|
1118
1046
|
}
|
|
1119
|
-
|
|
1047
|
+
logger4.warn("humanClick: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E\uFF0C\u8DF3\u8FC7\u70B9\u51FB");
|
|
1120
1048
|
return false;
|
|
1121
1049
|
}
|
|
1122
1050
|
const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.3;
|
|
1123
1051
|
const y = box.y + box.height / 2 + (Math.random() - 0.5) * box.height * 0.3;
|
|
1124
1052
|
await cursor.actions.move({ x, y });
|
|
1125
|
-
await (0,
|
|
1053
|
+
await (0, import_delay.default)(this.jitterMs(reactionDelay, 0.4));
|
|
1126
1054
|
await cursor.actions.click();
|
|
1127
1055
|
await restoreOnce();
|
|
1128
|
-
|
|
1056
|
+
logger4.success("humanClick");
|
|
1129
1057
|
return true;
|
|
1130
1058
|
} catch (error) {
|
|
1131
1059
|
await restoreOnce();
|
|
1132
|
-
|
|
1060
|
+
logger4.fail("humanClick", error);
|
|
1133
1061
|
throw error;
|
|
1134
1062
|
}
|
|
1135
1063
|
},
|
|
@@ -1140,9 +1068,9 @@ var Humanize = {
|
|
|
1140
1068
|
*/
|
|
1141
1069
|
async randomSleep(baseMs, jitterPercent = 0.3) {
|
|
1142
1070
|
const ms = this.jitterMs(baseMs, jitterPercent);
|
|
1143
|
-
|
|
1144
|
-
await (0,
|
|
1145
|
-
|
|
1071
|
+
logger4.start("randomSleep", `base=${baseMs}, actual=${ms}ms`);
|
|
1072
|
+
await (0, import_delay.default)(ms);
|
|
1073
|
+
logger4.success("randomSleep");
|
|
1146
1074
|
},
|
|
1147
1075
|
/**
|
|
1148
1076
|
* 模拟人类"注视"或"阅读"行为:鼠标在页面上随机微动
|
|
@@ -1152,16 +1080,16 @@ var Humanize = {
|
|
|
1152
1080
|
async simulateGaze(page, baseDurationMs = 2500) {
|
|
1153
1081
|
const cursor = $GetCursor(page);
|
|
1154
1082
|
const durationMs = this.jitterMs(baseDurationMs, 0.4);
|
|
1155
|
-
|
|
1083
|
+
logger4.start("simulateGaze", `duration=${durationMs}ms`);
|
|
1156
1084
|
const startTime = Date.now();
|
|
1157
1085
|
const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };
|
|
1158
1086
|
while (Date.now() - startTime < durationMs) {
|
|
1159
1087
|
const x = 100 + Math.random() * (viewportSize.width - 200);
|
|
1160
1088
|
const y = 100 + Math.random() * (viewportSize.height - 200);
|
|
1161
1089
|
await cursor.actions.move({ x, y });
|
|
1162
|
-
await (0,
|
|
1090
|
+
await (0, import_delay.default)(this.jitterMs(600, 0.5));
|
|
1163
1091
|
}
|
|
1164
|
-
|
|
1092
|
+
logger4.success("simulateGaze");
|
|
1165
1093
|
},
|
|
1166
1094
|
/**
|
|
1167
1095
|
* 人类化输入 - 带节奏变化(快-慢-停顿-偶尔加速)
|
|
@@ -1174,7 +1102,7 @@ var Humanize = {
|
|
|
1174
1102
|
* @param {number} [options.pauseBase=800] - 停顿时长基础值 (ms),实际 ±50% 抖动
|
|
1175
1103
|
*/
|
|
1176
1104
|
async humanType(page, selector, text, options = {}) {
|
|
1177
|
-
|
|
1105
|
+
logger4.start("humanType", `selector=${selector}, textLen=${text.length}`);
|
|
1178
1106
|
const {
|
|
1179
1107
|
baseDelay = 180,
|
|
1180
1108
|
pauseProbability = 0.08,
|
|
@@ -1183,7 +1111,7 @@ var Humanize = {
|
|
|
1183
1111
|
try {
|
|
1184
1112
|
const locator = page.locator(selector);
|
|
1185
1113
|
await Humanize.humanClick(page, locator);
|
|
1186
|
-
await (0,
|
|
1114
|
+
await (0, import_delay.default)(this.jitterMs(200, 0.4));
|
|
1187
1115
|
for (let i = 0; i < text.length; i++) {
|
|
1188
1116
|
const char = text[i];
|
|
1189
1117
|
let charDelay;
|
|
@@ -1195,16 +1123,16 @@ var Humanize = {
|
|
|
1195
1123
|
charDelay = this.jitterMs(baseDelay, 0.4);
|
|
1196
1124
|
}
|
|
1197
1125
|
await page.keyboard.type(char);
|
|
1198
|
-
await (0,
|
|
1126
|
+
await (0, import_delay.default)(charDelay);
|
|
1199
1127
|
if (Math.random() < pauseProbability && i < text.length - 1) {
|
|
1200
1128
|
const pauseTime = this.jitterMs(pauseBase, 0.5);
|
|
1201
|
-
|
|
1202
|
-
await (0,
|
|
1129
|
+
logger4.debug(`\u505C\u987F ${pauseTime}ms...`);
|
|
1130
|
+
await (0, import_delay.default)(pauseTime);
|
|
1203
1131
|
}
|
|
1204
1132
|
}
|
|
1205
|
-
|
|
1133
|
+
logger4.success("humanType");
|
|
1206
1134
|
} catch (error) {
|
|
1207
|
-
|
|
1135
|
+
logger4.fail("humanType", error);
|
|
1208
1136
|
throw error;
|
|
1209
1137
|
}
|
|
1210
1138
|
},
|
|
@@ -1214,22 +1142,22 @@ var Humanize = {
|
|
|
1214
1142
|
* @param {string} selector - 输入框选择器
|
|
1215
1143
|
*/
|
|
1216
1144
|
async humanClear(page, selector) {
|
|
1217
|
-
|
|
1145
|
+
logger4.start("humanClear", `selector=${selector}`);
|
|
1218
1146
|
try {
|
|
1219
1147
|
const locator = page.locator(selector);
|
|
1220
1148
|
await locator.click();
|
|
1221
|
-
await (0,
|
|
1149
|
+
await (0, import_delay.default)(this.jitterMs(200, 0.4));
|
|
1222
1150
|
const currentValue = await locator.inputValue();
|
|
1223
1151
|
if (!currentValue || currentValue.length === 0) {
|
|
1224
|
-
|
|
1152
|
+
logger4.success("humanClear", "already empty");
|
|
1225
1153
|
return;
|
|
1226
1154
|
}
|
|
1227
1155
|
await page.keyboard.press("Meta+A");
|
|
1228
|
-
await (0,
|
|
1156
|
+
await (0, import_delay.default)(this.jitterMs(100, 0.4));
|
|
1229
1157
|
await page.keyboard.press("Backspace");
|
|
1230
|
-
|
|
1158
|
+
logger4.success("humanClear");
|
|
1231
1159
|
} catch (error) {
|
|
1232
|
-
|
|
1160
|
+
logger4.fail("humanClear", error);
|
|
1233
1161
|
throw error;
|
|
1234
1162
|
}
|
|
1235
1163
|
},
|
|
@@ -1241,7 +1169,7 @@ var Humanize = {
|
|
|
1241
1169
|
async warmUpBrowsing(page, baseDuration = 3500) {
|
|
1242
1170
|
const cursor = $GetCursor(page);
|
|
1243
1171
|
const durationMs = this.jitterMs(baseDuration, 0.4);
|
|
1244
|
-
|
|
1172
|
+
logger4.start("warmUpBrowsing", `duration=${durationMs}ms`);
|
|
1245
1173
|
const startTime = Date.now();
|
|
1246
1174
|
const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };
|
|
1247
1175
|
try {
|
|
@@ -1251,18 +1179,18 @@ var Humanize = {
|
|
|
1251
1179
|
const x = 100 + Math.random() * (viewportSize.width - 200);
|
|
1252
1180
|
const y = 100 + Math.random() * (viewportSize.height - 200);
|
|
1253
1181
|
await cursor.actions.move({ x, y });
|
|
1254
|
-
await (0,
|
|
1182
|
+
await (0, import_delay.default)(this.jitterMs(350, 0.4));
|
|
1255
1183
|
} else if (action < 0.7) {
|
|
1256
1184
|
const scrollY = (Math.random() - 0.5) * 200;
|
|
1257
1185
|
await page.mouse.wheel(0, scrollY);
|
|
1258
|
-
await (0,
|
|
1186
|
+
await (0, import_delay.default)(this.jitterMs(500, 0.4));
|
|
1259
1187
|
} else {
|
|
1260
|
-
await (0,
|
|
1188
|
+
await (0, import_delay.default)(this.jitterMs(800, 0.5));
|
|
1261
1189
|
}
|
|
1262
1190
|
}
|
|
1263
|
-
|
|
1191
|
+
logger4.success("warmUpBrowsing");
|
|
1264
1192
|
} catch (error) {
|
|
1265
|
-
|
|
1193
|
+
logger4.fail("warmUpBrowsing", error);
|
|
1266
1194
|
throw error;
|
|
1267
1195
|
}
|
|
1268
1196
|
},
|
|
@@ -1276,7 +1204,7 @@ var Humanize = {
|
|
|
1276
1204
|
async naturalScroll(page, direction = "down", distance = 300, baseSteps = 5) {
|
|
1277
1205
|
const steps = Math.max(3, baseSteps + Math.floor(Math.random() * 3) - 1);
|
|
1278
1206
|
const actualDistance = this.jitterMs(distance, 0.15);
|
|
1279
|
-
|
|
1207
|
+
logger4.start("naturalScroll", `dir=${direction}, dist=${actualDistance}, steps=${steps}`);
|
|
1280
1208
|
const sign = direction === "down" ? 1 : -1;
|
|
1281
1209
|
const stepDistance = actualDistance / steps;
|
|
1282
1210
|
try {
|
|
@@ -1286,11 +1214,11 @@ var Humanize = {
|
|
|
1286
1214
|
const scrollAmount = stepDistance * factor * sign * jitter;
|
|
1287
1215
|
await page.mouse.wheel(0, scrollAmount);
|
|
1288
1216
|
const baseDelay = 60 + i * 25;
|
|
1289
|
-
await (0,
|
|
1217
|
+
await (0, import_delay.default)(this.jitterMs(baseDelay, 0.3));
|
|
1290
1218
|
}
|
|
1291
|
-
|
|
1219
|
+
logger4.success("naturalScroll");
|
|
1292
1220
|
} catch (error) {
|
|
1293
|
-
|
|
1221
|
+
logger4.fail("naturalScroll", error);
|
|
1294
1222
|
throw error;
|
|
1295
1223
|
}
|
|
1296
1224
|
}
|
|
@@ -1298,7 +1226,7 @@ var Humanize = {
|
|
|
1298
1226
|
|
|
1299
1227
|
// src/launch.js
|
|
1300
1228
|
var import_picomatch = __toESM(require("picomatch"), 1);
|
|
1301
|
-
var
|
|
1229
|
+
var logger5 = createInternalLogger("Launch");
|
|
1302
1230
|
var buildByPassDomainRule = (rawPattern) => {
|
|
1303
1231
|
const pattern = String(rawPattern || "").trim().toLowerCase();
|
|
1304
1232
|
if (!pattern) return null;
|
|
@@ -1362,15 +1290,15 @@ var Launch = {
|
|
|
1362
1290
|
}
|
|
1363
1291
|
const enableByPassLogger = Boolean(logOptions && logOptions.enable);
|
|
1364
1292
|
if (enableByPassLogger && launchProxy) {
|
|
1365
|
-
|
|
1293
|
+
logger5.info(
|
|
1366
1294
|
`[\u4EE3\u7406\u5DF2\u542F\u7528] \u4EE3\u7406\u670D\u52A1=${launchProxy.server} \u76F4\u8FDE\u57DF\u540D=${(byPassDomains || []).join(",")}`
|
|
1367
1295
|
);
|
|
1368
1296
|
} else if (enableByPassLogger && enableProxy && !launchProxy) {
|
|
1369
|
-
|
|
1297
|
+
logger5.info(
|
|
1370
1298
|
`[\u4EE3\u7406\u672A\u542F\u7528] enable_proxy=true \u4F46 proxy_url \u4E3A\u7A7A`
|
|
1371
1299
|
);
|
|
1372
1300
|
} else if (enableByPassLogger && !enableProxy && proxyUrl) {
|
|
1373
|
-
|
|
1301
|
+
logger5.info(
|
|
1374
1302
|
`[\u4EE3\u7406\u672A\u542F\u7528] enable_proxy=false \u4E14 proxy_url \u5DF2\u914D\u7F6E`
|
|
1375
1303
|
);
|
|
1376
1304
|
}
|
|
@@ -1392,7 +1320,7 @@ var Launch = {
|
|
|
1392
1320
|
}
|
|
1393
1321
|
const matchedRule = byPassRules.find((rule) => rule.test(hostname));
|
|
1394
1322
|
if (!matchedRule) return;
|
|
1395
|
-
|
|
1323
|
+
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}`);
|
|
1396
1324
|
};
|
|
1397
1325
|
page.on("request", requestHandler);
|
|
1398
1326
|
return recommendedGotoOptions;
|
|
@@ -1411,7 +1339,7 @@ var Launch = {
|
|
|
1411
1339
|
// src/live-view.js
|
|
1412
1340
|
var import_express = __toESM(require("express"), 1);
|
|
1413
1341
|
var import_apify = require("apify");
|
|
1414
|
-
var
|
|
1342
|
+
var logger6 = createInternalLogger("LiveView");
|
|
1415
1343
|
async function startLiveViewServer(liveViewKey) {
|
|
1416
1344
|
const app = (0, import_express.default)();
|
|
1417
1345
|
app.get("/", async (req, res) => {
|
|
@@ -1436,13 +1364,13 @@ async function startLiveViewServer(liveViewKey) {
|
|
|
1436
1364
|
</html>
|
|
1437
1365
|
`);
|
|
1438
1366
|
} catch (error) {
|
|
1439
|
-
|
|
1367
|
+
logger6.fail("Live View Server", error);
|
|
1440
1368
|
res.status(500).send(`\u65E0\u6CD5\u52A0\u8F7D\u5C4F\u5E55\u622A\u56FE: ${error.message}`);
|
|
1441
1369
|
}
|
|
1442
1370
|
});
|
|
1443
1371
|
const port = process.env.APIFY_CONTAINER_PORT || 4321;
|
|
1444
1372
|
app.listen(port, () => {
|
|
1445
|
-
|
|
1373
|
+
logger6.success("startLiveViewServer", `\u76D1\u542C\u7AEF\u53E3 ${port}`);
|
|
1446
1374
|
});
|
|
1447
1375
|
}
|
|
1448
1376
|
async function takeLiveScreenshot(liveViewKey, page, logMessage) {
|
|
@@ -1450,10 +1378,10 @@ async function takeLiveScreenshot(liveViewKey, page, logMessage) {
|
|
|
1450
1378
|
const buffer = await page.screenshot({ type: "png" });
|
|
1451
1379
|
await import_apify.Actor.setValue(liveViewKey, buffer, { contentType: "image/png" });
|
|
1452
1380
|
if (logMessage) {
|
|
1453
|
-
|
|
1381
|
+
logger6.info(`(\u622A\u56FE): ${logMessage}`);
|
|
1454
1382
|
}
|
|
1455
1383
|
} catch (e) {
|
|
1456
|
-
|
|
1384
|
+
logger6.warn(`\u65E0\u6CD5\u6355\u83B7 Live View \u5C4F\u5E55\u622A\u56FE: ${e.message}`);
|
|
1457
1385
|
}
|
|
1458
1386
|
}
|
|
1459
1387
|
var useLiveView = (liveViewKey = PresetOfLiveViewKey) => {
|
|
@@ -1472,7 +1400,7 @@ var LiveView = {
|
|
|
1472
1400
|
|
|
1473
1401
|
// src/captcha-monitor.js
|
|
1474
1402
|
var import_uuid = require("uuid");
|
|
1475
|
-
var
|
|
1403
|
+
var logger7 = createInternalLogger("Captcha");
|
|
1476
1404
|
function useCaptchaMonitor(page, options) {
|
|
1477
1405
|
const { domSelector, urlPattern, onDetected } = options;
|
|
1478
1406
|
if (!domSelector && !urlPattern) {
|
|
@@ -1545,7 +1473,7 @@ function useCaptchaMonitor(page, options) {
|
|
|
1545
1473
|
};
|
|
1546
1474
|
})();
|
|
1547
1475
|
}, { selector: domSelector, callbackName: exposedFunctionName, cleanerName });
|
|
1548
|
-
|
|
1476
|
+
logger7.success("useCaptchaMonitor", `DOM \u76D1\u63A7\u5DF2\u542F\u7528: ${domSelector}`);
|
|
1549
1477
|
cleanupFns.push(async () => {
|
|
1550
1478
|
try {
|
|
1551
1479
|
await page.evaluate((name) => {
|
|
@@ -1568,14 +1496,14 @@ function useCaptchaMonitor(page, options) {
|
|
|
1568
1496
|
}
|
|
1569
1497
|
};
|
|
1570
1498
|
page.on("framenavigated", frameHandler);
|
|
1571
|
-
|
|
1499
|
+
logger7.success("useCaptchaMonitor", `URL \u76D1\u63A7\u5DF2\u542F\u7528: ${urlPattern}`);
|
|
1572
1500
|
cleanupFns.push(async () => {
|
|
1573
1501
|
page.off("framenavigated", frameHandler);
|
|
1574
1502
|
});
|
|
1575
1503
|
}
|
|
1576
1504
|
return {
|
|
1577
1505
|
stop: async () => {
|
|
1578
|
-
|
|
1506
|
+
logger7.info("useCaptchaMonitor", "\u6B63\u5728\u505C\u6B62\u76D1\u63A7...");
|
|
1579
1507
|
for (const fn of cleanupFns) {
|
|
1580
1508
|
await fn();
|
|
1581
1509
|
}
|
|
@@ -1590,7 +1518,7 @@ var Captcha = {
|
|
|
1590
1518
|
// src/sse.js
|
|
1591
1519
|
var import_https = __toESM(require("https"), 1);
|
|
1592
1520
|
var import_url = require("url");
|
|
1593
|
-
var
|
|
1521
|
+
var logger8 = createInternalLogger("Sse");
|
|
1594
1522
|
var Sse = {
|
|
1595
1523
|
/**
|
|
1596
1524
|
* 解析 SSE 流文本
|
|
@@ -1609,11 +1537,11 @@ var Sse = {
|
|
|
1609
1537
|
events.push(JSON.parse(jsonContent));
|
|
1610
1538
|
}
|
|
1611
1539
|
} catch (e) {
|
|
1612
|
-
|
|
1540
|
+
logger8.debug("parseSseStream", `JSON \u89E3\u6790\u5931\u8D25: ${e.message}, line: ${line.substring(0, 100)}...`);
|
|
1613
1541
|
}
|
|
1614
1542
|
}
|
|
1615
1543
|
}
|
|
1616
|
-
|
|
1544
|
+
logger8.success("parseSseStream", `\u89E3\u6790\u5B8C\u6210, events \u6570\u91CF: ${events.length}`);
|
|
1617
1545
|
return events;
|
|
1618
1546
|
},
|
|
1619
1547
|
/**
|
|
@@ -1663,7 +1591,7 @@ var Sse = {
|
|
|
1663
1591
|
if (!autoUnroute) return;
|
|
1664
1592
|
if (unrouteRequested) return;
|
|
1665
1593
|
unrouteRequested = true;
|
|
1666
|
-
|
|
1594
|
+
logger8.info("[MITM] autoUnroute: \u53D6\u6D88\u540E\u7EED\u62E6\u622A");
|
|
1667
1595
|
page.unroute(urlPattern, routeHandler).catch(() => {
|
|
1668
1596
|
});
|
|
1669
1597
|
};
|
|
@@ -1683,19 +1611,19 @@ var Sse = {
|
|
|
1683
1611
|
};
|
|
1684
1612
|
const routeHandler = async (route) => {
|
|
1685
1613
|
if (firstMatchOnly && hasMatchedOnce) {
|
|
1686
|
-
|
|
1614
|
+
logger8.info(`[MITM] firstMatchOnly: \u653E\u884C\u540E\u7EED\u8BF7\u6C42: ${route.request().url()}`);
|
|
1687
1615
|
route.continue().catch(() => {
|
|
1688
1616
|
});
|
|
1689
1617
|
return;
|
|
1690
1618
|
}
|
|
1691
1619
|
if (firstMatchOnly && !hasMatchedOnce) {
|
|
1692
1620
|
hasMatchedOnce = true;
|
|
1693
|
-
|
|
1621
|
+
logger8.info("[MITM] firstMatchOnly: \u547D\u4E2D\u9996\u4E2A\u8BF7\u6C42\uFF0C\u53D6\u6D88\u540E\u7EED\u62E6\u622A");
|
|
1694
1622
|
page.unroute(urlPattern, routeHandler).catch(() => {
|
|
1695
1623
|
});
|
|
1696
1624
|
}
|
|
1697
1625
|
const request = route.request();
|
|
1698
|
-
|
|
1626
|
+
logger8.info(`[MITM] \u5DF2\u62E6\u622A\u8BF7\u6C42: ${request.url()}`);
|
|
1699
1627
|
try {
|
|
1700
1628
|
const headers = await request.allHeaders();
|
|
1701
1629
|
const postData = request.postData();
|
|
@@ -1720,7 +1648,7 @@ var Sse = {
|
|
|
1720
1648
|
clearTimeout(initialTimer);
|
|
1721
1649
|
initialTimer = null;
|
|
1722
1650
|
}
|
|
1723
|
-
|
|
1651
|
+
logger8.debug("[Intercept] \u5DF2\u63A5\u6536\u521D\u59CB\u6570\u636E");
|
|
1724
1652
|
}
|
|
1725
1653
|
chunks.push(chunk);
|
|
1726
1654
|
const textChunk = chunk.toString("utf-8");
|
|
@@ -1729,18 +1657,18 @@ var Sse = {
|
|
|
1729
1657
|
try {
|
|
1730
1658
|
onData(textChunk, safeResolve, accumulatedText);
|
|
1731
1659
|
} catch (e) {
|
|
1732
|
-
|
|
1660
|
+
logger8.fail(`onData \u9519\u8BEF`, e);
|
|
1733
1661
|
}
|
|
1734
1662
|
}
|
|
1735
1663
|
});
|
|
1736
1664
|
res.on("end", () => {
|
|
1737
|
-
|
|
1665
|
+
logger8.info("[MITM] \u4E0A\u6E38\u54CD\u5E94\u7ED3\u675F");
|
|
1738
1666
|
clearAllTimers();
|
|
1739
1667
|
if (onEnd) {
|
|
1740
1668
|
try {
|
|
1741
1669
|
onEnd(accumulatedText, safeResolve);
|
|
1742
1670
|
} catch (e) {
|
|
1743
|
-
|
|
1671
|
+
logger8.fail(`onEnd \u9519\u8BEF`, e);
|
|
1744
1672
|
}
|
|
1745
1673
|
} else if (!onData) {
|
|
1746
1674
|
safeResolve(accumulatedText);
|
|
@@ -1821,7 +1749,7 @@ var Sse = {
|
|
|
1821
1749
|
|
|
1822
1750
|
// src/mutation.js
|
|
1823
1751
|
var import_uuid2 = require("uuid");
|
|
1824
|
-
var
|
|
1752
|
+
var logger9 = createInternalLogger("Mutation");
|
|
1825
1753
|
var MUTATION_MONITOR_MODE = Object.freeze({
|
|
1826
1754
|
Added: "added",
|
|
1827
1755
|
Changed: "changed",
|
|
@@ -1854,14 +1782,14 @@ var Mutation = {
|
|
|
1854
1782
|
const stableTime = options.stableTime ?? 5 * 1e3;
|
|
1855
1783
|
const timeout = options.timeout ?? 120 * 1e3;
|
|
1856
1784
|
const onMutation = options.onMutation;
|
|
1857
|
-
|
|
1785
|
+
logger9.start("waitForStable", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, \u7A33\u5B9A\u65F6\u95F4=${stableTime}ms`);
|
|
1858
1786
|
if (initialTimeout > 0) {
|
|
1859
1787
|
const selectorQuery = selectorList.join(",");
|
|
1860
1788
|
try {
|
|
1861
1789
|
await page.waitForSelector(selectorQuery, { timeout: initialTimeout });
|
|
1862
|
-
|
|
1790
|
+
logger9.info(`waitForStable \u5DF2\u68C0\u6D4B\u5230\u5143\u7D20: ${selectorQuery}`);
|
|
1863
1791
|
} catch (e) {
|
|
1864
|
-
|
|
1792
|
+
logger9.warning(`waitForStable \u521D\u59CB\u7B49\u5F85\u8D85\u65F6 (${initialTimeout}ms): ${selectorQuery}`);
|
|
1865
1793
|
throw e;
|
|
1866
1794
|
}
|
|
1867
1795
|
}
|
|
@@ -1877,7 +1805,7 @@ var Mutation = {
|
|
|
1877
1805
|
return "__CONTINUE__";
|
|
1878
1806
|
}
|
|
1879
1807
|
});
|
|
1880
|
-
|
|
1808
|
+
logger9.info("waitForStable \u5DF2\u542F\u7528 onMutation \u56DE\u8C03");
|
|
1881
1809
|
} catch (e) {
|
|
1882
1810
|
}
|
|
1883
1811
|
}
|
|
@@ -1992,9 +1920,9 @@ var Mutation = {
|
|
|
1992
1920
|
{ selectorList, stableTime, timeout, callbackName, hasCallback: !!onMutation }
|
|
1993
1921
|
);
|
|
1994
1922
|
if (result.mutationCount === 0 && result.stableTime === 0) {
|
|
1995
|
-
|
|
1923
|
+
logger9.warning("waitForStable \u672A\u627E\u5230\u53EF\u76D1\u63A7\u7684\u5143\u7D20");
|
|
1996
1924
|
}
|
|
1997
|
-
|
|
1925
|
+
logger9.success("waitForStable", `DOM \u7A33\u5B9A, \u603B\u5171 ${result.mutationCount} \u6B21\u53D8\u5316${result.wasPaused ? ", \u66FE\u6682\u505C\u8BA1\u65F6" : ""}`);
|
|
1998
1926
|
return result;
|
|
1999
1927
|
},
|
|
2000
1928
|
/**
|
|
@@ -2014,7 +1942,7 @@ var Mutation = {
|
|
|
2014
1942
|
const onMutation = options.onMutation;
|
|
2015
1943
|
const rawMode = String(options.mode || MUTATION_MONITOR_MODE.Added).toLowerCase();
|
|
2016
1944
|
const mode = [MUTATION_MONITOR_MODE.Added, MUTATION_MONITOR_MODE.Changed, MUTATION_MONITOR_MODE.All].includes(rawMode) ? rawMode : MUTATION_MONITOR_MODE.Added;
|
|
2017
|
-
|
|
1945
|
+
logger9.start("useMonitor", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, mode=${mode}`);
|
|
2018
1946
|
const monitorKey = generateKey("pk_mon");
|
|
2019
1947
|
const callbackName = generateKey("pk_mon_cb");
|
|
2020
1948
|
const cleanerName = generateKey("pk_mon_clean");
|
|
@@ -2157,7 +2085,7 @@ var Mutation = {
|
|
|
2157
2085
|
return total;
|
|
2158
2086
|
};
|
|
2159
2087
|
}, { selectorList, monitorKey, callbackName, cleanerName, hasCallback: !!onMutation, mode });
|
|
2160
|
-
|
|
2088
|
+
logger9.success("useMonitor", "\u76D1\u63A7\u5668\u5DF2\u542F\u52A8");
|
|
2161
2089
|
return {
|
|
2162
2090
|
stop: async () => {
|
|
2163
2091
|
let totalMutations = 0;
|
|
@@ -2170,7 +2098,7 @@ var Mutation = {
|
|
|
2170
2098
|
}, cleanerName);
|
|
2171
2099
|
} catch (e) {
|
|
2172
2100
|
}
|
|
2173
|
-
|
|
2101
|
+
logger9.success("useMonitor.stop", `\u76D1\u63A7\u5DF2\u505C\u6B62, \u5171 ${totalMutations} \u6B21\u53D8\u5316`);
|
|
2174
2102
|
return { totalMutations };
|
|
2175
2103
|
}
|
|
2176
2104
|
};
|
|
@@ -3039,7 +2967,7 @@ var createTemplateLogger = (baseLogger = createBaseLogger()) => {
|
|
|
3039
2967
|
};
|
|
3040
2968
|
var getDefaultBaseLogger = () => createBaseLogger("");
|
|
3041
2969
|
var Logger = {
|
|
3042
|
-
setLogger: (
|
|
2970
|
+
setLogger: (logger11) => setDefaultLogger(logger11),
|
|
3043
2971
|
info: (message) => getDefaultBaseLogger().info(message),
|
|
3044
2972
|
success: (message) => getDefaultBaseLogger().success(message),
|
|
3045
2973
|
warning: (message) => getDefaultBaseLogger().warning(message),
|
|
@@ -3047,20 +2975,18 @@ var Logger = {
|
|
|
3047
2975
|
error: (message) => getDefaultBaseLogger().error(message),
|
|
3048
2976
|
debug: (message) => getDefaultBaseLogger().debug(message),
|
|
3049
2977
|
start: (message) => getDefaultBaseLogger().start(message),
|
|
3050
|
-
useTemplate: (
|
|
3051
|
-
if (
|
|
2978
|
+
useTemplate: (logger11) => {
|
|
2979
|
+
if (logger11) return createTemplateLogger(createBaseLogger("", logger11));
|
|
3052
2980
|
return createTemplateLogger();
|
|
3053
2981
|
}
|
|
3054
2982
|
};
|
|
3055
2983
|
|
|
3056
2984
|
// src/share.js
|
|
3057
|
-
var
|
|
3058
|
-
var
|
|
2985
|
+
var import_delay2 = __toESM(require("delay"), 1);
|
|
2986
|
+
var logger10 = createInternalLogger("Share");
|
|
3059
2987
|
var DEFAULT_TIMEOUT_MS = 50 * 1e3;
|
|
3060
2988
|
var DEFAULT_PAYLOAD_SNAPSHOT_MAX_LEN = 500;
|
|
3061
2989
|
var DEFAULT_POLL_INTERVAL_MS = 120;
|
|
3062
|
-
var DEFAULT_MOBILE_SCREENSHOT_WIDTH = 414;
|
|
3063
|
-
var MOBILE_VIEWPORT_MAX_WIDTH = 480;
|
|
3064
2990
|
var normalizePrefix = (value) => value == null ? void 0 : String(value).trim();
|
|
3065
2991
|
var toSnapshot = (value, maxLen) => {
|
|
3066
2992
|
const text = String(value || "");
|
|
@@ -3177,7 +3103,7 @@ var createDomShareMonitor = async (page, options = {}) => {
|
|
|
3177
3103
|
const onMatch = typeof options.onMatch === "function" ? options.onMatch : null;
|
|
3178
3104
|
const onTelemetry = typeof options.onTelemetry === "function" ? options.onTelemetry : null;
|
|
3179
3105
|
let matched = false;
|
|
3180
|
-
|
|
3106
|
+
logger10.info(`DOM \u76D1\u542C\u51C6\u5907\u6302\u8F7D: selectors=${toJsonInline(selectors, 120)}, mode=${mode}`);
|
|
3181
3107
|
const monitor = await Mutation.useMonitor(page, selectors, {
|
|
3182
3108
|
mode,
|
|
3183
3109
|
onMutation: (context = {}) => {
|
|
@@ -3195,12 +3121,12 @@ ${text}`;
|
|
|
3195
3121
|
});
|
|
3196
3122
|
}
|
|
3197
3123
|
if (mutationCount <= 5 || mutationCount % 50 === 0) {
|
|
3198
|
-
|
|
3124
|
+
logger10.info(`DOM \u53D8\u5316\u5DF2\u6355\u83B7: mutationCount=${mutationCount}, mutationNodes=${mutationNodes.length}`);
|
|
3199
3125
|
}
|
|
3200
3126
|
const [candidate] = Utils.parseLinks(rawDom, { prefix }) || [];
|
|
3201
3127
|
if (!candidate) return;
|
|
3202
3128
|
matched = true;
|
|
3203
|
-
|
|
3129
|
+
logger10.success("captureLink.domHit", `DOM \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: mutationCount=${mutationCount}, link=${candidate}`);
|
|
3204
3130
|
if (onMatch) {
|
|
3205
3131
|
onMatch({
|
|
3206
3132
|
link: candidate,
|
|
@@ -3216,7 +3142,7 @@ ${text}`;
|
|
|
3216
3142
|
return {
|
|
3217
3143
|
stop: async () => {
|
|
3218
3144
|
const result = await monitor.stop();
|
|
3219
|
-
|
|
3145
|
+
logger10.info(`DOM \u76D1\u542C\u5DF2\u505C\u6B62: totalMutations=${result?.totalMutations || 0}`);
|
|
3220
3146
|
return result;
|
|
3221
3147
|
}
|
|
3222
3148
|
};
|
|
@@ -3256,8 +3182,8 @@ var Share = {
|
|
|
3256
3182
|
if (share.mode === "response" && apiMatchers.length === 0) {
|
|
3257
3183
|
throw new Error("Share.captureLink requires share.xurl[0] api matcher when mode=response");
|
|
3258
3184
|
}
|
|
3259
|
-
|
|
3260
|
-
|
|
3185
|
+
logger10.start("captureLink", `mode=${share.mode}, timeoutMs=${timeoutMs}, prefix=${share.prefix}`);
|
|
3186
|
+
logger10.info(`captureLink \u914D\u7F6E: xurl=${toJsonInline(share.xurl)}, domMode=${domMode}, domSelectors=${toJsonInline(domSelectors, 120)}`);
|
|
3261
3187
|
const stats = {
|
|
3262
3188
|
actionTimedOut: false,
|
|
3263
3189
|
domMutationCount: 0,
|
|
@@ -3282,7 +3208,7 @@ var Share = {
|
|
|
3282
3208
|
link: validated,
|
|
3283
3209
|
payloadText: String(payloadText || "")
|
|
3284
3210
|
};
|
|
3285
|
-
|
|
3211
|
+
logger10.info(`\u5019\u9009\u94FE\u63A5\u5DF2\u786E\u8BA4: source=${source}, link=${validated}`);
|
|
3286
3212
|
return true;
|
|
3287
3213
|
};
|
|
3288
3214
|
const resolveResponseCandidate = (responseText) => {
|
|
@@ -3317,7 +3243,7 @@ var Share = {
|
|
|
3317
3243
|
try {
|
|
3318
3244
|
await monitor.stop();
|
|
3319
3245
|
} catch (error) {
|
|
3320
|
-
|
|
3246
|
+
logger10.warning(`\u505C\u6B62 DOM \u76D1\u542C\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
|
|
3321
3247
|
}
|
|
3322
3248
|
};
|
|
3323
3249
|
const onResponse = async (response) => {
|
|
@@ -3330,29 +3256,29 @@ var Share = {
|
|
|
3330
3256
|
stats.responseSampleUrls.push(url);
|
|
3331
3257
|
}
|
|
3332
3258
|
if (stats.responseObserved <= 5) {
|
|
3333
|
-
|
|
3259
|
+
logger10.info(`\u63A5\u53E3\u54CD\u5E94\u91C7\u6837(${stats.responseObserved}): ${url}`);
|
|
3334
3260
|
}
|
|
3335
3261
|
if (!apiMatchers.some((matcher) => url.includes(matcher))) return;
|
|
3336
3262
|
stats.responseMatched += 1;
|
|
3337
3263
|
stats.lastMatchedUrl = url;
|
|
3338
|
-
|
|
3264
|
+
logger10.info(`\u63A5\u53E3\u547D\u4E2D\u5339\u914D(${stats.responseMatched}): ${url}`);
|
|
3339
3265
|
const text = await response.text();
|
|
3340
3266
|
const hit = resolveResponseCandidate(text);
|
|
3341
3267
|
if (!hit?.link) {
|
|
3342
3268
|
if (stats.responseMatched <= 3) {
|
|
3343
|
-
|
|
3269
|
+
logger10.info(`\u63A5\u53E3\u89E3\u6790\u5B8C\u6210\u4F46\u672A\u63D0\u53D6\u5230\u5206\u4EAB\u94FE\u63A5: payloadSize=${text.length}`);
|
|
3344
3270
|
}
|
|
3345
3271
|
return;
|
|
3346
3272
|
}
|
|
3347
3273
|
stats.responseResolved += 1;
|
|
3348
|
-
|
|
3274
|
+
logger10.success("captureLink.responseHit", `\u63A5\u53E3\u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: url=${url}, link=${hit.link}`);
|
|
3349
3275
|
setCandidate("response", hit.link, hit.payloadText);
|
|
3350
3276
|
} catch (error) {
|
|
3351
|
-
|
|
3277
|
+
logger10.warning(`\u63A5\u53E3\u54CD\u5E94\u5904\u7406\u5F02\u5E38: ${error instanceof Error ? error.message : String(error)}`);
|
|
3352
3278
|
}
|
|
3353
3279
|
};
|
|
3354
3280
|
if (share.mode === "dom") {
|
|
3355
|
-
|
|
3281
|
+
logger10.info("\u5F53\u524D\u4E3A DOM \u6A21\u5F0F\uFF0C\u4EC5\u542F\u7528 DOM \u76D1\u542C");
|
|
3356
3282
|
domMonitor = await createDomShareMonitor(page, {
|
|
3357
3283
|
prefix: share.prefix,
|
|
3358
3284
|
selectors: domSelectors,
|
|
@@ -3367,14 +3293,14 @@ var Share = {
|
|
|
3367
3293
|
});
|
|
3368
3294
|
}
|
|
3369
3295
|
if (share.mode === "response") {
|
|
3370
|
-
|
|
3296
|
+
logger10.info(`\u5F53\u524D\u4E3A\u63A5\u53E3\u6A21\u5F0F\uFF0C\u6302\u8F7D response \u76D1\u542C: apiMatchers=${toJsonInline(apiMatchers, 160)}`);
|
|
3371
3297
|
page.on("response", onResponse);
|
|
3372
3298
|
}
|
|
3373
3299
|
const deadline = Date.now() + timeoutMs;
|
|
3374
3300
|
const getRemainingMs = () => Math.max(0, deadline - Date.now());
|
|
3375
3301
|
try {
|
|
3376
3302
|
const actionTimeout = getRemainingMs();
|
|
3377
|
-
|
|
3303
|
+
logger10.start("captureLink.performActions", `\u6267\u884C\u52A8\u4F5C\u9884\u7B97=${actionTimeout}ms`);
|
|
3378
3304
|
if (actionTimeout > 0) {
|
|
3379
3305
|
let timer = null;
|
|
3380
3306
|
let actionError = null;
|
|
@@ -3388,21 +3314,21 @@ var Share = {
|
|
|
3388
3314
|
const actionResult = await Promise.race([actionPromise, timeoutPromise]);
|
|
3389
3315
|
if (timer) clearTimeout(timer);
|
|
3390
3316
|
if (actionResult === "__ACTION_ERROR__") {
|
|
3391
|
-
|
|
3317
|
+
logger10.fail("captureLink.performActions", actionError);
|
|
3392
3318
|
throw actionError;
|
|
3393
3319
|
}
|
|
3394
3320
|
if (actionResult === "__ACTION_TIMEOUT__") {
|
|
3395
3321
|
stats.actionTimedOut = true;
|
|
3396
|
-
|
|
3322
|
+
logger10.warning(`performActions \u5DF2\u8D85\u65F6 (${actionTimeout}ms)\uFF0C\u52A8\u4F5C\u53EF\u80FD\u4ECD\u5728\u5F02\u6B65\u6267\u884C`);
|
|
3397
3323
|
} else {
|
|
3398
|
-
|
|
3324
|
+
logger10.success("captureLink.performActions", "\u6267\u884C\u52A8\u4F5C\u5B8C\u6210");
|
|
3399
3325
|
}
|
|
3400
3326
|
}
|
|
3401
3327
|
let nextProgressLogTs = Date.now() + 3e3;
|
|
3402
3328
|
while (true) {
|
|
3403
3329
|
const selected = share.mode === "dom" ? candidates.dom : candidates.response;
|
|
3404
3330
|
if (selected?.link) {
|
|
3405
|
-
|
|
3331
|
+
logger10.success("captureLink", `\u6355\u83B7\u6210\u529F: source=${share.mode}, link=${selected.link}`);
|
|
3406
3332
|
return {
|
|
3407
3333
|
link: selected.link,
|
|
3408
3334
|
payloadText: selected.payloadText,
|
|
@@ -3414,19 +3340,19 @@ var Share = {
|
|
|
3414
3340
|
if (remaining <= 0) break;
|
|
3415
3341
|
const now = Date.now();
|
|
3416
3342
|
if (now >= nextProgressLogTs) {
|
|
3417
|
-
|
|
3343
|
+
logger10.info(
|
|
3418
3344
|
`captureLink \u7B49\u5F85\u4E2D: remaining=${remaining}ms, domMutationCount=${stats.domMutationCount}, responseMatched=${stats.responseMatched}`
|
|
3419
3345
|
);
|
|
3420
3346
|
nextProgressLogTs = now + 5e3;
|
|
3421
3347
|
}
|
|
3422
|
-
await (0,
|
|
3348
|
+
await (0, import_delay2.default)(Math.max(0, Math.min(DEFAULT_POLL_INTERVAL_MS, remaining)));
|
|
3423
3349
|
}
|
|
3424
3350
|
if (share.mode === "response" && stats.responseMatched === 0) {
|
|
3425
|
-
|
|
3351
|
+
logger10.warning(
|
|
3426
3352
|
`\u63A5\u53E3\u76D1\u542C\u672A\u547D\u4E2D: apiMatchers=${toJsonInline(apiMatchers, 220)}, \u54CD\u5E94\u6837\u672CURLs=${toJsonInline(stats.responseSampleUrls, 420)}`
|
|
3427
3353
|
);
|
|
3428
3354
|
}
|
|
3429
|
-
|
|
3355
|
+
logger10.warning(
|
|
3430
3356
|
`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"}`
|
|
3431
3357
|
);
|
|
3432
3358
|
return {
|
|
@@ -3438,7 +3364,7 @@ var Share = {
|
|
|
3438
3364
|
} finally {
|
|
3439
3365
|
if (share.mode === "response") {
|
|
3440
3366
|
page.off("response", onResponse);
|
|
3441
|
-
|
|
3367
|
+
logger10.info("response \u76D1\u542C\u5DF2\u5378\u8F7D");
|
|
3442
3368
|
}
|
|
3443
3369
|
await stopDomMonitor();
|
|
3444
3370
|
}
|
|
@@ -3449,25 +3375,16 @@ var Share = {
|
|
|
3449
3375
|
* @param {import('playwright').Page} page
|
|
3450
3376
|
* @param {Object} [options]
|
|
3451
3377
|
* @param {number} [options.buffer]
|
|
3452
|
-
* @param {boolean
|
|
3378
|
+
* @param {boolean} [options.restore]
|
|
3453
3379
|
* @param {number} [options.maxHeight]
|
|
3454
|
-
* @param {boolean} [options.moblie]
|
|
3455
3380
|
* @returns {Promise<string>} base64 png
|
|
3456
3381
|
*/
|
|
3457
3382
|
async captureScreen(page, options = {}) {
|
|
3458
3383
|
const originalViewport = page.viewportSize();
|
|
3459
3384
|
const defaultBuffer = Math.round((originalViewport?.height || 1080) / 2);
|
|
3460
3385
|
const buffer = options.buffer ?? defaultBuffer;
|
|
3461
|
-
const
|
|
3462
|
-
const restoreMode = (() => {
|
|
3463
|
-
if (options.restore === "width-only" || options.restore === "height-only") return options.restore;
|
|
3464
|
-
if (typeof options.restore === "boolean") return options.restore ? "all" : "none";
|
|
3465
|
-
return useMobileViewport ? "width-only" : "none";
|
|
3466
|
-
})();
|
|
3386
|
+
const restore = options.restore ?? false;
|
|
3467
3387
|
const maxHeight = options.maxHeight ?? 8e3;
|
|
3468
|
-
const currentWidth = originalViewport?.width || 1280;
|
|
3469
|
-
const isCurrentMobileWidth = currentWidth <= MOBILE_VIEWPORT_MAX_WIDTH;
|
|
3470
|
-
const targetWidth = useMobileViewport ? isCurrentMobileWidth ? currentWidth : DEFAULT_MOBILE_SCREENSHOT_WIDTH : currentWidth;
|
|
3471
3388
|
try {
|
|
3472
3389
|
const maxScrollHeight = await page.evaluate(() => {
|
|
3473
3390
|
let maxHeight2 = document.body.scrollHeight;
|
|
@@ -3491,17 +3408,17 @@ var Share = {
|
|
|
3491
3408
|
});
|
|
3492
3409
|
const targetHeight = Math.min(maxScrollHeight + buffer, maxHeight);
|
|
3493
3410
|
await page.setViewportSize({
|
|
3494
|
-
width:
|
|
3411
|
+
width: originalViewport?.width || 1280,
|
|
3495
3412
|
height: targetHeight
|
|
3496
3413
|
});
|
|
3497
|
-
await (0,
|
|
3414
|
+
await (0, import_delay2.default)(1e3);
|
|
3498
3415
|
const buffer_ = await page.screenshot({
|
|
3499
3416
|
fullPage: true,
|
|
3500
3417
|
type: "png"
|
|
3501
3418
|
});
|
|
3502
3419
|
return buffer_.toString("base64");
|
|
3503
3420
|
} finally {
|
|
3504
|
-
if (
|
|
3421
|
+
if (restore) {
|
|
3505
3422
|
await page.evaluate(() => {
|
|
3506
3423
|
document.querySelectorAll(".__pk_expanded__").forEach((el) => {
|
|
3507
3424
|
el.style.overflow = el.dataset.pkOrigOverflow || "";
|
|
@@ -3514,16 +3431,7 @@ var Share = {
|
|
|
3514
3431
|
});
|
|
3515
3432
|
});
|
|
3516
3433
|
if (originalViewport) {
|
|
3517
|
-
|
|
3518
|
-
width: targetWidth,
|
|
3519
|
-
height: maxHeight
|
|
3520
|
-
};
|
|
3521
|
-
const shouldRestoreWidth = restoreMode === "all" || restoreMode === "width-only";
|
|
3522
|
-
const shouldRestoreHeight = restoreMode === "all" || restoreMode === "height-only";
|
|
3523
|
-
await page.setViewportSize({
|
|
3524
|
-
width: shouldRestoreWidth ? originalViewport.width : currentViewport.width,
|
|
3525
|
-
height: shouldRestoreHeight ? originalViewport.height : currentViewport.height
|
|
3526
|
-
});
|
|
3434
|
+
await page.setViewportSize(originalViewport);
|
|
3527
3435
|
}
|
|
3528
3436
|
}
|
|
3529
3437
|
}
|