@skrillex1224/playwright-toolkit 3.0.15 → 3.0.16
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/browser.d.ts +6 -0
- package/dist/browser.js +421 -163
- package/dist/browser.js.map +4 -4
- package/dist/index.cjs +1021 -497
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +1021 -497
- package/dist/index.js.map +4 -4
- package/index.d.ts +49 -9
- package/package.json +9 -1
- package/scripts/postinstall.js +203 -0
package/dist/index.cjs
CHANGED
|
@@ -40,9 +40,12 @@ __export(constants_exports, {
|
|
|
40
40
|
ActorInfo: () => ActorInfo,
|
|
41
41
|
Code: () => Code,
|
|
42
42
|
Device: () => Device,
|
|
43
|
+
Mode: () => Mode,
|
|
43
44
|
PresetOfLiveViewKey: () => PresetOfLiveViewKey,
|
|
44
45
|
Status: () => Status,
|
|
45
|
-
|
|
46
|
+
mode: () => mode,
|
|
47
|
+
normalizeDevice: () => normalizeDevice,
|
|
48
|
+
normalizeMode: () => normalizeMode
|
|
46
49
|
});
|
|
47
50
|
var Code = {
|
|
48
51
|
Success: 0,
|
|
@@ -62,6 +65,14 @@ var Device = Object.freeze({
|
|
|
62
65
|
Desktop: "desktop",
|
|
63
66
|
Mobile: "mobile"
|
|
64
67
|
});
|
|
68
|
+
var Mode = Object.freeze({
|
|
69
|
+
Default: "default",
|
|
70
|
+
Cloak: "cloak"
|
|
71
|
+
});
|
|
72
|
+
var mode = Object.freeze({
|
|
73
|
+
default: Mode.Default,
|
|
74
|
+
cloak: Mode.Cloak
|
|
75
|
+
});
|
|
65
76
|
var normalizeDevice = (value, fallback = Device.Desktop) => {
|
|
66
77
|
const normalizedFallback = String(fallback || "").trim().toLowerCase() === Device.Mobile ? Device.Mobile : Device.Desktop;
|
|
67
78
|
const raw = String(value || "").trim().toLowerCase();
|
|
@@ -69,6 +80,13 @@ var normalizeDevice = (value, fallback = Device.Desktop) => {
|
|
|
69
80
|
if (raw === Device.Desktop) return Device.Desktop;
|
|
70
81
|
return normalizedFallback;
|
|
71
82
|
};
|
|
83
|
+
var normalizeMode = (value, fallback = Mode.Default) => {
|
|
84
|
+
const normalizedFallback = String(fallback || "").trim().toLowerCase() === Mode.Cloak ? Mode.Cloak : Mode.Default;
|
|
85
|
+
const raw = String(value || "").trim().toLowerCase();
|
|
86
|
+
if (raw === Mode.Cloak) return Mode.Cloak;
|
|
87
|
+
if (raw === Mode.Default) return Mode.Default;
|
|
88
|
+
return normalizedFallback;
|
|
89
|
+
};
|
|
72
90
|
var createActorInfo = (info) => {
|
|
73
91
|
const normalizeDomain = (value) => {
|
|
74
92
|
if (!value) return "";
|
|
@@ -83,7 +101,7 @@ var createActorInfo = (info) => {
|
|
|
83
101
|
const normalizeShare2 = (value) => {
|
|
84
102
|
const raw = value && typeof value === "object" ? value : {};
|
|
85
103
|
const modeRaw = String(raw.mode || "dom").trim().toLowerCase();
|
|
86
|
-
const
|
|
104
|
+
const mode2 = ["dom", "response", "custom"].includes(modeRaw) ? modeRaw : "dom";
|
|
87
105
|
const prefix = String(raw.prefix || "").trim();
|
|
88
106
|
const rawXurl = Array.isArray(raw.xurl) ? raw.xurl : [];
|
|
89
107
|
const normalizeMatcherList = (input) => {
|
|
@@ -128,7 +146,7 @@ var createActorInfo = (info) => {
|
|
|
128
146
|
xurl.push(...extraPaths);
|
|
129
147
|
}
|
|
130
148
|
return {
|
|
131
|
-
mode,
|
|
149
|
+
mode: mode2,
|
|
132
150
|
prefix,
|
|
133
151
|
xurl
|
|
134
152
|
};
|
|
@@ -136,7 +154,6 @@ var createActorInfo = (info) => {
|
|
|
136
154
|
const buildLandingUrl = ({ protocol: protocol2, domain: domain2, path: path4 }) => {
|
|
137
155
|
const safeProtocol = String(protocol2).trim();
|
|
138
156
|
const safeDomain = normalizeDomain(domain2);
|
|
139
|
-
if (!safeDomain) return "";
|
|
140
157
|
const safePath = normalizePath(path4);
|
|
141
158
|
return `${safeProtocol}://${safeDomain}${safePath}`;
|
|
142
159
|
};
|
|
@@ -344,18 +361,6 @@ var ActorInfo = {
|
|
|
344
361
|
prefix: "",
|
|
345
362
|
xurl: []
|
|
346
363
|
}
|
|
347
|
-
}),
|
|
348
|
-
// 通用网页抓取 Actor:入口 URL 来自 query,因此这里只声明统一的 Actor 元信息。
|
|
349
|
-
webpage: createActorInfo({
|
|
350
|
-
key: "webpage",
|
|
351
|
-
name: "\u901A\u7528\u7F51\u9875",
|
|
352
|
-
domain: "",
|
|
353
|
-
path: "/",
|
|
354
|
-
share: {
|
|
355
|
-
mode: "dom",
|
|
356
|
-
prefix: "",
|
|
357
|
-
xurl: []
|
|
358
|
-
}
|
|
359
364
|
})
|
|
360
365
|
};
|
|
361
366
|
|
|
@@ -387,18 +392,18 @@ var fallbackLog = {
|
|
|
387
392
|
error: (...args) => console.error(...args),
|
|
388
393
|
debug: (...args) => console.debug ? console.debug(...args) : console.log(...args)
|
|
389
394
|
};
|
|
390
|
-
var resolveLogMethod = (
|
|
391
|
-
if (
|
|
392
|
-
return
|
|
395
|
+
var resolveLogMethod = (logger17, name) => {
|
|
396
|
+
if (logger17 && typeof logger17[name] === "function") {
|
|
397
|
+
return logger17[name].bind(logger17);
|
|
393
398
|
}
|
|
394
|
-
if (name === "warning" &&
|
|
395
|
-
return
|
|
399
|
+
if (name === "warning" && logger17 && typeof logger17.warn === "function") {
|
|
400
|
+
return logger17.warn.bind(logger17);
|
|
396
401
|
}
|
|
397
402
|
return fallbackLog[name];
|
|
398
403
|
};
|
|
399
404
|
var defaultLogger = null;
|
|
400
|
-
var setDefaultLogger = (
|
|
401
|
-
defaultLogger =
|
|
405
|
+
var setDefaultLogger = (logger17) => {
|
|
406
|
+
defaultLogger = logger17;
|
|
402
407
|
};
|
|
403
408
|
var resolveLogger = (explicitLogger) => {
|
|
404
409
|
if (explicitLogger && typeof explicitLogger.info === "function") {
|
|
@@ -425,8 +430,8 @@ var colorize = (text, color) => {
|
|
|
425
430
|
var createBaseLogger = (prefix = "", explicitLogger) => {
|
|
426
431
|
const name = prefix ? String(prefix) : "";
|
|
427
432
|
const dispatch = (methodName, icon, message, color) => {
|
|
428
|
-
const
|
|
429
|
-
const logFn = resolveLogMethod(
|
|
433
|
+
const logger17 = resolveLogger(explicitLogger);
|
|
434
|
+
const logFn = resolveLogMethod(logger17, methodName);
|
|
430
435
|
const timestamp = colorize(`[${formatTimestamp()}]`, ANSI.gray);
|
|
431
436
|
const line = formatLine(name, icon, message);
|
|
432
437
|
const coloredLine = colorize(line, color);
|
|
@@ -780,7 +785,7 @@ var adjustAffixedElementsForExpandedScreenshot = async (page, options = {}) => {
|
|
|
780
785
|
if (safeTargetHeight <= viewportHeight + 1) {
|
|
781
786
|
return 0;
|
|
782
787
|
}
|
|
783
|
-
const
|
|
788
|
+
const hasOwn2 = (source, key) => Object.prototype.hasOwnProperty.call(source, key);
|
|
784
789
|
const isVisible = (el, style, rect) => {
|
|
785
790
|
if (!el || !style || !rect) return false;
|
|
786
791
|
if (style.display === "none" || style.visibility === "hidden" || style.visibility === "collapse") {
|
|
@@ -820,7 +825,7 @@ var adjustAffixedElementsForExpandedScreenshot = async (page, options = {}) => {
|
|
|
820
825
|
return true;
|
|
821
826
|
});
|
|
822
827
|
topLevelCandidates.forEach(({ el, position, edge }) => {
|
|
823
|
-
if (!
|
|
828
|
+
if (!hasOwn2(el.dataset, "pkAffixedAdjusted")) {
|
|
824
829
|
el.dataset.pkAffixedAdjusted = "1";
|
|
825
830
|
el.dataset.pkOrigPosition = el.style.getPropertyValue("position") || "";
|
|
826
831
|
el.dataset.pkOrigPositionPriority = el.style.getPropertyPriority("position") || "";
|
|
@@ -851,7 +856,7 @@ var adjustAffixedElementsForExpandedScreenshot = async (page, options = {}) => {
|
|
|
851
856
|
};
|
|
852
857
|
var restoreAffixedElementsForExpandedScreenshot = async (page) => {
|
|
853
858
|
await page.evaluate((className) => {
|
|
854
|
-
const
|
|
859
|
+
const hasOwn2 = (source, key) => Object.prototype.hasOwnProperty.call(source, key);
|
|
855
860
|
const expansionKeys = [
|
|
856
861
|
"pkOrigOverflow",
|
|
857
862
|
"pkOrigHeight",
|
|
@@ -859,28 +864,28 @@ var restoreAffixedElementsForExpandedScreenshot = async (page) => {
|
|
|
859
864
|
"pkOrigMaxHeight"
|
|
860
865
|
];
|
|
861
866
|
document.querySelectorAll('[data-pk-affixed-adjusted="1"]').forEach((el) => {
|
|
862
|
-
if (
|
|
867
|
+
if (hasOwn2(el.dataset, "pkOrigPosition")) {
|
|
863
868
|
el.style.setProperty("position", el.dataset.pkOrigPosition || "", el.dataset.pkOrigPositionPriority || "");
|
|
864
869
|
delete el.dataset.pkOrigPosition;
|
|
865
870
|
delete el.dataset.pkOrigPositionPriority;
|
|
866
871
|
}
|
|
867
|
-
if (
|
|
872
|
+
if (hasOwn2(el.dataset, "pkOrigTop")) {
|
|
868
873
|
el.style.setProperty("top", el.dataset.pkOrigTop || "", el.dataset.pkOrigTopPriority || "");
|
|
869
874
|
delete el.dataset.pkOrigTop;
|
|
870
875
|
delete el.dataset.pkOrigTopPriority;
|
|
871
876
|
}
|
|
872
|
-
if (
|
|
877
|
+
if (hasOwn2(el.dataset, "pkOrigBottom")) {
|
|
873
878
|
el.style.setProperty("bottom", el.dataset.pkOrigBottom || "", el.dataset.pkOrigBottomPriority || "");
|
|
874
879
|
delete el.dataset.pkOrigBottom;
|
|
875
880
|
delete el.dataset.pkOrigBottomPriority;
|
|
876
881
|
}
|
|
877
|
-
if (
|
|
882
|
+
if (hasOwn2(el.dataset, "pkOrigTranslate")) {
|
|
878
883
|
el.style.setProperty("translate", el.dataset.pkOrigTranslate || "", el.dataset.pkOrigTranslatePriority || "");
|
|
879
884
|
delete el.dataset.pkOrigTranslate;
|
|
880
885
|
delete el.dataset.pkOrigTranslatePriority;
|
|
881
886
|
}
|
|
882
887
|
delete el.dataset.pkAffixedAdjusted;
|
|
883
|
-
const stillExpanded = expansionKeys.some((key) =>
|
|
888
|
+
const stillExpanded = expansionKeys.some((key) => hasOwn2(el.dataset, key));
|
|
884
889
|
if (!stillExpanded) {
|
|
885
890
|
el.classList.remove(className);
|
|
886
891
|
}
|
|
@@ -923,7 +928,7 @@ var prepareExpandedFullPageScreenshot = async (page, options = {}) => {
|
|
|
923
928
|
viewportResized
|
|
924
929
|
};
|
|
925
930
|
};
|
|
926
|
-
var restoreExpandedFullPageScreenshot = async (page,
|
|
931
|
+
var restoreExpandedFullPageScreenshot = async (page, state2 = {}) => {
|
|
927
932
|
await page.evaluate((className) => {
|
|
928
933
|
const targets = new Set([
|
|
929
934
|
...document.querySelectorAll(`.${className}`),
|
|
@@ -947,8 +952,8 @@ var restoreExpandedFullPageScreenshot = async (page, state = {}) => {
|
|
|
947
952
|
el.classList.remove(className);
|
|
948
953
|
});
|
|
949
954
|
}, EXPANDED_SCROLLABLE_CLASS);
|
|
950
|
-
if (
|
|
951
|
-
await page.setViewportSize(
|
|
955
|
+
if (state2?.originalViewport && state2?.viewportResized) {
|
|
956
|
+
await page.setViewportSize(state2.originalViewport);
|
|
952
957
|
}
|
|
953
958
|
};
|
|
954
959
|
var capturePageScreenshot = async (page, options = {}) => {
|
|
@@ -1005,21 +1010,21 @@ var capturePageScreenshot = async (page, options = {}) => {
|
|
|
1005
1010
|
}
|
|
1006
1011
|
};
|
|
1007
1012
|
var captureExpandedFullPageScreenshot = async (page, options = {}) => {
|
|
1008
|
-
const
|
|
1013
|
+
const state2 = await prepareExpandedFullPageScreenshot(page, options);
|
|
1009
1014
|
try {
|
|
1010
1015
|
return await capturePageScreenshot(page, {
|
|
1011
1016
|
fullPage: true,
|
|
1012
1017
|
type: options.type || "png",
|
|
1013
1018
|
quality: options.quality,
|
|
1014
1019
|
timeout: options.timeout,
|
|
1015
|
-
maxClipHeight:
|
|
1020
|
+
maxClipHeight: state2.targetHeight
|
|
1016
1021
|
});
|
|
1017
1022
|
} finally {
|
|
1018
1023
|
await restoreAffixedElementsForExpandedScreenshot(page).catch((error) => {
|
|
1019
1024
|
logger.warning(`\u79FB\u52A8\u7AEF\u5438\u9644\u5143\u7D20\u6062\u590D\u5931\u8D25: ${error?.message || error}`);
|
|
1020
1025
|
});
|
|
1021
1026
|
if (options.restore) {
|
|
1022
|
-
await restoreExpandedFullPageScreenshot(page,
|
|
1027
|
+
await restoreExpandedFullPageScreenshot(page, state2);
|
|
1023
1028
|
}
|
|
1024
1029
|
}
|
|
1025
1030
|
};
|
|
@@ -1938,8 +1943,8 @@ var normalizeBrowserProfile = (value) => {
|
|
|
1938
1943
|
payload: buildBrowserProfilePayload(core, observed)
|
|
1939
1944
|
};
|
|
1940
1945
|
};
|
|
1941
|
-
var rememberRuntimeState = (
|
|
1942
|
-
rememberedRuntimeState = deepClone(
|
|
1946
|
+
var rememberRuntimeState = (state2) => {
|
|
1947
|
+
rememberedRuntimeState = deepClone(state2);
|
|
1943
1948
|
return rememberedRuntimeState;
|
|
1944
1949
|
};
|
|
1945
1950
|
var normalizeRuntimeState = (source = {}, actor = "") => {
|
|
@@ -1998,7 +2003,7 @@ var RuntimeEnv = {
|
|
|
1998
2003
|
} else {
|
|
1999
2004
|
delete normalizedRuntime.browser_profile;
|
|
2000
2005
|
}
|
|
2001
|
-
const
|
|
2006
|
+
const state2 = {
|
|
2002
2007
|
actor: resolvedActor,
|
|
2003
2008
|
device,
|
|
2004
2009
|
runtime: normalizedRuntime,
|
|
@@ -2012,73 +2017,73 @@ var RuntimeEnv = {
|
|
|
2012
2017
|
browserProfileCore: browserProfile.core,
|
|
2013
2018
|
browserProfileObserved: browserProfile.observed
|
|
2014
2019
|
};
|
|
2015
|
-
rememberRuntimeState(
|
|
2016
|
-
return
|
|
2020
|
+
rememberRuntimeState(state2);
|
|
2021
|
+
return state2;
|
|
2017
2022
|
},
|
|
2018
2023
|
// buildEnvPatch 只构造允许回写到后端 env 的字段集合。
|
|
2019
2024
|
buildEnvPatch(source = {}, actor = "") {
|
|
2020
|
-
const
|
|
2021
|
-
const browserProfile = buildBrowserProfilePayload(
|
|
2025
|
+
const state2 = normalizeRuntimeState(source, actor);
|
|
2026
|
+
const browserProfile = buildBrowserProfilePayload(state2.browserProfileCore, state2.browserProfileObserved);
|
|
2022
2027
|
const envPatch = {
|
|
2023
|
-
...Array.isArray(
|
|
2024
|
-
...Object.keys(
|
|
2025
|
-
...Object.keys(
|
|
2028
|
+
...Array.isArray(state2.cookies) && state2.cookies.length > 0 ? { cookies: state2.cookies } : {},
|
|
2029
|
+
...Object.keys(state2.localStorage || {}).length > 0 ? { local_storage: state2.localStorage } : {},
|
|
2030
|
+
...Object.keys(state2.sessionStorage || {}).length > 0 ? { session_storage: state2.sessionStorage } : {},
|
|
2026
2031
|
...Object.keys(browserProfile).length > 0 ? { browser_profile: browserProfile } : {}
|
|
2027
2032
|
};
|
|
2028
2033
|
return Object.keys(envPatch).length > 0 ? envPatch : null;
|
|
2029
2034
|
},
|
|
2030
2035
|
// hasLoginState 只判断 runtime 是否存在有效载荷,不再区分具体字段来源。
|
|
2031
2036
|
hasLoginState(source = {}, actor = "") {
|
|
2032
|
-
const
|
|
2033
|
-
return isPlainObject(
|
|
2037
|
+
const state2 = normalizeRuntimeState(source, actor);
|
|
2038
|
+
return isPlainObject(state2.runtime) && Object.keys(state2.runtime || {}).length > 0;
|
|
2034
2039
|
},
|
|
2035
2040
|
rememberState(source = {}) {
|
|
2036
|
-
const
|
|
2037
|
-
rememberRuntimeState(
|
|
2041
|
+
const state2 = normalizeRuntimeState(source);
|
|
2042
|
+
rememberRuntimeState(state2);
|
|
2038
2043
|
return RuntimeEnv.peekRememberedState();
|
|
2039
2044
|
},
|
|
2040
2045
|
peekRememberedState() {
|
|
2041
2046
|
return rememberedRuntimeState ? deepClone(rememberedRuntimeState) : null;
|
|
2042
2047
|
},
|
|
2043
2048
|
getBrowserProfileCore(source = {}, actor = "") {
|
|
2044
|
-
const
|
|
2045
|
-
return deepClone(
|
|
2049
|
+
const state2 = normalizeRuntimeState(source, actor);
|
|
2050
|
+
return deepClone(state2.browserProfileCore || {});
|
|
2046
2051
|
},
|
|
2047
2052
|
setBrowserProfileCore(source = {}, core = {}, actor = "") {
|
|
2048
|
-
const
|
|
2053
|
+
const state2 = normalizeRuntimeState(source, actor);
|
|
2049
2054
|
const normalizedCore = normalizeBrowserProfileCore({
|
|
2050
2055
|
...core,
|
|
2051
|
-
device: normalizeKnownDevice(core?.device) ||
|
|
2056
|
+
device: normalizeKnownDevice(core?.device) || state2.device
|
|
2052
2057
|
});
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
if (Object.keys(
|
|
2056
|
-
|
|
2058
|
+
state2.browserProfileCore = normalizedCore;
|
|
2059
|
+
state2.browserProfile = buildBrowserProfilePayload(normalizedCore, state2.browserProfileObserved);
|
|
2060
|
+
if (Object.keys(state2.browserProfile).length > 0) {
|
|
2061
|
+
state2.runtime.browser_profile = state2.browserProfile;
|
|
2057
2062
|
} else {
|
|
2058
|
-
delete
|
|
2063
|
+
delete state2.runtime.browser_profile;
|
|
2059
2064
|
}
|
|
2060
|
-
rememberRuntimeState(
|
|
2061
|
-
return
|
|
2065
|
+
rememberRuntimeState(state2);
|
|
2066
|
+
return state2;
|
|
2062
2067
|
},
|
|
2063
2068
|
// applyToPage 只负责把登录态相关字段注入页面:
|
|
2064
2069
|
// cookies / localStorage / sessionStorage。
|
|
2065
2070
|
// 指纹、时区、UA、viewport 的回放发生在 launch.js 启动阶段,不在这里做。
|
|
2066
2071
|
async applyToPage(page, source = {}, options = {}) {
|
|
2067
2072
|
if (!page) return;
|
|
2068
|
-
let
|
|
2073
|
+
let state2 = normalizeRuntimeState(source, options?.actor || "");
|
|
2069
2074
|
if (typeof options?.preapply === "function") {
|
|
2070
|
-
|
|
2071
|
-
rememberRuntimeState(
|
|
2075
|
+
state2 = await options.preapply(state2) || state2;
|
|
2076
|
+
rememberRuntimeState(state2);
|
|
2072
2077
|
}
|
|
2073
2078
|
Object.defineProperty(page, PageRuntimeStateKey, {
|
|
2074
2079
|
configurable: true,
|
|
2075
2080
|
enumerable: false,
|
|
2076
2081
|
writable: true,
|
|
2077
|
-
value:
|
|
2082
|
+
value: state2
|
|
2078
2083
|
});
|
|
2079
|
-
const localStorage =
|
|
2080
|
-
const sessionStorage =
|
|
2081
|
-
const cookies = (
|
|
2084
|
+
const localStorage = state2.localStorage || {};
|
|
2085
|
+
const sessionStorage = state2.sessionStorage || {};
|
|
2086
|
+
const cookies = (state2.cookies || []).map((cookie) => {
|
|
2082
2087
|
const normalized = { ...cookie };
|
|
2083
2088
|
if (!normalized.path) {
|
|
2084
2089
|
normalized.path = "/";
|
|
@@ -2116,8 +2121,8 @@ var RuntimeEnv = {
|
|
|
2116
2121
|
},
|
|
2117
2122
|
// captureEnvPatch 在任务结束时采集最新环境快照,用于 pushSuccess / pushFailed 自动回写。
|
|
2118
2123
|
async captureEnvPatch(page, source = {}, options = {}) {
|
|
2119
|
-
const
|
|
2120
|
-
const baseline = RuntimeEnv.buildEnvPatch(
|
|
2124
|
+
const state2 = normalizeRuntimeState(source, options?.actor || "");
|
|
2125
|
+
const baseline = RuntimeEnv.buildEnvPatch(state2) || {};
|
|
2121
2126
|
if (!page || typeof page.evaluate !== "function" || typeof page.context !== "function") {
|
|
2122
2127
|
return Object.keys(baseline).length > 0 ? baseline : null;
|
|
2123
2128
|
}
|
|
@@ -2136,7 +2141,7 @@ var RuntimeEnv = {
|
|
|
2136
2141
|
cookies
|
|
2137
2142
|
},
|
|
2138
2143
|
{
|
|
2139
|
-
browserProfileCore:
|
|
2144
|
+
browserProfileCore: state2.browserProfileCore
|
|
2140
2145
|
}
|
|
2141
2146
|
);
|
|
2142
2147
|
return RuntimeEnv.mergeEnvPatches(baseline, capturedPatch);
|
|
@@ -2150,11 +2155,11 @@ var RuntimeEnv = {
|
|
|
2150
2155
|
var logger3 = createInternalLogger("ApifyKit");
|
|
2151
2156
|
var resolveRuntimeContext = (input) => {
|
|
2152
2157
|
const rememberedState = RuntimeEnv.peekRememberedState();
|
|
2153
|
-
const
|
|
2154
|
-
const envPatch = RuntimeEnv.buildEnvPatch(
|
|
2158
|
+
const state2 = rememberedState || RuntimeEnv.parseInput(input || {});
|
|
2159
|
+
const envPatch = RuntimeEnv.buildEnvPatch(state2) || null;
|
|
2155
2160
|
return {
|
|
2156
|
-
actor:
|
|
2157
|
-
runtime:
|
|
2161
|
+
actor: state2.actor,
|
|
2162
|
+
runtime: state2.runtime,
|
|
2158
2163
|
envPatch
|
|
2159
2164
|
};
|
|
2160
2165
|
};
|
|
@@ -2513,8 +2518,82 @@ var Utils = {
|
|
|
2513
2518
|
}
|
|
2514
2519
|
};
|
|
2515
2520
|
|
|
2516
|
-
// src/
|
|
2517
|
-
var
|
|
2521
|
+
// src/internals/context.js
|
|
2522
|
+
var state = {
|
|
2523
|
+
mode: Mode.Default
|
|
2524
|
+
};
|
|
2525
|
+
var normalizeStrategies = (strategies) => strategies && typeof strategies === "object" ? strategies : {};
|
|
2526
|
+
var ToolkitContext = {
|
|
2527
|
+
get mode() {
|
|
2528
|
+
return state.mode;
|
|
2529
|
+
},
|
|
2530
|
+
setMode(mode2 = Mode.Default) {
|
|
2531
|
+
state.mode = normalizeMode(mode2, Mode.Default);
|
|
2532
|
+
return state.mode;
|
|
2533
|
+
}
|
|
2534
|
+
};
|
|
2535
|
+
var getToolkitMode = () => state.mode;
|
|
2536
|
+
var setToolkitMode = (mode2 = Mode.Default) => ToolkitContext.setMode(mode2);
|
|
2537
|
+
var resolveModeStrategy = (strategies = {}, mode2 = getToolkitMode(), fallbackMode = Mode.Default) => {
|
|
2538
|
+
const normalizedStrategies = normalizeStrategies(strategies);
|
|
2539
|
+
const normalizedMode = normalizeMode(mode2, fallbackMode);
|
|
2540
|
+
const strategy = normalizedStrategies[normalizedMode] ?? normalizedStrategies[fallbackMode] ?? Object.values(normalizedStrategies).find(Boolean) ?? null;
|
|
2541
|
+
return {
|
|
2542
|
+
mode: normalizedMode,
|
|
2543
|
+
strategy
|
|
2544
|
+
};
|
|
2545
|
+
};
|
|
2546
|
+
|
|
2547
|
+
// src/internals/reflect.js
|
|
2548
|
+
var normalizeStrategies2 = (strategies) => strategies && typeof strategies === "object" ? strategies : {};
|
|
2549
|
+
var collectFunctionNames = (strategies = []) => {
|
|
2550
|
+
const names = /* @__PURE__ */ new Set();
|
|
2551
|
+
for (const strategy of strategies) {
|
|
2552
|
+
if (!strategy || typeof strategy !== "object") continue;
|
|
2553
|
+
for (const name of Reflect.ownKeys(strategy)) {
|
|
2554
|
+
if (typeof name === "string" && typeof strategy[name] === "function") {
|
|
2555
|
+
names.add(name);
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2558
|
+
}
|
|
2559
|
+
return names;
|
|
2560
|
+
};
|
|
2561
|
+
var methodDescriptor = (namespace, name, resolveTarget) => ({
|
|
2562
|
+
enumerable: true,
|
|
2563
|
+
configurable: true,
|
|
2564
|
+
writable: true,
|
|
2565
|
+
value: (...args) => {
|
|
2566
|
+
const { mode: mode2, strategy } = resolveTarget(args);
|
|
2567
|
+
const method = strategy?.[name];
|
|
2568
|
+
if (typeof method !== "function") {
|
|
2569
|
+
throw new Error(`${namespace}.${name} is not available in ${mode2} mode`);
|
|
2570
|
+
}
|
|
2571
|
+
return method.apply(strategy, args);
|
|
2572
|
+
}
|
|
2573
|
+
});
|
|
2574
|
+
var withModeReflect = (namespace, strategies = {}) => {
|
|
2575
|
+
const normalizedStrategies = normalizeStrategies2(strategies);
|
|
2576
|
+
const baseStrategy = normalizedStrategies.default ?? Object.values(normalizedStrategies).find(Boolean);
|
|
2577
|
+
const names = collectFunctionNames([baseStrategy]);
|
|
2578
|
+
const descriptors = {};
|
|
2579
|
+
for (const name of names) {
|
|
2580
|
+
descriptors[name] = methodDescriptor(namespace, name, () => resolveModeStrategy(normalizedStrategies));
|
|
2581
|
+
}
|
|
2582
|
+
return Object.defineProperties({}, descriptors);
|
|
2583
|
+
};
|
|
2584
|
+
var withPageReflect = (namespace, resolveStrategy, strategies = []) => {
|
|
2585
|
+
const names = collectFunctionNames(strategies);
|
|
2586
|
+
const descriptors = {};
|
|
2587
|
+
for (const name of names) {
|
|
2588
|
+
descriptors[name] = methodDescriptor(namespace, name, ([page]) => ({
|
|
2589
|
+
mode: "page",
|
|
2590
|
+
strategy: resolveStrategy(page)
|
|
2591
|
+
}));
|
|
2592
|
+
}
|
|
2593
|
+
return Object.defineProperties({}, descriptors);
|
|
2594
|
+
};
|
|
2595
|
+
|
|
2596
|
+
// src/internals/anti-cheat/default.js
|
|
2518
2597
|
var BASE_CONFIG = Object.freeze({
|
|
2519
2598
|
locale: "zh-CN",
|
|
2520
2599
|
acceptLanguage: "zh-CN,zh;q=0.9",
|
|
@@ -2549,7 +2628,7 @@ function buildFingerprintOptions({ locale = BASE_CONFIG.locale, browserMajorVers
|
|
|
2549
2628
|
}
|
|
2550
2629
|
return options;
|
|
2551
2630
|
}
|
|
2552
|
-
var
|
|
2631
|
+
var DefaultAntiCheat = {
|
|
2553
2632
|
/**
|
|
2554
2633
|
* 获取统一的基础配置
|
|
2555
2634
|
*/
|
|
@@ -2586,6 +2665,47 @@ var AntiCheat = {
|
|
|
2586
2665
|
}
|
|
2587
2666
|
};
|
|
2588
2667
|
|
|
2668
|
+
// src/internals/anti-cheat/cloak.js
|
|
2669
|
+
var CLOAK_BASE_CONFIG = Object.freeze({
|
|
2670
|
+
locale: "",
|
|
2671
|
+
acceptLanguage: "",
|
|
2672
|
+
timezoneId: "",
|
|
2673
|
+
timezoneOffset: null,
|
|
2674
|
+
geolocation: null
|
|
2675
|
+
});
|
|
2676
|
+
var normalizeHeaders = (headers) => headers && typeof headers === "object" ? headers : {};
|
|
2677
|
+
var CloakAntiCheat = {
|
|
2678
|
+
/**
|
|
2679
|
+
* Cloak 自身会负责浏览器指纹,toolkit 在该模式下尽量不再注入额外反检测配置。
|
|
2680
|
+
*/
|
|
2681
|
+
getBaseConfig() {
|
|
2682
|
+
return { ...CLOAK_BASE_CONFIG };
|
|
2683
|
+
},
|
|
2684
|
+
getFingerprintGeneratorOptions() {
|
|
2685
|
+
return {};
|
|
2686
|
+
},
|
|
2687
|
+
getLaunchArgs() {
|
|
2688
|
+
return [];
|
|
2689
|
+
},
|
|
2690
|
+
getTlsFingerprintOptions() {
|
|
2691
|
+
return {};
|
|
2692
|
+
},
|
|
2693
|
+
applyLocaleHeaders(headers, acceptLanguage = "") {
|
|
2694
|
+
const normalizedHeaders = normalizeHeaders(headers);
|
|
2695
|
+
if (acceptLanguage && !normalizedHeaders["accept-language"]) {
|
|
2696
|
+
normalizedHeaders["accept-language"] = acceptLanguage;
|
|
2697
|
+
}
|
|
2698
|
+
return normalizedHeaders;
|
|
2699
|
+
}
|
|
2700
|
+
};
|
|
2701
|
+
|
|
2702
|
+
// src/anti-cheat.js
|
|
2703
|
+
var antiCheatStrategies = {
|
|
2704
|
+
[Mode.Default]: DefaultAntiCheat,
|
|
2705
|
+
[Mode.Cloak]: CloakAntiCheat
|
|
2706
|
+
};
|
|
2707
|
+
var AntiCheat = withModeReflect("AntiCheat", antiCheatStrategies);
|
|
2708
|
+
|
|
2589
2709
|
// src/device-input.js
|
|
2590
2710
|
var resolveDeviceFromPage = (page) => normalizeDevice(page?.[PageRuntimeStateKey]?.device);
|
|
2591
2711
|
var assertPage = (page, method) => {
|
|
@@ -2985,12 +3105,12 @@ var resolveDescriptor = (descriptor, device) => {
|
|
|
2985
3105
|
}
|
|
2986
3106
|
return resolved;
|
|
2987
3107
|
};
|
|
2988
|
-
var attachRuntimeState = (page,
|
|
3108
|
+
var attachRuntimeState = (page, state2) => {
|
|
2989
3109
|
Object.defineProperty(page, PageRuntimeStateKey, {
|
|
2990
3110
|
configurable: true,
|
|
2991
3111
|
enumerable: false,
|
|
2992
3112
|
writable: true,
|
|
2993
|
-
value:
|
|
3113
|
+
value: state2
|
|
2994
3114
|
});
|
|
2995
3115
|
};
|
|
2996
3116
|
var restoreRuntimeState = (page, snapshot) => {
|
|
@@ -3136,10 +3256,13 @@ var DeviceView = {
|
|
|
3136
3256
|
}
|
|
3137
3257
|
};
|
|
3138
3258
|
|
|
3259
|
+
// src/internals/humanize/index.js
|
|
3260
|
+
var import_delay4 = __toESM(require("delay"), 1);
|
|
3261
|
+
|
|
3139
3262
|
// src/internals/humanize/desktop.js
|
|
3140
3263
|
var import_delay2 = __toESM(require("delay"), 1);
|
|
3141
3264
|
var import_ghost_cursor_playwright = require("ghost-cursor-playwright");
|
|
3142
|
-
var
|
|
3265
|
+
var logger5 = createInternalLogger("Humanize");
|
|
3143
3266
|
var $CursorWeakMap = /* @__PURE__ */ new WeakMap();
|
|
3144
3267
|
function $GetCursor(page) {
|
|
3145
3268
|
const cursor = $CursorWeakMap.get(page);
|
|
@@ -3167,13 +3290,13 @@ var Humanize = {
|
|
|
3167
3290
|
*/
|
|
3168
3291
|
async initializeCursor(page) {
|
|
3169
3292
|
if ($CursorWeakMap.has(page)) {
|
|
3170
|
-
|
|
3293
|
+
logger5.debug("initializeCursor: cursor already exists, skipping");
|
|
3171
3294
|
return;
|
|
3172
3295
|
}
|
|
3173
|
-
|
|
3296
|
+
logger5.start("initializeCursor", "creating cursor");
|
|
3174
3297
|
const cursor = await (0, import_ghost_cursor_playwright.createCursor)(page);
|
|
3175
3298
|
$CursorWeakMap.set(page, cursor);
|
|
3176
|
-
|
|
3299
|
+
logger5.success("initializeCursor", "cursor initialized");
|
|
3177
3300
|
},
|
|
3178
3301
|
/**
|
|
3179
3302
|
* 人类化鼠标移动 - 使用 ghost-cursor 移动到指定位置或元素
|
|
@@ -3183,17 +3306,17 @@ var Humanize = {
|
|
|
3183
3306
|
*/
|
|
3184
3307
|
async humanMove(page, target) {
|
|
3185
3308
|
const cursor = $GetCursor(page);
|
|
3186
|
-
|
|
3309
|
+
logger5.start("humanMove", `target=${typeof target === "string" ? target : "element/coords"}`);
|
|
3187
3310
|
try {
|
|
3188
3311
|
if (typeof target === "string") {
|
|
3189
3312
|
const element = await page.$(target);
|
|
3190
3313
|
if (!element) {
|
|
3191
|
-
|
|
3314
|
+
logger5.warn(`humanMove: \u5143\u7D20\u4E0D\u5B58\u5728 ${target}`);
|
|
3192
3315
|
return false;
|
|
3193
3316
|
}
|
|
3194
3317
|
const box = await element.boundingBox();
|
|
3195
3318
|
if (!box) {
|
|
3196
|
-
|
|
3319
|
+
logger5.warn(`humanMove: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E ${target}`);
|
|
3197
3320
|
return false;
|
|
3198
3321
|
}
|
|
3199
3322
|
const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.2;
|
|
@@ -3209,10 +3332,10 @@ var Humanize = {
|
|
|
3209
3332
|
await cursor.actions.move({ x, y });
|
|
3210
3333
|
}
|
|
3211
3334
|
}
|
|
3212
|
-
|
|
3335
|
+
logger5.success("humanMove");
|
|
3213
3336
|
return true;
|
|
3214
3337
|
} catch (error) {
|
|
3215
|
-
|
|
3338
|
+
logger5.fail("humanMove", error);
|
|
3216
3339
|
throw error;
|
|
3217
3340
|
}
|
|
3218
3341
|
},
|
|
@@ -3236,12 +3359,12 @@ var Humanize = {
|
|
|
3236
3359
|
maxDurationMs = maxSteps * 220 + 800
|
|
3237
3360
|
} = options;
|
|
3238
3361
|
const targetDesc = typeof target === "string" ? target : "ElementHandle";
|
|
3239
|
-
|
|
3362
|
+
logger5.start("humanScroll", `target=${targetDesc}`);
|
|
3240
3363
|
let element;
|
|
3241
3364
|
if (typeof target === "string") {
|
|
3242
3365
|
element = await page.$(target);
|
|
3243
3366
|
if (!element) {
|
|
3244
|
-
|
|
3367
|
+
logger5.warn(`humanScroll | \u5143\u7D20\u672A\u627E\u5230: ${target}`);
|
|
3245
3368
|
return { element: null, didScroll: false };
|
|
3246
3369
|
}
|
|
3247
3370
|
} else {
|
|
@@ -3316,26 +3439,26 @@ var Humanize = {
|
|
|
3316
3439
|
try {
|
|
3317
3440
|
for (let i = 0; i < maxSteps; i++) {
|
|
3318
3441
|
if (Date.now() - startTime > maxDurationMs) {
|
|
3319
|
-
|
|
3442
|
+
logger5.warn(`humanScroll | \u8D85\u65F6\u4FDD\u62A4\u89E6\u53D1 (${maxDurationMs}ms)`);
|
|
3320
3443
|
return { element, didScroll };
|
|
3321
3444
|
}
|
|
3322
3445
|
const status = await checkVisibility();
|
|
3323
3446
|
if (status.code === "VISIBLE") {
|
|
3324
3447
|
if (status.isFixed) {
|
|
3325
|
-
|
|
3448
|
+
logger5.info("humanScroll | fixed \u5BB9\u5668\u5185\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
|
|
3326
3449
|
} else {
|
|
3327
|
-
|
|
3450
|
+
logger5.debug("humanScroll | \u5143\u7D20\u53EF\u89C1\u4E14\u65E0\u906E\u6321");
|
|
3328
3451
|
}
|
|
3329
|
-
|
|
3452
|
+
logger5.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
|
|
3330
3453
|
return { element, didScroll };
|
|
3331
3454
|
}
|
|
3332
|
-
|
|
3455
|
+
logger5.debug(`humanScroll | \u6B65\u9AA4 ${i + 1}/${maxSteps}: ${status.reason} ${status.direction ? `(${status.direction})` : ""}`);
|
|
3333
3456
|
if (status.code === "OBSTRUCTED" && status.obstruction) {
|
|
3334
|
-
|
|
3457
|
+
logger5.debug(`humanScroll | \u88AB\u4EE5\u4E0B\u5143\u7D20\u906E\u6321 <${status.obstruction.tag} id="${status.obstruction.id}">`);
|
|
3335
3458
|
}
|
|
3336
3459
|
const scrollRect = await getScrollableRect2();
|
|
3337
3460
|
if (!scrollRect && status.isFixed) {
|
|
3338
|
-
|
|
3461
|
+
logger5.warn("humanScroll | fixed \u5BB9\u5668\u5185\u4E14\u65E0\u53EF\u6EDA\u52A8\u7956\u5148\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
|
|
3339
3462
|
return { element, didScroll };
|
|
3340
3463
|
}
|
|
3341
3464
|
const stepMin = scrollRect ? Math.min(minStep, Math.max(60, scrollRect.height * 0.4)) : minStep;
|
|
@@ -3371,10 +3494,10 @@ var Humanize = {
|
|
|
3371
3494
|
didScroll = true;
|
|
3372
3495
|
await (0, import_delay2.default)(this.jitterMs(20 + Math.random() * 40, 0.2));
|
|
3373
3496
|
}
|
|
3374
|
-
|
|
3497
|
+
logger5.warn(`humanScroll | \u5728 ${maxSteps} \u6B65\u540E\u65E0\u6CD5\u786E\u4FDD\u53EF\u89C1\u6027`);
|
|
3375
3498
|
return { element, didScroll };
|
|
3376
3499
|
} catch (error) {
|
|
3377
|
-
|
|
3500
|
+
logger5.fail("humanScroll", error);
|
|
3378
3501
|
throw error;
|
|
3379
3502
|
}
|
|
3380
3503
|
},
|
|
@@ -3392,7 +3515,7 @@ var Humanize = {
|
|
|
3392
3515
|
const cursor = $GetCursor(page);
|
|
3393
3516
|
const { reactionDelay = 250, throwOnMissing = true, scrollIfNeeded = true, restore = false } = options;
|
|
3394
3517
|
const targetDesc = target == null ? "Current Position" : typeof target === "string" ? target : "ElementHandle";
|
|
3395
|
-
|
|
3518
|
+
logger5.start("humanClick", `target=${targetDesc}`);
|
|
3396
3519
|
const restoreOnce = async () => {
|
|
3397
3520
|
if (restoreOnce.restored) return;
|
|
3398
3521
|
restoreOnce.restored = true;
|
|
@@ -3401,14 +3524,14 @@ var Humanize = {
|
|
|
3401
3524
|
await (0, import_delay2.default)(this.jitterMs(1e3));
|
|
3402
3525
|
await restoreOnce.do();
|
|
3403
3526
|
} catch (restoreError) {
|
|
3404
|
-
|
|
3527
|
+
logger5.warn(`humanClick: \u6062\u590D\u6EDA\u52A8\u4F4D\u7F6E\u5931\u8D25: ${restoreError.message}`);
|
|
3405
3528
|
}
|
|
3406
3529
|
};
|
|
3407
3530
|
try {
|
|
3408
3531
|
if (target == null) {
|
|
3409
3532
|
await (0, import_delay2.default)(this.jitterMs(reactionDelay, 0.4));
|
|
3410
3533
|
await cursor.actions.click();
|
|
3411
|
-
|
|
3534
|
+
logger5.success("humanClick", "Clicked current position");
|
|
3412
3535
|
return true;
|
|
3413
3536
|
}
|
|
3414
3537
|
let element;
|
|
@@ -3418,7 +3541,7 @@ var Humanize = {
|
|
|
3418
3541
|
if (throwOnMissing) {
|
|
3419
3542
|
throw new Error(`\u627E\u4E0D\u5230\u5143\u7D20 ${target}`);
|
|
3420
3543
|
}
|
|
3421
|
-
|
|
3544
|
+
logger5.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${target}`);
|
|
3422
3545
|
return false;
|
|
3423
3546
|
}
|
|
3424
3547
|
} else {
|
|
@@ -3434,7 +3557,7 @@ var Humanize = {
|
|
|
3434
3557
|
if (throwOnMissing) {
|
|
3435
3558
|
throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5143\u7D20\u4F4D\u7F6E");
|
|
3436
3559
|
}
|
|
3437
|
-
|
|
3560
|
+
logger5.warn("humanClick: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E\uFF0C\u8DF3\u8FC7\u70B9\u51FB");
|
|
3438
3561
|
return false;
|
|
3439
3562
|
}
|
|
3440
3563
|
const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.3;
|
|
@@ -3443,11 +3566,11 @@ var Humanize = {
|
|
|
3443
3566
|
await (0, import_delay2.default)(this.jitterMs(reactionDelay, 0.4));
|
|
3444
3567
|
await cursor.actions.click();
|
|
3445
3568
|
await restoreOnce();
|
|
3446
|
-
|
|
3569
|
+
logger5.success("humanClick");
|
|
3447
3570
|
return true;
|
|
3448
3571
|
} catch (error) {
|
|
3449
3572
|
await restoreOnce();
|
|
3450
|
-
|
|
3573
|
+
logger5.fail("humanClick", error);
|
|
3451
3574
|
throw error;
|
|
3452
3575
|
}
|
|
3453
3576
|
},
|
|
@@ -3458,9 +3581,9 @@ var Humanize = {
|
|
|
3458
3581
|
*/
|
|
3459
3582
|
async randomSleep(baseMs, jitterPercent = 0.3) {
|
|
3460
3583
|
const ms = this.jitterMs(baseMs, jitterPercent);
|
|
3461
|
-
|
|
3584
|
+
logger5.start("randomSleep", `base=${baseMs}, actual=${ms}ms`);
|
|
3462
3585
|
await (0, import_delay2.default)(ms);
|
|
3463
|
-
|
|
3586
|
+
logger5.success("randomSleep");
|
|
3464
3587
|
},
|
|
3465
3588
|
/**
|
|
3466
3589
|
* 模拟人类"注视"或"阅读"行为:鼠标在页面上随机微动
|
|
@@ -3470,7 +3593,7 @@ var Humanize = {
|
|
|
3470
3593
|
async simulateGaze(page, baseDurationMs = 2500) {
|
|
3471
3594
|
const cursor = $GetCursor(page);
|
|
3472
3595
|
const durationMs = this.jitterMs(baseDurationMs, 0.4);
|
|
3473
|
-
|
|
3596
|
+
logger5.start("simulateGaze", `duration=${durationMs}ms`);
|
|
3474
3597
|
const startTime = Date.now();
|
|
3475
3598
|
const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };
|
|
3476
3599
|
while (Date.now() - startTime < durationMs) {
|
|
@@ -3479,7 +3602,7 @@ var Humanize = {
|
|
|
3479
3602
|
await cursor.actions.move({ x, y });
|
|
3480
3603
|
await (0, import_delay2.default)(this.jitterMs(600, 0.5));
|
|
3481
3604
|
}
|
|
3482
|
-
|
|
3605
|
+
logger5.success("simulateGaze");
|
|
3483
3606
|
},
|
|
3484
3607
|
/**
|
|
3485
3608
|
* 人类化输入 - 带节奏变化(快-慢-停顿-偶尔加速)
|
|
@@ -3492,7 +3615,7 @@ var Humanize = {
|
|
|
3492
3615
|
* @param {number} [options.pauseBase=800] - 停顿时长基础值 (ms),实际 ±50% 抖动
|
|
3493
3616
|
*/
|
|
3494
3617
|
async humanType(page, selector, text, options = {}) {
|
|
3495
|
-
|
|
3618
|
+
logger5.start("humanType", `selector=${selector}, textLen=${text.length}`);
|
|
3496
3619
|
const {
|
|
3497
3620
|
baseDelay = 180,
|
|
3498
3621
|
pauseProbability = 0.08,
|
|
@@ -3516,13 +3639,13 @@ var Humanize = {
|
|
|
3516
3639
|
await (0, import_delay2.default)(charDelay);
|
|
3517
3640
|
if (Math.random() < pauseProbability && i < text.length - 1) {
|
|
3518
3641
|
const pauseTime = this.jitterMs(pauseBase, 0.5);
|
|
3519
|
-
|
|
3642
|
+
logger5.debug(`\u505C\u987F ${pauseTime}ms...`);
|
|
3520
3643
|
await (0, import_delay2.default)(pauseTime);
|
|
3521
3644
|
}
|
|
3522
3645
|
}
|
|
3523
|
-
|
|
3646
|
+
logger5.success("humanType");
|
|
3524
3647
|
} catch (error) {
|
|
3525
|
-
|
|
3648
|
+
logger5.fail("humanType", error);
|
|
3526
3649
|
throw error;
|
|
3527
3650
|
}
|
|
3528
3651
|
},
|
|
@@ -3546,7 +3669,7 @@ var Humanize = {
|
|
|
3546
3669
|
keyboardOptions = {}
|
|
3547
3670
|
} = pressOptions || {};
|
|
3548
3671
|
const targetDesc = hasTarget ? typeof targetOrKey === "string" ? targetOrKey : "ElementHandle" : "current focus";
|
|
3549
|
-
|
|
3672
|
+
logger5.start("humanPress", `key=${key}, target=${targetDesc}`);
|
|
3550
3673
|
try {
|
|
3551
3674
|
if (hasTarget) {
|
|
3552
3675
|
await this.humanClick(page, targetOrKey, { reactionDelay: focusDelay, scrollIfNeeded, throwOnMissing });
|
|
@@ -3556,10 +3679,10 @@ var Humanize = {
|
|
|
3556
3679
|
...keyboardOptions,
|
|
3557
3680
|
delay: this.jitterMs(holdDelay, 0.5)
|
|
3558
3681
|
});
|
|
3559
|
-
|
|
3682
|
+
logger5.success("humanPress");
|
|
3560
3683
|
return true;
|
|
3561
3684
|
} catch (error) {
|
|
3562
|
-
|
|
3685
|
+
logger5.fail("humanPress", error);
|
|
3563
3686
|
throw error;
|
|
3564
3687
|
}
|
|
3565
3688
|
},
|
|
@@ -3569,22 +3692,22 @@ var Humanize = {
|
|
|
3569
3692
|
* @param {string} selector - 输入框选择器
|
|
3570
3693
|
*/
|
|
3571
3694
|
async humanClear(page, selector) {
|
|
3572
|
-
|
|
3695
|
+
logger5.start("humanClear", `selector=${selector}`);
|
|
3573
3696
|
try {
|
|
3574
3697
|
const locator = page.locator(selector);
|
|
3575
3698
|
await locator.click();
|
|
3576
3699
|
await (0, import_delay2.default)(this.jitterMs(200, 0.4));
|
|
3577
3700
|
const currentValue = await locator.inputValue();
|
|
3578
3701
|
if (!currentValue || currentValue.length === 0) {
|
|
3579
|
-
|
|
3702
|
+
logger5.success("humanClear", "already empty");
|
|
3580
3703
|
return;
|
|
3581
3704
|
}
|
|
3582
3705
|
await page.keyboard.press("Meta+A");
|
|
3583
3706
|
await (0, import_delay2.default)(this.jitterMs(100, 0.4));
|
|
3584
3707
|
await page.keyboard.press("Backspace");
|
|
3585
|
-
|
|
3708
|
+
logger5.success("humanClear");
|
|
3586
3709
|
} catch (error) {
|
|
3587
|
-
|
|
3710
|
+
logger5.fail("humanClear", error);
|
|
3588
3711
|
throw error;
|
|
3589
3712
|
}
|
|
3590
3713
|
},
|
|
@@ -3596,7 +3719,7 @@ var Humanize = {
|
|
|
3596
3719
|
async warmUpBrowsing(page, baseDuration = 3500) {
|
|
3597
3720
|
const cursor = $GetCursor(page);
|
|
3598
3721
|
const durationMs = this.jitterMs(baseDuration, 0.4);
|
|
3599
|
-
|
|
3722
|
+
logger5.start("warmUpBrowsing", `duration=${durationMs}ms`);
|
|
3600
3723
|
const startTime = Date.now();
|
|
3601
3724
|
const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };
|
|
3602
3725
|
try {
|
|
@@ -3615,9 +3738,9 @@ var Humanize = {
|
|
|
3615
3738
|
await (0, import_delay2.default)(this.jitterMs(800, 0.5));
|
|
3616
3739
|
}
|
|
3617
3740
|
}
|
|
3618
|
-
|
|
3741
|
+
logger5.success("warmUpBrowsing");
|
|
3619
3742
|
} catch (error) {
|
|
3620
|
-
|
|
3743
|
+
logger5.fail("warmUpBrowsing", error);
|
|
3621
3744
|
throw error;
|
|
3622
3745
|
}
|
|
3623
3746
|
},
|
|
@@ -3631,7 +3754,7 @@ var Humanize = {
|
|
|
3631
3754
|
async naturalScroll(page, direction = "down", distance = 300, baseSteps = 5) {
|
|
3632
3755
|
const steps = Math.max(3, baseSteps + Math.floor(Math.random() * 3) - 1);
|
|
3633
3756
|
const actualDistance = this.jitterMs(distance, 0.15);
|
|
3634
|
-
|
|
3757
|
+
logger5.start("naturalScroll", `dir=${direction}, dist=${actualDistance}, steps=${steps}`);
|
|
3635
3758
|
const sign = direction === "down" ? 1 : -1;
|
|
3636
3759
|
const stepDistance = actualDistance / steps;
|
|
3637
3760
|
try {
|
|
@@ -3643,9 +3766,9 @@ var Humanize = {
|
|
|
3643
3766
|
const baseDelay = 60 + i * 25;
|
|
3644
3767
|
await (0, import_delay2.default)(this.jitterMs(baseDelay, 0.3));
|
|
3645
3768
|
}
|
|
3646
|
-
|
|
3769
|
+
logger5.success("naturalScroll");
|
|
3647
3770
|
} catch (error) {
|
|
3648
|
-
|
|
3771
|
+
logger5.fail("naturalScroll", error);
|
|
3649
3772
|
throw error;
|
|
3650
3773
|
}
|
|
3651
3774
|
}
|
|
@@ -3674,7 +3797,7 @@ var resolveElement = async (page, target, { throwOnMissing = true } = {}) => {
|
|
|
3674
3797
|
var waitJitter = (base, jitterPercent = 0.3) => (0, import_delay3.default)(jitterMs(base, jitterPercent));
|
|
3675
3798
|
|
|
3676
3799
|
// src/internals/humanize/mobile.js
|
|
3677
|
-
var
|
|
3800
|
+
var logger6 = createInternalLogger("Humanize.Mobile");
|
|
3678
3801
|
var initializedPages = /* @__PURE__ */ new WeakSet();
|
|
3679
3802
|
var DEFAULT_TAP_TIMEOUT_MS = 2500;
|
|
3680
3803
|
var DEFAULT_MOUSE_TAP_FALLBACK_TIMEOUT_MS = 1200;
|
|
@@ -4044,7 +4167,7 @@ var restoreWindowFromSnapshot = async (page, before, after) => {
|
|
|
4044
4167
|
return;
|
|
4045
4168
|
}
|
|
4046
4169
|
await page.evaluate(
|
|
4047
|
-
(
|
|
4170
|
+
(state2) => window.scrollTo(state2.x, state2.y),
|
|
4048
4171
|
{ x: Number(before.scrollX || 0), y: Number(before.scrollY || 0) }
|
|
4049
4172
|
).catch(() => {
|
|
4050
4173
|
});
|
|
@@ -4131,7 +4254,7 @@ var dispatchTouchSwipe = async (page, deltaY, options = {}) => {
|
|
|
4131
4254
|
}
|
|
4132
4255
|
return true;
|
|
4133
4256
|
} catch (error) {
|
|
4134
|
-
|
|
4257
|
+
logger6.debug(`touch swipe fallback: ${error?.message || error}`);
|
|
4135
4258
|
try {
|
|
4136
4259
|
await page.evaluate((amount) => window.scrollBy(0, amount), deltaY);
|
|
4137
4260
|
await waitJitter(120, 0.35);
|
|
@@ -4165,7 +4288,7 @@ var tapPoint = async (page, point, options = {}) => {
|
|
|
4165
4288
|
);
|
|
4166
4289
|
return { method: "touchscreen" };
|
|
4167
4290
|
} catch (error) {
|
|
4168
|
-
|
|
4291
|
+
logger6.warn(`tapPoint | touchscreen.tap \u5931\u8D25\u6216\u8D85\u65F6\uFF0C\u5C1D\u8BD5\u9F20\u6807\u515C\u5E95: ${error?.message || error}`);
|
|
4169
4292
|
if (!allowMouseFallback) throw error;
|
|
4170
4293
|
}
|
|
4171
4294
|
}
|
|
@@ -4181,10 +4304,10 @@ var MobileHumanize = {
|
|
|
4181
4304
|
async initializeCursor(page) {
|
|
4182
4305
|
if (initializedPages.has(page)) return;
|
|
4183
4306
|
initializedPages.add(page);
|
|
4184
|
-
|
|
4307
|
+
logger6.debug("initializeCursor: mobile mode uses touch gestures, cursor init skipped");
|
|
4185
4308
|
},
|
|
4186
4309
|
async humanMove(page, target) {
|
|
4187
|
-
|
|
4310
|
+
logger6.debug(`humanMove: mobile no-op target=${typeof target === "string" ? target : "element/coords"}`);
|
|
4188
4311
|
if (typeof target === "string" || target && typeof target.boundingBox === "function") {
|
|
4189
4312
|
const element = await resolveElement(page, target, { throwOnMissing: false });
|
|
4190
4313
|
if (!element) {
|
|
@@ -4203,10 +4326,10 @@ var MobileHumanize = {
|
|
|
4203
4326
|
throwOnMissing = false
|
|
4204
4327
|
} = options;
|
|
4205
4328
|
const targetDesc = describeTarget(target);
|
|
4206
|
-
|
|
4329
|
+
logger6.start("humanScroll", `target=${targetDesc}`);
|
|
4207
4330
|
const element = await resolveElement(page, target, { throwOnMissing });
|
|
4208
4331
|
if (!element) {
|
|
4209
|
-
|
|
4332
|
+
logger6.warn(`humanScroll | \u5143\u7D20\u672A\u627E\u5230: ${targetDesc}`);
|
|
4210
4333
|
return { element: null, didScroll: false, restore: null };
|
|
4211
4334
|
}
|
|
4212
4335
|
const startTime = Date.now();
|
|
@@ -4215,42 +4338,42 @@ var MobileHumanize = {
|
|
|
4215
4338
|
const status = await checkElementVisibility(element);
|
|
4216
4339
|
if (status.code === "VISIBLE") {
|
|
4217
4340
|
if (status.isFixed) {
|
|
4218
|
-
|
|
4341
|
+
logger6.info("humanScroll | fixed/sticky \u5BB9\u5668\u5185\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
|
|
4219
4342
|
} else {
|
|
4220
|
-
|
|
4343
|
+
logger6.debug("humanScroll | \u5143\u7D20\u53EF\u89C1\u4E14\u65E0\u906E\u6321");
|
|
4221
4344
|
}
|
|
4222
|
-
|
|
4345
|
+
logger6.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
|
|
4223
4346
|
return { element, didScroll, restore: null };
|
|
4224
4347
|
}
|
|
4225
4348
|
if (status.code === "ZERO_DIMENSIONS" || status.code === "NOT_INTERACTABLE") {
|
|
4226
|
-
|
|
4349
|
+
logger6.warn(`humanScroll | \u5143\u7D20\u4E0D\u53EF\u6EDA\u52A8\u81F3\u53EF\u70B9\u51FB\u72B6\u6001: ${status.reason || status.code}`);
|
|
4227
4350
|
return { element, didScroll, restore: null };
|
|
4228
4351
|
}
|
|
4229
4352
|
const scrollRect = await getScrollableRect(element);
|
|
4230
4353
|
if (!scrollRect && status.isFixed && status.code === "OUT_OF_VIEWPORT") {
|
|
4231
|
-
|
|
4354
|
+
logger6.warn(`humanScroll | fixed/sticky \u76EE\u6807\u4E0D\u5728\u89C6\u53E3\u5185\uFF0C\u9875\u9762\u6EDA\u52A8\u65E0\u6CD5\u6539\u53D8\u5176\u4F4D\u7F6E (direction=${status.direction || "unknown"})`);
|
|
4232
4355
|
return { element, didScroll, restore: null, unscrollable: true };
|
|
4233
4356
|
}
|
|
4234
4357
|
if (!scrollRect && status.isFixed && status.code === "OBSTRUCTED") {
|
|
4235
|
-
|
|
4358
|
+
logger6.warn(`humanScroll | fixed/sticky \u76EE\u6807\u88AB\u906E\u6321\uFF0C\u6EDA\u52A8\u65E0\u6CD5\u89E3\u9664 (${status.obstruction?.tag || "unknown"})`);
|
|
4236
4359
|
return { element, didScroll, restore: null, unscrollable: true };
|
|
4237
4360
|
}
|
|
4238
4361
|
if (scrollRect && status.code === "OBSTRUCTED" && status.obstruction?.isFixed) {
|
|
4239
4362
|
const moved = await scrollAwayFromObstruction(element, status);
|
|
4240
4363
|
if (moved.moved) {
|
|
4241
|
-
|
|
4364
|
+
logger6.debug(`humanScroll | sticky/fixed \u906E\u6321\u8865\u507F\u6EDA\u52A8 top=${Math.round(moved.scrollTop || 0)}`);
|
|
4242
4365
|
await waitJitter(90, 0.3);
|
|
4243
4366
|
didScroll = true;
|
|
4244
4367
|
continue;
|
|
4245
4368
|
}
|
|
4246
4369
|
}
|
|
4247
4370
|
if (Date.now() - startTime > maxDurationMs) {
|
|
4248
|
-
|
|
4371
|
+
logger6.warn(`humanScroll | mobile timeout (${maxDurationMs}ms, status=${status.code}, direction=${status.direction || "unknown"}, fixed=${Boolean(status.isFixed)})`);
|
|
4249
4372
|
return { element, didScroll, restore: null };
|
|
4250
4373
|
}
|
|
4251
4374
|
const stepMin = scrollRect ? Math.min(minStep, Math.max(60, scrollRect.height * 0.4)) : minStep;
|
|
4252
4375
|
const stepMax = scrollRect ? Math.min(maxStep, Math.max(stepMin + 40, scrollRect.height * 0.8)) : maxStep;
|
|
4253
|
-
|
|
4376
|
+
logger6.debug(`humanScroll | \u6B65\u9AA4 ${i + 1}/${maxSteps}: ${status.reason || status.code} ${status.direction ? `(${status.direction})` : ""}`);
|
|
4254
4377
|
const distance = stepMin + Math.random() * Math.max(1, stepMax - stepMin);
|
|
4255
4378
|
let deltaY = status.direction === "up" ? -distance : distance;
|
|
4256
4379
|
if (status.code === "OBSTRUCTED") {
|
|
@@ -4290,8 +4413,8 @@ var MobileHumanize = {
|
|
|
4290
4413
|
if (scrollRect && beforeWindowState) {
|
|
4291
4414
|
const afterWindowState = await page.evaluate(() => ({ x: window.scrollX, y: window.scrollY }));
|
|
4292
4415
|
if (Math.abs(afterWindowState.x - beforeWindowState.x) > 2 || Math.abs(afterWindowState.y - beforeWindowState.y) > 2) {
|
|
4293
|
-
await page.evaluate((
|
|
4294
|
-
|
|
4416
|
+
await page.evaluate((state2) => window.scrollTo(state2.x, state2.y), beforeWindowState);
|
|
4417
|
+
logger6.debug(`humanScroll | \u7A97\u53E3\u6EDA\u52A8\u56DE\u6536 from=${Math.round(afterWindowState.y)} to=${Math.round(beforeWindowState.y)}`);
|
|
4295
4418
|
}
|
|
4296
4419
|
}
|
|
4297
4420
|
let afterElementSnapshot = null;
|
|
@@ -4305,7 +4428,7 @@ var MobileHumanize = {
|
|
|
4305
4428
|
const afterSnapshot = await readAfterElementSnapshot();
|
|
4306
4429
|
if (isTargetImmobileAfterScroll(beforeElementSnapshot, afterSnapshot)) {
|
|
4307
4430
|
await restoreWindowFromSnapshot(page, beforeElementSnapshot, afterSnapshot);
|
|
4308
|
-
|
|
4431
|
+
logger6.warn(`humanScroll | \u76EE\u6807\u4E0D\u968F\u9875\u9762\u6EDA\u52A8\u79FB\u52A8\uFF0C\u9875\u9762\u6EDA\u52A8\u65E0\u6CD5\u6539\u53D8\u5176\u4F4D\u7F6E (status=${status.code}, direction=${status.direction || "unknown"})`);
|
|
4309
4432
|
return { element, didScroll, restore: null, unscrollable: true };
|
|
4310
4433
|
}
|
|
4311
4434
|
}
|
|
@@ -4337,12 +4460,12 @@ var MobileHumanize = {
|
|
|
4337
4460
|
const moved = beforeState.kind !== afterState.kind || Math.abs(topDelta) > 2 || Math.abs(leftDelta) > 2;
|
|
4338
4461
|
if (!moved) {
|
|
4339
4462
|
const fallback = await scrollScrollableAncestor(element, deltaY);
|
|
4340
|
-
|
|
4463
|
+
logger6.debug(`humanScroll | \u5BB9\u5668\u89E6\u6478\u65E0\u6548\uFF0C\u76F4\u63A5\u6EDA\u52A8 fallback=${fallback.scroller ? "ancestor" : "window"} top=${Math.round(fallback.scrollTop || 0)}`);
|
|
4341
4464
|
} else if (beforeState.kind === afterState.kind && Math.abs(expectedDelta) > 24 && Math.sign(topDelta || expectedDelta) === Math.sign(expectedDelta) && Math.abs(topDelta) < Math.min(Math.abs(expectedDelta) * 0.45, 96)) {
|
|
4342
4465
|
const residualDelta = expectedDelta - topDelta;
|
|
4343
4466
|
if (Math.sign(residualDelta) === Math.sign(expectedDelta) && Math.abs(residualDelta) > 24) {
|
|
4344
4467
|
const fallback = await scrollScrollableAncestor(element, residualDelta);
|
|
4345
|
-
|
|
4468
|
+
logger6.debug(`humanScroll | \u5BB9\u5668\u89E6\u6478\u8DDD\u79BB\u4E0D\u8DB3\uFF0C\u8865\u507F\u6EDA\u52A8 fallback=${fallback.scroller ? "ancestor" : "window"} top=${Math.round(fallback.scrollTop || 0)}`);
|
|
4346
4469
|
}
|
|
4347
4470
|
}
|
|
4348
4471
|
}
|
|
@@ -4350,7 +4473,7 @@ var MobileHumanize = {
|
|
|
4350
4473
|
const afterSnapshot = await getElementViewportSnapshot(element).catch(() => null);
|
|
4351
4474
|
if (isTargetImmobileAfterScroll(beforeElementSnapshot, afterSnapshot)) {
|
|
4352
4475
|
await restoreWindowFromSnapshot(page, beforeElementSnapshot, afterSnapshot);
|
|
4353
|
-
|
|
4476
|
+
logger6.warn(`humanScroll | \u76EE\u6807\u4E0D\u968F\u6EDA\u52A8\u5BB9\u5668\u79FB\u52A8\uFF0C\u6EDA\u52A8\u65E0\u6CD5\u6539\u53D8\u5176\u4F4D\u7F6E (status=${status.code}, direction=${status.direction || "unknown"})`);
|
|
4354
4477
|
return { element, didScroll, restore: null, unscrollable: true };
|
|
4355
4478
|
}
|
|
4356
4479
|
}
|
|
@@ -4361,14 +4484,14 @@ var MobileHumanize = {
|
|
|
4361
4484
|
await waitJitter(80, 0.3);
|
|
4362
4485
|
const finalStatus = await checkElementVisibility(element);
|
|
4363
4486
|
if (finalStatus.code === "VISIBLE") {
|
|
4364
|
-
|
|
4365
|
-
|
|
4487
|
+
logger6.info("humanScroll | \u539F\u751F scrollIntoViewIfNeeded \u515C\u5E95\u6210\u529F");
|
|
4488
|
+
logger6.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
|
|
4366
4489
|
return { element, didScroll: true, restore: null };
|
|
4367
4490
|
}
|
|
4368
4491
|
} catch (fallbackError) {
|
|
4369
|
-
|
|
4492
|
+
logger6.debug(`humanScroll | native fallback failed: ${fallbackError?.message || fallbackError}`);
|
|
4370
4493
|
}
|
|
4371
|
-
|
|
4494
|
+
logger6.warn(`humanScroll | \u5728 ${maxSteps} \u6B65\u540E\u65E0\u6CD5\u786E\u4FDD\u53EF\u89C1\u6027`);
|
|
4372
4495
|
return { element, didScroll, restore: null };
|
|
4373
4496
|
},
|
|
4374
4497
|
async humanClick(page, target, options = {}) {
|
|
@@ -4383,7 +4506,7 @@ var MobileHumanize = {
|
|
|
4383
4506
|
fallbackDomClickOnTapError = true
|
|
4384
4507
|
} = options;
|
|
4385
4508
|
const targetDesc = describeTarget(target);
|
|
4386
|
-
|
|
4509
|
+
logger6.start("humanClick", `target=${targetDesc}`);
|
|
4387
4510
|
try {
|
|
4388
4511
|
if (target == null) {
|
|
4389
4512
|
const viewport = resolveViewport(page);
|
|
@@ -4395,12 +4518,12 @@ var MobileHumanize = {
|
|
|
4395
4518
|
timeoutMs: tapTimeoutMs,
|
|
4396
4519
|
mouseFallbackTimeoutMs
|
|
4397
4520
|
});
|
|
4398
|
-
|
|
4521
|
+
logger6.success("humanClick", "Tapped current position");
|
|
4399
4522
|
return true;
|
|
4400
4523
|
}
|
|
4401
4524
|
const element = await resolveElement(page, target, { throwOnMissing });
|
|
4402
4525
|
if (!element) {
|
|
4403
|
-
|
|
4526
|
+
logger6.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${targetDesc}`);
|
|
4404
4527
|
return false;
|
|
4405
4528
|
}
|
|
4406
4529
|
const scrollResult = scrollIfNeeded ? await MobileHumanize.humanScroll(page, element, { throwOnMissing }) : null;
|
|
@@ -4424,19 +4547,19 @@ var MobileHumanize = {
|
|
|
4424
4547
|
).catch(() => null);
|
|
4425
4548
|
}
|
|
4426
4549
|
if (fallback?.activated) {
|
|
4427
|
-
|
|
4550
|
+
logger6.warn(`humanClick: \u4E0D\u53EF\u6EDA\u52A8\u76EE\u6807\u4E0D\u53EF\u7269\u7406\u70B9\u51FB\uFF0C\u5DF2\u7528 ${fallback.method} \u6FC0\u6D3B`);
|
|
4428
4551
|
return true;
|
|
4429
4552
|
}
|
|
4430
4553
|
}
|
|
4431
4554
|
const message = `\u5143\u7D20\u4E0D\u53EF\u70B9\u51FB: ${status.reason || status.code}`;
|
|
4432
4555
|
if (throwOnMissing) throw new Error(message);
|
|
4433
|
-
|
|
4556
|
+
logger6.warn(`humanClick: ${message}\uFF0C\u8DF3\u8FC7\u70B9\u51FB`);
|
|
4434
4557
|
return false;
|
|
4435
4558
|
}
|
|
4436
4559
|
const box = await element.boundingBox();
|
|
4437
4560
|
if (!box) {
|
|
4438
4561
|
if (throwOnMissing) throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5143\u7D20\u4F4D\u7F6E");
|
|
4439
|
-
|
|
4562
|
+
logger6.warn("humanClick: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E\uFF0C\u8DF3\u8FC7\u70B9\u51FB");
|
|
4440
4563
|
return false;
|
|
4441
4564
|
}
|
|
4442
4565
|
await waitJitter(reactionDelay, 0.45);
|
|
@@ -4457,13 +4580,13 @@ var MobileHumanize = {
|
|
|
4457
4580
|
"activation fallback"
|
|
4458
4581
|
).catch(() => null);
|
|
4459
4582
|
if (!fallback?.activated) throw tapError;
|
|
4460
|
-
|
|
4583
|
+
logger6.warn(`humanClick: tap \u5931\u8D25\u540E\u5DF2\u7528 ${fallback.method} \u515C\u5E95: ${tapError?.message || tapError}`);
|
|
4461
4584
|
}
|
|
4462
4585
|
await waitJitter(120, 0.35);
|
|
4463
|
-
|
|
4586
|
+
logger6.success("humanClick");
|
|
4464
4587
|
return true;
|
|
4465
4588
|
} catch (error) {
|
|
4466
|
-
|
|
4589
|
+
logger6.fail("humanClick", error);
|
|
4467
4590
|
throw error;
|
|
4468
4591
|
}
|
|
4469
4592
|
},
|
|
@@ -4516,7 +4639,7 @@ var MobileHumanize = {
|
|
|
4516
4639
|
keyboardOptions = {}
|
|
4517
4640
|
} = pressOptions || {};
|
|
4518
4641
|
const targetDesc = hasTarget ? describeTarget(targetOrKey) : "current focus";
|
|
4519
|
-
|
|
4642
|
+
logger6.start("humanPress", `key=${key}, target=${targetDesc}`);
|
|
4520
4643
|
try {
|
|
4521
4644
|
if (hasTarget) {
|
|
4522
4645
|
await MobileHumanize.humanClick(page, targetOrKey, {
|
|
@@ -4530,10 +4653,10 @@ var MobileHumanize = {
|
|
|
4530
4653
|
...keyboardOptions,
|
|
4531
4654
|
delay: jitterMs(holdDelay, 0.5)
|
|
4532
4655
|
});
|
|
4533
|
-
|
|
4656
|
+
logger6.success("humanPress");
|
|
4534
4657
|
return true;
|
|
4535
4658
|
} catch (error) {
|
|
4536
|
-
|
|
4659
|
+
logger6.fail("humanPress", error);
|
|
4537
4660
|
throw error;
|
|
4538
4661
|
}
|
|
4539
4662
|
},
|
|
@@ -4600,65 +4723,96 @@ var MobileHumanize = {
|
|
|
4600
4723
|
}
|
|
4601
4724
|
};
|
|
4602
4725
|
|
|
4603
|
-
// src/humanize.js
|
|
4726
|
+
// src/internals/humanize/default.js
|
|
4604
4727
|
var resolveDeviceFromPage2 = (page) => normalizeDevice(page?.[PageRuntimeStateKey]?.device);
|
|
4605
4728
|
var resolveDelegate = (page) => {
|
|
4606
4729
|
return resolveDeviceFromPage2(page) === Device.Mobile ? MobileHumanize : Humanize;
|
|
4607
4730
|
};
|
|
4608
|
-
var
|
|
4609
|
-
|
|
4610
|
-
|
|
4731
|
+
var DefaultHumanizeDevice = withPageReflect(
|
|
4732
|
+
"DefaultHumanize",
|
|
4733
|
+
resolveDelegate,
|
|
4734
|
+
[Humanize, MobileHumanize]
|
|
4735
|
+
);
|
|
4736
|
+
|
|
4737
|
+
// src/internals/humanize/cloak.js
|
|
4738
|
+
var FORCE_CLICK = Object.freeze({
|
|
4739
|
+
forceClick: true,
|
|
4740
|
+
clickOptions: { force: true }
|
|
4741
|
+
});
|
|
4742
|
+
var pointOrNull = async (target) => {
|
|
4743
|
+
if (!target || typeof target.boundingBox !== "function") return null;
|
|
4744
|
+
const box = await target.boundingBox().catch(() => null);
|
|
4745
|
+
return box ? { x: box.x + box.width / 2, y: box.y + box.height / 2 } : null;
|
|
4611
4746
|
};
|
|
4612
|
-
var
|
|
4613
|
-
|
|
4614
|
-
return
|
|
4615
|
-
},
|
|
4616
|
-
initializeCursor(page) {
|
|
4617
|
-
return callDelegate("initializeCursor", page, []);
|
|
4747
|
+
var CloakHumanizeInput = {
|
|
4748
|
+
async initializeCursor(page) {
|
|
4749
|
+
return Boolean(page);
|
|
4618
4750
|
},
|
|
4619
|
-
humanMove(page, target) {
|
|
4620
|
-
|
|
4751
|
+
async humanMove(page, target) {
|
|
4752
|
+
const point = target?.x != null && target?.y != null ? target : await pointOrNull(typeof target === "string" ? page.locator(target).first() : target);
|
|
4753
|
+
return point ? await DeviceInput.move(page, point, { forceMouse: true }) : false;
|
|
4621
4754
|
},
|
|
4622
|
-
humanScroll(page, target
|
|
4623
|
-
|
|
4755
|
+
async humanScroll(page, target) {
|
|
4756
|
+
const element = typeof target === "string" ? page.locator(target).first() : target;
|
|
4757
|
+
if (!element) return { element: null, didScroll: false, restore: null };
|
|
4758
|
+
await element.scrollIntoViewIfNeeded?.();
|
|
4759
|
+
return { element, didScroll: true, restore: null };
|
|
4624
4760
|
},
|
|
4625
|
-
humanClick(page, target
|
|
4626
|
-
return
|
|
4761
|
+
async humanClick(page, target) {
|
|
4762
|
+
return await DeviceInput.click(page, target, FORCE_CLICK);
|
|
4627
4763
|
},
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
return delegate.randomSleep(maybeBaseMs, maybeJitterPercent);
|
|
4632
|
-
}
|
|
4633
|
-
return Humanize.randomSleep(pageOrBaseMs, maybeBaseMs);
|
|
4764
|
+
async humanType(page, selector, text) {
|
|
4765
|
+
await DeviceInput.click(page, selector, FORCE_CLICK);
|
|
4766
|
+
return await DeviceInput.keyboardType(page, text);
|
|
4634
4767
|
},
|
|
4635
|
-
|
|
4636
|
-
return
|
|
4768
|
+
async humanPress(page, targetOrKey, maybeKey) {
|
|
4769
|
+
return await DeviceInput.press(page, targetOrKey, maybeKey, {
|
|
4770
|
+
clickOptions: FORCE_CLICK,
|
|
4771
|
+
keyboardOptions: {}
|
|
4772
|
+
});
|
|
4637
4773
|
},
|
|
4638
|
-
|
|
4639
|
-
return
|
|
4774
|
+
async humanClear(page, selector) {
|
|
4775
|
+
return await DeviceInput.fill(page, selector, "", { force: true });
|
|
4640
4776
|
},
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
return callDelegate("humanPress", page, [targetOrKey, maybeKey, options]);
|
|
4644
|
-
}
|
|
4645
|
-
return callDelegate("humanPress", page, [targetOrKey, maybeKey || options]);
|
|
4777
|
+
async simulateGaze(page) {
|
|
4778
|
+
return await DeviceInput.move(page, { x: 0, y: 0 }, { forceMouse: true });
|
|
4646
4779
|
},
|
|
4647
|
-
|
|
4648
|
-
return
|
|
4780
|
+
async warmUpBrowsing(page) {
|
|
4781
|
+
return await this.simulateGaze(page);
|
|
4649
4782
|
},
|
|
4650
|
-
|
|
4651
|
-
|
|
4783
|
+
async naturalScroll(page, direction = "down", distance = 300) {
|
|
4784
|
+
const sign = direction === "down" ? 1 : -1;
|
|
4785
|
+
await page.mouse.wheel(0, Number(distance || 0) * sign);
|
|
4786
|
+
}
|
|
4787
|
+
};
|
|
4788
|
+
|
|
4789
|
+
// src/internals/humanize/index.js
|
|
4790
|
+
var HumanizeCommon = {
|
|
4791
|
+
jitterMs(base, jitterPercent = 0.3) {
|
|
4792
|
+
return jitterMs(base, jitterPercent);
|
|
4652
4793
|
},
|
|
4653
|
-
|
|
4654
|
-
|
|
4794
|
+
async randomSleep(pageOrBaseMs, maybeBaseMs, maybeJitterPercent) {
|
|
4795
|
+
const hasPage = pageOrBaseMs && typeof pageOrBaseMs === "object" && typeof pageOrBaseMs.evaluate === "function";
|
|
4796
|
+
const baseMs = hasPage ? maybeBaseMs : pageOrBaseMs;
|
|
4797
|
+
const jitterPercent = hasPage ? maybeJitterPercent : maybeBaseMs;
|
|
4798
|
+
await (0, import_delay4.default)(jitterMs(baseMs, jitterPercent ?? 0.3));
|
|
4655
4799
|
}
|
|
4656
4800
|
};
|
|
4801
|
+
var DefaultHumanize = Object.assign({}, DefaultHumanizeDevice, HumanizeCommon);
|
|
4802
|
+
var CloakHumanize = Object.assign({}, CloakHumanizeInput, HumanizeCommon);
|
|
4657
4803
|
|
|
4658
|
-
// src/
|
|
4804
|
+
// src/humanize.js
|
|
4805
|
+
var humanizeStrategies = {
|
|
4806
|
+
[Mode.Default]: DefaultHumanize,
|
|
4807
|
+
[Mode.Cloak]: CloakHumanize
|
|
4808
|
+
};
|
|
4809
|
+
var Humanize2 = withModeReflect("Humanize", humanizeStrategies);
|
|
4810
|
+
|
|
4811
|
+
// src/internals/launch/default.js
|
|
4659
4812
|
var import_node_child_process = require("node:child_process");
|
|
4660
4813
|
var import_fingerprint_generator = require("fingerprint-generator");
|
|
4661
4814
|
var import_fingerprint_injector = require("fingerprint-injector");
|
|
4815
|
+
var import_playwright2 = require("playwright");
|
|
4662
4816
|
|
|
4663
4817
|
// src/proxy-bypass.js
|
|
4664
4818
|
var import_picomatch = __toESM(require("picomatch"), 1);
|
|
@@ -4740,9 +4894,107 @@ var ByPass = {
|
|
|
4740
4894
|
resolveRouteByProxy
|
|
4741
4895
|
};
|
|
4742
4896
|
|
|
4743
|
-
// src/launch.js
|
|
4897
|
+
// src/internals/launch/traffic.js
|
|
4898
|
+
var logger7 = createInternalLogger("Launch");
|
|
4899
|
+
var normalizeObject = (value) => {
|
|
4900
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
4901
|
+
return {};
|
|
4902
|
+
}
|
|
4903
|
+
return value;
|
|
4904
|
+
};
|
|
4905
|
+
var parseProxyConfiguration = (proxyConfiguration = {}) => {
|
|
4906
|
+
const config = normalizeObject(proxyConfiguration);
|
|
4907
|
+
const proxyUrl = String(config.proxy_url || "").trim();
|
|
4908
|
+
const enableProxy = typeof config.enable_proxy === "boolean" ? config.enable_proxy : proxyUrl !== "";
|
|
4909
|
+
const byPassDomains = enableProxy && proxyUrl ? ByPass.normalizeByPassDomains(config.by_pass_domains) : [];
|
|
4910
|
+
return {
|
|
4911
|
+
byPassDomains,
|
|
4912
|
+
enableProxy,
|
|
4913
|
+
proxyUrl
|
|
4914
|
+
};
|
|
4915
|
+
};
|
|
4916
|
+
var resolveLaunchTraffic = ({
|
|
4917
|
+
proxyConfiguration = {},
|
|
4918
|
+
debugMode = false,
|
|
4919
|
+
useMeter = true
|
|
4920
|
+
} = {}) => {
|
|
4921
|
+
const { byPassDomains, enableProxy, proxyUrl } = parseProxyConfiguration(proxyConfiguration);
|
|
4922
|
+
const byPassRules = ByPass.buildByPassDomainRules(byPassDomains);
|
|
4923
|
+
const proxyMeter = useMeter && enableProxy && proxyUrl ? ProxyMeterRuntime.startProxyMeter({ proxyUrl, debugMode }) : null;
|
|
4924
|
+
const launchProxy = proxyMeter ? { server: proxyMeter.server } : null;
|
|
4925
|
+
if (launchProxy && byPassDomains.length > 0) {
|
|
4926
|
+
launchProxy.bypass = byPassDomains.join(",");
|
|
4927
|
+
}
|
|
4928
|
+
return {
|
|
4929
|
+
byPassDomains,
|
|
4930
|
+
byPassRules,
|
|
4931
|
+
enableProxy,
|
|
4932
|
+
proxyUrl,
|
|
4933
|
+
launchProxy
|
|
4934
|
+
};
|
|
4935
|
+
};
|
|
4936
|
+
var logLaunchTraffic = ({
|
|
4937
|
+
byPassDomains = [],
|
|
4938
|
+
debugMode = false,
|
|
4939
|
+
enabled = false,
|
|
4940
|
+
enableProxy = false,
|
|
4941
|
+
explicitProxy = false,
|
|
4942
|
+
launchProxy = null,
|
|
4943
|
+
proxyUrl = ""
|
|
4944
|
+
} = {}) => {
|
|
4945
|
+
if (!enabled) return;
|
|
4946
|
+
if (explicitProxy) {
|
|
4947
|
+
logger7.info("[\u4EE3\u7406\u5DF2\u542F\u7528] \u4F7F\u7528\u663E\u5F0F proxy \u914D\u7F6E\uFF0C\u8DF3\u8FC7 toolkit \u672C\u5730\u6D41\u91CF\u89C2\u6D4B");
|
|
4948
|
+
return;
|
|
4949
|
+
}
|
|
4950
|
+
if (launchProxy) {
|
|
4951
|
+
let upstreamLabel = "";
|
|
4952
|
+
try {
|
|
4953
|
+
const parsedProxyUrl = new URL(proxyUrl.includes("://") ? proxyUrl : `http://${proxyUrl}`);
|
|
4954
|
+
upstreamLabel = `${parsedProxyUrl.protocol}//${parsedProxyUrl.host}`;
|
|
4955
|
+
} catch {
|
|
4956
|
+
}
|
|
4957
|
+
logger7.info(
|
|
4958
|
+
`[\u4EE3\u7406\u5DF2\u542F\u7528] \u672C\u5730=${launchProxy.server} \u4E0A\u6E38=${upstreamLabel || "-"} \u76F4\u8FDE\u57DF\u540D=${byPassDomains.join(",")}`
|
|
4959
|
+
);
|
|
4960
|
+
logger7.info(`[\u6D41\u91CF\u89C2\u6D4B] \u9010\u8BF7\u6C42\u8C03\u8BD5=${Boolean(debugMode) ? "\u5F00\u542F" : "\u5173\u95ED"}\uFF08\u6C47\u603B\u59CB\u7EC8\u5F00\u542F\uFF09`);
|
|
4961
|
+
return;
|
|
4962
|
+
}
|
|
4963
|
+
if (enableProxy) {
|
|
4964
|
+
logger7.info("[\u4EE3\u7406\u672A\u542F\u7528] enable_proxy=true \u4F46 proxy_url \u4E3A\u7A7A");
|
|
4965
|
+
} else if (proxyUrl) {
|
|
4966
|
+
logger7.info("[\u4EE3\u7406\u672A\u542F\u7528] enable_proxy=false \u4E14 proxy_url \u5DF2\u914D\u7F6E");
|
|
4967
|
+
}
|
|
4968
|
+
logger7.info(`[\u6D41\u91CF\u89C2\u6D4B] \u9010\u8BF7\u6C42\u8C03\u8BD5=${Boolean(debugMode) ? "\u5F00\u542F" : "\u5173\u95ED"}\uFF08\u6C47\u603B\u59CB\u7EC8\u5F00\u542F\uFF09`);
|
|
4969
|
+
};
|
|
4970
|
+
var createLaunchTrafficHook = ({
|
|
4971
|
+
byPassDomains = [],
|
|
4972
|
+
byPassRules = [],
|
|
4973
|
+
enabled = false,
|
|
4974
|
+
launchProxy = null
|
|
4975
|
+
} = {}) => {
|
|
4976
|
+
const patchedPages = /* @__PURE__ */ new WeakSet();
|
|
4977
|
+
return (page) => {
|
|
4978
|
+
if (!page || typeof page.on !== "function" || patchedPages.has(page)) {
|
|
4979
|
+
return;
|
|
4980
|
+
}
|
|
4981
|
+
patchedPages.add(page);
|
|
4982
|
+
page.on("request", (req) => {
|
|
4983
|
+
const requestUrl = req.url();
|
|
4984
|
+
const resourceType = req.resourceType();
|
|
4985
|
+
const matched = byPassDomains.length > 0 ? ByPass.findMatchedByPassRule(byPassRules, requestUrl) : null;
|
|
4986
|
+
if (launchProxy) {
|
|
4987
|
+
ProxyMeterRuntime.recordProxyMeterResourceType(requestUrl, resourceType);
|
|
4988
|
+
}
|
|
4989
|
+
if (!enabled || byPassDomains.length === 0) return;
|
|
4990
|
+
if (!matched || !matched.rule) return;
|
|
4991
|
+
logger7.info(`[\u76F4\u8FDE\u547D\u4E2D] \u89C4\u5219=${matched.rule.pattern} \u57DF\u540D=${matched.hostname} \u8D44\u6E90\u7C7B\u578B=${resourceType} \u65B9\u6CD5=${req.method()} \u5730\u5740=${requestUrl}`);
|
|
4992
|
+
});
|
|
4993
|
+
};
|
|
4994
|
+
};
|
|
4995
|
+
|
|
4996
|
+
// src/internals/launch/default.js
|
|
4744
4997
|
var logger8 = createInternalLogger("Launch");
|
|
4745
|
-
var REQUEST_HOOK_FLAG = Symbol("playwright-toolkit-request-hook");
|
|
4746
4998
|
var injectedContexts = /* @__PURE__ */ new WeakSet();
|
|
4747
4999
|
var browserMajorVersionCache = /* @__PURE__ */ new Map();
|
|
4748
5000
|
var DEFAULT_BROWSER_PROFILE_SCHEMA_VERSION = 1;
|
|
@@ -4754,16 +5006,6 @@ var DEFAULT_CRAWLER_BASE_OPTIONS = Object.freeze({
|
|
|
4754
5006
|
navigationTimeoutSecs: 120
|
|
4755
5007
|
});
|
|
4756
5008
|
var fingerprintInjector = new import_fingerprint_injector.FingerprintInjector();
|
|
4757
|
-
var resolveProxyLaunchOptions = (proxyConfiguration = {}) => {
|
|
4758
|
-
const config = proxyConfiguration && typeof proxyConfiguration === "object" && !Array.isArray(proxyConfiguration) ? proxyConfiguration : {};
|
|
4759
|
-
const proxyUrl = String(config.proxy_url || "").trim();
|
|
4760
|
-
const enableProxy = typeof config.enable_proxy === "boolean" ? config.enable_proxy : proxyUrl !== "";
|
|
4761
|
-
if (!enableProxy || !proxyUrl) {
|
|
4762
|
-
return { byPassDomains: [], enableProxy, proxyUrl };
|
|
4763
|
-
}
|
|
4764
|
-
const byPassDomains = ByPass.normalizeByPassDomains(config.by_pass_domains);
|
|
4765
|
-
return { byPassDomains, enableProxy, proxyUrl };
|
|
4766
|
-
};
|
|
4767
5009
|
var parseChromeMajorVersion = (rawValue = "") => {
|
|
4768
5010
|
const match = String(rawValue || "").match(/(?:Chrome|Chromium)(?:\/|\s+(?:for Testing\s+)?)(\d+)/i);
|
|
4769
5011
|
return match ? Number(match[1] || 0) : 0;
|
|
@@ -4807,7 +5049,7 @@ var resolveCoreDevice = (core = {}) => {
|
|
|
4807
5049
|
};
|
|
4808
5050
|
var buildFingerprintGenerator = ({ locale, browserMajorVersion, device }) => {
|
|
4809
5051
|
return new import_fingerprint_generator.FingerprintGenerator(
|
|
4810
|
-
|
|
5052
|
+
DefaultAntiCheat.getFingerprintGeneratorOptions({
|
|
4811
5053
|
locale,
|
|
4812
5054
|
browserMajorVersion,
|
|
4813
5055
|
device
|
|
@@ -4851,7 +5093,7 @@ var buildReplayableBrowserProfile = (runtimeState, launcher) => {
|
|
|
4851
5093
|
}
|
|
4852
5094
|
let nextState = RuntimeEnv.rememberState(runtimeState);
|
|
4853
5095
|
let browserProfileCore = RuntimeEnv.getBrowserProfileCore(nextState);
|
|
4854
|
-
const timezoneId = String(browserProfileCore?.timezone_id || "").trim() ||
|
|
5096
|
+
const timezoneId = String(browserProfileCore?.timezone_id || "").trim() || DefaultAntiCheat.getBaseConfig().timezoneId;
|
|
4855
5097
|
const locale = DEFAULT_LOCALE;
|
|
4856
5098
|
const currentBrowserMajorVersion = detectBrowserMajorVersion(launcher);
|
|
4857
5099
|
const storedBrowserMajorVersion = Number(browserProfileCore?.browser_major_version || 0);
|
|
@@ -4930,7 +5172,7 @@ var applyFingerprintPageOptions = (pageOptions = {}, { fingerprintWithHeaders =
|
|
|
4930
5172
|
pageOptions.timezoneId = timezoneId;
|
|
4931
5173
|
}
|
|
4932
5174
|
};
|
|
4933
|
-
var buildReplayBrowserPoolOptions = (browserProfileCore
|
|
5175
|
+
var buildReplayBrowserPoolOptions = (browserProfileCore) => {
|
|
4934
5176
|
const fingerprintWithHeaders = browserProfileCore?.fingerprint;
|
|
4935
5177
|
const fingerprint = fingerprintWithHeaders?.fingerprint;
|
|
4936
5178
|
if (!fingerprintWithHeaders || !fingerprint) {
|
|
@@ -4939,16 +5181,13 @@ var buildReplayBrowserPoolOptions = (browserProfileCore, modifyPageOptions = nul
|
|
|
4939
5181
|
return {
|
|
4940
5182
|
useFingerprints: false,
|
|
4941
5183
|
prePageCreateHooks: [
|
|
4942
|
-
|
|
5184
|
+
(_pageId, _browserController, pageOptions = {}) => {
|
|
4943
5185
|
if (!pageOptions || typeof pageOptions !== "object") return;
|
|
4944
5186
|
applyFingerprintPageOptions(pageOptions, {
|
|
4945
5187
|
fingerprintWithHeaders,
|
|
4946
5188
|
locale: browserProfileCore.locale,
|
|
4947
5189
|
timezoneId: browserProfileCore.timezone_id
|
|
4948
5190
|
});
|
|
4949
|
-
if (modifyPageOptions) {
|
|
4950
|
-
await modifyPageOptions(pageOptions, { pageId, browserController });
|
|
4951
|
-
}
|
|
4952
5191
|
}
|
|
4953
5192
|
],
|
|
4954
5193
|
postPageCreateHooks: [
|
|
@@ -4963,7 +5202,7 @@ var buildReplayBrowserPoolOptions = (browserProfileCore, modifyPageOptions = nul
|
|
|
4963
5202
|
]
|
|
4964
5203
|
};
|
|
4965
5204
|
};
|
|
4966
|
-
var
|
|
5205
|
+
var DefaultLaunch = {
|
|
4967
5206
|
getPlaywrightCrawlerOptions(options = {}) {
|
|
4968
5207
|
const normalizedOptions = Array.isArray(options) ? { customArgs: options } : options || {};
|
|
4969
5208
|
const {
|
|
@@ -4974,54 +5213,36 @@ var Launch = {
|
|
|
4974
5213
|
debugMode = false,
|
|
4975
5214
|
isRunningOnApify = false,
|
|
4976
5215
|
launcher = null,
|
|
4977
|
-
hooks = {},
|
|
4978
5216
|
preNavigationHooks = [],
|
|
4979
5217
|
postNavigationHooks = [],
|
|
4980
5218
|
runtimeState = null
|
|
4981
5219
|
} = normalizedOptions;
|
|
4982
5220
|
const device = resolveRuntimeDevice(runtimeState);
|
|
4983
|
-
const
|
|
4984
|
-
const
|
|
4985
|
-
const
|
|
4986
|
-
const
|
|
4987
|
-
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
|
|
4991
|
-
const
|
|
4992
|
-
const replayBrowserPoolOptions = buildReplayBrowserPoolOptions(replayContext.browserProfileCore, modifyPageOptions);
|
|
5221
|
+
const effectiveLauncher = launcher || import_playwright2.chromium;
|
|
5222
|
+
const enableByPassLogger = Boolean(logOptions && logOptions.enable);
|
|
5223
|
+
const traffic = resolveLaunchTraffic({ proxyConfiguration, debugMode });
|
|
5224
|
+
const trafficHook = createLaunchTrafficHook({
|
|
5225
|
+
...traffic,
|
|
5226
|
+
enabled: enableByPassLogger
|
|
5227
|
+
});
|
|
5228
|
+
const replayContext = buildReplayableBrowserProfile(runtimeState, effectiveLauncher);
|
|
5229
|
+
const replayBrowserPoolOptions = buildReplayBrowserPoolOptions(replayContext.browserProfileCore);
|
|
4993
5230
|
const launchLocale = String(replayContext.browserProfileCore?.locale || DEFAULT_LOCALE).trim() || DEFAULT_LOCALE;
|
|
4994
5231
|
const launchOptions = {
|
|
4995
5232
|
args: [
|
|
4996
|
-
...
|
|
5233
|
+
...DefaultAntiCheat.getLaunchArgs({ locale: launchLocale }),
|
|
4997
5234
|
...customArgs
|
|
4998
5235
|
],
|
|
4999
5236
|
ignoreDefaultArgs: ["--enable-automation"]
|
|
5000
5237
|
};
|
|
5001
|
-
if (launchProxy) {
|
|
5002
|
-
launchOptions.proxy = launchProxy;
|
|
5003
|
-
}
|
|
5004
|
-
const enableByPassLogger = Boolean(logOptions && logOptions.enable);
|
|
5005
|
-
if (enableByPassLogger && launchProxy) {
|
|
5006
|
-
let upstreamLabel = "";
|
|
5007
|
-
try {
|
|
5008
|
-
const parsedProxyUrl = new URL(proxyUrl.includes("://") ? proxyUrl : `http://${proxyUrl}`);
|
|
5009
|
-
upstreamLabel = `${parsedProxyUrl.protocol}//${parsedProxyUrl.host}`;
|
|
5010
|
-
} catch {
|
|
5011
|
-
}
|
|
5012
|
-
logger8.info(
|
|
5013
|
-
`[\u4EE3\u7406\u5DF2\u542F\u7528] \u672C\u5730=${launchProxy.server} \u4E0A\u6E38=${upstreamLabel || "-"} \u76F4\u8FDE\u57DF\u540D=${(byPassDomains || []).join(",")}`
|
|
5014
|
-
);
|
|
5015
|
-
logger8.info(`[\u6D41\u91CF\u89C2\u6D4B] \u9010\u8BF7\u6C42\u8C03\u8BD5=${Boolean(debugMode) ? "\u5F00\u542F" : "\u5173\u95ED"}\uFF08\u6C47\u603B\u59CB\u7EC8\u5F00\u542F\uFF09`);
|
|
5016
|
-
} else if (enableByPassLogger && enableProxy && !launchProxy) {
|
|
5017
|
-
logger8.info("[\u4EE3\u7406\u672A\u542F\u7528] enable_proxy=true \u4F46 proxy_url \u4E3A\u7A7A");
|
|
5018
|
-
logger8.info(`[\u6D41\u91CF\u89C2\u6D4B] \u9010\u8BF7\u6C42\u8C03\u8BD5=${Boolean(debugMode) ? "\u5F00\u542F" : "\u5173\u95ED"}\uFF08\u6C47\u603B\u59CB\u7EC8\u5F00\u542F\uFF09`);
|
|
5019
|
-
} else if (enableByPassLogger && !enableProxy && proxyUrl) {
|
|
5020
|
-
logger8.info("[\u4EE3\u7406\u672A\u542F\u7528] enable_proxy=false \u4E14 proxy_url \u5DF2\u914D\u7F6E");
|
|
5021
|
-
logger8.info(`[\u6D41\u91CF\u89C2\u6D4B] \u9010\u8BF7\u6C42\u8C03\u8BD5=${Boolean(debugMode) ? "\u5F00\u542F" : "\u5173\u95ED"}\uFF08\u6C47\u603B\u59CB\u7EC8\u5F00\u542F\uFF09`);
|
|
5022
|
-
} else if (enableByPassLogger) {
|
|
5023
|
-
logger8.info(`[\u6D41\u91CF\u89C2\u6D4B] \u9010\u8BF7\u6C42\u8C03\u8BD5=${Boolean(debugMode) ? "\u5F00\u542F" : "\u5173\u95ED"}\uFF08\u6C47\u603B\u59CB\u7EC8\u5F00\u542F\uFF09`);
|
|
5238
|
+
if (traffic.launchProxy) {
|
|
5239
|
+
launchOptions.proxy = traffic.launchProxy;
|
|
5024
5240
|
}
|
|
5241
|
+
logLaunchTraffic({
|
|
5242
|
+
...traffic,
|
|
5243
|
+
debugMode,
|
|
5244
|
+
enabled: enableByPassLogger
|
|
5245
|
+
});
|
|
5025
5246
|
const onPageCreated = (page) => {
|
|
5026
5247
|
const recommendedGotoOptions = {
|
|
5027
5248
|
waitUntil: "commit"
|
|
@@ -5029,31 +5250,14 @@ var Launch = {
|
|
|
5029
5250
|
if (!page || typeof page.on !== "function") {
|
|
5030
5251
|
return recommendedGotoOptions;
|
|
5031
5252
|
}
|
|
5032
|
-
|
|
5033
|
-
return recommendedGotoOptions;
|
|
5034
|
-
}
|
|
5035
|
-
page[REQUEST_HOOK_FLAG] = true;
|
|
5036
|
-
const requestHandler = (req) => {
|
|
5037
|
-
const requestUrl = req.url();
|
|
5038
|
-
const resourceType = req.resourceType();
|
|
5039
|
-
const matched = byPassDomains.length > 0 ? ByPass.findMatchedByPassRule(byPassRules, requestUrl) : null;
|
|
5040
|
-
if (launchProxy) {
|
|
5041
|
-
ProxyMeterRuntime.recordProxyMeterResourceType(requestUrl, resourceType);
|
|
5042
|
-
}
|
|
5043
|
-
if (!enableByPassLogger || byPassDomains.length === 0) return;
|
|
5044
|
-
if (!matched || !matched.rule) return;
|
|
5045
|
-
logger8.info(`[\u76F4\u8FDE\u547D\u4E2D] \u89C4\u5219=${matched.rule.pattern} \u57DF\u540D=${matched.hostname} \u8D44\u6E90\u7C7B\u578B=${resourceType} \u65B9\u6CD5=${req.method()} \u5730\u5740=${requestUrl}`);
|
|
5046
|
-
};
|
|
5047
|
-
page.on("request", requestHandler);
|
|
5253
|
+
trafficHook(page);
|
|
5048
5254
|
return recommendedGotoOptions;
|
|
5049
5255
|
};
|
|
5050
5256
|
const launchContext = {
|
|
5051
5257
|
useIncognitoPages: true,
|
|
5052
|
-
launchOptions
|
|
5258
|
+
launchOptions,
|
|
5259
|
+
launcher: effectiveLauncher
|
|
5053
5260
|
};
|
|
5054
|
-
if (launcher) {
|
|
5055
|
-
launchContext.launcher = launcher;
|
|
5056
|
-
}
|
|
5057
5261
|
const crawlerBaseOptions = {
|
|
5058
5262
|
...DEFAULT_CRAWLER_BASE_OPTIONS,
|
|
5059
5263
|
headless: !runInHeadfulMode || isRunningOnApify,
|
|
@@ -5061,23 +5265,20 @@ var Launch = {
|
|
|
5061
5265
|
browserPoolOptions: replayBrowserPoolOptions || {
|
|
5062
5266
|
useFingerprints: true,
|
|
5063
5267
|
fingerprintOptions: {
|
|
5064
|
-
fingerprintGeneratorOptions:
|
|
5268
|
+
fingerprintGeneratorOptions: DefaultAntiCheat.getFingerprintGeneratorOptions({
|
|
5065
5269
|
locale: launchLocale,
|
|
5066
5270
|
device
|
|
5067
5271
|
})
|
|
5068
5272
|
},
|
|
5069
5273
|
prePageCreateHooks: [
|
|
5070
|
-
|
|
5274
|
+
(_pageId, browserController, pageOptions = {}) => {
|
|
5071
5275
|
const fingerprintWithHeaders = browserController?.launchContext?.fingerprint;
|
|
5072
|
-
const timezoneId =
|
|
5276
|
+
const timezoneId = DefaultAntiCheat.getBaseConfig().timezoneId;
|
|
5073
5277
|
applyFingerprintPageOptions(pageOptions, {
|
|
5074
5278
|
fingerprintWithHeaders,
|
|
5075
5279
|
locale: launchLocale,
|
|
5076
5280
|
timezoneId
|
|
5077
5281
|
});
|
|
5078
|
-
if (modifyPageOptions) {
|
|
5079
|
-
await modifyPageOptions(pageOptions, { pageId, browserController });
|
|
5080
|
-
}
|
|
5081
5282
|
}
|
|
5082
5283
|
]
|
|
5083
5284
|
},
|
|
@@ -5099,10 +5300,303 @@ var Launch = {
|
|
|
5099
5300
|
}
|
|
5100
5301
|
};
|
|
5101
5302
|
|
|
5303
|
+
// src/internals/launch/cloak.js
|
|
5304
|
+
var import_node_child_process2 = require("node:child_process");
|
|
5305
|
+
var import_node_util = require("node:util");
|
|
5306
|
+
var logger9 = createInternalLogger("Launch");
|
|
5307
|
+
var execFileAsync = (0, import_node_util.promisify)(import_node_child_process2.execFile);
|
|
5308
|
+
var DEFAULT_CLOAK_CRAWLER_BASE_OPTIONS = Object.freeze({
|
|
5309
|
+
maxConcurrency: 1,
|
|
5310
|
+
maxRequestRetries: 0,
|
|
5311
|
+
requestHandlerTimeoutSecs: 240,
|
|
5312
|
+
navigationTimeoutSecs: 120
|
|
5313
|
+
});
|
|
5314
|
+
var DEFAULT_CLOAK_HUMANIZE_OPTIONS = Object.freeze({
|
|
5315
|
+
humanize: true
|
|
5316
|
+
});
|
|
5317
|
+
var DEFAULT_CLOAK_GOTO_OPTIONS = Object.freeze({
|
|
5318
|
+
waitUntil: "commit"
|
|
5319
|
+
});
|
|
5320
|
+
var DEFAULT_CLOAK_FINGERPRINT_PLATFORM = "linux";
|
|
5321
|
+
var CLOAK_FINGERPRINT_PLATFORM_ARG_PREFIX = "--fingerprint-platform=";
|
|
5322
|
+
var SUPPORTED_CLOAK_FINGERPRINT_PLATFORMS = /* @__PURE__ */ new Set(["linux", "macos", "windows"]);
|
|
5323
|
+
var cachedCloakModulePromise = null;
|
|
5324
|
+
var hasOwn = (target, key) => Object.prototype.hasOwnProperty.call(target, key);
|
|
5325
|
+
var loadCloakModule = async () => {
|
|
5326
|
+
if (!cachedCloakModulePromise) {
|
|
5327
|
+
cachedCloakModulePromise = import("cloakbrowser").catch((error) => {
|
|
5328
|
+
cachedCloakModulePromise = null;
|
|
5329
|
+
throw new Error("Cloak \u6A21\u5757\u52A0\u8F7D\u5931\u8D25\uFF0C\u8BF7\u786E\u8BA4\u5F53\u524D\u8FD0\u884C\u73AF\u5883\u5DF2\u5B89\u88C5 cloakbrowser\u3002", {
|
|
5330
|
+
cause: error
|
|
5331
|
+
});
|
|
5332
|
+
});
|
|
5333
|
+
}
|
|
5334
|
+
return cachedCloakModulePromise;
|
|
5335
|
+
};
|
|
5336
|
+
var buildCloakLaunchOptions = async (options = {}) => {
|
|
5337
|
+
const { buildLaunchOptions } = await loadCloakModule();
|
|
5338
|
+
return await buildLaunchOptions(normalizeObject2(options));
|
|
5339
|
+
};
|
|
5340
|
+
var normalizeObject2 = (value) => {
|
|
5341
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
5342
|
+
return {};
|
|
5343
|
+
}
|
|
5344
|
+
return value;
|
|
5345
|
+
};
|
|
5346
|
+
var normalizeStringArray = (value) => {
|
|
5347
|
+
if (!Array.isArray(value)) {
|
|
5348
|
+
return [];
|
|
5349
|
+
}
|
|
5350
|
+
return value.map((item) => String(item || "").trim()).filter(Boolean);
|
|
5351
|
+
};
|
|
5352
|
+
var resolveCloakFingerprintPlatformArg = (fingerprintPlatform = "", args = []) => {
|
|
5353
|
+
const normalizedFingerprintPlatform = String(fingerprintPlatform || "").trim().toLowerCase();
|
|
5354
|
+
if (SUPPORTED_CLOAK_FINGERPRINT_PLATFORMS.has(normalizedFingerprintPlatform)) {
|
|
5355
|
+
return `${CLOAK_FINGERPRINT_PLATFORM_ARG_PREFIX}${normalizedFingerprintPlatform}`;
|
|
5356
|
+
}
|
|
5357
|
+
const existingArg = normalizeStringArray(args).find((value) => value.startsWith(CLOAK_FINGERPRINT_PLATFORM_ARG_PREFIX));
|
|
5358
|
+
if (existingArg) {
|
|
5359
|
+
return existingArg;
|
|
5360
|
+
}
|
|
5361
|
+
return `${CLOAK_FINGERPRINT_PLATFORM_ARG_PREFIX}${DEFAULT_CLOAK_FINGERPRINT_PLATFORM}`;
|
|
5362
|
+
};
|
|
5363
|
+
var resolveCloakProxy = (proxyConfiguration = {}) => {
|
|
5364
|
+
const config = normalizeObject2(proxyConfiguration);
|
|
5365
|
+
const proxyUrl = String(config.proxy_url || "").trim();
|
|
5366
|
+
const enableProxy = typeof config.enable_proxy === "boolean" ? config.enable_proxy : proxyUrl !== "";
|
|
5367
|
+
if (!enableProxy || !proxyUrl) {
|
|
5368
|
+
return null;
|
|
5369
|
+
}
|
|
5370
|
+
const byPassDomains = ByPass.normalizeByPassDomains(config.by_pass_domains);
|
|
5371
|
+
if (byPassDomains.length === 0) {
|
|
5372
|
+
return proxyUrl;
|
|
5373
|
+
}
|
|
5374
|
+
const parsedProxyUrl = new URL(proxyUrl.includes("://") ? proxyUrl : `http://${proxyUrl}`);
|
|
5375
|
+
return {
|
|
5376
|
+
server: `${parsedProxyUrl.protocol}//${parsedProxyUrl.host}`,
|
|
5377
|
+
username: decodeURIComponent(parsedProxyUrl.username || ""),
|
|
5378
|
+
password: decodeURIComponent(parsedProxyUrl.password || ""),
|
|
5379
|
+
bypass: byPassDomains.join(",")
|
|
5380
|
+
};
|
|
5381
|
+
};
|
|
5382
|
+
var extractFingerprintArg = (launchOptions = {}) => {
|
|
5383
|
+
const args = Array.isArray(launchOptions?.args) ? launchOptions.args : [];
|
|
5384
|
+
return args.find((value) => String(value || "").startsWith("--fingerprint=")) || "";
|
|
5385
|
+
};
|
|
5386
|
+
var createStableGotoHook = (recommendedGotoOptions = DEFAULT_CLOAK_GOTO_OPTIONS) => {
|
|
5387
|
+
const normalizedRecommendedGotoOptions = normalizeObject2(recommendedGotoOptions);
|
|
5388
|
+
const fallbackGotoOptions = Object.keys(normalizedRecommendedGotoOptions).length > 0 ? normalizedRecommendedGotoOptions : DEFAULT_CLOAK_GOTO_OPTIONS;
|
|
5389
|
+
return async (_crawlingContext, gotoOptions = {}) => {
|
|
5390
|
+
for (const [key, value] of Object.entries(fallbackGotoOptions)) {
|
|
5391
|
+
if (gotoOptions[key] == null) {
|
|
5392
|
+
gotoOptions[key] = value;
|
|
5393
|
+
}
|
|
5394
|
+
}
|
|
5395
|
+
};
|
|
5396
|
+
};
|
|
5397
|
+
var attachCloakHumanizeHook = ({
|
|
5398
|
+
browserPoolOptions = {},
|
|
5399
|
+
activeBrowsers,
|
|
5400
|
+
patchedBrowsers,
|
|
5401
|
+
humanizeOptions = DEFAULT_CLOAK_HUMANIZE_OPTIONS
|
|
5402
|
+
} = {}) => {
|
|
5403
|
+
const normalizedBrowserPoolOptions = normalizeObject2(browserPoolOptions);
|
|
5404
|
+
const shouldHumanize = humanizeOptions !== false;
|
|
5405
|
+
const normalizedHumanizeOptions = shouldHumanize ? {
|
|
5406
|
+
...DEFAULT_CLOAK_HUMANIZE_OPTIONS,
|
|
5407
|
+
...normalizeObject2(humanizeOptions)
|
|
5408
|
+
} : null;
|
|
5409
|
+
return {
|
|
5410
|
+
...normalizedBrowserPoolOptions,
|
|
5411
|
+
useFingerprints: false,
|
|
5412
|
+
postLaunchHooks: [
|
|
5413
|
+
...Array.isArray(normalizedBrowserPoolOptions.postLaunchHooks) ? normalizedBrowserPoolOptions.postLaunchHooks : [],
|
|
5414
|
+
async (_pageId, browserController) => {
|
|
5415
|
+
const browser = browserController?.browser;
|
|
5416
|
+
if (!browser || typeof browser.contexts !== "function") {
|
|
5417
|
+
return;
|
|
5418
|
+
}
|
|
5419
|
+
activeBrowsers.add(browser);
|
|
5420
|
+
if (typeof browser.once === "function") {
|
|
5421
|
+
browser.once("disconnected", () => {
|
|
5422
|
+
activeBrowsers.delete(browser);
|
|
5423
|
+
});
|
|
5424
|
+
}
|
|
5425
|
+
if (!shouldHumanize || patchedBrowsers.has(browser)) {
|
|
5426
|
+
return;
|
|
5427
|
+
}
|
|
5428
|
+
const { humanizeBrowser } = await loadCloakModule();
|
|
5429
|
+
await humanizeBrowser(browser, normalizedHumanizeOptions);
|
|
5430
|
+
patchedBrowsers.add(browser);
|
|
5431
|
+
}
|
|
5432
|
+
]
|
|
5433
|
+
};
|
|
5434
|
+
};
|
|
5435
|
+
var closeTrackedBrowsers = async (activeBrowsers) => {
|
|
5436
|
+
const browsers = Array.from(activeBrowsers || []);
|
|
5437
|
+
activeBrowsers?.clear?.();
|
|
5438
|
+
await Promise.allSettled(
|
|
5439
|
+
browsers.map(async (browser) => {
|
|
5440
|
+
if (!browser || typeof browser.isConnected !== "function" || !browser.isConnected()) {
|
|
5441
|
+
return;
|
|
5442
|
+
}
|
|
5443
|
+
await browser.close().catch(() => {
|
|
5444
|
+
});
|
|
5445
|
+
})
|
|
5446
|
+
);
|
|
5447
|
+
};
|
|
5448
|
+
var forceTerminateBrowsersByFingerprintArg = async (fingerprintArg) => {
|
|
5449
|
+
if (!fingerprintArg) {
|
|
5450
|
+
return;
|
|
5451
|
+
}
|
|
5452
|
+
await execFileAsync("pkill", ["-f", "--", fingerprintArg]).catch((error) => {
|
|
5453
|
+
if (error?.code === 1 || error?.code === "ENOENT") {
|
|
5454
|
+
return;
|
|
5455
|
+
}
|
|
5456
|
+
logger9.info(`\u5F3A\u5236\u5173\u95ED Cloak \u8FDB\u7A0B\u5931\u8D25\uFF08\u5FFD\u7565\uFF09: ${error?.message || String(error)}`);
|
|
5457
|
+
});
|
|
5458
|
+
};
|
|
5459
|
+
var CloakLaunch = {
|
|
5460
|
+
resolveProxyConfiguration(proxyConfiguration = {}) {
|
|
5461
|
+
return resolveCloakProxy(proxyConfiguration);
|
|
5462
|
+
},
|
|
5463
|
+
extractFingerprintArg(launchOptions = {}) {
|
|
5464
|
+
return extractFingerprintArg(launchOptions);
|
|
5465
|
+
},
|
|
5466
|
+
createStableGotoHook(recommendedGotoOptions = DEFAULT_CLOAK_GOTO_OPTIONS) {
|
|
5467
|
+
return createStableGotoHook(recommendedGotoOptions);
|
|
5468
|
+
},
|
|
5469
|
+
async getPlaywrightCrawlerOptions(options = {}) {
|
|
5470
|
+
const runtime2 = await CloakLaunch.createPlaywrightCrawlerRuntime(options);
|
|
5471
|
+
return Object.defineProperties(runtime2.crawlerOptions, {
|
|
5472
|
+
cleanup: {
|
|
5473
|
+
enumerable: false,
|
|
5474
|
+
value: runtime2.cleanup
|
|
5475
|
+
},
|
|
5476
|
+
closeActiveBrowsers: {
|
|
5477
|
+
enumerable: false,
|
|
5478
|
+
value: runtime2.closeActiveBrowsers
|
|
5479
|
+
},
|
|
5480
|
+
forceTerminateActiveProcesses: {
|
|
5481
|
+
enumerable: false,
|
|
5482
|
+
value: runtime2.forceTerminateActiveProcesses
|
|
5483
|
+
}
|
|
5484
|
+
});
|
|
5485
|
+
},
|
|
5486
|
+
async buildLaunchOptions(options = {}) {
|
|
5487
|
+
return await buildCloakLaunchOptions(options);
|
|
5488
|
+
},
|
|
5489
|
+
async createPlaywrightCrawlerRuntime(options = {}) {
|
|
5490
|
+
const normalizedOptions = normalizeObject2(options);
|
|
5491
|
+
const {
|
|
5492
|
+
proxyConfiguration = {},
|
|
5493
|
+
log: logOptions = null,
|
|
5494
|
+
debugMode = false,
|
|
5495
|
+
runInHeadfulMode = false,
|
|
5496
|
+
isRunningOnApify = false,
|
|
5497
|
+
launcher = null,
|
|
5498
|
+
fingerprintPlatform = "",
|
|
5499
|
+
cloakOptions = {},
|
|
5500
|
+
humanizeOptions = DEFAULT_CLOAK_HUMANIZE_OPTIONS,
|
|
5501
|
+
crawlerBaseOptions = {},
|
|
5502
|
+
browserPoolOptions = {},
|
|
5503
|
+
launchContext = {},
|
|
5504
|
+
preNavigationHooks = [],
|
|
5505
|
+
postNavigationHooks = [],
|
|
5506
|
+
recommendedGotoOptions = DEFAULT_CLOAK_GOTO_OPTIONS
|
|
5507
|
+
} = normalizedOptions;
|
|
5508
|
+
const normalizedCloakOptions = normalizeObject2(cloakOptions);
|
|
5509
|
+
const activeBrowsers = /* @__PURE__ */ new Set();
|
|
5510
|
+
const patchedBrowsers = /* @__PURE__ */ new WeakSet();
|
|
5511
|
+
const defaultArgs = isRunningOnApify ? ["--no-sandbox", "--disable-setuid-sandbox"] : [];
|
|
5512
|
+
const fingerprintPlatformArg = resolveCloakFingerprintPlatformArg(fingerprintPlatform, normalizedCloakOptions.args);
|
|
5513
|
+
const extraArgs = normalizeStringArray(normalizedCloakOptions.args).filter((value) => !value.startsWith(CLOAK_FINGERPRINT_PLATFORM_ARG_PREFIX));
|
|
5514
|
+
const hasExplicitProxy = hasOwn(normalizedCloakOptions, "proxy");
|
|
5515
|
+
const proxyLaunchState = hasExplicitProxy ? resolveLaunchTraffic({ proxyConfiguration, debugMode, useMeter: false }) : resolveLaunchTraffic({ proxyConfiguration, debugMode });
|
|
5516
|
+
const proxy = hasExplicitProxy ? normalizedCloakOptions.proxy : proxyLaunchState.launchProxy;
|
|
5517
|
+
const headless = hasOwn(normalizedCloakOptions, "headless") ? normalizedCloakOptions.headless : !runInHeadfulMode || isRunningOnApify;
|
|
5518
|
+
const enableByPassLogger = Boolean(logOptions && logOptions.enable);
|
|
5519
|
+
const mergedCloakOptions = {
|
|
5520
|
+
...normalizedCloakOptions,
|
|
5521
|
+
headless,
|
|
5522
|
+
proxy,
|
|
5523
|
+
args: [...defaultArgs, ...extraArgs, fingerprintPlatformArg]
|
|
5524
|
+
};
|
|
5525
|
+
const launchOptions = await buildCloakLaunchOptions(mergedCloakOptions);
|
|
5526
|
+
const fingerprintArg = extractFingerprintArg(launchOptions);
|
|
5527
|
+
const internalPreNavigationHook = createStableGotoHook(recommendedGotoOptions);
|
|
5528
|
+
const trafficHook = createLaunchTrafficHook({
|
|
5529
|
+
byPassDomains: proxyLaunchState.byPassDomains,
|
|
5530
|
+
byPassRules: proxyLaunchState.byPassRules,
|
|
5531
|
+
enabled: enableByPassLogger,
|
|
5532
|
+
launchProxy: proxyLaunchState.launchProxy
|
|
5533
|
+
});
|
|
5534
|
+
const normalizedPreNavigationHooks = Array.isArray(preNavigationHooks) ? preNavigationHooks : [];
|
|
5535
|
+
const normalizedPostNavigationHooks = Array.isArray(postNavigationHooks) ? postNavigationHooks : [];
|
|
5536
|
+
logLaunchTraffic({
|
|
5537
|
+
...proxyLaunchState,
|
|
5538
|
+
debugMode,
|
|
5539
|
+
enabled: enableByPassLogger,
|
|
5540
|
+
explicitProxy: hasExplicitProxy
|
|
5541
|
+
});
|
|
5542
|
+
const crawlerOptions = {
|
|
5543
|
+
...DEFAULT_CLOAK_CRAWLER_BASE_OPTIONS,
|
|
5544
|
+
...normalizeObject2(crawlerBaseOptions),
|
|
5545
|
+
headless,
|
|
5546
|
+
launchContext: {
|
|
5547
|
+
useIncognitoPages: true,
|
|
5548
|
+
...normalizeObject2(launchContext),
|
|
5549
|
+
...launcher ? { launcher } : {},
|
|
5550
|
+
launchOptions
|
|
5551
|
+
},
|
|
5552
|
+
browserPoolOptions: attachCloakHumanizeHook({
|
|
5553
|
+
browserPoolOptions,
|
|
5554
|
+
activeBrowsers,
|
|
5555
|
+
patchedBrowsers,
|
|
5556
|
+
humanizeOptions
|
|
5557
|
+
}),
|
|
5558
|
+
preNavigationHooks: [
|
|
5559
|
+
async (crawlingContext, gotoOptions = {}) => {
|
|
5560
|
+
trafficHook(crawlingContext?.page);
|
|
5561
|
+
await internalPreNavigationHook(crawlingContext, gotoOptions);
|
|
5562
|
+
},
|
|
5563
|
+
...normalizedPreNavigationHooks
|
|
5564
|
+
],
|
|
5565
|
+
...normalizedPostNavigationHooks.length > 0 ? { postNavigationHooks: normalizedPostNavigationHooks } : {}
|
|
5566
|
+
};
|
|
5567
|
+
const closeActiveBrowsers = async () => {
|
|
5568
|
+
await closeTrackedBrowsers(activeBrowsers);
|
|
5569
|
+
};
|
|
5570
|
+
const forceTerminateActiveProcesses = async () => {
|
|
5571
|
+
await forceTerminateBrowsersByFingerprintArg(fingerprintArg);
|
|
5572
|
+
};
|
|
5573
|
+
const cleanup = async () => {
|
|
5574
|
+
await closeActiveBrowsers();
|
|
5575
|
+
await forceTerminateActiveProcesses();
|
|
5576
|
+
};
|
|
5577
|
+
return {
|
|
5578
|
+
headless,
|
|
5579
|
+
launchOptions,
|
|
5580
|
+
fingerprintArg,
|
|
5581
|
+
crawlerOptions,
|
|
5582
|
+
closeActiveBrowsers,
|
|
5583
|
+
forceTerminateActiveProcesses,
|
|
5584
|
+
cleanup
|
|
5585
|
+
};
|
|
5586
|
+
}
|
|
5587
|
+
};
|
|
5588
|
+
|
|
5589
|
+
// src/launch.js
|
|
5590
|
+
var launchStrategies = {
|
|
5591
|
+
[Mode.Default]: DefaultLaunch,
|
|
5592
|
+
[Mode.Cloak]: CloakLaunch
|
|
5593
|
+
};
|
|
5594
|
+
var Launch = withModeReflect("Launch", launchStrategies);
|
|
5595
|
+
|
|
5102
5596
|
// src/live-view.js
|
|
5103
5597
|
var import_express = __toESM(require("express"), 1);
|
|
5104
5598
|
var import_apify = require("apify");
|
|
5105
|
-
var
|
|
5599
|
+
var logger10 = createInternalLogger("LiveView");
|
|
5106
5600
|
async function startLiveViewServer(liveViewKey) {
|
|
5107
5601
|
const app = (0, import_express.default)();
|
|
5108
5602
|
app.get("/", async (req, res) => {
|
|
@@ -5127,13 +5621,13 @@ async function startLiveViewServer(liveViewKey) {
|
|
|
5127
5621
|
</html>
|
|
5128
5622
|
`);
|
|
5129
5623
|
} catch (error) {
|
|
5130
|
-
|
|
5624
|
+
logger10.fail("Live View Server", error);
|
|
5131
5625
|
res.status(500).send(`\u65E0\u6CD5\u52A0\u8F7D\u5C4F\u5E55\u622A\u56FE: ${error.message}`);
|
|
5132
5626
|
}
|
|
5133
5627
|
});
|
|
5134
5628
|
const port = process.env.APIFY_CONTAINER_PORT || 4321;
|
|
5135
5629
|
app.listen(port, () => {
|
|
5136
|
-
|
|
5630
|
+
logger10.success("startLiveViewServer", `\u76D1\u542C\u7AEF\u53E3 ${port}`);
|
|
5137
5631
|
});
|
|
5138
5632
|
}
|
|
5139
5633
|
async function takeLiveScreenshot(liveViewKey, page, logMessage) {
|
|
@@ -5141,10 +5635,10 @@ async function takeLiveScreenshot(liveViewKey, page, logMessage) {
|
|
|
5141
5635
|
const buffer = await capturePageScreenshot(page, { type: "png" });
|
|
5142
5636
|
await import_apify.Actor.setValue(liveViewKey, buffer, { contentType: "image/png" });
|
|
5143
5637
|
if (logMessage) {
|
|
5144
|
-
|
|
5638
|
+
logger10.info(`(\u622A\u56FE): ${logMessage}`);
|
|
5145
5639
|
}
|
|
5146
5640
|
} catch (e) {
|
|
5147
|
-
|
|
5641
|
+
logger10.warn(`\u65E0\u6CD5\u6355\u83B7 Live View \u5C4F\u5E55\u622A\u56FE: ${e.message}`);
|
|
5148
5642
|
}
|
|
5149
5643
|
}
|
|
5150
5644
|
var useLiveView = (liveViewKey = PresetOfLiveViewKey) => {
|
|
@@ -5161,9 +5655,6 @@ var LiveView = {
|
|
|
5161
5655
|
useLiveView
|
|
5162
5656
|
};
|
|
5163
5657
|
|
|
5164
|
-
// src/chaptcha.js
|
|
5165
|
-
var import_uuid = require("uuid");
|
|
5166
|
-
|
|
5167
5658
|
// src/internals/captcha/bytedance.js
|
|
5168
5659
|
var import_promises = require("fs/promises");
|
|
5169
5660
|
var import_path2 = __toESM(require("path"), 1);
|
|
@@ -5253,7 +5744,7 @@ var dragCaptchaAction = async (page, sourceLocator, targetLocator, options = {})
|
|
|
5253
5744
|
};
|
|
5254
5745
|
|
|
5255
5746
|
// src/internals/captcha/bytedance.js
|
|
5256
|
-
var
|
|
5747
|
+
var logger11 = createInternalLogger("Captcha");
|
|
5257
5748
|
var DEFAULT_BYTEDANCE_CAPTCHA_OPTIONS = Object.freeze({
|
|
5258
5749
|
apiType: "31234",
|
|
5259
5750
|
maxRetries: 3,
|
|
@@ -5385,7 +5876,7 @@ var collectCaptchaDebugInfo = async (page, frame, iframeLocator, attempt, phase,
|
|
|
5385
5876
|
}
|
|
5386
5877
|
await (0, import_promises.writeFile)(infoPath, JSON.stringify(payload, null, 2), "utf8");
|
|
5387
5878
|
}
|
|
5388
|
-
|
|
5879
|
+
logger11.info(`\u5DF2\u5199\u51FA\u9A8C\u8BC1\u7801\u8C03\u8BD5\u4EA7\u7269\uFF1A${debugDir}`);
|
|
5389
5880
|
};
|
|
5390
5881
|
var maybeCollectCaptchaDebugInfo = async (page, frame, iframeLocator, attempt, phase, options, extra = null) => {
|
|
5391
5882
|
if (!options.debugArtifacts) {
|
|
@@ -5422,14 +5913,14 @@ var getVerifycenterCaptchaContext = async (page, options) => {
|
|
|
5422
5913
|
if (!isContainerVisible) {
|
|
5423
5914
|
return null;
|
|
5424
5915
|
}
|
|
5425
|
-
|
|
5916
|
+
logger11.info("\u68C0\u6D4B\u5230\u9A8C\u8BC1\u7801\u5BB9\u5668\uFF0C\u5F00\u59CB\u7B49\u5F85 iframe \u52A0\u8F7D\u3002");
|
|
5426
5917
|
let iframeLocator = page.locator(options.iframeSelector).first();
|
|
5427
5918
|
let isIframeVisible = await waitForVisible(
|
|
5428
5919
|
iframeLocator,
|
|
5429
5920
|
options.iframeVisibleTimeoutMs
|
|
5430
5921
|
);
|
|
5431
5922
|
if (!isIframeVisible) {
|
|
5432
|
-
|
|
5923
|
+
logger11.warn("\u672A\u5728\u9884\u671F\u9009\u62E9\u5668\u4E2D\u627E\u5230 verifycenter iframe\uFF0C\u5C1D\u8BD5\u5BB9\u5668\u5185\u4EFB\u610F iframe\u3002");
|
|
5433
5924
|
iframeLocator = captchaContainer.locator(options.iframeFallbackSelector).first();
|
|
5434
5925
|
isIframeVisible = await waitForVisible(
|
|
5435
5926
|
iframeLocator,
|
|
@@ -5439,7 +5930,7 @@ var getVerifycenterCaptchaContext = async (page, options) => {
|
|
|
5439
5930
|
if (!isIframeVisible) {
|
|
5440
5931
|
throw new Error("verifycenter iframe not found inside captcha container.");
|
|
5441
5932
|
}
|
|
5442
|
-
|
|
5933
|
+
logger11.info("\u9A8C\u8BC1\u7801 iframe \u5DF2\u53EF\u89C1\uFF0C\u5F00\u59CB\u89E3\u6790\u5185\u5BB9 frame\u3002");
|
|
5443
5934
|
const frame = await resolveContentFrame(page, iframeLocator, options);
|
|
5444
5935
|
if (!frame) {
|
|
5445
5936
|
throw new Error("Failed to resolve verifycenter iframe content frame.");
|
|
@@ -5555,11 +6046,11 @@ var refreshCaptcha = async (page, frame, options) => {
|
|
|
5555
6046
|
const clicked = await clickCaptchaAction(frame, options.refreshTexts, {
|
|
5556
6047
|
...options,
|
|
5557
6048
|
page,
|
|
5558
|
-
logger:
|
|
6049
|
+
logger: logger11,
|
|
5559
6050
|
forceMouse: true
|
|
5560
6051
|
}).catch(() => false);
|
|
5561
6052
|
if (!clicked) {
|
|
5562
|
-
|
|
6053
|
+
logger11.warn("Refresh button not found.");
|
|
5563
6054
|
return false;
|
|
5564
6055
|
}
|
|
5565
6056
|
await page.waitForTimeout(options.refreshWaitMs);
|
|
@@ -5590,24 +6081,24 @@ var waitForCaptchaChallengeReady = async (page, frame, options) => {
|
|
|
5590
6081
|
const hasGuideMaskVisible = options.guideMaskSelector ? await frame.locator(options.guideMaskSelector).first().isVisible({ timeout: options.loadingIndicatorVisibleTimeoutMs }).catch(() => false) : false;
|
|
5591
6082
|
hasSeenGuideMask = hasSeenGuideMask || hasGuideMaskVisible;
|
|
5592
6083
|
if (hasGuideMaskVisible && !hasLoggedGuideMask) {
|
|
5593
|
-
|
|
6084
|
+
logger11.info("\u68C0\u6D4B\u5230\u9A8C\u8BC1\u7801\u64CD\u4F5C\u5F15\u5BFC\u5C42\uFF0C\u7B49\u5F85\u5176\u6D88\u5931\u540E\u518D\u5F00\u59CB\u8BC6\u522B\u3002");
|
|
5594
6085
|
hasLoggedGuideMask = true;
|
|
5595
6086
|
}
|
|
5596
6087
|
if (!isLoadingVisible && hasVisibleSourceImage && hasVisibleDropTarget && !hasGuideMaskVisible) {
|
|
5597
|
-
|
|
6088
|
+
logger11.info(
|
|
5598
6089
|
hasSeenGuideMask ? "\u9A8C\u8BC1\u7801\u56FE\u7247\u548C\u62D6\u62FD\u533A\u57DF\u5DF2\u5C31\u7EEA\uFF0C\u5F15\u5BFC\u5C42\u5DF2\u6D88\u5931\u3002" : hasSeenLoading ? "\u9A8C\u8BC1\u7801\u56FE\u7247\u5DF2\u52A0\u8F7D\u5B8C\u6210\u3002" : "\u9A8C\u8BC1\u7801\u56FE\u7247\u5DF2\u5C31\u7EEA\u3002"
|
|
5599
6090
|
);
|
|
5600
6091
|
return;
|
|
5601
6092
|
}
|
|
5602
6093
|
if (hasErrorTextVisible) {
|
|
5603
|
-
|
|
6094
|
+
logger11.warn("\u9A8C\u8BC1\u7801\u9762\u677F\u51FA\u73B0\u7F51\u7EDC\u5F02\u5E38\u6587\u6848\uFF0C\u5C1D\u8BD5\u7ACB\u5373\u5237\u65B0\u9898\u76EE\u3002");
|
|
5604
6095
|
await refreshCaptcha(page, frame, options);
|
|
5605
6096
|
refreshDeadline = Date.now() + options.challengeReadyRefreshTimeoutMs;
|
|
5606
6097
|
hasSeenLoading = false;
|
|
5607
6098
|
continue;
|
|
5608
6099
|
}
|
|
5609
6100
|
if ((!hasVisibleSourceImage || !hasVisibleDropTarget) && Date.now() >= refreshDeadline) {
|
|
5610
|
-
|
|
6101
|
+
logger11.warn(`\u9A8C\u8BC1\u7801\u9898\u76EE\u8D85\u8FC7 ${options.challengeReadyRefreshTimeoutMs}ms \u4ECD\u672A\u51C6\u5907\u597D\uFF0C\u5C1D\u8BD5\u5237\u65B0\u9898\u76EE\u3002`);
|
|
5611
6102
|
await refreshCaptcha(page, frame, options);
|
|
5612
6103
|
refreshDeadline = Date.now() + options.challengeReadyRefreshTimeoutMs;
|
|
5613
6104
|
hasSeenLoading = false;
|
|
@@ -5655,7 +6146,7 @@ var dragPromptCaptchaImage = async (page, frame, iframeLocator, sourceLocator, d
|
|
|
5655
6146
|
accepted
|
|
5656
6147
|
};
|
|
5657
6148
|
dragAttempts.push(attemptInfo);
|
|
5658
|
-
|
|
6149
|
+
logger11.info(
|
|
5659
6150
|
`\u9A8C\u8BC1\u7801\u62D6\u62FD\u7B2C ${visualIndex + 1} \u5F20\uFF0C\u65B9\u6848 ${plan.name}\uFF0Cbadge ${baselineState.badgeCount} -> ${afterState.badgeCount}\uFF0Cselected ${baselineState.selectedCount} -> ${afterState.selectedCount}`
|
|
5660
6151
|
);
|
|
5661
6152
|
if (accepted) {
|
|
@@ -5673,7 +6164,7 @@ var dragPromptCaptchaImage = async (page, frame, iframeLocator, sourceLocator, d
|
|
|
5673
6164
|
dragAttempts,
|
|
5674
6165
|
finalState: await readPromptCaptchaState(frame, options)
|
|
5675
6166
|
}).catch((error) => {
|
|
5676
|
-
|
|
6167
|
+
logger11.warn(`\u9A8C\u8BC1\u7801\u62D6\u62FD\u5931\u8D25\u8C03\u8BD5\u6293\u53D6\u5931\u8D25\uFF1A${error?.message || error}`);
|
|
5677
6168
|
});
|
|
5678
6169
|
return {
|
|
5679
6170
|
accepted: false,
|
|
@@ -5690,16 +6181,16 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
|
|
|
5690
6181
|
...options
|
|
5691
6182
|
};
|
|
5692
6183
|
if (!config.token) {
|
|
5693
|
-
|
|
6184
|
+
logger11.warn("\u7F3A\u5C11\u9A8C\u8BC1\u7801 token\uFF0C\u8DF3\u8FC7\u81EA\u52A8\u8BC6\u522B\u3002");
|
|
5694
6185
|
return false;
|
|
5695
6186
|
}
|
|
5696
|
-
|
|
6187
|
+
logger11.info("\u5F53\u524D\u4F7F\u7528\u672Ctool\u2014\u2014\u6D4B\u8BD5\u7248\u672C");
|
|
5697
6188
|
for (let attempt = 1; attempt <= config.maxRetries; attempt += 1) {
|
|
5698
|
-
|
|
6189
|
+
logger11.info(`\u5F00\u59CB\u7B2C ${attempt}/${config.maxRetries} \u6B21 verifycenter \u9A8C\u8BC1\u7801\u8BC6\u522B\u3002`);
|
|
5699
6190
|
try {
|
|
5700
6191
|
const captchaContext = await getVerifycenterCaptchaContext(page, config);
|
|
5701
6192
|
if (!captchaContext) {
|
|
5702
|
-
|
|
6193
|
+
logger11.info("Captcha container is not visible anymore.");
|
|
5703
6194
|
return true;
|
|
5704
6195
|
}
|
|
5705
6196
|
const { iframeLocator, frame } = captchaContext;
|
|
@@ -5712,7 +6203,7 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
|
|
|
5712
6203
|
"ready",
|
|
5713
6204
|
config
|
|
5714
6205
|
).catch((error) => {
|
|
5715
|
-
|
|
6206
|
+
logger11.warn(`\u9A8C\u8BC1\u7801\u8C03\u8BD5\u6293\u53D6\u5931\u8D25\uFF1A${error?.message || error}`);
|
|
5716
6207
|
});
|
|
5717
6208
|
await page.waitForTimeout(config.recognitionDelayMs);
|
|
5718
6209
|
const screenshotBuffer = await iframeLocator.screenshot();
|
|
@@ -5724,16 +6215,16 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
|
|
|
5724
6215
|
});
|
|
5725
6216
|
const serialNumbers = extractCaptchaSerialNumbers(apiResponse);
|
|
5726
6217
|
if (apiResponse?.code !== config.recognitionSuccessCode || serialNumbers.length === 0) {
|
|
5727
|
-
|
|
6218
|
+
logger11.warn(
|
|
5728
6219
|
`\u9A8C\u8BC1\u7801\u8BC6\u522B\u5931\u8D25\u3002code=${apiResponse?.code}, msg=${apiResponse?.msg || "unknown"}`
|
|
5729
6220
|
);
|
|
5730
6221
|
await refreshCaptcha(page, frame, config);
|
|
5731
6222
|
continue;
|
|
5732
6223
|
}
|
|
5733
|
-
|
|
6224
|
+
logger11.info(`\u9A8C\u8BC1\u7801\u8BC6\u522B\u6210\u529F\uFF0C\u5E8F\u53F7\uFF1A${serialNumbers.join(", ")}`);
|
|
5734
6225
|
const dropTarget = await findCaptchaDropTarget(frame, config);
|
|
5735
6226
|
if (!dropTarget) {
|
|
5736
|
-
|
|
6227
|
+
logger11.warn("\u672A\u627E\u5230\u9A8C\u8BC1\u7801\u62D6\u62FD\u76EE\u6807\u533A\u57DF\u3002");
|
|
5737
6228
|
await refreshCaptcha(page, frame, config);
|
|
5738
6229
|
continue;
|
|
5739
6230
|
}
|
|
@@ -5744,7 +6235,7 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
|
|
|
5744
6235
|
`Captcha image indexes could not be normalized. raw=${serialNumbers.join(", ")}, count=${orderedSourceImages.length}`
|
|
5745
6236
|
);
|
|
5746
6237
|
}
|
|
5747
|
-
|
|
6238
|
+
logger11.info(`\u9A8C\u8BC1\u7801\u89C6\u89C9\u4F4D\u5E8F\u6620\u5C04\uFF1A${normalizedIndexes.map((index) => index + 1).join(", ")}`);
|
|
5748
6239
|
for (const imageIndex of normalizedIndexes) {
|
|
5749
6240
|
if (imageIndex < 0 || imageIndex >= orderedSourceImages.length) {
|
|
5750
6241
|
throw new Error(
|
|
@@ -5776,52 +6267,55 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
|
|
|
5776
6267
|
}
|
|
5777
6268
|
}
|
|
5778
6269
|
const beforeSubmitState = await readPromptCaptchaState(frame, config);
|
|
5779
|
-
|
|
6270
|
+
logger11.info(
|
|
5780
6271
|
`\u63D0\u4EA4\u524D\u9A8C\u8BC1\u7801\u72B6\u6001\uFF1Abadge=${beforeSubmitState.badgeCount}, selected=${beforeSubmitState.selectedCount}, submitDisabled=${beforeSubmitState.submitDisabled}`
|
|
5781
6272
|
);
|
|
5782
6273
|
const submitted = await clickCaptchaAction(frame, config.submitTexts, {
|
|
5783
6274
|
...config,
|
|
5784
6275
|
page,
|
|
5785
|
-
logger:
|
|
6276
|
+
logger: logger11,
|
|
5786
6277
|
forceMouse: true,
|
|
5787
6278
|
actionVisibleTimeoutMs: config.submitReadyTimeoutMs
|
|
5788
6279
|
}).catch(() => false);
|
|
5789
6280
|
if (!submitted) {
|
|
5790
|
-
|
|
6281
|
+
logger11.warn("\u672A\u627E\u5230\u63D0\u4EA4\u6309\u94AE\uFF0C\u53EF\u80FD\u4F1A\u81EA\u52A8\u63D0\u4EA4\u3002");
|
|
5791
6282
|
}
|
|
5792
6283
|
await page.waitForTimeout(config.submitWaitMs);
|
|
5793
6284
|
const afterSubmitState = await readPromptCaptchaState(frame, config);
|
|
5794
|
-
|
|
6285
|
+
logger11.info(
|
|
5795
6286
|
`\u63D0\u4EA4\u540E\u9A8C\u8BC1\u7801\u72B6\u6001\uFF1Abadge=${afterSubmitState.badgeCount}, selected=${afterSubmitState.selectedCount}, submitDisabled=${afterSubmitState.submitDisabled}`
|
|
5796
6287
|
);
|
|
5797
6288
|
const stillVisible = await iframeLocator.isVisible({ timeout: config.containerVisibleTimeoutMs }).catch(() => false);
|
|
5798
6289
|
if (!stillVisible) {
|
|
5799
|
-
|
|
6290
|
+
logger11.info("\u9A8C\u8BC1\u7801\u8BC6\u522B\u5E76\u63D0\u4EA4\u6210\u529F\u3002");
|
|
5800
6291
|
return true;
|
|
5801
6292
|
}
|
|
5802
6293
|
await maybeCollectCaptchaDebugInfo(page, frame, iframeLocator, attempt, "submit-still-visible", config, {
|
|
5803
6294
|
beforeSubmitState,
|
|
5804
6295
|
afterSubmitState
|
|
5805
6296
|
}).catch((error) => {
|
|
5806
|
-
|
|
6297
|
+
logger11.warn(`\u63D0\u4EA4\u540E\u9A8C\u8BC1\u7801\u8C03\u8BD5\u6293\u53D6\u5931\u8D25\uFF1A${error?.message || error}`);
|
|
5807
6298
|
});
|
|
5808
|
-
|
|
6299
|
+
logger11.warn("\u63D0\u4EA4\u540E\u9A8C\u8BC1\u7801 iframe \u4ECD\u7136\u53EF\u89C1\uFF0C\u51C6\u5907\u5237\u65B0\u540E\u91CD\u8BD5\u3002");
|
|
5809
6300
|
await page.waitForTimeout(2e3);
|
|
5810
6301
|
await refreshCaptcha(page, frame, config);
|
|
5811
6302
|
} catch (error) {
|
|
5812
|
-
|
|
6303
|
+
logger11.error(`\u7B2C ${attempt}/${config.maxRetries} \u6B21\u9A8C\u8BC1\u7801\u8BC6\u522B\u5931\u8D25\uFF1A${error?.message || error}`);
|
|
5813
6304
|
}
|
|
5814
6305
|
if (attempt < config.maxRetries) {
|
|
5815
6306
|
await page.waitForTimeout(config.retryDelayBaseMs + attempt * config.retryDelayStepMs);
|
|
5816
6307
|
}
|
|
5817
6308
|
}
|
|
5818
|
-
|
|
6309
|
+
logger11.error(`\u91CD\u8BD5 ${config.maxRetries} \u6B21\u540E\uFF0C\u9A8C\u8BC1\u7801\u4ECD\u672A\u8BC6\u522B\u6210\u529F\u3002`);
|
|
5819
6310
|
return false;
|
|
5820
6311
|
}
|
|
5821
6312
|
var sloveCaptcha = solveCaptcha;
|
|
5822
6313
|
|
|
5823
6314
|
// src/chaptcha.js
|
|
5824
|
-
var
|
|
6315
|
+
var logger12 = createInternalLogger("Captcha");
|
|
6316
|
+
var DOM_MONITOR_WAIT_TIMEOUT_MS = 1e3;
|
|
6317
|
+
var DOM_MONITOR_POST_DETECT_HIDDEN_WAIT_MS = 300;
|
|
6318
|
+
var DOM_MONITOR_RECOVERY_WAIT_MS = 100;
|
|
5825
6319
|
var DEFAULT_CAPTCHA_RECOGNITION_OPTIONS = Object.freeze({
|
|
5826
6320
|
token: "eKJvBfwfN0YRav0-VD_44E2VBSfm7l0YtddUQ7cFySI",
|
|
5827
6321
|
apiUrl: "https://api.jfbym.com/api/YmServer/customApi"
|
|
@@ -5842,6 +6336,15 @@ var mergeDefinedOptions = (...sources) => {
|
|
|
5842
6336
|
}
|
|
5843
6337
|
return merged;
|
|
5844
6338
|
};
|
|
6339
|
+
var sleep = (ms) => new Promise((resolve) => {
|
|
6340
|
+
setTimeout(resolve, ms);
|
|
6341
|
+
});
|
|
6342
|
+
var getErrorMessage = (error) => String(error?.message || error || "");
|
|
6343
|
+
var isTimeoutError = (error) => error?.name === "TimeoutError" || getErrorMessage(error).includes("Timeout");
|
|
6344
|
+
var isPageLifecycleError = (error) => {
|
|
6345
|
+
const message = getErrorMessage(error);
|
|
6346
|
+
return message.includes("Execution context was destroyed") || message.includes("Frame was detached") || message.includes("Target page, context or browser has been closed") || message.includes("Target closed") || message.includes("Most likely the page has been closed");
|
|
6347
|
+
};
|
|
5845
6348
|
function useCaptchaMonitor(page, options) {
|
|
5846
6349
|
const { domSelector, urlPattern, onDetected } = options;
|
|
5847
6350
|
if (!domSelector && !urlPattern) {
|
|
@@ -5853,10 +6356,13 @@ function useCaptchaMonitor(page, options) {
|
|
|
5853
6356
|
let isStopped = false;
|
|
5854
6357
|
let isHandling = false;
|
|
5855
6358
|
let frameHandler = null;
|
|
5856
|
-
let
|
|
6359
|
+
let domMonitorTask = null;
|
|
6360
|
+
let lastTriggeredAt = 0;
|
|
5857
6361
|
const triggerDetected = async () => {
|
|
5858
|
-
|
|
6362
|
+
const now = Date.now();
|
|
6363
|
+
if (isStopped || isHandling || now - lastTriggeredAt < 250) return;
|
|
5859
6364
|
isHandling = true;
|
|
6365
|
+
lastTriggeredAt = now;
|
|
5860
6366
|
try {
|
|
5861
6367
|
await onDetected();
|
|
5862
6368
|
} finally {
|
|
@@ -5865,60 +6371,38 @@ function useCaptchaMonitor(page, options) {
|
|
|
5865
6371
|
};
|
|
5866
6372
|
const cleanupFns = [];
|
|
5867
6373
|
if (domSelector) {
|
|
5868
|
-
|
|
5869
|
-
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
|
|
5873
|
-
|
|
5874
|
-
|
|
5875
|
-
|
|
5876
|
-
|
|
5877
|
-
|
|
5878
|
-
|
|
5879
|
-
}
|
|
5880
|
-
|
|
5881
|
-
|
|
5882
|
-
|
|
5883
|
-
|
|
5884
|
-
|
|
5885
|
-
|
|
5886
|
-
|
|
5887
|
-
const shouldCheck = mutations.some((mutation) => mutation.addedNodes.length > 0);
|
|
5888
|
-
if (shouldCheck && observer) {
|
|
5889
|
-
checkAndReport();
|
|
5890
|
-
}
|
|
5891
|
-
});
|
|
5892
|
-
const mountObserver = () => {
|
|
5893
|
-
const target = document.documentElement;
|
|
5894
|
-
if (target && observer) {
|
|
5895
|
-
observer.observe(target, { childList: true, subtree: true });
|
|
6374
|
+
domMonitorTask = (async () => {
|
|
6375
|
+
const locator = page.locator(domSelector).first();
|
|
6376
|
+
while (!isStopped) {
|
|
6377
|
+
try {
|
|
6378
|
+
await locator.waitFor({ state: "visible", timeout: DOM_MONITOR_WAIT_TIMEOUT_MS });
|
|
6379
|
+
if (isStopped) break;
|
|
6380
|
+
await triggerDetected();
|
|
6381
|
+
if (isStopped) break;
|
|
6382
|
+
await locator.waitFor({
|
|
6383
|
+
state: "hidden",
|
|
6384
|
+
timeout: DOM_MONITOR_POST_DETECT_HIDDEN_WAIT_MS
|
|
6385
|
+
}).catch(() => {
|
|
6386
|
+
});
|
|
6387
|
+
} catch (error) {
|
|
6388
|
+
if (isStopped) break;
|
|
6389
|
+
if (page?.isClosed?.() && isPageLifecycleError(error)) break;
|
|
6390
|
+
if (isTimeoutError(error) || isPageLifecycleError(error)) {
|
|
6391
|
+
await sleep(DOM_MONITOR_RECOVERY_WAIT_MS);
|
|
6392
|
+
continue;
|
|
5896
6393
|
}
|
|
5897
|
-
|
|
5898
|
-
|
|
5899
|
-
|
|
5900
|
-
|
|
5901
|
-
|
|
6394
|
+
logger12.warning(
|
|
6395
|
+
"useCaptchaMonitor",
|
|
6396
|
+
`DOM \u76D1\u63A7\u51FA\u73B0\u5F02\u5E38\uFF08\u7EE7\u7EED\u91CD\u8BD5\uFF09: selector=${domSelector}, error=${getErrorMessage(error)}`
|
|
6397
|
+
);
|
|
6398
|
+
await sleep(DOM_MONITOR_RECOVERY_WAIT_MS);
|
|
5902
6399
|
}
|
|
5903
|
-
window[cleanupName] = () => {
|
|
5904
|
-
if (observer) {
|
|
5905
|
-
observer.disconnect();
|
|
5906
|
-
observer = null;
|
|
5907
|
-
}
|
|
5908
|
-
};
|
|
5909
|
-
})();
|
|
5910
|
-
}, { selector: domSelector, callbackName: exposedFunctionName, cleanerName });
|
|
5911
|
-
logger11.success("useCaptchaMonitor", `DOM \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${domSelector}`);
|
|
5912
|
-
cleanupFns.push(async () => {
|
|
5913
|
-
try {
|
|
5914
|
-
await page.evaluate((name) => {
|
|
5915
|
-
if (window[name]) {
|
|
5916
|
-
window[name]();
|
|
5917
|
-
delete window[name];
|
|
5918
|
-
}
|
|
5919
|
-
}, cleanerName);
|
|
5920
|
-
} catch {
|
|
5921
6400
|
}
|
|
6401
|
+
})();
|
|
6402
|
+
logger12.success("useCaptchaMonitor", `DOM \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${domSelector}`);
|
|
6403
|
+
cleanupFns.push(async () => {
|
|
6404
|
+
await domMonitorTask?.catch(() => {
|
|
6405
|
+
});
|
|
5922
6406
|
});
|
|
5923
6407
|
}
|
|
5924
6408
|
if (urlPattern) {
|
|
@@ -5932,18 +6416,24 @@ function useCaptchaMonitor(page, options) {
|
|
|
5932
6416
|
}
|
|
5933
6417
|
};
|
|
5934
6418
|
page.on("framenavigated", frameHandler);
|
|
5935
|
-
|
|
6419
|
+
logger12.success("useCaptchaMonitor", `URL \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${urlPattern}`);
|
|
6420
|
+
Promise.resolve().then(async () => {
|
|
6421
|
+
if (!isStopped && page.url().includes(urlPattern)) {
|
|
6422
|
+
await triggerDetected();
|
|
6423
|
+
}
|
|
6424
|
+
}).catch(() => {
|
|
6425
|
+
});
|
|
5936
6426
|
cleanupFns.push(async () => {
|
|
5937
6427
|
page.off("framenavigated", frameHandler);
|
|
5938
6428
|
});
|
|
5939
6429
|
}
|
|
5940
6430
|
return {
|
|
5941
6431
|
stop: async () => {
|
|
5942
|
-
|
|
6432
|
+
logger12.info("\u6B63\u5728\u505C\u6B62\u9A8C\u8BC1\u7801\u76D1\u63A7...");
|
|
6433
|
+
isStopped = true;
|
|
5943
6434
|
for (const fn of cleanupFns) {
|
|
5944
6435
|
await fn();
|
|
5945
6436
|
}
|
|
5946
|
-
isStopped = true;
|
|
5947
6437
|
}
|
|
5948
6438
|
};
|
|
5949
6439
|
}
|
|
@@ -5978,7 +6468,7 @@ async function solveCaptchaWithStrategy(strategyName, page, options = {}) {
|
|
|
5978
6468
|
);
|
|
5979
6469
|
return strategy.sloveCaptcha(page, resolvedOptions, {
|
|
5980
6470
|
callCaptchaRecognitionApi,
|
|
5981
|
-
logger:
|
|
6471
|
+
logger: logger12
|
|
5982
6472
|
});
|
|
5983
6473
|
}
|
|
5984
6474
|
var Captcha = {
|
|
@@ -5988,15 +6478,15 @@ var Captcha = {
|
|
|
5988
6478
|
|
|
5989
6479
|
// src/mutation.js
|
|
5990
6480
|
var import_node_crypto = require("node:crypto");
|
|
5991
|
-
var
|
|
5992
|
-
var
|
|
6481
|
+
var import_uuid = require("uuid");
|
|
6482
|
+
var logger13 = createInternalLogger("Mutation");
|
|
5993
6483
|
var MUTATION_MONITOR_MODE = Object.freeze({
|
|
5994
6484
|
Added: "added",
|
|
5995
6485
|
Changed: "changed",
|
|
5996
6486
|
All: "all"
|
|
5997
6487
|
});
|
|
5998
6488
|
function generateKey(prefix) {
|
|
5999
|
-
return `__${prefix}_${(0,
|
|
6489
|
+
return `__${prefix}_${(0, import_uuid.v4)().replace(/-/g, "_")}`;
|
|
6000
6490
|
}
|
|
6001
6491
|
var Mutation = {
|
|
6002
6492
|
Mode: MUTATION_MONITOR_MODE,
|
|
@@ -6022,14 +6512,14 @@ var Mutation = {
|
|
|
6022
6512
|
const stableTime = options.stableTime ?? 5 * 1e3;
|
|
6023
6513
|
const timeout = options.timeout ?? 120 * 1e3;
|
|
6024
6514
|
const onMutation = options.onMutation;
|
|
6025
|
-
|
|
6515
|
+
logger13.start("waitForStable", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, \u7A33\u5B9A\u65F6\u95F4=${stableTime}ms`);
|
|
6026
6516
|
if (initialTimeout > 0) {
|
|
6027
6517
|
const selectorQuery = selectorList.join(",");
|
|
6028
6518
|
try {
|
|
6029
6519
|
await page.waitForSelector(selectorQuery, { timeout: initialTimeout });
|
|
6030
|
-
|
|
6520
|
+
logger13.info(`waitForStable \u5DF2\u68C0\u6D4B\u5230\u5143\u7D20: ${selectorQuery}`);
|
|
6031
6521
|
} catch (e) {
|
|
6032
|
-
|
|
6522
|
+
logger13.warning(`waitForStable \u521D\u59CB\u7B49\u5F85\u8D85\u65F6 (${initialTimeout}ms): ${selectorQuery}`);
|
|
6033
6523
|
throw e;
|
|
6034
6524
|
}
|
|
6035
6525
|
}
|
|
@@ -6045,7 +6535,7 @@ var Mutation = {
|
|
|
6045
6535
|
return "__CONTINUE__";
|
|
6046
6536
|
}
|
|
6047
6537
|
});
|
|
6048
|
-
|
|
6538
|
+
logger13.info("waitForStable \u5DF2\u542F\u7528 onMutation \u56DE\u8C03");
|
|
6049
6539
|
} catch (e) {
|
|
6050
6540
|
}
|
|
6051
6541
|
}
|
|
@@ -6160,9 +6650,9 @@ var Mutation = {
|
|
|
6160
6650
|
{ selectorList, stableTime, timeout, callbackName, hasCallback: !!onMutation }
|
|
6161
6651
|
);
|
|
6162
6652
|
if (result.mutationCount === 0 && result.stableTime === 0) {
|
|
6163
|
-
|
|
6653
|
+
logger13.warning("waitForStable \u672A\u627E\u5230\u53EF\u76D1\u63A7\u7684\u5143\u7D20");
|
|
6164
6654
|
}
|
|
6165
|
-
|
|
6655
|
+
logger13.success("waitForStable", `DOM \u7A33\u5B9A, \u603B\u5171 ${result.mutationCount} \u6B21\u53D8\u5316${result.wasPaused ? ", \u66FE\u6682\u505C\u8BA1\u65F6" : ""}`);
|
|
6166
6656
|
return result;
|
|
6167
6657
|
},
|
|
6168
6658
|
/**
|
|
@@ -6186,7 +6676,7 @@ var Mutation = {
|
|
|
6186
6676
|
const overallTimeout = options.timeout ?? 180 * 1e3;
|
|
6187
6677
|
const onMutation = options.onMutation;
|
|
6188
6678
|
const pollInterval = 500;
|
|
6189
|
-
const
|
|
6679
|
+
const sleep2 = (ms) => new Promise((resolve) => {
|
|
6190
6680
|
setTimeout(resolve, ms);
|
|
6191
6681
|
});
|
|
6192
6682
|
const truncate = (value, max = 800) => {
|
|
@@ -6334,29 +6824,29 @@ var Mutation = {
|
|
|
6334
6824
|
return "__CONTINUE__";
|
|
6335
6825
|
}
|
|
6336
6826
|
};
|
|
6337
|
-
|
|
6827
|
+
logger13.start(
|
|
6338
6828
|
"waitForStableAcrossRoots",
|
|
6339
6829
|
`\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668(\u8DE8 root), \u7A33\u5B9A\u65F6\u95F4=${waitForStableTime}ms`
|
|
6340
6830
|
);
|
|
6341
6831
|
if (initialTimeout > 0) {
|
|
6342
6832
|
try {
|
|
6343
6833
|
await page.waitForSelector(selectorQuery, { timeout: initialTimeout });
|
|
6344
|
-
|
|
6834
|
+
logger13.info(`waitForStableAcrossRoots \u5DF2\u68C0\u6D4B\u5230\u5143\u7D20: ${selectorQuery}`);
|
|
6345
6835
|
} catch (e) {
|
|
6346
|
-
|
|
6836
|
+
logger13.warning(`waitForStableAcrossRoots \u521D\u59CB\u7B49\u5F85\u8D85\u65F6 (${initialTimeout}ms): ${selectorQuery}`);
|
|
6347
6837
|
throw e;
|
|
6348
6838
|
}
|
|
6349
6839
|
}
|
|
6350
|
-
let
|
|
6351
|
-
if (!
|
|
6352
|
-
|
|
6840
|
+
let state2 = await buildState();
|
|
6841
|
+
if (!state2?.hasMatched) {
|
|
6842
|
+
logger13.warning("waitForStableAcrossRoots \u672A\u627E\u5230\u53EF\u76D1\u63A7\u7684\u5143\u7D20");
|
|
6353
6843
|
return { mutationCount: 0, stableTime: 0, wasPaused: false };
|
|
6354
6844
|
}
|
|
6355
6845
|
let mutationCount = 0;
|
|
6356
6846
|
let stableSince = 0;
|
|
6357
6847
|
let isPaused = false;
|
|
6358
6848
|
let wasPaused = false;
|
|
6359
|
-
let lastSnapshotKey =
|
|
6849
|
+
let lastSnapshotKey = state2.snapshotKey;
|
|
6360
6850
|
const applyPauseSignal = (signal) => {
|
|
6361
6851
|
const nextPaused = signal === "__PAUSE__";
|
|
6362
6852
|
if (nextPaused) {
|
|
@@ -6370,15 +6860,15 @@ var Mutation = {
|
|
|
6370
6860
|
};
|
|
6371
6861
|
const initialSignal = await invokeMutationCallback({
|
|
6372
6862
|
mutationCount: 0,
|
|
6373
|
-
html:
|
|
6374
|
-
text:
|
|
6375
|
-
mutationNodes:
|
|
6863
|
+
html: state2.html || "",
|
|
6864
|
+
text: state2.text || "",
|
|
6865
|
+
mutationNodes: state2.mutationNodes || []
|
|
6376
6866
|
});
|
|
6377
6867
|
applyPauseSignal(initialSignal);
|
|
6378
6868
|
const deadline = Date.now() + overallTimeout;
|
|
6379
|
-
let lastState =
|
|
6869
|
+
let lastState = state2;
|
|
6380
6870
|
while (Date.now() < deadline) {
|
|
6381
|
-
await
|
|
6871
|
+
await sleep2(pollInterval);
|
|
6382
6872
|
lastState = await buildState();
|
|
6383
6873
|
if (!lastState?.hasMatched) {
|
|
6384
6874
|
continue;
|
|
@@ -6386,7 +6876,7 @@ var Mutation = {
|
|
|
6386
6876
|
if (lastState.snapshotKey !== lastSnapshotKey) {
|
|
6387
6877
|
lastSnapshotKey = lastState.snapshotKey;
|
|
6388
6878
|
mutationCount += 1;
|
|
6389
|
-
|
|
6879
|
+
logger13.info(
|
|
6390
6880
|
`waitForStableAcrossRoots \u53D8\u5316#${mutationCount}, len=${lastState.snapshotLength}, path=${lastState.primaryPath || "unknown"}, preview="${truncate(lastState.text, 120)}"`
|
|
6391
6881
|
);
|
|
6392
6882
|
const signal = await invokeMutationCallback({
|
|
@@ -6399,7 +6889,7 @@ var Mutation = {
|
|
|
6399
6889
|
continue;
|
|
6400
6890
|
}
|
|
6401
6891
|
if (!isPaused && stableSince > 0 && Date.now() - stableSince >= waitForStableTime) {
|
|
6402
|
-
|
|
6892
|
+
logger13.success("waitForStableAcrossRoots", `DOM \u7A33\u5B9A, \u603B\u5171 ${mutationCount} \u6B21\u53D8\u5316${wasPaused ? ", \u66FE\u6682\u505C\u8BA1\u65F6" : ""}`);
|
|
6403
6893
|
return {
|
|
6404
6894
|
mutationCount,
|
|
6405
6895
|
stableTime: waitForStableTime,
|
|
@@ -6425,8 +6915,8 @@ var Mutation = {
|
|
|
6425
6915
|
const selectorList = Array.isArray(selectors) ? selectors : [selectors];
|
|
6426
6916
|
const onMutation = options.onMutation;
|
|
6427
6917
|
const rawMode = String(options.mode || MUTATION_MONITOR_MODE.Added).toLowerCase();
|
|
6428
|
-
const
|
|
6429
|
-
|
|
6918
|
+
const mode2 = [MUTATION_MONITOR_MODE.Added, MUTATION_MONITOR_MODE.Changed, MUTATION_MONITOR_MODE.All].includes(rawMode) ? rawMode : MUTATION_MONITOR_MODE.Added;
|
|
6919
|
+
logger13.start("useMonitor", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, mode=${mode2}`);
|
|
6430
6920
|
const monitorKey = generateKey("pk_mon");
|
|
6431
6921
|
const callbackName = generateKey("pk_mon_cb");
|
|
6432
6922
|
const cleanerName = generateKey("pk_mon_clean");
|
|
@@ -6441,7 +6931,7 @@ var Mutation = {
|
|
|
6441
6931
|
} catch (e) {
|
|
6442
6932
|
}
|
|
6443
6933
|
}
|
|
6444
|
-
await page.evaluate(({ selectorList: selectorList2, monitorKey: monitorKey2, callbackName: callbackName2, cleanerName: cleanerName2, hasCallback, mode:
|
|
6934
|
+
await page.evaluate(({ selectorList: selectorList2, monitorKey: monitorKey2, callbackName: callbackName2, cleanerName: cleanerName2, hasCallback, mode: mode3 }) => {
|
|
6445
6935
|
const monitor = {
|
|
6446
6936
|
observers: [],
|
|
6447
6937
|
totalMutations: 0,
|
|
@@ -6485,7 +6975,7 @@ var Mutation = {
|
|
|
6485
6975
|
const collectMutationNodes = (mutations) => {
|
|
6486
6976
|
const mutationNodes = [];
|
|
6487
6977
|
for (const mutation of mutations) {
|
|
6488
|
-
if (
|
|
6978
|
+
if (mode3 === "added") {
|
|
6489
6979
|
if (mutation.type !== "childList") continue;
|
|
6490
6980
|
const added = Array.from(mutation.addedNodes || []);
|
|
6491
6981
|
for (const node of added) {
|
|
@@ -6493,7 +6983,7 @@ var Mutation = {
|
|
|
6493
6983
|
}
|
|
6494
6984
|
continue;
|
|
6495
6985
|
}
|
|
6496
|
-
if (
|
|
6986
|
+
if (mode3 === "changed") {
|
|
6497
6987
|
if (mutation.type === "attributes" || mutation.type === "characterData") {
|
|
6498
6988
|
mutationNodes.push(serializeNode(mutation.target, mutation.type));
|
|
6499
6989
|
} else if (mutation.type === "childList") {
|
|
@@ -6553,8 +7043,8 @@ var Mutation = {
|
|
|
6553
7043
|
observer.observe(element, {
|
|
6554
7044
|
childList: true,
|
|
6555
7045
|
subtree: true,
|
|
6556
|
-
characterData:
|
|
6557
|
-
attributes:
|
|
7046
|
+
characterData: mode3 !== "added",
|
|
7047
|
+
attributes: mode3 !== "added"
|
|
6558
7048
|
});
|
|
6559
7049
|
monitor.observers.push(observer);
|
|
6560
7050
|
});
|
|
@@ -6568,8 +7058,8 @@ var Mutation = {
|
|
|
6568
7058
|
delete window[cleanerName2];
|
|
6569
7059
|
return total;
|
|
6570
7060
|
};
|
|
6571
|
-
}, { selectorList, monitorKey, callbackName, cleanerName, hasCallback: !!onMutation, mode });
|
|
6572
|
-
|
|
7061
|
+
}, { selectorList, monitorKey, callbackName, cleanerName, hasCallback: !!onMutation, mode: mode2 });
|
|
7062
|
+
logger13.success("useMonitor", "\u76D1\u63A7\u5668\u5DF2\u542F\u52A8");
|
|
6573
7063
|
return {
|
|
6574
7064
|
stop: async () => {
|
|
6575
7065
|
let totalMutations = 0;
|
|
@@ -6582,7 +7072,7 @@ var Mutation = {
|
|
|
6582
7072
|
}, cleanerName);
|
|
6583
7073
|
} catch (e) {
|
|
6584
7074
|
}
|
|
6585
|
-
|
|
7075
|
+
logger13.success("useMonitor.stop", `\u76D1\u63A7\u5DF2\u505C\u6B62, \u5171 ${totalMutations} \u6B21\u53D8\u5316`);
|
|
6586
7076
|
return { totalMutations };
|
|
6587
7077
|
}
|
|
6588
7078
|
};
|
|
@@ -7451,7 +7941,7 @@ var createTemplateLogger = (baseLogger = createBaseLogger()) => {
|
|
|
7451
7941
|
};
|
|
7452
7942
|
var getDefaultBaseLogger = () => createBaseLogger("");
|
|
7453
7943
|
var Logger = {
|
|
7454
|
-
setLogger: (
|
|
7944
|
+
setLogger: (logger17) => setDefaultLogger(logger17),
|
|
7455
7945
|
info: (message) => getDefaultBaseLogger().info(message),
|
|
7456
7946
|
success: (message) => getDefaultBaseLogger().success(message),
|
|
7457
7947
|
warning: (message) => getDefaultBaseLogger().warning(message),
|
|
@@ -7459,14 +7949,14 @@ var Logger = {
|
|
|
7459
7949
|
error: (message) => getDefaultBaseLogger().error(message),
|
|
7460
7950
|
debug: (message) => getDefaultBaseLogger().debug(message),
|
|
7461
7951
|
start: (message) => getDefaultBaseLogger().start(message),
|
|
7462
|
-
useTemplate: (
|
|
7463
|
-
if (
|
|
7952
|
+
useTemplate: (logger17) => {
|
|
7953
|
+
if (logger17) return createTemplateLogger(createBaseLogger("", logger17));
|
|
7464
7954
|
return createTemplateLogger();
|
|
7465
7955
|
}
|
|
7466
7956
|
};
|
|
7467
7957
|
|
|
7468
7958
|
// src/share.js
|
|
7469
|
-
var
|
|
7959
|
+
var import_delay5 = __toESM(require("delay"), 1);
|
|
7470
7960
|
|
|
7471
7961
|
// src/internals/watermarkify.js
|
|
7472
7962
|
var DEFAULT_TIMEZONE_OFFSET = 8;
|
|
@@ -7534,7 +8024,7 @@ var LOCATION_NETWORK_SUFFIX_PATTERNS = [
|
|
|
7534
8024
|
];
|
|
7535
8025
|
var cachedStripLogoSrcPromise = null;
|
|
7536
8026
|
var cachedEnrichmentByContext = /* @__PURE__ */ new WeakMap();
|
|
7537
|
-
var
|
|
8027
|
+
var logger14 = createInternalLogger("Watermarkify");
|
|
7538
8028
|
var normalizeText = (value) => String(value || "").trim();
|
|
7539
8029
|
var toInline = (value, maxLen = 200) => {
|
|
7540
8030
|
const text = normalizeText(value);
|
|
@@ -7776,9 +8266,9 @@ var resolveWithCustomResolver = async (page, baseMeta, options = {}) => {
|
|
|
7776
8266
|
location: toInline(resolved.location, 80)
|
|
7777
8267
|
};
|
|
7778
8268
|
if (enrichment.ip || enrichment.location) {
|
|
7779
|
-
|
|
8269
|
+
logger14.info(`\u81EA\u5B9A\u4E49 resolver \u547D\u4E2D: ip=${enrichment.ip || "-"}, loc=${enrichment.location || "-"}`);
|
|
7780
8270
|
} else {
|
|
7781
|
-
|
|
8271
|
+
logger14.warning("\u81EA\u5B9A\u4E49 resolver \u5DF2\u6267\u884C\uFF0C\u4F46\u672A\u8FD4\u56DE IP/Loc");
|
|
7782
8272
|
}
|
|
7783
8273
|
return enrichment;
|
|
7784
8274
|
} finally {
|
|
@@ -7962,14 +8452,17 @@ var buildWatermarkifyRenderHtml = ({ imageSrc, overlaySvg, width, height, imageH
|
|
|
7962
8452
|
</html>
|
|
7963
8453
|
`;
|
|
7964
8454
|
};
|
|
7965
|
-
var
|
|
8455
|
+
var normalizeWatermarkifyRenderMode = (value) => {
|
|
8456
|
+
return String(value || Mode.Default).trim().toLowerCase() === Mode.Cloak ? Mode.Cloak : Mode.Default;
|
|
8457
|
+
};
|
|
8458
|
+
var composeScreenshotBufferWithBrowser = async (page, buffer, overlaySvg, imageInfo = {}, options = {}) => {
|
|
7966
8459
|
if (!page || typeof page.context !== "function") {
|
|
7967
|
-
|
|
8460
|
+
logger14.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u8DF3\u8FC7: \u7F3A\u5C11\u53EF\u7528 page");
|
|
7968
8461
|
return buffer;
|
|
7969
8462
|
}
|
|
7970
8463
|
const renderScope = await openProbePage(page);
|
|
7971
8464
|
if (!renderScope?.page) {
|
|
7972
|
-
|
|
8465
|
+
logger14.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u8DF3\u8FC7: \u65E0\u6CD5\u521B\u5EFA render page");
|
|
7973
8466
|
return buffer;
|
|
7974
8467
|
}
|
|
7975
8468
|
try {
|
|
@@ -7986,15 +8479,35 @@ var composeScreenshotBufferWithBrowser = async (page, buffer, overlaySvg, imageI
|
|
|
7986
8479
|
height: viewportHeight
|
|
7987
8480
|
}).catch(() => {
|
|
7988
8481
|
});
|
|
7989
|
-
|
|
7990
|
-
|
|
7991
|
-
|
|
7992
|
-
|
|
7993
|
-
|
|
7994
|
-
|
|
7995
|
-
|
|
7996
|
-
|
|
7997
|
-
|
|
8482
|
+
const renderMode = normalizeWatermarkifyRenderMode(options.mode);
|
|
8483
|
+
if (renderMode === Mode.Cloak) {
|
|
8484
|
+
const renderHtml = buildWatermarkifyRenderHtml({
|
|
8485
|
+
imageSrc: `data:${imageInfo.mimeType || "image/png"};base64,${buffer.toString("base64")}`,
|
|
8486
|
+
overlaySvg,
|
|
8487
|
+
width: safeWidth,
|
|
8488
|
+
height: safeHeight,
|
|
8489
|
+
imageHeight: safeImageHeight
|
|
8490
|
+
});
|
|
8491
|
+
await renderPage.goto("about:blank", {
|
|
8492
|
+
waitUntil: "commit"
|
|
8493
|
+
}).catch(() => {
|
|
8494
|
+
});
|
|
8495
|
+
await renderPage.evaluate((html) => {
|
|
8496
|
+
document.open();
|
|
8497
|
+
document.write(html);
|
|
8498
|
+
document.close();
|
|
8499
|
+
}, renderHtml);
|
|
8500
|
+
} else {
|
|
8501
|
+
await renderPage.setContent(buildWatermarkifyRenderHtml({
|
|
8502
|
+
imageSrc: `data:${imageInfo.mimeType || "image/png"};base64,${buffer.toString("base64")}`,
|
|
8503
|
+
overlaySvg,
|
|
8504
|
+
width: safeWidth,
|
|
8505
|
+
height: safeHeight,
|
|
8506
|
+
imageHeight: safeImageHeight
|
|
8507
|
+
}), {
|
|
8508
|
+
waitUntil: "load"
|
|
8509
|
+
});
|
|
8510
|
+
}
|
|
7998
8511
|
await renderPage.waitForFunction(() => {
|
|
7999
8512
|
const image = document.getElementById("pk-base-image");
|
|
8000
8513
|
return image instanceof HTMLImageElement && image.complete && image.naturalWidth > 0 && image.naturalHeight > 0;
|
|
@@ -8014,13 +8527,13 @@ var composeScreenshotBufferWithBrowser = async (page, buffer, overlaySvg, imageI
|
|
|
8014
8527
|
fullPage: true,
|
|
8015
8528
|
animations: "disabled"
|
|
8016
8529
|
}).catch((error) => {
|
|
8017
|
-
|
|
8530
|
+
logger14.warning(`watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
|
|
8018
8531
|
return null;
|
|
8019
8532
|
});
|
|
8020
8533
|
if (Buffer.isBuffer(composed) && composed.length > 0) {
|
|
8021
8534
|
return composed;
|
|
8022
8535
|
}
|
|
8023
|
-
|
|
8536
|
+
logger14.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u5931\u8D25: \u672A\u5F97\u5230\u6709\u6548\u622A\u56FE\u7ED3\u679C");
|
|
8024
8537
|
return buffer;
|
|
8025
8538
|
} finally {
|
|
8026
8539
|
await renderScope.close().catch(() => {
|
|
@@ -8033,7 +8546,7 @@ var resolveWithIpLookup = async (page, options = {}) => {
|
|
|
8033
8546
|
}
|
|
8034
8547
|
const probeScope = await openProbePage(page);
|
|
8035
8548
|
if (!probeScope?.page) {
|
|
8036
|
-
|
|
8549
|
+
logger14.warning("ipLookup \u8DF3\u8FC7: \u65E0\u6CD5\u521B\u5EFA probe page");
|
|
8037
8550
|
return null;
|
|
8038
8551
|
}
|
|
8039
8552
|
const timeoutMs = Math.max(
|
|
@@ -8042,12 +8555,12 @@ var resolveWithIpLookup = async (page, options = {}) => {
|
|
|
8042
8555
|
);
|
|
8043
8556
|
try {
|
|
8044
8557
|
const probePage = probeScope.page;
|
|
8045
|
-
|
|
8558
|
+
logger14.info(`ipLookup \u5C1D\u8BD5: url=${DEFAULT_IP_LOOKUP_URL}, timeoutMs=${timeoutMs}`);
|
|
8046
8559
|
const response = await probePage.goto(DEFAULT_IP_LOOKUP_URL, {
|
|
8047
8560
|
waitUntil: "commit",
|
|
8048
8561
|
timeout: timeoutMs
|
|
8049
8562
|
}).catch((error) => {
|
|
8050
|
-
|
|
8563
|
+
logger14.warning(`ipLookup \u8BF7\u6C42\u5931\u8D25: url=${DEFAULT_IP_LOOKUP_URL}, error=${error instanceof Error ? error.message : String(error)}`);
|
|
8051
8564
|
return null;
|
|
8052
8565
|
});
|
|
8053
8566
|
const status = response && typeof response.status === "function" ? response.status() : 0;
|
|
@@ -8069,13 +8582,13 @@ var resolveWithIpLookup = async (page, options = {}) => {
|
|
|
8069
8582
|
}
|
|
8070
8583
|
const parsed = parseIpIpJsonResponse(rawText);
|
|
8071
8584
|
if (parsed?.ip || parsed?.location) {
|
|
8072
|
-
|
|
8585
|
+
logger14.info(`ipLookup \u6210\u529F: url=${DEFAULT_IP_LOOKUP_URL}, status=${status || "-"}, contentType=${contentType || "-"}, ip=${parsed.ip || "-"}, loc=${parsed.location || "-"}`);
|
|
8073
8586
|
return parsed;
|
|
8074
8587
|
}
|
|
8075
|
-
|
|
8588
|
+
logger14.warning(`ipLookup \u672A\u89E3\u6790\u51FA IP/Loc: url=${DEFAULT_IP_LOOKUP_URL}, status=${status || "-"}, contentType=${contentType || "-"}, preview=${shortenTail(rawText, 120) || "[empty]"}`);
|
|
8076
8589
|
return null;
|
|
8077
8590
|
} catch (error) {
|
|
8078
|
-
|
|
8591
|
+
logger14.warning(`ipLookup \u6267\u884C\u5F02\u5E38\uFF0C\u672A\u83B7\u5F97 IP/Loc: ${error instanceof Error ? error.message : String(error)}`);
|
|
8079
8592
|
return null;
|
|
8080
8593
|
} finally {
|
|
8081
8594
|
await probeScope.close().catch(() => {
|
|
@@ -8089,10 +8602,10 @@ var resolveEnrichment = async (page, baseMeta, options) => {
|
|
|
8089
8602
|
ip: toInline(options.ip, 80),
|
|
8090
8603
|
location: toInline(options.location, 80)
|
|
8091
8604
|
};
|
|
8092
|
-
|
|
8605
|
+
logger14.info(`enrichment \u5F00\u59CB: host=${baseMeta.hostname || "-"}, hasPresetIp=${Boolean(merged.ip)}, hasPresetLoc=${Boolean(merged.location)}, ipLookup=${options.ipLookup !== false}`);
|
|
8093
8606
|
if (!merged.ip || !merged.location) {
|
|
8094
8607
|
if (cached?.ip || cached?.location) {
|
|
8095
|
-
|
|
8608
|
+
logger14.info(`enrichment \u547D\u4E2D\u4E0A\u4E0B\u6587\u7F13\u5B58: ip=${cached.ip || "-"}, loc=${cached.location || "-"}`);
|
|
8096
8609
|
}
|
|
8097
8610
|
fillEnrichment(merged, cached);
|
|
8098
8611
|
}
|
|
@@ -8116,15 +8629,15 @@ var resolveEnrichment = async (page, baseMeta, options) => {
|
|
|
8116
8629
|
"x-geo-country"
|
|
8117
8630
|
]), 80);
|
|
8118
8631
|
if (!merged.location || isWeakLocationValue(merged.location) && headerLocation) {
|
|
8119
|
-
|
|
8632
|
+
logger14.info(`enrichment \u4F7F\u7528\u54CD\u5E94\u5934\u8865\u5145 Loc: ${headerLocation || "-"}`);
|
|
8120
8633
|
merged.location = headerLocation || merged.location;
|
|
8121
8634
|
}
|
|
8122
8635
|
}
|
|
8123
8636
|
writeCachedEnrichment(page, merged);
|
|
8124
8637
|
if (merged.ip || merged.location) {
|
|
8125
|
-
|
|
8638
|
+
logger14.info(`enrichment \u5B8C\u6210: ip=${merged.ip || "-"}, loc=${merged.location || "-"}`);
|
|
8126
8639
|
} else {
|
|
8127
|
-
|
|
8640
|
+
logger14.warning("enrichment \u5B8C\u6210: \u672A\u83B7\u5F97 IP/Loc");
|
|
8128
8641
|
}
|
|
8129
8642
|
return merged;
|
|
8130
8643
|
};
|
|
@@ -8929,7 +9442,7 @@ var buildWatermarkifySvg = (meta, imageWidth, imageHeight) => {
|
|
|
8929
9442
|
</svg>
|
|
8930
9443
|
`;
|
|
8931
9444
|
};
|
|
8932
|
-
var watermarkifyScreenshotBuffer = async (buffer, meta, page = null) => {
|
|
9445
|
+
var watermarkifyScreenshotBuffer = async (buffer, meta, page = null, options = {}) => {
|
|
8933
9446
|
const hasWatermark = meta?.watermark?.enabled !== false && normalizeText(meta?.watermarkText);
|
|
8934
9447
|
const hasStrip = meta?.strip?.enabled !== false && Array.isArray(meta?.stripSegments) && meta.stripSegments.length > 0;
|
|
8935
9448
|
if (!Buffer.isBuffer(buffer) || !meta || !hasWatermark && !hasStrip) {
|
|
@@ -8937,7 +9450,7 @@ var watermarkifyScreenshotBuffer = async (buffer, meta, page = null) => {
|
|
|
8937
9450
|
}
|
|
8938
9451
|
const imageInfo = readImageInfo(buffer);
|
|
8939
9452
|
if (!imageInfo.width || !imageInfo.height || !imageInfo.mimeType) {
|
|
8940
|
-
|
|
9453
|
+
logger14.warning("watermarkify \u8DF3\u8FC7: \u65E0\u6CD5\u89E3\u6790\u622A\u56FE\u5C3A\u5BF8\u6216\u683C\u5F0F");
|
|
8941
9454
|
return buffer;
|
|
8942
9455
|
}
|
|
8943
9456
|
const isMobileStrip = normalizeDevice(meta.device) === Device.Mobile && hasStrip;
|
|
@@ -8950,12 +9463,12 @@ var watermarkifyScreenshotBuffer = async (buffer, meta, page = null) => {
|
|
|
8950
9463
|
if (!overlaySvg) {
|
|
8951
9464
|
return buffer;
|
|
8952
9465
|
}
|
|
8953
|
-
return await composeScreenshotBufferWithBrowser(page, buffer, overlaySvg, outputImageInfo);
|
|
9466
|
+
return await composeScreenshotBufferWithBrowser(page, buffer, overlaySvg, outputImageInfo, options);
|
|
8954
9467
|
};
|
|
8955
9468
|
|
|
8956
9469
|
// src/internals/compression.js
|
|
8957
9470
|
var import_jimp = require("jimp");
|
|
8958
|
-
var
|
|
9471
|
+
var logger15 = createInternalLogger("Compression");
|
|
8959
9472
|
var DEFAULT_SCREENSHOT_MAX_BYTES = 5 * 1024 * 1024;
|
|
8960
9473
|
var DEFAULT_SCREENSHOT_OUTPUT_TYPE = "jpeg";
|
|
8961
9474
|
var DEFAULT_SCREENSHOT_QUALITY = 0.72;
|
|
@@ -9074,18 +9587,18 @@ var compressImageBufferToBase64 = async (buffer, compression) => {
|
|
|
9074
9587
|
return buffer.toString("base64");
|
|
9075
9588
|
}
|
|
9076
9589
|
const result = await compressImageBuffer(buffer, compression).catch((error) => {
|
|
9077
|
-
|
|
9590
|
+
logger15.warning(`captureScreen \u538B\u7F29\u5931\u8D25\uFF0C\u8FD4\u56DE\u539F\u56FE: ${error instanceof Error ? error.message : String(error)}`);
|
|
9078
9591
|
return null;
|
|
9079
9592
|
});
|
|
9080
9593
|
if (!result?.buffer) {
|
|
9081
9594
|
return buffer.toString("base64");
|
|
9082
9595
|
}
|
|
9083
9596
|
if (result.withinLimit) {
|
|
9084
|
-
|
|
9597
|
+
logger15.info(
|
|
9085
9598
|
`captureScreen \u5DF2\u538B\u7F29: ${originalBytes} -> ${result.bytes} bytes, format=${result.format}, quality=${result.quality}, scale=${result.scale}, size=${result.width}x${result.height}`
|
|
9086
9599
|
);
|
|
9087
9600
|
} else {
|
|
9088
|
-
|
|
9601
|
+
logger15.warning(
|
|
9089
9602
|
`captureScreen \u538B\u7F29\u540E\u4ECD\u8D85\u8FC7\u76EE\u6807: ${originalBytes} -> ${result.bytes} bytes, maxBytes=${compression.maxBytes}, format=${result.format}, quality=${result.quality}, scale=${result.scale}`
|
|
9090
9603
|
);
|
|
9091
9604
|
}
|
|
@@ -9093,7 +9606,7 @@ var compressImageBufferToBase64 = async (buffer, compression) => {
|
|
|
9093
9606
|
};
|
|
9094
9607
|
|
|
9095
9608
|
// src/share.js
|
|
9096
|
-
var
|
|
9609
|
+
var logger16 = createInternalLogger("Share");
|
|
9097
9610
|
var DEFAULT_TIMEOUT_MS2 = 50 * 1e3;
|
|
9098
9611
|
var DEFAULT_PAYLOAD_SNAPSHOT_MAX_LEN = 500;
|
|
9099
9612
|
var DEFAULT_POLL_INTERVAL_MS = 120;
|
|
@@ -9163,9 +9676,9 @@ var normalizeXurl = (value) => {
|
|
|
9163
9676
|
var normalizeShare = (share) => {
|
|
9164
9677
|
const source = share && typeof share === "object" ? share : {};
|
|
9165
9678
|
const modeRaw = String(source.mode || "dom").trim().toLowerCase();
|
|
9166
|
-
const
|
|
9679
|
+
const mode2 = ["dom", "response", "custom"].includes(modeRaw) ? modeRaw : "dom";
|
|
9167
9680
|
return {
|
|
9168
|
-
mode,
|
|
9681
|
+
mode: mode2,
|
|
9169
9682
|
prefix: normalizePrefix(source.prefix),
|
|
9170
9683
|
xurl: normalizeXurl(source.xurl)
|
|
9171
9684
|
};
|
|
@@ -9226,13 +9739,13 @@ var parseJsonSafely = (text) => {
|
|
|
9226
9739
|
var createDomShareMonitor = async (page, options = {}) => {
|
|
9227
9740
|
const prefix = normalizePrefix(options.prefix);
|
|
9228
9741
|
const selectors = options.selectors ?? "html";
|
|
9229
|
-
const
|
|
9742
|
+
const mode2 = options.mode ?? Mutation.Mode.All;
|
|
9230
9743
|
const onMatch = typeof options.onMatch === "function" ? options.onMatch : null;
|
|
9231
9744
|
const onTelemetry = typeof options.onTelemetry === "function" ? options.onTelemetry : null;
|
|
9232
9745
|
let matched = false;
|
|
9233
|
-
|
|
9746
|
+
logger16.info(`DOM \u76D1\u542C\u51C6\u5907\u6302\u8F7D: selectors=${toJsonInline(selectors, 120)}, mode=${mode2}`);
|
|
9234
9747
|
const monitor = await Mutation.useMonitor(page, selectors, {
|
|
9235
|
-
mode,
|
|
9748
|
+
mode: mode2,
|
|
9236
9749
|
onMutation: (context = {}) => {
|
|
9237
9750
|
if (matched) return;
|
|
9238
9751
|
const mutationCount = Number(context.mutationCount || 0);
|
|
@@ -9248,12 +9761,12 @@ ${text}`;
|
|
|
9248
9761
|
});
|
|
9249
9762
|
}
|
|
9250
9763
|
if (mutationCount <= 5 || mutationCount % 50 === 0) {
|
|
9251
|
-
|
|
9764
|
+
logger16.info(`DOM \u53D8\u5316\u5DF2\u6355\u83B7: mutationCount=${mutationCount}, mutationNodes=${mutationNodes.length}`);
|
|
9252
9765
|
}
|
|
9253
9766
|
const [candidate] = Utils.parseLinks(rawDom, { prefix }) || [];
|
|
9254
9767
|
if (!candidate) return;
|
|
9255
9768
|
matched = true;
|
|
9256
|
-
|
|
9769
|
+
logger16.success("captureLink.domHit", `DOM \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: mutationCount=${mutationCount}, link=${candidate}`);
|
|
9257
9770
|
if (onMatch) {
|
|
9258
9771
|
onMatch({
|
|
9259
9772
|
link: candidate,
|
|
@@ -9269,7 +9782,7 @@ ${text}`;
|
|
|
9269
9782
|
return {
|
|
9270
9783
|
stop: async () => {
|
|
9271
9784
|
const result = await monitor.stop();
|
|
9272
|
-
|
|
9785
|
+
logger16.info(`DOM \u76D1\u542C\u5DF2\u505C\u6B62: totalMutations=${result?.totalMutations || 0}`);
|
|
9273
9786
|
return result;
|
|
9274
9787
|
}
|
|
9275
9788
|
};
|
|
@@ -9318,8 +9831,8 @@ var Share = {
|
|
|
9318
9831
|
if (share.mode === "response" && apiMatchers.length === 0) {
|
|
9319
9832
|
throw new Error("Share.captureLink requires share.xurl[0] api matcher when mode=response");
|
|
9320
9833
|
}
|
|
9321
|
-
|
|
9322
|
-
|
|
9834
|
+
logger16.start("captureLink", `mode=${share.mode}, timeoutMs=${timeoutDisabled ? "disabled" : timeoutMs}, prefix=${share.prefix}`);
|
|
9835
|
+
logger16.info(`captureLink \u914D\u7F6E: xurl=${toJsonInline(share.xurl)}, domMode=${domMode}, domSelectors=${toJsonInline(domSelectors, 120)}`);
|
|
9323
9836
|
const stats = {
|
|
9324
9837
|
actionTimedOut: false,
|
|
9325
9838
|
domMutationCount: 0,
|
|
@@ -9331,7 +9844,7 @@ var Share = {
|
|
|
9331
9844
|
responseSampleUrls: []
|
|
9332
9845
|
};
|
|
9333
9846
|
if (isAborted()) {
|
|
9334
|
-
|
|
9847
|
+
logger16.warning(`captureLink \u5DF2\u53D6\u6D88: ${abortReason()}`);
|
|
9335
9848
|
return {
|
|
9336
9849
|
link: null,
|
|
9337
9850
|
payloadText: "",
|
|
@@ -9354,7 +9867,7 @@ var Share = {
|
|
|
9354
9867
|
link: validated,
|
|
9355
9868
|
payloadText: String(payloadText || "")
|
|
9356
9869
|
};
|
|
9357
|
-
|
|
9870
|
+
logger16.info(`\u5019\u9009\u94FE\u63A5\u5DF2\u786E\u8BA4: source=${source}, link=${validated}`);
|
|
9358
9871
|
return true;
|
|
9359
9872
|
};
|
|
9360
9873
|
const resolveResponseCandidate = (responseText) => {
|
|
@@ -9389,7 +9902,7 @@ var Share = {
|
|
|
9389
9902
|
try {
|
|
9390
9903
|
await monitor.stop();
|
|
9391
9904
|
} catch (error) {
|
|
9392
|
-
|
|
9905
|
+
logger16.warning(`\u505C\u6B62 DOM \u76D1\u542C\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
|
|
9393
9906
|
}
|
|
9394
9907
|
};
|
|
9395
9908
|
const onResponse = async (response) => {
|
|
@@ -9403,29 +9916,29 @@ var Share = {
|
|
|
9403
9916
|
stats.responseSampleUrls.push(url);
|
|
9404
9917
|
}
|
|
9405
9918
|
if (stats.responseObserved <= 5) {
|
|
9406
|
-
|
|
9919
|
+
logger16.info(`\u63A5\u53E3\u54CD\u5E94\u91C7\u6837(${stats.responseObserved}): ${url}`);
|
|
9407
9920
|
}
|
|
9408
9921
|
if (!apiMatchers.some((matcher) => url.includes(matcher))) return;
|
|
9409
9922
|
stats.responseMatched += 1;
|
|
9410
9923
|
stats.lastMatchedUrl = url;
|
|
9411
|
-
|
|
9924
|
+
logger16.info(`\u63A5\u53E3\u547D\u4E2D\u5339\u914D(${stats.responseMatched}): ${url}`);
|
|
9412
9925
|
const text = await response.text();
|
|
9413
9926
|
const hit = resolveResponseCandidate(text);
|
|
9414
9927
|
if (!hit?.link) {
|
|
9415
9928
|
if (stats.responseMatched <= 3) {
|
|
9416
|
-
|
|
9929
|
+
logger16.info(`\u63A5\u53E3\u89E3\u6790\u5B8C\u6210\u4F46\u672A\u63D0\u53D6\u5230\u5206\u4EAB\u94FE\u63A5: payloadSize=${text.length}`);
|
|
9417
9930
|
}
|
|
9418
9931
|
return;
|
|
9419
9932
|
}
|
|
9420
9933
|
stats.responseResolved += 1;
|
|
9421
|
-
|
|
9934
|
+
logger16.success("captureLink.responseHit", `\u63A5\u53E3\u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: url=${url}, link=${hit.link}`);
|
|
9422
9935
|
setCandidate("response", hit.link, hit.payloadText);
|
|
9423
9936
|
} catch (error) {
|
|
9424
|
-
|
|
9937
|
+
logger16.warning(`\u63A5\u53E3\u54CD\u5E94\u5904\u7406\u5F02\u5E38: ${error instanceof Error ? error.message : String(error)}`);
|
|
9425
9938
|
}
|
|
9426
9939
|
};
|
|
9427
9940
|
if (share.mode === "dom") {
|
|
9428
|
-
|
|
9941
|
+
logger16.info("\u5F53\u524D\u4E3A DOM \u6A21\u5F0F\uFF0C\u4EC5\u542F\u7528 DOM \u76D1\u542C");
|
|
9429
9942
|
domMonitor = await createDomShareMonitor(page, {
|
|
9430
9943
|
prefix: share.prefix,
|
|
9431
9944
|
selectors: domSelectors,
|
|
@@ -9440,17 +9953,17 @@ var Share = {
|
|
|
9440
9953
|
});
|
|
9441
9954
|
}
|
|
9442
9955
|
if (share.mode === "response") {
|
|
9443
|
-
|
|
9956
|
+
logger16.info(`\u5F53\u524D\u4E3A\u63A5\u53E3\u6A21\u5F0F\uFF0C\u6302\u8F7D response \u76D1\u542C: apiMatchers=${toJsonInline(apiMatchers, 160)}`);
|
|
9444
9957
|
page.on("response", onResponse);
|
|
9445
9958
|
}
|
|
9446
9959
|
if (share.mode === "custom") {
|
|
9447
|
-
|
|
9960
|
+
logger16.info("\u5F53\u524D\u4E3A custom \u6A21\u5F0F\uFF0C\u5C06\u4F7F\u7528 performActions \u8FD4\u56DE\u503C");
|
|
9448
9961
|
}
|
|
9449
9962
|
const deadline = timeoutDisabled ? Infinity : Date.now() + timeoutMs;
|
|
9450
9963
|
const getRemainingMs = () => timeoutDisabled ? Infinity : Math.max(0, deadline - Date.now());
|
|
9451
9964
|
try {
|
|
9452
9965
|
const actionTimeout = getRemainingMs();
|
|
9453
|
-
|
|
9966
|
+
logger16.start("captureLink.performActions", `\u6267\u884C\u52A8\u4F5C\u9884\u7B97=${timeoutDisabled ? "disabled" : `${actionTimeout}ms`}`);
|
|
9454
9967
|
let actionValue;
|
|
9455
9968
|
if (!isAborted() && actionTimeout > 0) {
|
|
9456
9969
|
let timer = null;
|
|
@@ -9463,30 +9976,30 @@ var Share = {
|
|
|
9463
9976
|
]);
|
|
9464
9977
|
if (timer) clearTimeout(timer);
|
|
9465
9978
|
if (actionResult.type === "error") {
|
|
9466
|
-
|
|
9979
|
+
logger16.fail("captureLink.performActions", actionResult.error);
|
|
9467
9980
|
throw actionResult.error;
|
|
9468
9981
|
}
|
|
9469
9982
|
if (actionResult.type === "timeout") {
|
|
9470
9983
|
stats.actionTimedOut = true;
|
|
9471
|
-
|
|
9984
|
+
logger16.warning(`performActions \u5DF2\u8D85\u65F6 (${actionTimeout}ms)\uFF0C\u52A8\u4F5C\u53EF\u80FD\u4ECD\u5728\u5F02\u6B65\u6267\u884C`);
|
|
9472
9985
|
} else {
|
|
9473
9986
|
actionValue = actionResult.result;
|
|
9474
|
-
|
|
9987
|
+
logger16.success("captureLink.performActions", "\u6267\u884C\u52A8\u4F5C\u5B8C\u6210");
|
|
9475
9988
|
}
|
|
9476
9989
|
}
|
|
9477
9990
|
if (share.mode === "custom") {
|
|
9478
9991
|
const customLink = typeof actionValue === "string" ? actionValue : actionValue?.link || actionValue?.payloadText;
|
|
9479
9992
|
const customPayloadText = typeof actionValue === "string" ? actionValue : actionValue?.payloadText;
|
|
9480
9993
|
if (setCandidate("custom", customLink, customPayloadText)) {
|
|
9481
|
-
|
|
9994
|
+
logger16.success("captureLink.customResult", `custom \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: link=${candidates.custom.link}`);
|
|
9482
9995
|
} else {
|
|
9483
|
-
|
|
9996
|
+
logger16.warning("performActions \u6267\u884C\u5B8C\u6210\u4F46\u672A\u8FD4\u56DE\u6709\u6548\u5206\u4EAB\u94FE\u63A5");
|
|
9484
9997
|
}
|
|
9485
9998
|
}
|
|
9486
9999
|
let nextProgressLogTs = Date.now() + 3e3;
|
|
9487
10000
|
while (true) {
|
|
9488
10001
|
if (isAborted()) {
|
|
9489
|
-
|
|
10002
|
+
logger16.warning(`captureLink \u5DF2\u53D6\u6D88: ${abortReason()}`);
|
|
9490
10003
|
return {
|
|
9491
10004
|
link: null,
|
|
9492
10005
|
payloadText: "",
|
|
@@ -9496,7 +10009,7 @@ var Share = {
|
|
|
9496
10009
|
}
|
|
9497
10010
|
const selected = candidates[share.mode];
|
|
9498
10011
|
if (selected?.link) {
|
|
9499
|
-
|
|
10012
|
+
logger16.success("captureLink", `\u6355\u83B7\u6210\u529F: source=${share.mode}, link=${selected.link}`);
|
|
9500
10013
|
return {
|
|
9501
10014
|
link: selected.link,
|
|
9502
10015
|
payloadText: selected.payloadText,
|
|
@@ -9509,19 +10022,19 @@ var Share = {
|
|
|
9509
10022
|
if (remaining <= 0) break;
|
|
9510
10023
|
const now = Date.now();
|
|
9511
10024
|
if (now >= nextProgressLogTs) {
|
|
9512
|
-
|
|
10025
|
+
logger16.info(
|
|
9513
10026
|
`captureLink \u7B49\u5F85\u4E2D: remaining=${timeoutDisabled ? "disabled" : `${remaining}ms`}, domMutationCount=${stats.domMutationCount}, responseMatched=${stats.responseMatched}`
|
|
9514
10027
|
);
|
|
9515
10028
|
nextProgressLogTs = now + 5e3;
|
|
9516
10029
|
}
|
|
9517
|
-
await (0,
|
|
10030
|
+
await (0, import_delay5.default)(Math.max(0, Math.min(DEFAULT_POLL_INTERVAL_MS, remaining)));
|
|
9518
10031
|
}
|
|
9519
10032
|
if (!timeoutDisabled && share.mode === "response" && stats.responseMatched === 0) {
|
|
9520
|
-
|
|
10033
|
+
logger16.warning(
|
|
9521
10034
|
`\u63A5\u53E3\u76D1\u542C\u672A\u547D\u4E2D: apiMatchers=${toJsonInline(apiMatchers, 220)}, \u54CD\u5E94\u6837\u672CURLs=${toJsonInline(stats.responseSampleUrls, 420)}`
|
|
9522
10035
|
);
|
|
9523
10036
|
}
|
|
9524
|
-
|
|
10037
|
+
logger16.warning(
|
|
9525
10038
|
`captureLink ${timeoutDisabled ? "\u672A\u62FF\u5230\u94FE\u63A5" : "\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"}`
|
|
9526
10039
|
);
|
|
9527
10040
|
return {
|
|
@@ -9533,7 +10046,7 @@ var Share = {
|
|
|
9533
10046
|
} finally {
|
|
9534
10047
|
if (share.mode === "response") {
|
|
9535
10048
|
page.off("response", onResponse);
|
|
9536
|
-
|
|
10049
|
+
logger16.info("response \u76D1\u542C\u5DF2\u5378\u8F7D");
|
|
9537
10050
|
}
|
|
9538
10051
|
await stopDomMonitor();
|
|
9539
10052
|
}
|
|
@@ -9548,12 +10061,14 @@ var Share = {
|
|
|
9548
10061
|
* @param {number} [options.maxBytes] 默认 5MiB,返回 base64 超过后会压缩
|
|
9549
10062
|
* @param {'jpeg'|'jpg'} [options.type] 压缩输出格式,默认 jpeg
|
|
9550
10063
|
* @param {boolean|Object} [options.compression] 传 false 可关闭压缩
|
|
10064
|
+
* @param {'default'|'cloak'} [options.mode] 截图水印合成模式,默认取当前 toolkit mode
|
|
9551
10065
|
* @returns {Promise<string>} base64 image
|
|
9552
10066
|
*/
|
|
9553
10067
|
async captureScreen(page, options = {}) {
|
|
9554
10068
|
const restore = options.restore ?? false;
|
|
9555
10069
|
const screenshotWatermarkify = resolveCaptureScreenWatermarkify(page, options.watermarkify);
|
|
9556
10070
|
const compression = resolveImageCompression(options);
|
|
10071
|
+
const screenshotMode = options.mode ?? getToolkitMode();
|
|
9557
10072
|
const captureOptions = {
|
|
9558
10073
|
restore,
|
|
9559
10074
|
maxHeight: options.maxHeight,
|
|
@@ -9568,7 +10083,9 @@ var Share = {
|
|
|
9568
10083
|
...screenshotWatermarkify,
|
|
9569
10084
|
capturedAt
|
|
9570
10085
|
});
|
|
9571
|
-
outputBuffer = await watermarkifyScreenshotBuffer(rawBuffer, watermarkifyMeta, page
|
|
10086
|
+
outputBuffer = await watermarkifyScreenshotBuffer(rawBuffer, watermarkifyMeta, page, {
|
|
10087
|
+
mode: screenshotMode
|
|
10088
|
+
});
|
|
9572
10089
|
}
|
|
9573
10090
|
return await compressImageBufferToBase64(outputBuffer, compression);
|
|
9574
10091
|
}
|
|
@@ -9576,8 +10093,13 @@ var Share = {
|
|
|
9576
10093
|
|
|
9577
10094
|
// entrys/node.js
|
|
9578
10095
|
Logger.setLogger(import_crawlee.log);
|
|
9579
|
-
var
|
|
9580
|
-
|
|
10096
|
+
var ToolkitMode = Object.freeze({
|
|
10097
|
+
default: Mode.Default,
|
|
10098
|
+
cloak: Mode.Cloak
|
|
10099
|
+
});
|
|
10100
|
+
var usePlaywrightToolKit = (mode2 = Mode.Default) => {
|
|
10101
|
+
setToolkitMode(mode2);
|
|
10102
|
+
const toolkit = {
|
|
9581
10103
|
ApifyKit,
|
|
9582
10104
|
AntiCheat,
|
|
9583
10105
|
DeviceInput,
|
|
@@ -9597,7 +10119,9 @@ var usePlaywrightToolKit = () => {
|
|
|
9597
10119
|
ByPass,
|
|
9598
10120
|
$Internals: { LOG_TEMPLATES, stripAnsi }
|
|
9599
10121
|
};
|
|
10122
|
+
return toolkit;
|
|
9600
10123
|
};
|
|
10124
|
+
usePlaywrightToolKit.Mode = ToolkitMode;
|
|
9601
10125
|
// Annotate the CommonJS export names for ESM import in node:
|
|
9602
10126
|
0 && (module.exports = {
|
|
9603
10127
|
usePlaywrightToolKit
|