@skrillex1224/playwright-toolkit 3.0.14 → 3.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.js +161 -409
- package/dist/browser.js.map +4 -4
- package/dist/index.cjs +479 -992
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +479 -992
- package/dist/index.js.map +4 -4
- package/index.d.ts +9 -40
- package/package.json +1 -7
package/dist/index.cjs
CHANGED
|
@@ -40,11 +40,9 @@ __export(constants_exports, {
|
|
|
40
40
|
ActorInfo: () => ActorInfo,
|
|
41
41
|
Code: () => Code,
|
|
42
42
|
Device: () => Device,
|
|
43
|
-
Mode: () => Mode,
|
|
44
43
|
PresetOfLiveViewKey: () => PresetOfLiveViewKey,
|
|
45
44
|
Status: () => Status,
|
|
46
|
-
normalizeDevice: () => normalizeDevice
|
|
47
|
-
normalizeMode: () => normalizeMode
|
|
45
|
+
normalizeDevice: () => normalizeDevice
|
|
48
46
|
});
|
|
49
47
|
var Code = {
|
|
50
48
|
Success: 0,
|
|
@@ -64,10 +62,6 @@ var Device = Object.freeze({
|
|
|
64
62
|
Desktop: "desktop",
|
|
65
63
|
Mobile: "mobile"
|
|
66
64
|
});
|
|
67
|
-
var Mode = Object.freeze({
|
|
68
|
-
Default: "default",
|
|
69
|
-
Cloak: "cloak"
|
|
70
|
-
});
|
|
71
65
|
var normalizeDevice = (value, fallback = Device.Desktop) => {
|
|
72
66
|
const normalizedFallback = String(fallback || "").trim().toLowerCase() === Device.Mobile ? Device.Mobile : Device.Desktop;
|
|
73
67
|
const raw = String(value || "").trim().toLowerCase();
|
|
@@ -75,13 +69,6 @@ var normalizeDevice = (value, fallback = Device.Desktop) => {
|
|
|
75
69
|
if (raw === Device.Desktop) return Device.Desktop;
|
|
76
70
|
return normalizedFallback;
|
|
77
71
|
};
|
|
78
|
-
var normalizeMode = (value, fallback = Mode.Default) => {
|
|
79
|
-
const normalizedFallback = String(fallback || "").trim().toLowerCase() === Mode.Cloak ? Mode.Cloak : Mode.Default;
|
|
80
|
-
const raw = String(value || "").trim().toLowerCase();
|
|
81
|
-
if (raw === Mode.Cloak) return Mode.Cloak;
|
|
82
|
-
if (raw === Mode.Default) return Mode.Default;
|
|
83
|
-
return normalizedFallback;
|
|
84
|
-
};
|
|
85
72
|
var createActorInfo = (info) => {
|
|
86
73
|
const normalizeDomain = (value) => {
|
|
87
74
|
if (!value) return "";
|
|
@@ -149,6 +136,7 @@ var createActorInfo = (info) => {
|
|
|
149
136
|
const buildLandingUrl = ({ protocol: protocol2, domain: domain2, path: path4 }) => {
|
|
150
137
|
const safeProtocol = String(protocol2).trim();
|
|
151
138
|
const safeDomain = normalizeDomain(domain2);
|
|
139
|
+
if (!safeDomain) return "";
|
|
152
140
|
const safePath = normalizePath(path4);
|
|
153
141
|
return `${safeProtocol}://${safeDomain}${safePath}`;
|
|
154
142
|
};
|
|
@@ -356,6 +344,18 @@ var ActorInfo = {
|
|
|
356
344
|
prefix: "",
|
|
357
345
|
xurl: []
|
|
358
346
|
}
|
|
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
359
|
})
|
|
360
360
|
};
|
|
361
361
|
|
|
@@ -387,18 +387,18 @@ var fallbackLog = {
|
|
|
387
387
|
error: (...args) => console.error(...args),
|
|
388
388
|
debug: (...args) => console.debug ? console.debug(...args) : console.log(...args)
|
|
389
389
|
};
|
|
390
|
-
var resolveLogMethod = (
|
|
391
|
-
if (
|
|
392
|
-
return
|
|
390
|
+
var resolveLogMethod = (logger16, name) => {
|
|
391
|
+
if (logger16 && typeof logger16[name] === "function") {
|
|
392
|
+
return logger16[name].bind(logger16);
|
|
393
393
|
}
|
|
394
|
-
if (name === "warning" &&
|
|
395
|
-
return
|
|
394
|
+
if (name === "warning" && logger16 && typeof logger16.warn === "function") {
|
|
395
|
+
return logger16.warn.bind(logger16);
|
|
396
396
|
}
|
|
397
397
|
return fallbackLog[name];
|
|
398
398
|
};
|
|
399
399
|
var defaultLogger = null;
|
|
400
|
-
var setDefaultLogger = (
|
|
401
|
-
defaultLogger =
|
|
400
|
+
var setDefaultLogger = (logger16) => {
|
|
401
|
+
defaultLogger = logger16;
|
|
402
402
|
};
|
|
403
403
|
var resolveLogger = (explicitLogger) => {
|
|
404
404
|
if (explicitLogger && typeof explicitLogger.info === "function") {
|
|
@@ -425,8 +425,8 @@ var colorize = (text, color) => {
|
|
|
425
425
|
var createBaseLogger = (prefix = "", explicitLogger) => {
|
|
426
426
|
const name = prefix ? String(prefix) : "";
|
|
427
427
|
const dispatch = (methodName, icon, message, color) => {
|
|
428
|
-
const
|
|
429
|
-
const logFn = resolveLogMethod(
|
|
428
|
+
const logger16 = resolveLogger(explicitLogger);
|
|
429
|
+
const logFn = resolveLogMethod(logger16, methodName);
|
|
430
430
|
const timestamp = colorize(`[${formatTimestamp()}]`, ANSI.gray);
|
|
431
431
|
const line = formatLine(name, icon, message);
|
|
432
432
|
const coloredLine = colorize(line, color);
|
|
@@ -780,7 +780,7 @@ var adjustAffixedElementsForExpandedScreenshot = async (page, options = {}) => {
|
|
|
780
780
|
if (safeTargetHeight <= viewportHeight + 1) {
|
|
781
781
|
return 0;
|
|
782
782
|
}
|
|
783
|
-
const
|
|
783
|
+
const hasOwn = (source, key) => Object.prototype.hasOwnProperty.call(source, key);
|
|
784
784
|
const isVisible = (el, style, rect) => {
|
|
785
785
|
if (!el || !style || !rect) return false;
|
|
786
786
|
if (style.display === "none" || style.visibility === "hidden" || style.visibility === "collapse") {
|
|
@@ -820,7 +820,7 @@ var adjustAffixedElementsForExpandedScreenshot = async (page, options = {}) => {
|
|
|
820
820
|
return true;
|
|
821
821
|
});
|
|
822
822
|
topLevelCandidates.forEach(({ el, position, edge }) => {
|
|
823
|
-
if (!
|
|
823
|
+
if (!hasOwn(el.dataset, "pkAffixedAdjusted")) {
|
|
824
824
|
el.dataset.pkAffixedAdjusted = "1";
|
|
825
825
|
el.dataset.pkOrigPosition = el.style.getPropertyValue("position") || "";
|
|
826
826
|
el.dataset.pkOrigPositionPriority = el.style.getPropertyPriority("position") || "";
|
|
@@ -851,7 +851,7 @@ var adjustAffixedElementsForExpandedScreenshot = async (page, options = {}) => {
|
|
|
851
851
|
};
|
|
852
852
|
var restoreAffixedElementsForExpandedScreenshot = async (page) => {
|
|
853
853
|
await page.evaluate((className) => {
|
|
854
|
-
const
|
|
854
|
+
const hasOwn = (source, key) => Object.prototype.hasOwnProperty.call(source, key);
|
|
855
855
|
const expansionKeys = [
|
|
856
856
|
"pkOrigOverflow",
|
|
857
857
|
"pkOrigHeight",
|
|
@@ -859,28 +859,28 @@ var restoreAffixedElementsForExpandedScreenshot = async (page) => {
|
|
|
859
859
|
"pkOrigMaxHeight"
|
|
860
860
|
];
|
|
861
861
|
document.querySelectorAll('[data-pk-affixed-adjusted="1"]').forEach((el) => {
|
|
862
|
-
if (
|
|
862
|
+
if (hasOwn(el.dataset, "pkOrigPosition")) {
|
|
863
863
|
el.style.setProperty("position", el.dataset.pkOrigPosition || "", el.dataset.pkOrigPositionPriority || "");
|
|
864
864
|
delete el.dataset.pkOrigPosition;
|
|
865
865
|
delete el.dataset.pkOrigPositionPriority;
|
|
866
866
|
}
|
|
867
|
-
if (
|
|
867
|
+
if (hasOwn(el.dataset, "pkOrigTop")) {
|
|
868
868
|
el.style.setProperty("top", el.dataset.pkOrigTop || "", el.dataset.pkOrigTopPriority || "");
|
|
869
869
|
delete el.dataset.pkOrigTop;
|
|
870
870
|
delete el.dataset.pkOrigTopPriority;
|
|
871
871
|
}
|
|
872
|
-
if (
|
|
872
|
+
if (hasOwn(el.dataset, "pkOrigBottom")) {
|
|
873
873
|
el.style.setProperty("bottom", el.dataset.pkOrigBottom || "", el.dataset.pkOrigBottomPriority || "");
|
|
874
874
|
delete el.dataset.pkOrigBottom;
|
|
875
875
|
delete el.dataset.pkOrigBottomPriority;
|
|
876
876
|
}
|
|
877
|
-
if (
|
|
877
|
+
if (hasOwn(el.dataset, "pkOrigTranslate")) {
|
|
878
878
|
el.style.setProperty("translate", el.dataset.pkOrigTranslate || "", el.dataset.pkOrigTranslatePriority || "");
|
|
879
879
|
delete el.dataset.pkOrigTranslate;
|
|
880
880
|
delete el.dataset.pkOrigTranslatePriority;
|
|
881
881
|
}
|
|
882
882
|
delete el.dataset.pkAffixedAdjusted;
|
|
883
|
-
const stillExpanded = expansionKeys.some((key) =>
|
|
883
|
+
const stillExpanded = expansionKeys.some((key) => hasOwn(el.dataset, key));
|
|
884
884
|
if (!stillExpanded) {
|
|
885
885
|
el.classList.remove(className);
|
|
886
886
|
}
|
|
@@ -923,7 +923,7 @@ var prepareExpandedFullPageScreenshot = async (page, options = {}) => {
|
|
|
923
923
|
viewportResized
|
|
924
924
|
};
|
|
925
925
|
};
|
|
926
|
-
var restoreExpandedFullPageScreenshot = async (page,
|
|
926
|
+
var restoreExpandedFullPageScreenshot = async (page, state = {}) => {
|
|
927
927
|
await page.evaluate((className) => {
|
|
928
928
|
const targets = new Set([
|
|
929
929
|
...document.querySelectorAll(`.${className}`),
|
|
@@ -947,8 +947,8 @@ var restoreExpandedFullPageScreenshot = async (page, state2 = {}) => {
|
|
|
947
947
|
el.classList.remove(className);
|
|
948
948
|
});
|
|
949
949
|
}, EXPANDED_SCROLLABLE_CLASS);
|
|
950
|
-
if (
|
|
951
|
-
await page.setViewportSize(
|
|
950
|
+
if (state?.originalViewport && state?.viewportResized) {
|
|
951
|
+
await page.setViewportSize(state.originalViewport);
|
|
952
952
|
}
|
|
953
953
|
};
|
|
954
954
|
var capturePageScreenshot = async (page, options = {}) => {
|
|
@@ -1005,21 +1005,21 @@ var capturePageScreenshot = async (page, options = {}) => {
|
|
|
1005
1005
|
}
|
|
1006
1006
|
};
|
|
1007
1007
|
var captureExpandedFullPageScreenshot = async (page, options = {}) => {
|
|
1008
|
-
const
|
|
1008
|
+
const state = await prepareExpandedFullPageScreenshot(page, options);
|
|
1009
1009
|
try {
|
|
1010
1010
|
return await capturePageScreenshot(page, {
|
|
1011
1011
|
fullPage: true,
|
|
1012
1012
|
type: options.type || "png",
|
|
1013
1013
|
quality: options.quality,
|
|
1014
1014
|
timeout: options.timeout,
|
|
1015
|
-
maxClipHeight:
|
|
1015
|
+
maxClipHeight: state.targetHeight
|
|
1016
1016
|
});
|
|
1017
1017
|
} finally {
|
|
1018
1018
|
await restoreAffixedElementsForExpandedScreenshot(page).catch((error) => {
|
|
1019
1019
|
logger.warning(`\u79FB\u52A8\u7AEF\u5438\u9644\u5143\u7D20\u6062\u590D\u5931\u8D25: ${error?.message || error}`);
|
|
1020
1020
|
});
|
|
1021
1021
|
if (options.restore) {
|
|
1022
|
-
await restoreExpandedFullPageScreenshot(page,
|
|
1022
|
+
await restoreExpandedFullPageScreenshot(page, state);
|
|
1023
1023
|
}
|
|
1024
1024
|
}
|
|
1025
1025
|
};
|
|
@@ -1938,8 +1938,8 @@ var normalizeBrowserProfile = (value) => {
|
|
|
1938
1938
|
payload: buildBrowserProfilePayload(core, observed)
|
|
1939
1939
|
};
|
|
1940
1940
|
};
|
|
1941
|
-
var rememberRuntimeState = (
|
|
1942
|
-
rememberedRuntimeState = deepClone(
|
|
1941
|
+
var rememberRuntimeState = (state) => {
|
|
1942
|
+
rememberedRuntimeState = deepClone(state);
|
|
1943
1943
|
return rememberedRuntimeState;
|
|
1944
1944
|
};
|
|
1945
1945
|
var normalizeRuntimeState = (source = {}, actor = "") => {
|
|
@@ -1998,7 +1998,7 @@ var RuntimeEnv = {
|
|
|
1998
1998
|
} else {
|
|
1999
1999
|
delete normalizedRuntime.browser_profile;
|
|
2000
2000
|
}
|
|
2001
|
-
const
|
|
2001
|
+
const state = {
|
|
2002
2002
|
actor: resolvedActor,
|
|
2003
2003
|
device,
|
|
2004
2004
|
runtime: normalizedRuntime,
|
|
@@ -2012,73 +2012,73 @@ var RuntimeEnv = {
|
|
|
2012
2012
|
browserProfileCore: browserProfile.core,
|
|
2013
2013
|
browserProfileObserved: browserProfile.observed
|
|
2014
2014
|
};
|
|
2015
|
-
rememberRuntimeState(
|
|
2016
|
-
return
|
|
2015
|
+
rememberRuntimeState(state);
|
|
2016
|
+
return state;
|
|
2017
2017
|
},
|
|
2018
2018
|
// buildEnvPatch 只构造允许回写到后端 env 的字段集合。
|
|
2019
2019
|
buildEnvPatch(source = {}, actor = "") {
|
|
2020
|
-
const
|
|
2021
|
-
const browserProfile = buildBrowserProfilePayload(
|
|
2020
|
+
const state = normalizeRuntimeState(source, actor);
|
|
2021
|
+
const browserProfile = buildBrowserProfilePayload(state.browserProfileCore, state.browserProfileObserved);
|
|
2022
2022
|
const envPatch = {
|
|
2023
|
-
...Array.isArray(
|
|
2024
|
-
...Object.keys(
|
|
2025
|
-
...Object.keys(
|
|
2023
|
+
...Array.isArray(state.cookies) && state.cookies.length > 0 ? { cookies: state.cookies } : {},
|
|
2024
|
+
...Object.keys(state.localStorage || {}).length > 0 ? { local_storage: state.localStorage } : {},
|
|
2025
|
+
...Object.keys(state.sessionStorage || {}).length > 0 ? { session_storage: state.sessionStorage } : {},
|
|
2026
2026
|
...Object.keys(browserProfile).length > 0 ? { browser_profile: browserProfile } : {}
|
|
2027
2027
|
};
|
|
2028
2028
|
return Object.keys(envPatch).length > 0 ? envPatch : null;
|
|
2029
2029
|
},
|
|
2030
2030
|
// hasLoginState 只判断 runtime 是否存在有效载荷,不再区分具体字段来源。
|
|
2031
2031
|
hasLoginState(source = {}, actor = "") {
|
|
2032
|
-
const
|
|
2033
|
-
return isPlainObject(
|
|
2032
|
+
const state = normalizeRuntimeState(source, actor);
|
|
2033
|
+
return isPlainObject(state.runtime) && Object.keys(state.runtime || {}).length > 0;
|
|
2034
2034
|
},
|
|
2035
2035
|
rememberState(source = {}) {
|
|
2036
|
-
const
|
|
2037
|
-
rememberRuntimeState(
|
|
2036
|
+
const state = normalizeRuntimeState(source);
|
|
2037
|
+
rememberRuntimeState(state);
|
|
2038
2038
|
return RuntimeEnv.peekRememberedState();
|
|
2039
2039
|
},
|
|
2040
2040
|
peekRememberedState() {
|
|
2041
2041
|
return rememberedRuntimeState ? deepClone(rememberedRuntimeState) : null;
|
|
2042
2042
|
},
|
|
2043
2043
|
getBrowserProfileCore(source = {}, actor = "") {
|
|
2044
|
-
const
|
|
2045
|
-
return deepClone(
|
|
2044
|
+
const state = normalizeRuntimeState(source, actor);
|
|
2045
|
+
return deepClone(state.browserProfileCore || {});
|
|
2046
2046
|
},
|
|
2047
2047
|
setBrowserProfileCore(source = {}, core = {}, actor = "") {
|
|
2048
|
-
const
|
|
2048
|
+
const state = normalizeRuntimeState(source, actor);
|
|
2049
2049
|
const normalizedCore = normalizeBrowserProfileCore({
|
|
2050
2050
|
...core,
|
|
2051
|
-
device: normalizeKnownDevice(core?.device) ||
|
|
2051
|
+
device: normalizeKnownDevice(core?.device) || state.device
|
|
2052
2052
|
});
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
if (Object.keys(
|
|
2056
|
-
|
|
2053
|
+
state.browserProfileCore = normalizedCore;
|
|
2054
|
+
state.browserProfile = buildBrowserProfilePayload(normalizedCore, state.browserProfileObserved);
|
|
2055
|
+
if (Object.keys(state.browserProfile).length > 0) {
|
|
2056
|
+
state.runtime.browser_profile = state.browserProfile;
|
|
2057
2057
|
} else {
|
|
2058
|
-
delete
|
|
2058
|
+
delete state.runtime.browser_profile;
|
|
2059
2059
|
}
|
|
2060
|
-
rememberRuntimeState(
|
|
2061
|
-
return
|
|
2060
|
+
rememberRuntimeState(state);
|
|
2061
|
+
return state;
|
|
2062
2062
|
},
|
|
2063
2063
|
// applyToPage 只负责把登录态相关字段注入页面:
|
|
2064
2064
|
// cookies / localStorage / sessionStorage。
|
|
2065
2065
|
// 指纹、时区、UA、viewport 的回放发生在 launch.js 启动阶段,不在这里做。
|
|
2066
2066
|
async applyToPage(page, source = {}, options = {}) {
|
|
2067
2067
|
if (!page) return;
|
|
2068
|
-
let
|
|
2068
|
+
let state = normalizeRuntimeState(source, options?.actor || "");
|
|
2069
2069
|
if (typeof options?.preapply === "function") {
|
|
2070
|
-
|
|
2071
|
-
rememberRuntimeState(
|
|
2070
|
+
state = await options.preapply(state) || state;
|
|
2071
|
+
rememberRuntimeState(state);
|
|
2072
2072
|
}
|
|
2073
2073
|
Object.defineProperty(page, PageRuntimeStateKey, {
|
|
2074
2074
|
configurable: true,
|
|
2075
2075
|
enumerable: false,
|
|
2076
2076
|
writable: true,
|
|
2077
|
-
value:
|
|
2077
|
+
value: state
|
|
2078
2078
|
});
|
|
2079
|
-
const localStorage =
|
|
2080
|
-
const sessionStorage =
|
|
2081
|
-
const cookies = (
|
|
2079
|
+
const localStorage = state.localStorage || {};
|
|
2080
|
+
const sessionStorage = state.sessionStorage || {};
|
|
2081
|
+
const cookies = (state.cookies || []).map((cookie) => {
|
|
2082
2082
|
const normalized = { ...cookie };
|
|
2083
2083
|
if (!normalized.path) {
|
|
2084
2084
|
normalized.path = "/";
|
|
@@ -2116,8 +2116,8 @@ var RuntimeEnv = {
|
|
|
2116
2116
|
},
|
|
2117
2117
|
// captureEnvPatch 在任务结束时采集最新环境快照,用于 pushSuccess / pushFailed 自动回写。
|
|
2118
2118
|
async captureEnvPatch(page, source = {}, options = {}) {
|
|
2119
|
-
const
|
|
2120
|
-
const baseline = RuntimeEnv.buildEnvPatch(
|
|
2119
|
+
const state = normalizeRuntimeState(source, options?.actor || "");
|
|
2120
|
+
const baseline = RuntimeEnv.buildEnvPatch(state) || {};
|
|
2121
2121
|
if (!page || typeof page.evaluate !== "function" || typeof page.context !== "function") {
|
|
2122
2122
|
return Object.keys(baseline).length > 0 ? baseline : null;
|
|
2123
2123
|
}
|
|
@@ -2136,7 +2136,7 @@ var RuntimeEnv = {
|
|
|
2136
2136
|
cookies
|
|
2137
2137
|
},
|
|
2138
2138
|
{
|
|
2139
|
-
browserProfileCore:
|
|
2139
|
+
browserProfileCore: state.browserProfileCore
|
|
2140
2140
|
}
|
|
2141
2141
|
);
|
|
2142
2142
|
return RuntimeEnv.mergeEnvPatches(baseline, capturedPatch);
|
|
@@ -2150,11 +2150,11 @@ var RuntimeEnv = {
|
|
|
2150
2150
|
var logger3 = createInternalLogger("ApifyKit");
|
|
2151
2151
|
var resolveRuntimeContext = (input) => {
|
|
2152
2152
|
const rememberedState = RuntimeEnv.peekRememberedState();
|
|
2153
|
-
const
|
|
2154
|
-
const envPatch = RuntimeEnv.buildEnvPatch(
|
|
2153
|
+
const state = rememberedState || RuntimeEnv.parseInput(input || {});
|
|
2154
|
+
const envPatch = RuntimeEnv.buildEnvPatch(state) || null;
|
|
2155
2155
|
return {
|
|
2156
|
-
actor:
|
|
2157
|
-
runtime:
|
|
2156
|
+
actor: state.actor,
|
|
2157
|
+
runtime: state.runtime,
|
|
2158
2158
|
envPatch
|
|
2159
2159
|
};
|
|
2160
2160
|
};
|
|
@@ -2513,82 +2513,8 @@ var Utils = {
|
|
|
2513
2513
|
}
|
|
2514
2514
|
};
|
|
2515
2515
|
|
|
2516
|
-
// src/
|
|
2517
|
-
var
|
|
2518
|
-
mode: Mode.Default
|
|
2519
|
-
};
|
|
2520
|
-
var normalizeStrategies = (strategies) => strategies && typeof strategies === "object" ? strategies : {};
|
|
2521
|
-
var ToolkitContext = {
|
|
2522
|
-
get mode() {
|
|
2523
|
-
return state.mode;
|
|
2524
|
-
},
|
|
2525
|
-
setMode(mode = Mode.Default) {
|
|
2526
|
-
state.mode = normalizeMode(mode, Mode.Default);
|
|
2527
|
-
return state.mode;
|
|
2528
|
-
}
|
|
2529
|
-
};
|
|
2530
|
-
var getToolkitMode = () => state.mode;
|
|
2531
|
-
var setToolkitMode = (mode = Mode.Default) => ToolkitContext.setMode(mode);
|
|
2532
|
-
var resolveModeStrategy = (strategies = {}, mode = getToolkitMode(), fallbackMode = Mode.Default) => {
|
|
2533
|
-
const normalizedStrategies = normalizeStrategies(strategies);
|
|
2534
|
-
const normalizedMode = normalizeMode(mode, fallbackMode);
|
|
2535
|
-
const strategy = normalizedStrategies[normalizedMode] ?? normalizedStrategies[fallbackMode] ?? Object.values(normalizedStrategies).find(Boolean) ?? null;
|
|
2536
|
-
return {
|
|
2537
|
-
mode: normalizedMode,
|
|
2538
|
-
strategy
|
|
2539
|
-
};
|
|
2540
|
-
};
|
|
2541
|
-
|
|
2542
|
-
// src/internals/reflect.js
|
|
2543
|
-
var normalizeStrategies2 = (strategies) => strategies && typeof strategies === "object" ? strategies : {};
|
|
2544
|
-
var collectFunctionNames = (strategies = []) => {
|
|
2545
|
-
const names = /* @__PURE__ */ new Set();
|
|
2546
|
-
for (const strategy of strategies) {
|
|
2547
|
-
if (!strategy || typeof strategy !== "object") continue;
|
|
2548
|
-
for (const name of Reflect.ownKeys(strategy)) {
|
|
2549
|
-
if (typeof name === "string" && typeof strategy[name] === "function") {
|
|
2550
|
-
names.add(name);
|
|
2551
|
-
}
|
|
2552
|
-
}
|
|
2553
|
-
}
|
|
2554
|
-
return names;
|
|
2555
|
-
};
|
|
2556
|
-
var methodDescriptor = (namespace, name, resolveTarget) => ({
|
|
2557
|
-
enumerable: true,
|
|
2558
|
-
configurable: true,
|
|
2559
|
-
writable: true,
|
|
2560
|
-
value: (...args) => {
|
|
2561
|
-
const { mode, strategy } = resolveTarget(args);
|
|
2562
|
-
const method = strategy?.[name];
|
|
2563
|
-
if (typeof method !== "function") {
|
|
2564
|
-
throw new Error(`${namespace}.${name} is not available in ${mode} mode`);
|
|
2565
|
-
}
|
|
2566
|
-
return method.apply(strategy, args);
|
|
2567
|
-
}
|
|
2568
|
-
});
|
|
2569
|
-
var withModeReflect = (namespace, strategies = {}) => {
|
|
2570
|
-
const normalizedStrategies = normalizeStrategies2(strategies);
|
|
2571
|
-
const baseStrategy = normalizedStrategies.default ?? Object.values(normalizedStrategies).find(Boolean);
|
|
2572
|
-
const names = collectFunctionNames([baseStrategy]);
|
|
2573
|
-
const descriptors = {};
|
|
2574
|
-
for (const name of names) {
|
|
2575
|
-
descriptors[name] = methodDescriptor(namespace, name, () => resolveModeStrategy(normalizedStrategies));
|
|
2576
|
-
}
|
|
2577
|
-
return Object.defineProperties({}, descriptors);
|
|
2578
|
-
};
|
|
2579
|
-
var withPageReflect = (namespace, resolveStrategy, strategies = []) => {
|
|
2580
|
-
const names = collectFunctionNames(strategies);
|
|
2581
|
-
const descriptors = {};
|
|
2582
|
-
for (const name of names) {
|
|
2583
|
-
descriptors[name] = methodDescriptor(namespace, name, ([page]) => ({
|
|
2584
|
-
mode: "page",
|
|
2585
|
-
strategy: resolveStrategy(page)
|
|
2586
|
-
}));
|
|
2587
|
-
}
|
|
2588
|
-
return Object.defineProperties({}, descriptors);
|
|
2589
|
-
};
|
|
2590
|
-
|
|
2591
|
-
// src/internals/anti-cheat/default.js
|
|
2516
|
+
// src/anti-cheat.js
|
|
2517
|
+
var logger5 = createInternalLogger("AntiCheat");
|
|
2592
2518
|
var BASE_CONFIG = Object.freeze({
|
|
2593
2519
|
locale: "zh-CN",
|
|
2594
2520
|
acceptLanguage: "zh-CN,zh;q=0.9",
|
|
@@ -2623,7 +2549,7 @@ function buildFingerprintOptions({ locale = BASE_CONFIG.locale, browserMajorVers
|
|
|
2623
2549
|
}
|
|
2624
2550
|
return options;
|
|
2625
2551
|
}
|
|
2626
|
-
var
|
|
2552
|
+
var AntiCheat = {
|
|
2627
2553
|
/**
|
|
2628
2554
|
* 获取统一的基础配置
|
|
2629
2555
|
*/
|
|
@@ -2660,47 +2586,6 @@ var DefaultAntiCheat = {
|
|
|
2660
2586
|
}
|
|
2661
2587
|
};
|
|
2662
2588
|
|
|
2663
|
-
// src/internals/anti-cheat/cloak.js
|
|
2664
|
-
var CLOAK_BASE_CONFIG = Object.freeze({
|
|
2665
|
-
locale: "",
|
|
2666
|
-
acceptLanguage: "",
|
|
2667
|
-
timezoneId: "",
|
|
2668
|
-
timezoneOffset: null,
|
|
2669
|
-
geolocation: null
|
|
2670
|
-
});
|
|
2671
|
-
var normalizeHeaders = (headers) => headers && typeof headers === "object" ? headers : {};
|
|
2672
|
-
var CloakAntiCheat = {
|
|
2673
|
-
/**
|
|
2674
|
-
* Cloak 自身会负责浏览器指纹,toolkit 在该模式下尽量不再注入额外反检测配置。
|
|
2675
|
-
*/
|
|
2676
|
-
getBaseConfig() {
|
|
2677
|
-
return { ...CLOAK_BASE_CONFIG };
|
|
2678
|
-
},
|
|
2679
|
-
getFingerprintGeneratorOptions() {
|
|
2680
|
-
return {};
|
|
2681
|
-
},
|
|
2682
|
-
getLaunchArgs() {
|
|
2683
|
-
return [];
|
|
2684
|
-
},
|
|
2685
|
-
getTlsFingerprintOptions() {
|
|
2686
|
-
return {};
|
|
2687
|
-
},
|
|
2688
|
-
applyLocaleHeaders(headers, acceptLanguage = "") {
|
|
2689
|
-
const normalizedHeaders = normalizeHeaders(headers);
|
|
2690
|
-
if (acceptLanguage && !normalizedHeaders["accept-language"]) {
|
|
2691
|
-
normalizedHeaders["accept-language"] = acceptLanguage;
|
|
2692
|
-
}
|
|
2693
|
-
return normalizedHeaders;
|
|
2694
|
-
}
|
|
2695
|
-
};
|
|
2696
|
-
|
|
2697
|
-
// src/anti-cheat.js
|
|
2698
|
-
var antiCheatStrategies = {
|
|
2699
|
-
[Mode.Default]: DefaultAntiCheat,
|
|
2700
|
-
[Mode.Cloak]: CloakAntiCheat
|
|
2701
|
-
};
|
|
2702
|
-
var AntiCheat = withModeReflect("AntiCheat", antiCheatStrategies);
|
|
2703
|
-
|
|
2704
2589
|
// src/device-input.js
|
|
2705
2590
|
var resolveDeviceFromPage = (page) => normalizeDevice(page?.[PageRuntimeStateKey]?.device);
|
|
2706
2591
|
var assertPage = (page, method) => {
|
|
@@ -3100,12 +2985,12 @@ var resolveDescriptor = (descriptor, device) => {
|
|
|
3100
2985
|
}
|
|
3101
2986
|
return resolved;
|
|
3102
2987
|
};
|
|
3103
|
-
var attachRuntimeState = (page,
|
|
2988
|
+
var attachRuntimeState = (page, state) => {
|
|
3104
2989
|
Object.defineProperty(page, PageRuntimeStateKey, {
|
|
3105
2990
|
configurable: true,
|
|
3106
2991
|
enumerable: false,
|
|
3107
2992
|
writable: true,
|
|
3108
|
-
value:
|
|
2993
|
+
value: state
|
|
3109
2994
|
});
|
|
3110
2995
|
};
|
|
3111
2996
|
var restoreRuntimeState = (page, snapshot) => {
|
|
@@ -3251,13 +3136,10 @@ var DeviceView = {
|
|
|
3251
3136
|
}
|
|
3252
3137
|
};
|
|
3253
3138
|
|
|
3254
|
-
// src/internals/humanize/index.js
|
|
3255
|
-
var import_delay4 = __toESM(require("delay"), 1);
|
|
3256
|
-
|
|
3257
3139
|
// src/internals/humanize/desktop.js
|
|
3258
3140
|
var import_delay2 = __toESM(require("delay"), 1);
|
|
3259
3141
|
var import_ghost_cursor_playwright = require("ghost-cursor-playwright");
|
|
3260
|
-
var
|
|
3142
|
+
var logger6 = createInternalLogger("Humanize");
|
|
3261
3143
|
var $CursorWeakMap = /* @__PURE__ */ new WeakMap();
|
|
3262
3144
|
function $GetCursor(page) {
|
|
3263
3145
|
const cursor = $CursorWeakMap.get(page);
|
|
@@ -3285,13 +3167,13 @@ var Humanize = {
|
|
|
3285
3167
|
*/
|
|
3286
3168
|
async initializeCursor(page) {
|
|
3287
3169
|
if ($CursorWeakMap.has(page)) {
|
|
3288
|
-
|
|
3170
|
+
logger6.debug("initializeCursor: cursor already exists, skipping");
|
|
3289
3171
|
return;
|
|
3290
3172
|
}
|
|
3291
|
-
|
|
3173
|
+
logger6.start("initializeCursor", "creating cursor");
|
|
3292
3174
|
const cursor = await (0, import_ghost_cursor_playwright.createCursor)(page);
|
|
3293
3175
|
$CursorWeakMap.set(page, cursor);
|
|
3294
|
-
|
|
3176
|
+
logger6.success("initializeCursor", "cursor initialized");
|
|
3295
3177
|
},
|
|
3296
3178
|
/**
|
|
3297
3179
|
* 人类化鼠标移动 - 使用 ghost-cursor 移动到指定位置或元素
|
|
@@ -3301,17 +3183,17 @@ var Humanize = {
|
|
|
3301
3183
|
*/
|
|
3302
3184
|
async humanMove(page, target) {
|
|
3303
3185
|
const cursor = $GetCursor(page);
|
|
3304
|
-
|
|
3186
|
+
logger6.start("humanMove", `target=${typeof target === "string" ? target : "element/coords"}`);
|
|
3305
3187
|
try {
|
|
3306
3188
|
if (typeof target === "string") {
|
|
3307
3189
|
const element = await page.$(target);
|
|
3308
3190
|
if (!element) {
|
|
3309
|
-
|
|
3191
|
+
logger6.warn(`humanMove: \u5143\u7D20\u4E0D\u5B58\u5728 ${target}`);
|
|
3310
3192
|
return false;
|
|
3311
3193
|
}
|
|
3312
3194
|
const box = await element.boundingBox();
|
|
3313
3195
|
if (!box) {
|
|
3314
|
-
|
|
3196
|
+
logger6.warn(`humanMove: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E ${target}`);
|
|
3315
3197
|
return false;
|
|
3316
3198
|
}
|
|
3317
3199
|
const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.2;
|
|
@@ -3327,10 +3209,10 @@ var Humanize = {
|
|
|
3327
3209
|
await cursor.actions.move({ x, y });
|
|
3328
3210
|
}
|
|
3329
3211
|
}
|
|
3330
|
-
|
|
3212
|
+
logger6.success("humanMove");
|
|
3331
3213
|
return true;
|
|
3332
3214
|
} catch (error) {
|
|
3333
|
-
|
|
3215
|
+
logger6.fail("humanMove", error);
|
|
3334
3216
|
throw error;
|
|
3335
3217
|
}
|
|
3336
3218
|
},
|
|
@@ -3354,12 +3236,12 @@ var Humanize = {
|
|
|
3354
3236
|
maxDurationMs = maxSteps * 220 + 800
|
|
3355
3237
|
} = options;
|
|
3356
3238
|
const targetDesc = typeof target === "string" ? target : "ElementHandle";
|
|
3357
|
-
|
|
3239
|
+
logger6.start("humanScroll", `target=${targetDesc}`);
|
|
3358
3240
|
let element;
|
|
3359
3241
|
if (typeof target === "string") {
|
|
3360
3242
|
element = await page.$(target);
|
|
3361
3243
|
if (!element) {
|
|
3362
|
-
|
|
3244
|
+
logger6.warn(`humanScroll | \u5143\u7D20\u672A\u627E\u5230: ${target}`);
|
|
3363
3245
|
return { element: null, didScroll: false };
|
|
3364
3246
|
}
|
|
3365
3247
|
} else {
|
|
@@ -3434,26 +3316,26 @@ var Humanize = {
|
|
|
3434
3316
|
try {
|
|
3435
3317
|
for (let i = 0; i < maxSteps; i++) {
|
|
3436
3318
|
if (Date.now() - startTime > maxDurationMs) {
|
|
3437
|
-
|
|
3319
|
+
logger6.warn(`humanScroll | \u8D85\u65F6\u4FDD\u62A4\u89E6\u53D1 (${maxDurationMs}ms)`);
|
|
3438
3320
|
return { element, didScroll };
|
|
3439
3321
|
}
|
|
3440
3322
|
const status = await checkVisibility();
|
|
3441
3323
|
if (status.code === "VISIBLE") {
|
|
3442
3324
|
if (status.isFixed) {
|
|
3443
|
-
|
|
3325
|
+
logger6.info("humanScroll | fixed \u5BB9\u5668\u5185\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
|
|
3444
3326
|
} else {
|
|
3445
|
-
|
|
3327
|
+
logger6.debug("humanScroll | \u5143\u7D20\u53EF\u89C1\u4E14\u65E0\u906E\u6321");
|
|
3446
3328
|
}
|
|
3447
|
-
|
|
3329
|
+
logger6.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
|
|
3448
3330
|
return { element, didScroll };
|
|
3449
3331
|
}
|
|
3450
|
-
|
|
3332
|
+
logger6.debug(`humanScroll | \u6B65\u9AA4 ${i + 1}/${maxSteps}: ${status.reason} ${status.direction ? `(${status.direction})` : ""}`);
|
|
3451
3333
|
if (status.code === "OBSTRUCTED" && status.obstruction) {
|
|
3452
|
-
|
|
3334
|
+
logger6.debug(`humanScroll | \u88AB\u4EE5\u4E0B\u5143\u7D20\u906E\u6321 <${status.obstruction.tag} id="${status.obstruction.id}">`);
|
|
3453
3335
|
}
|
|
3454
3336
|
const scrollRect = await getScrollableRect2();
|
|
3455
3337
|
if (!scrollRect && status.isFixed) {
|
|
3456
|
-
|
|
3338
|
+
logger6.warn("humanScroll | fixed \u5BB9\u5668\u5185\u4E14\u65E0\u53EF\u6EDA\u52A8\u7956\u5148\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
|
|
3457
3339
|
return { element, didScroll };
|
|
3458
3340
|
}
|
|
3459
3341
|
const stepMin = scrollRect ? Math.min(minStep, Math.max(60, scrollRect.height * 0.4)) : minStep;
|
|
@@ -3489,10 +3371,10 @@ var Humanize = {
|
|
|
3489
3371
|
didScroll = true;
|
|
3490
3372
|
await (0, import_delay2.default)(this.jitterMs(20 + Math.random() * 40, 0.2));
|
|
3491
3373
|
}
|
|
3492
|
-
|
|
3374
|
+
logger6.warn(`humanScroll | \u5728 ${maxSteps} \u6B65\u540E\u65E0\u6CD5\u786E\u4FDD\u53EF\u89C1\u6027`);
|
|
3493
3375
|
return { element, didScroll };
|
|
3494
3376
|
} catch (error) {
|
|
3495
|
-
|
|
3377
|
+
logger6.fail("humanScroll", error);
|
|
3496
3378
|
throw error;
|
|
3497
3379
|
}
|
|
3498
3380
|
},
|
|
@@ -3510,7 +3392,7 @@ var Humanize = {
|
|
|
3510
3392
|
const cursor = $GetCursor(page);
|
|
3511
3393
|
const { reactionDelay = 250, throwOnMissing = true, scrollIfNeeded = true, restore = false } = options;
|
|
3512
3394
|
const targetDesc = target == null ? "Current Position" : typeof target === "string" ? target : "ElementHandle";
|
|
3513
|
-
|
|
3395
|
+
logger6.start("humanClick", `target=${targetDesc}`);
|
|
3514
3396
|
const restoreOnce = async () => {
|
|
3515
3397
|
if (restoreOnce.restored) return;
|
|
3516
3398
|
restoreOnce.restored = true;
|
|
@@ -3519,14 +3401,14 @@ var Humanize = {
|
|
|
3519
3401
|
await (0, import_delay2.default)(this.jitterMs(1e3));
|
|
3520
3402
|
await restoreOnce.do();
|
|
3521
3403
|
} catch (restoreError) {
|
|
3522
|
-
|
|
3404
|
+
logger6.warn(`humanClick: \u6062\u590D\u6EDA\u52A8\u4F4D\u7F6E\u5931\u8D25: ${restoreError.message}`);
|
|
3523
3405
|
}
|
|
3524
3406
|
};
|
|
3525
3407
|
try {
|
|
3526
3408
|
if (target == null) {
|
|
3527
3409
|
await (0, import_delay2.default)(this.jitterMs(reactionDelay, 0.4));
|
|
3528
3410
|
await cursor.actions.click();
|
|
3529
|
-
|
|
3411
|
+
logger6.success("humanClick", "Clicked current position");
|
|
3530
3412
|
return true;
|
|
3531
3413
|
}
|
|
3532
3414
|
let element;
|
|
@@ -3536,7 +3418,7 @@ var Humanize = {
|
|
|
3536
3418
|
if (throwOnMissing) {
|
|
3537
3419
|
throw new Error(`\u627E\u4E0D\u5230\u5143\u7D20 ${target}`);
|
|
3538
3420
|
}
|
|
3539
|
-
|
|
3421
|
+
logger6.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${target}`);
|
|
3540
3422
|
return false;
|
|
3541
3423
|
}
|
|
3542
3424
|
} else {
|
|
@@ -3552,7 +3434,7 @@ var Humanize = {
|
|
|
3552
3434
|
if (throwOnMissing) {
|
|
3553
3435
|
throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5143\u7D20\u4F4D\u7F6E");
|
|
3554
3436
|
}
|
|
3555
|
-
|
|
3437
|
+
logger6.warn("humanClick: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E\uFF0C\u8DF3\u8FC7\u70B9\u51FB");
|
|
3556
3438
|
return false;
|
|
3557
3439
|
}
|
|
3558
3440
|
const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.3;
|
|
@@ -3561,11 +3443,11 @@ var Humanize = {
|
|
|
3561
3443
|
await (0, import_delay2.default)(this.jitterMs(reactionDelay, 0.4));
|
|
3562
3444
|
await cursor.actions.click();
|
|
3563
3445
|
await restoreOnce();
|
|
3564
|
-
|
|
3446
|
+
logger6.success("humanClick");
|
|
3565
3447
|
return true;
|
|
3566
3448
|
} catch (error) {
|
|
3567
3449
|
await restoreOnce();
|
|
3568
|
-
|
|
3450
|
+
logger6.fail("humanClick", error);
|
|
3569
3451
|
throw error;
|
|
3570
3452
|
}
|
|
3571
3453
|
},
|
|
@@ -3576,9 +3458,9 @@ var Humanize = {
|
|
|
3576
3458
|
*/
|
|
3577
3459
|
async randomSleep(baseMs, jitterPercent = 0.3) {
|
|
3578
3460
|
const ms = this.jitterMs(baseMs, jitterPercent);
|
|
3579
|
-
|
|
3461
|
+
logger6.start("randomSleep", `base=${baseMs}, actual=${ms}ms`);
|
|
3580
3462
|
await (0, import_delay2.default)(ms);
|
|
3581
|
-
|
|
3463
|
+
logger6.success("randomSleep");
|
|
3582
3464
|
},
|
|
3583
3465
|
/**
|
|
3584
3466
|
* 模拟人类"注视"或"阅读"行为:鼠标在页面上随机微动
|
|
@@ -3588,7 +3470,7 @@ var Humanize = {
|
|
|
3588
3470
|
async simulateGaze(page, baseDurationMs = 2500) {
|
|
3589
3471
|
const cursor = $GetCursor(page);
|
|
3590
3472
|
const durationMs = this.jitterMs(baseDurationMs, 0.4);
|
|
3591
|
-
|
|
3473
|
+
logger6.start("simulateGaze", `duration=${durationMs}ms`);
|
|
3592
3474
|
const startTime = Date.now();
|
|
3593
3475
|
const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };
|
|
3594
3476
|
while (Date.now() - startTime < durationMs) {
|
|
@@ -3597,7 +3479,7 @@ var Humanize = {
|
|
|
3597
3479
|
await cursor.actions.move({ x, y });
|
|
3598
3480
|
await (0, import_delay2.default)(this.jitterMs(600, 0.5));
|
|
3599
3481
|
}
|
|
3600
|
-
|
|
3482
|
+
logger6.success("simulateGaze");
|
|
3601
3483
|
},
|
|
3602
3484
|
/**
|
|
3603
3485
|
* 人类化输入 - 带节奏变化(快-慢-停顿-偶尔加速)
|
|
@@ -3610,7 +3492,7 @@ var Humanize = {
|
|
|
3610
3492
|
* @param {number} [options.pauseBase=800] - 停顿时长基础值 (ms),实际 ±50% 抖动
|
|
3611
3493
|
*/
|
|
3612
3494
|
async humanType(page, selector, text, options = {}) {
|
|
3613
|
-
|
|
3495
|
+
logger6.start("humanType", `selector=${selector}, textLen=${text.length}`);
|
|
3614
3496
|
const {
|
|
3615
3497
|
baseDelay = 180,
|
|
3616
3498
|
pauseProbability = 0.08,
|
|
@@ -3634,13 +3516,13 @@ var Humanize = {
|
|
|
3634
3516
|
await (0, import_delay2.default)(charDelay);
|
|
3635
3517
|
if (Math.random() < pauseProbability && i < text.length - 1) {
|
|
3636
3518
|
const pauseTime = this.jitterMs(pauseBase, 0.5);
|
|
3637
|
-
|
|
3519
|
+
logger6.debug(`\u505C\u987F ${pauseTime}ms...`);
|
|
3638
3520
|
await (0, import_delay2.default)(pauseTime);
|
|
3639
3521
|
}
|
|
3640
3522
|
}
|
|
3641
|
-
|
|
3523
|
+
logger6.success("humanType");
|
|
3642
3524
|
} catch (error) {
|
|
3643
|
-
|
|
3525
|
+
logger6.fail("humanType", error);
|
|
3644
3526
|
throw error;
|
|
3645
3527
|
}
|
|
3646
3528
|
},
|
|
@@ -3664,7 +3546,7 @@ var Humanize = {
|
|
|
3664
3546
|
keyboardOptions = {}
|
|
3665
3547
|
} = pressOptions || {};
|
|
3666
3548
|
const targetDesc = hasTarget ? typeof targetOrKey === "string" ? targetOrKey : "ElementHandle" : "current focus";
|
|
3667
|
-
|
|
3549
|
+
logger6.start("humanPress", `key=${key}, target=${targetDesc}`);
|
|
3668
3550
|
try {
|
|
3669
3551
|
if (hasTarget) {
|
|
3670
3552
|
await this.humanClick(page, targetOrKey, { reactionDelay: focusDelay, scrollIfNeeded, throwOnMissing });
|
|
@@ -3674,10 +3556,10 @@ var Humanize = {
|
|
|
3674
3556
|
...keyboardOptions,
|
|
3675
3557
|
delay: this.jitterMs(holdDelay, 0.5)
|
|
3676
3558
|
});
|
|
3677
|
-
|
|
3559
|
+
logger6.success("humanPress");
|
|
3678
3560
|
return true;
|
|
3679
3561
|
} catch (error) {
|
|
3680
|
-
|
|
3562
|
+
logger6.fail("humanPress", error);
|
|
3681
3563
|
throw error;
|
|
3682
3564
|
}
|
|
3683
3565
|
},
|
|
@@ -3687,22 +3569,22 @@ var Humanize = {
|
|
|
3687
3569
|
* @param {string} selector - 输入框选择器
|
|
3688
3570
|
*/
|
|
3689
3571
|
async humanClear(page, selector) {
|
|
3690
|
-
|
|
3572
|
+
logger6.start("humanClear", `selector=${selector}`);
|
|
3691
3573
|
try {
|
|
3692
3574
|
const locator = page.locator(selector);
|
|
3693
3575
|
await locator.click();
|
|
3694
3576
|
await (0, import_delay2.default)(this.jitterMs(200, 0.4));
|
|
3695
3577
|
const currentValue = await locator.inputValue();
|
|
3696
3578
|
if (!currentValue || currentValue.length === 0) {
|
|
3697
|
-
|
|
3579
|
+
logger6.success("humanClear", "already empty");
|
|
3698
3580
|
return;
|
|
3699
3581
|
}
|
|
3700
3582
|
await page.keyboard.press("Meta+A");
|
|
3701
3583
|
await (0, import_delay2.default)(this.jitterMs(100, 0.4));
|
|
3702
3584
|
await page.keyboard.press("Backspace");
|
|
3703
|
-
|
|
3585
|
+
logger6.success("humanClear");
|
|
3704
3586
|
} catch (error) {
|
|
3705
|
-
|
|
3587
|
+
logger6.fail("humanClear", error);
|
|
3706
3588
|
throw error;
|
|
3707
3589
|
}
|
|
3708
3590
|
},
|
|
@@ -3714,7 +3596,7 @@ var Humanize = {
|
|
|
3714
3596
|
async warmUpBrowsing(page, baseDuration = 3500) {
|
|
3715
3597
|
const cursor = $GetCursor(page);
|
|
3716
3598
|
const durationMs = this.jitterMs(baseDuration, 0.4);
|
|
3717
|
-
|
|
3599
|
+
logger6.start("warmUpBrowsing", `duration=${durationMs}ms`);
|
|
3718
3600
|
const startTime = Date.now();
|
|
3719
3601
|
const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };
|
|
3720
3602
|
try {
|
|
@@ -3733,9 +3615,9 @@ var Humanize = {
|
|
|
3733
3615
|
await (0, import_delay2.default)(this.jitterMs(800, 0.5));
|
|
3734
3616
|
}
|
|
3735
3617
|
}
|
|
3736
|
-
|
|
3618
|
+
logger6.success("warmUpBrowsing");
|
|
3737
3619
|
} catch (error) {
|
|
3738
|
-
|
|
3620
|
+
logger6.fail("warmUpBrowsing", error);
|
|
3739
3621
|
throw error;
|
|
3740
3622
|
}
|
|
3741
3623
|
},
|
|
@@ -3749,7 +3631,7 @@ var Humanize = {
|
|
|
3749
3631
|
async naturalScroll(page, direction = "down", distance = 300, baseSteps = 5) {
|
|
3750
3632
|
const steps = Math.max(3, baseSteps + Math.floor(Math.random() * 3) - 1);
|
|
3751
3633
|
const actualDistance = this.jitterMs(distance, 0.15);
|
|
3752
|
-
|
|
3634
|
+
logger6.start("naturalScroll", `dir=${direction}, dist=${actualDistance}, steps=${steps}`);
|
|
3753
3635
|
const sign = direction === "down" ? 1 : -1;
|
|
3754
3636
|
const stepDistance = actualDistance / steps;
|
|
3755
3637
|
try {
|
|
@@ -3761,9 +3643,9 @@ var Humanize = {
|
|
|
3761
3643
|
const baseDelay = 60 + i * 25;
|
|
3762
3644
|
await (0, import_delay2.default)(this.jitterMs(baseDelay, 0.3));
|
|
3763
3645
|
}
|
|
3764
|
-
|
|
3646
|
+
logger6.success("naturalScroll");
|
|
3765
3647
|
} catch (error) {
|
|
3766
|
-
|
|
3648
|
+
logger6.fail("naturalScroll", error);
|
|
3767
3649
|
throw error;
|
|
3768
3650
|
}
|
|
3769
3651
|
}
|
|
@@ -3792,7 +3674,7 @@ var resolveElement = async (page, target, { throwOnMissing = true } = {}) => {
|
|
|
3792
3674
|
var waitJitter = (base, jitterPercent = 0.3) => (0, import_delay3.default)(jitterMs(base, jitterPercent));
|
|
3793
3675
|
|
|
3794
3676
|
// src/internals/humanize/mobile.js
|
|
3795
|
-
var
|
|
3677
|
+
var logger7 = createInternalLogger("Humanize.Mobile");
|
|
3796
3678
|
var initializedPages = /* @__PURE__ */ new WeakSet();
|
|
3797
3679
|
var DEFAULT_TAP_TIMEOUT_MS = 2500;
|
|
3798
3680
|
var DEFAULT_MOUSE_TAP_FALLBACK_TIMEOUT_MS = 1200;
|
|
@@ -4162,7 +4044,7 @@ var restoreWindowFromSnapshot = async (page, before, after) => {
|
|
|
4162
4044
|
return;
|
|
4163
4045
|
}
|
|
4164
4046
|
await page.evaluate(
|
|
4165
|
-
(
|
|
4047
|
+
(state) => window.scrollTo(state.x, state.y),
|
|
4166
4048
|
{ x: Number(before.scrollX || 0), y: Number(before.scrollY || 0) }
|
|
4167
4049
|
).catch(() => {
|
|
4168
4050
|
});
|
|
@@ -4249,7 +4131,7 @@ var dispatchTouchSwipe = async (page, deltaY, options = {}) => {
|
|
|
4249
4131
|
}
|
|
4250
4132
|
return true;
|
|
4251
4133
|
} catch (error) {
|
|
4252
|
-
|
|
4134
|
+
logger7.debug(`touch swipe fallback: ${error?.message || error}`);
|
|
4253
4135
|
try {
|
|
4254
4136
|
await page.evaluate((amount) => window.scrollBy(0, amount), deltaY);
|
|
4255
4137
|
await waitJitter(120, 0.35);
|
|
@@ -4283,7 +4165,7 @@ var tapPoint = async (page, point, options = {}) => {
|
|
|
4283
4165
|
);
|
|
4284
4166
|
return { method: "touchscreen" };
|
|
4285
4167
|
} catch (error) {
|
|
4286
|
-
|
|
4168
|
+
logger7.warn(`tapPoint | touchscreen.tap \u5931\u8D25\u6216\u8D85\u65F6\uFF0C\u5C1D\u8BD5\u9F20\u6807\u515C\u5E95: ${error?.message || error}`);
|
|
4287
4169
|
if (!allowMouseFallback) throw error;
|
|
4288
4170
|
}
|
|
4289
4171
|
}
|
|
@@ -4299,10 +4181,10 @@ var MobileHumanize = {
|
|
|
4299
4181
|
async initializeCursor(page) {
|
|
4300
4182
|
if (initializedPages.has(page)) return;
|
|
4301
4183
|
initializedPages.add(page);
|
|
4302
|
-
|
|
4184
|
+
logger7.debug("initializeCursor: mobile mode uses touch gestures, cursor init skipped");
|
|
4303
4185
|
},
|
|
4304
4186
|
async humanMove(page, target) {
|
|
4305
|
-
|
|
4187
|
+
logger7.debug(`humanMove: mobile no-op target=${typeof target === "string" ? target : "element/coords"}`);
|
|
4306
4188
|
if (typeof target === "string" || target && typeof target.boundingBox === "function") {
|
|
4307
4189
|
const element = await resolveElement(page, target, { throwOnMissing: false });
|
|
4308
4190
|
if (!element) {
|
|
@@ -4321,10 +4203,10 @@ var MobileHumanize = {
|
|
|
4321
4203
|
throwOnMissing = false
|
|
4322
4204
|
} = options;
|
|
4323
4205
|
const targetDesc = describeTarget(target);
|
|
4324
|
-
|
|
4206
|
+
logger7.start("humanScroll", `target=${targetDesc}`);
|
|
4325
4207
|
const element = await resolveElement(page, target, { throwOnMissing });
|
|
4326
4208
|
if (!element) {
|
|
4327
|
-
|
|
4209
|
+
logger7.warn(`humanScroll | \u5143\u7D20\u672A\u627E\u5230: ${targetDesc}`);
|
|
4328
4210
|
return { element: null, didScroll: false, restore: null };
|
|
4329
4211
|
}
|
|
4330
4212
|
const startTime = Date.now();
|
|
@@ -4333,42 +4215,42 @@ var MobileHumanize = {
|
|
|
4333
4215
|
const status = await checkElementVisibility(element);
|
|
4334
4216
|
if (status.code === "VISIBLE") {
|
|
4335
4217
|
if (status.isFixed) {
|
|
4336
|
-
|
|
4218
|
+
logger7.info("humanScroll | fixed/sticky \u5BB9\u5668\u5185\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
|
|
4337
4219
|
} else {
|
|
4338
|
-
|
|
4220
|
+
logger7.debug("humanScroll | \u5143\u7D20\u53EF\u89C1\u4E14\u65E0\u906E\u6321");
|
|
4339
4221
|
}
|
|
4340
|
-
|
|
4222
|
+
logger7.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
|
|
4341
4223
|
return { element, didScroll, restore: null };
|
|
4342
4224
|
}
|
|
4343
4225
|
if (status.code === "ZERO_DIMENSIONS" || status.code === "NOT_INTERACTABLE") {
|
|
4344
|
-
|
|
4226
|
+
logger7.warn(`humanScroll | \u5143\u7D20\u4E0D\u53EF\u6EDA\u52A8\u81F3\u53EF\u70B9\u51FB\u72B6\u6001: ${status.reason || status.code}`);
|
|
4345
4227
|
return { element, didScroll, restore: null };
|
|
4346
4228
|
}
|
|
4347
4229
|
const scrollRect = await getScrollableRect(element);
|
|
4348
4230
|
if (!scrollRect && status.isFixed && status.code === "OUT_OF_VIEWPORT") {
|
|
4349
|
-
|
|
4231
|
+
logger7.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"})`);
|
|
4350
4232
|
return { element, didScroll, restore: null, unscrollable: true };
|
|
4351
4233
|
}
|
|
4352
4234
|
if (!scrollRect && status.isFixed && status.code === "OBSTRUCTED") {
|
|
4353
|
-
|
|
4235
|
+
logger7.warn(`humanScroll | fixed/sticky \u76EE\u6807\u88AB\u906E\u6321\uFF0C\u6EDA\u52A8\u65E0\u6CD5\u89E3\u9664 (${status.obstruction?.tag || "unknown"})`);
|
|
4354
4236
|
return { element, didScroll, restore: null, unscrollable: true };
|
|
4355
4237
|
}
|
|
4356
4238
|
if (scrollRect && status.code === "OBSTRUCTED" && status.obstruction?.isFixed) {
|
|
4357
4239
|
const moved = await scrollAwayFromObstruction(element, status);
|
|
4358
4240
|
if (moved.moved) {
|
|
4359
|
-
|
|
4241
|
+
logger7.debug(`humanScroll | sticky/fixed \u906E\u6321\u8865\u507F\u6EDA\u52A8 top=${Math.round(moved.scrollTop || 0)}`);
|
|
4360
4242
|
await waitJitter(90, 0.3);
|
|
4361
4243
|
didScroll = true;
|
|
4362
4244
|
continue;
|
|
4363
4245
|
}
|
|
4364
4246
|
}
|
|
4365
4247
|
if (Date.now() - startTime > maxDurationMs) {
|
|
4366
|
-
|
|
4248
|
+
logger7.warn(`humanScroll | mobile timeout (${maxDurationMs}ms, status=${status.code}, direction=${status.direction || "unknown"}, fixed=${Boolean(status.isFixed)})`);
|
|
4367
4249
|
return { element, didScroll, restore: null };
|
|
4368
4250
|
}
|
|
4369
4251
|
const stepMin = scrollRect ? Math.min(minStep, Math.max(60, scrollRect.height * 0.4)) : minStep;
|
|
4370
4252
|
const stepMax = scrollRect ? Math.min(maxStep, Math.max(stepMin + 40, scrollRect.height * 0.8)) : maxStep;
|
|
4371
|
-
|
|
4253
|
+
logger7.debug(`humanScroll | \u6B65\u9AA4 ${i + 1}/${maxSteps}: ${status.reason || status.code} ${status.direction ? `(${status.direction})` : ""}`);
|
|
4372
4254
|
const distance = stepMin + Math.random() * Math.max(1, stepMax - stepMin);
|
|
4373
4255
|
let deltaY = status.direction === "up" ? -distance : distance;
|
|
4374
4256
|
if (status.code === "OBSTRUCTED") {
|
|
@@ -4408,8 +4290,8 @@ var MobileHumanize = {
|
|
|
4408
4290
|
if (scrollRect && beforeWindowState) {
|
|
4409
4291
|
const afterWindowState = await page.evaluate(() => ({ x: window.scrollX, y: window.scrollY }));
|
|
4410
4292
|
if (Math.abs(afterWindowState.x - beforeWindowState.x) > 2 || Math.abs(afterWindowState.y - beforeWindowState.y) > 2) {
|
|
4411
|
-
await page.evaluate((
|
|
4412
|
-
|
|
4293
|
+
await page.evaluate((state) => window.scrollTo(state.x, state.y), beforeWindowState);
|
|
4294
|
+
logger7.debug(`humanScroll | \u7A97\u53E3\u6EDA\u52A8\u56DE\u6536 from=${Math.round(afterWindowState.y)} to=${Math.round(beforeWindowState.y)}`);
|
|
4413
4295
|
}
|
|
4414
4296
|
}
|
|
4415
4297
|
let afterElementSnapshot = null;
|
|
@@ -4423,7 +4305,7 @@ var MobileHumanize = {
|
|
|
4423
4305
|
const afterSnapshot = await readAfterElementSnapshot();
|
|
4424
4306
|
if (isTargetImmobileAfterScroll(beforeElementSnapshot, afterSnapshot)) {
|
|
4425
4307
|
await restoreWindowFromSnapshot(page, beforeElementSnapshot, afterSnapshot);
|
|
4426
|
-
|
|
4308
|
+
logger7.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"})`);
|
|
4427
4309
|
return { element, didScroll, restore: null, unscrollable: true };
|
|
4428
4310
|
}
|
|
4429
4311
|
}
|
|
@@ -4455,12 +4337,12 @@ var MobileHumanize = {
|
|
|
4455
4337
|
const moved = beforeState.kind !== afterState.kind || Math.abs(topDelta) > 2 || Math.abs(leftDelta) > 2;
|
|
4456
4338
|
if (!moved) {
|
|
4457
4339
|
const fallback = await scrollScrollableAncestor(element, deltaY);
|
|
4458
|
-
|
|
4340
|
+
logger7.debug(`humanScroll | \u5BB9\u5668\u89E6\u6478\u65E0\u6548\uFF0C\u76F4\u63A5\u6EDA\u52A8 fallback=${fallback.scroller ? "ancestor" : "window"} top=${Math.round(fallback.scrollTop || 0)}`);
|
|
4459
4341
|
} 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)) {
|
|
4460
4342
|
const residualDelta = expectedDelta - topDelta;
|
|
4461
4343
|
if (Math.sign(residualDelta) === Math.sign(expectedDelta) && Math.abs(residualDelta) > 24) {
|
|
4462
4344
|
const fallback = await scrollScrollableAncestor(element, residualDelta);
|
|
4463
|
-
|
|
4345
|
+
logger7.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)}`);
|
|
4464
4346
|
}
|
|
4465
4347
|
}
|
|
4466
4348
|
}
|
|
@@ -4468,7 +4350,7 @@ var MobileHumanize = {
|
|
|
4468
4350
|
const afterSnapshot = await getElementViewportSnapshot(element).catch(() => null);
|
|
4469
4351
|
if (isTargetImmobileAfterScroll(beforeElementSnapshot, afterSnapshot)) {
|
|
4470
4352
|
await restoreWindowFromSnapshot(page, beforeElementSnapshot, afterSnapshot);
|
|
4471
|
-
|
|
4353
|
+
logger7.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"})`);
|
|
4472
4354
|
return { element, didScroll, restore: null, unscrollable: true };
|
|
4473
4355
|
}
|
|
4474
4356
|
}
|
|
@@ -4479,14 +4361,14 @@ var MobileHumanize = {
|
|
|
4479
4361
|
await waitJitter(80, 0.3);
|
|
4480
4362
|
const finalStatus = await checkElementVisibility(element);
|
|
4481
4363
|
if (finalStatus.code === "VISIBLE") {
|
|
4482
|
-
|
|
4483
|
-
|
|
4364
|
+
logger7.info("humanScroll | \u539F\u751F scrollIntoViewIfNeeded \u515C\u5E95\u6210\u529F");
|
|
4365
|
+
logger7.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
|
|
4484
4366
|
return { element, didScroll: true, restore: null };
|
|
4485
4367
|
}
|
|
4486
4368
|
} catch (fallbackError) {
|
|
4487
|
-
|
|
4369
|
+
logger7.debug(`humanScroll | native fallback failed: ${fallbackError?.message || fallbackError}`);
|
|
4488
4370
|
}
|
|
4489
|
-
|
|
4371
|
+
logger7.warn(`humanScroll | \u5728 ${maxSteps} \u6B65\u540E\u65E0\u6CD5\u786E\u4FDD\u53EF\u89C1\u6027`);
|
|
4490
4372
|
return { element, didScroll, restore: null };
|
|
4491
4373
|
},
|
|
4492
4374
|
async humanClick(page, target, options = {}) {
|
|
@@ -4501,7 +4383,7 @@ var MobileHumanize = {
|
|
|
4501
4383
|
fallbackDomClickOnTapError = true
|
|
4502
4384
|
} = options;
|
|
4503
4385
|
const targetDesc = describeTarget(target);
|
|
4504
|
-
|
|
4386
|
+
logger7.start("humanClick", `target=${targetDesc}`);
|
|
4505
4387
|
try {
|
|
4506
4388
|
if (target == null) {
|
|
4507
4389
|
const viewport = resolveViewport(page);
|
|
@@ -4513,12 +4395,12 @@ var MobileHumanize = {
|
|
|
4513
4395
|
timeoutMs: tapTimeoutMs,
|
|
4514
4396
|
mouseFallbackTimeoutMs
|
|
4515
4397
|
});
|
|
4516
|
-
|
|
4398
|
+
logger7.success("humanClick", "Tapped current position");
|
|
4517
4399
|
return true;
|
|
4518
4400
|
}
|
|
4519
4401
|
const element = await resolveElement(page, target, { throwOnMissing });
|
|
4520
4402
|
if (!element) {
|
|
4521
|
-
|
|
4403
|
+
logger7.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${targetDesc}`);
|
|
4522
4404
|
return false;
|
|
4523
4405
|
}
|
|
4524
4406
|
const scrollResult = scrollIfNeeded ? await MobileHumanize.humanScroll(page, element, { throwOnMissing }) : null;
|
|
@@ -4542,19 +4424,19 @@ var MobileHumanize = {
|
|
|
4542
4424
|
).catch(() => null);
|
|
4543
4425
|
}
|
|
4544
4426
|
if (fallback?.activated) {
|
|
4545
|
-
|
|
4427
|
+
logger7.warn(`humanClick: \u4E0D\u53EF\u6EDA\u52A8\u76EE\u6807\u4E0D\u53EF\u7269\u7406\u70B9\u51FB\uFF0C\u5DF2\u7528 ${fallback.method} \u6FC0\u6D3B`);
|
|
4546
4428
|
return true;
|
|
4547
4429
|
}
|
|
4548
4430
|
}
|
|
4549
4431
|
const message = `\u5143\u7D20\u4E0D\u53EF\u70B9\u51FB: ${status.reason || status.code}`;
|
|
4550
4432
|
if (throwOnMissing) throw new Error(message);
|
|
4551
|
-
|
|
4433
|
+
logger7.warn(`humanClick: ${message}\uFF0C\u8DF3\u8FC7\u70B9\u51FB`);
|
|
4552
4434
|
return false;
|
|
4553
4435
|
}
|
|
4554
4436
|
const box = await element.boundingBox();
|
|
4555
4437
|
if (!box) {
|
|
4556
4438
|
if (throwOnMissing) throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5143\u7D20\u4F4D\u7F6E");
|
|
4557
|
-
|
|
4439
|
+
logger7.warn("humanClick: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E\uFF0C\u8DF3\u8FC7\u70B9\u51FB");
|
|
4558
4440
|
return false;
|
|
4559
4441
|
}
|
|
4560
4442
|
await waitJitter(reactionDelay, 0.45);
|
|
@@ -4575,13 +4457,13 @@ var MobileHumanize = {
|
|
|
4575
4457
|
"activation fallback"
|
|
4576
4458
|
).catch(() => null);
|
|
4577
4459
|
if (!fallback?.activated) throw tapError;
|
|
4578
|
-
|
|
4460
|
+
logger7.warn(`humanClick: tap \u5931\u8D25\u540E\u5DF2\u7528 ${fallback.method} \u515C\u5E95: ${tapError?.message || tapError}`);
|
|
4579
4461
|
}
|
|
4580
4462
|
await waitJitter(120, 0.35);
|
|
4581
|
-
|
|
4463
|
+
logger7.success("humanClick");
|
|
4582
4464
|
return true;
|
|
4583
4465
|
} catch (error) {
|
|
4584
|
-
|
|
4466
|
+
logger7.fail("humanClick", error);
|
|
4585
4467
|
throw error;
|
|
4586
4468
|
}
|
|
4587
4469
|
},
|
|
@@ -4634,7 +4516,7 @@ var MobileHumanize = {
|
|
|
4634
4516
|
keyboardOptions = {}
|
|
4635
4517
|
} = pressOptions || {};
|
|
4636
4518
|
const targetDesc = hasTarget ? describeTarget(targetOrKey) : "current focus";
|
|
4637
|
-
|
|
4519
|
+
logger7.start("humanPress", `key=${key}, target=${targetDesc}`);
|
|
4638
4520
|
try {
|
|
4639
4521
|
if (hasTarget) {
|
|
4640
4522
|
await MobileHumanize.humanClick(page, targetOrKey, {
|
|
@@ -4648,10 +4530,10 @@ var MobileHumanize = {
|
|
|
4648
4530
|
...keyboardOptions,
|
|
4649
4531
|
delay: jitterMs(holdDelay, 0.5)
|
|
4650
4532
|
});
|
|
4651
|
-
|
|
4533
|
+
logger7.success("humanPress");
|
|
4652
4534
|
return true;
|
|
4653
4535
|
} catch (error) {
|
|
4654
|
-
|
|
4536
|
+
logger7.fail("humanPress", error);
|
|
4655
4537
|
throw error;
|
|
4656
4538
|
}
|
|
4657
4539
|
},
|
|
@@ -4718,92 +4600,62 @@ var MobileHumanize = {
|
|
|
4718
4600
|
}
|
|
4719
4601
|
};
|
|
4720
4602
|
|
|
4721
|
-
// src/
|
|
4603
|
+
// src/humanize.js
|
|
4722
4604
|
var resolveDeviceFromPage2 = (page) => normalizeDevice(page?.[PageRuntimeStateKey]?.device);
|
|
4723
4605
|
var resolveDelegate = (page) => {
|
|
4724
4606
|
return resolveDeviceFromPage2(page) === Device.Mobile ? MobileHumanize : Humanize;
|
|
4725
4607
|
};
|
|
4726
|
-
var
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
[Humanize, MobileHumanize]
|
|
4730
|
-
);
|
|
4731
|
-
|
|
4732
|
-
// src/internals/humanize/cloak.js
|
|
4733
|
-
var FORCE_CLICK = Object.freeze({
|
|
4734
|
-
forceClick: true,
|
|
4735
|
-
clickOptions: { force: true }
|
|
4736
|
-
});
|
|
4737
|
-
var pointOrNull = async (target) => {
|
|
4738
|
-
if (!target || typeof target.boundingBox !== "function") return null;
|
|
4739
|
-
const box = await target.boundingBox().catch(() => null);
|
|
4740
|
-
return box ? { x: box.x + box.width / 2, y: box.y + box.height / 2 } : null;
|
|
4608
|
+
var callDelegate = (method, page, args) => {
|
|
4609
|
+
const delegate = resolveDelegate(page);
|
|
4610
|
+
return delegate[method](page, ...args);
|
|
4741
4611
|
};
|
|
4742
|
-
var
|
|
4743
|
-
|
|
4744
|
-
return
|
|
4612
|
+
var Humanize2 = {
|
|
4613
|
+
jitterMs(base, jitterPercent = 0.3) {
|
|
4614
|
+
return Humanize.jitterMs(base, jitterPercent);
|
|
4745
4615
|
},
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
return point ? await DeviceInput.move(page, point, { forceMouse: true }) : false;
|
|
4616
|
+
initializeCursor(page) {
|
|
4617
|
+
return callDelegate("initializeCursor", page, []);
|
|
4749
4618
|
},
|
|
4750
|
-
|
|
4751
|
-
|
|
4752
|
-
if (!element) return { element: null, didScroll: false, restore: null };
|
|
4753
|
-
await element.scrollIntoViewIfNeeded?.();
|
|
4754
|
-
return { element, didScroll: true, restore: null };
|
|
4619
|
+
humanMove(page, target) {
|
|
4620
|
+
return callDelegate("humanMove", page, [target]);
|
|
4755
4621
|
},
|
|
4756
|
-
|
|
4757
|
-
return
|
|
4622
|
+
humanScroll(page, target, options = {}) {
|
|
4623
|
+
return callDelegate("humanScroll", page, [target, options]);
|
|
4758
4624
|
},
|
|
4759
|
-
|
|
4760
|
-
|
|
4761
|
-
return await DeviceInput.keyboardType(page, text);
|
|
4625
|
+
humanClick(page, target, options = {}) {
|
|
4626
|
+
return callDelegate("humanClick", page, [target, options]);
|
|
4762
4627
|
},
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
}
|
|
4628
|
+
randomSleep(pageOrBaseMs, maybeBaseMs, maybeJitterPercent) {
|
|
4629
|
+
if (pageOrBaseMs && typeof pageOrBaseMs === "object" && typeof pageOrBaseMs.evaluate === "function") {
|
|
4630
|
+
const delegate = resolveDelegate(pageOrBaseMs);
|
|
4631
|
+
return delegate.randomSleep(maybeBaseMs, maybeJitterPercent);
|
|
4632
|
+
}
|
|
4633
|
+
return Humanize.randomSleep(pageOrBaseMs, maybeBaseMs);
|
|
4768
4634
|
},
|
|
4769
|
-
|
|
4770
|
-
return
|
|
4635
|
+
simulateGaze(page, baseDurationMs = 2500) {
|
|
4636
|
+
return callDelegate("simulateGaze", page, [baseDurationMs]);
|
|
4771
4637
|
},
|
|
4772
|
-
|
|
4773
|
-
return
|
|
4638
|
+
humanType(page, selector, text, options = {}) {
|
|
4639
|
+
return callDelegate("humanType", page, [selector, text, options]);
|
|
4774
4640
|
},
|
|
4775
|
-
|
|
4776
|
-
|
|
4641
|
+
humanPress(page, targetOrKey, maybeKey, options = {}) {
|
|
4642
|
+
if (typeof maybeKey === "string") {
|
|
4643
|
+
return callDelegate("humanPress", page, [targetOrKey, maybeKey, options]);
|
|
4644
|
+
}
|
|
4645
|
+
return callDelegate("humanPress", page, [targetOrKey, maybeKey || options]);
|
|
4777
4646
|
},
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
await page.mouse.wheel(0, Number(distance || 0) * sign);
|
|
4781
|
-
}
|
|
4782
|
-
};
|
|
4783
|
-
|
|
4784
|
-
// src/internals/humanize/index.js
|
|
4785
|
-
var HumanizeCommon = {
|
|
4786
|
-
jitterMs(base, jitterPercent = 0.3) {
|
|
4787
|
-
return jitterMs(base, jitterPercent);
|
|
4647
|
+
humanClear(page, selector) {
|
|
4648
|
+
return callDelegate("humanClear", page, [selector]);
|
|
4788
4649
|
},
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4650
|
+
warmUpBrowsing(page, baseDuration = 3500) {
|
|
4651
|
+
return callDelegate("warmUpBrowsing", page, [baseDuration]);
|
|
4652
|
+
},
|
|
4653
|
+
naturalScroll(page, direction = "down", distance = 300, baseSteps = 5) {
|
|
4654
|
+
return callDelegate("naturalScroll", page, [direction, distance, baseSteps]);
|
|
4794
4655
|
}
|
|
4795
4656
|
};
|
|
4796
|
-
var DefaultHumanize = Object.assign({}, DefaultHumanizeDevice, HumanizeCommon);
|
|
4797
|
-
var CloakHumanize = Object.assign({}, CloakHumanizeInput, HumanizeCommon);
|
|
4798
4657
|
|
|
4799
|
-
// src/
|
|
4800
|
-
var humanizeStrategies = {
|
|
4801
|
-
[Mode.Default]: DefaultHumanize,
|
|
4802
|
-
[Mode.Cloak]: CloakHumanize
|
|
4803
|
-
};
|
|
4804
|
-
var Humanize2 = withModeReflect("Humanize", humanizeStrategies);
|
|
4805
|
-
|
|
4806
|
-
// src/internals/launch/default.js
|
|
4658
|
+
// src/launch.js
|
|
4807
4659
|
var import_node_child_process = require("node:child_process");
|
|
4808
4660
|
var import_fingerprint_generator = require("fingerprint-generator");
|
|
4809
4661
|
var import_fingerprint_injector = require("fingerprint-injector");
|
|
@@ -4888,107 +4740,9 @@ var ByPass = {
|
|
|
4888
4740
|
resolveRouteByProxy
|
|
4889
4741
|
};
|
|
4890
4742
|
|
|
4891
|
-
// src/
|
|
4892
|
-
var logger7 = createInternalLogger("Launch");
|
|
4893
|
-
var normalizeObject = (value) => {
|
|
4894
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
4895
|
-
return {};
|
|
4896
|
-
}
|
|
4897
|
-
return value;
|
|
4898
|
-
};
|
|
4899
|
-
var parseProxyConfiguration = (proxyConfiguration = {}) => {
|
|
4900
|
-
const config = normalizeObject(proxyConfiguration);
|
|
4901
|
-
const proxyUrl = String(config.proxy_url || "").trim();
|
|
4902
|
-
const enableProxy = typeof config.enable_proxy === "boolean" ? config.enable_proxy : proxyUrl !== "";
|
|
4903
|
-
const byPassDomains = enableProxy && proxyUrl ? ByPass.normalizeByPassDomains(config.by_pass_domains) : [];
|
|
4904
|
-
return {
|
|
4905
|
-
byPassDomains,
|
|
4906
|
-
enableProxy,
|
|
4907
|
-
proxyUrl
|
|
4908
|
-
};
|
|
4909
|
-
};
|
|
4910
|
-
var resolveLaunchTraffic = ({
|
|
4911
|
-
proxyConfiguration = {},
|
|
4912
|
-
debugMode = false,
|
|
4913
|
-
useMeter = true
|
|
4914
|
-
} = {}) => {
|
|
4915
|
-
const { byPassDomains, enableProxy, proxyUrl } = parseProxyConfiguration(proxyConfiguration);
|
|
4916
|
-
const byPassRules = ByPass.buildByPassDomainRules(byPassDomains);
|
|
4917
|
-
const proxyMeter = useMeter && enableProxy && proxyUrl ? ProxyMeterRuntime.startProxyMeter({ proxyUrl, debugMode }) : null;
|
|
4918
|
-
const launchProxy = proxyMeter ? { server: proxyMeter.server } : null;
|
|
4919
|
-
if (launchProxy && byPassDomains.length > 0) {
|
|
4920
|
-
launchProxy.bypass = byPassDomains.join(",");
|
|
4921
|
-
}
|
|
4922
|
-
return {
|
|
4923
|
-
byPassDomains,
|
|
4924
|
-
byPassRules,
|
|
4925
|
-
enableProxy,
|
|
4926
|
-
proxyUrl,
|
|
4927
|
-
launchProxy
|
|
4928
|
-
};
|
|
4929
|
-
};
|
|
4930
|
-
var logLaunchTraffic = ({
|
|
4931
|
-
byPassDomains = [],
|
|
4932
|
-
debugMode = false,
|
|
4933
|
-
enabled = false,
|
|
4934
|
-
enableProxy = false,
|
|
4935
|
-
explicitProxy = false,
|
|
4936
|
-
launchProxy = null,
|
|
4937
|
-
proxyUrl = ""
|
|
4938
|
-
} = {}) => {
|
|
4939
|
-
if (!enabled) return;
|
|
4940
|
-
if (explicitProxy) {
|
|
4941
|
-
logger7.info("[\u4EE3\u7406\u5DF2\u542F\u7528] \u4F7F\u7528\u663E\u5F0F proxy \u914D\u7F6E\uFF0C\u8DF3\u8FC7 toolkit \u672C\u5730\u6D41\u91CF\u89C2\u6D4B");
|
|
4942
|
-
return;
|
|
4943
|
-
}
|
|
4944
|
-
if (launchProxy) {
|
|
4945
|
-
let upstreamLabel = "";
|
|
4946
|
-
try {
|
|
4947
|
-
const parsedProxyUrl = new URL(proxyUrl.includes("://") ? proxyUrl : `http://${proxyUrl}`);
|
|
4948
|
-
upstreamLabel = `${parsedProxyUrl.protocol}//${parsedProxyUrl.host}`;
|
|
4949
|
-
} catch {
|
|
4950
|
-
}
|
|
4951
|
-
logger7.info(
|
|
4952
|
-
`[\u4EE3\u7406\u5DF2\u542F\u7528] \u672C\u5730=${launchProxy.server} \u4E0A\u6E38=${upstreamLabel || "-"} \u76F4\u8FDE\u57DF\u540D=${byPassDomains.join(",")}`
|
|
4953
|
-
);
|
|
4954
|
-
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`);
|
|
4955
|
-
return;
|
|
4956
|
-
}
|
|
4957
|
-
if (enableProxy) {
|
|
4958
|
-
logger7.info("[\u4EE3\u7406\u672A\u542F\u7528] enable_proxy=true \u4F46 proxy_url \u4E3A\u7A7A");
|
|
4959
|
-
} else if (proxyUrl) {
|
|
4960
|
-
logger7.info("[\u4EE3\u7406\u672A\u542F\u7528] enable_proxy=false \u4E14 proxy_url \u5DF2\u914D\u7F6E");
|
|
4961
|
-
}
|
|
4962
|
-
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`);
|
|
4963
|
-
};
|
|
4964
|
-
var createLaunchTrafficHook = ({
|
|
4965
|
-
byPassDomains = [],
|
|
4966
|
-
byPassRules = [],
|
|
4967
|
-
enabled = false,
|
|
4968
|
-
launchProxy = null
|
|
4969
|
-
} = {}) => {
|
|
4970
|
-
const patchedPages = /* @__PURE__ */ new WeakSet();
|
|
4971
|
-
return (page) => {
|
|
4972
|
-
if (!page || typeof page.on !== "function" || patchedPages.has(page)) {
|
|
4973
|
-
return;
|
|
4974
|
-
}
|
|
4975
|
-
patchedPages.add(page);
|
|
4976
|
-
page.on("request", (req) => {
|
|
4977
|
-
const requestUrl = req.url();
|
|
4978
|
-
const resourceType = req.resourceType();
|
|
4979
|
-
const matched = byPassDomains.length > 0 ? ByPass.findMatchedByPassRule(byPassRules, requestUrl) : null;
|
|
4980
|
-
if (launchProxy) {
|
|
4981
|
-
ProxyMeterRuntime.recordProxyMeterResourceType(requestUrl, resourceType);
|
|
4982
|
-
}
|
|
4983
|
-
if (!enabled || byPassDomains.length === 0) return;
|
|
4984
|
-
if (!matched || !matched.rule) return;
|
|
4985
|
-
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}`);
|
|
4986
|
-
});
|
|
4987
|
-
};
|
|
4988
|
-
};
|
|
4989
|
-
|
|
4990
|
-
// src/internals/launch/default.js
|
|
4743
|
+
// src/launch.js
|
|
4991
4744
|
var logger8 = createInternalLogger("Launch");
|
|
4745
|
+
var REQUEST_HOOK_FLAG = Symbol("playwright-toolkit-request-hook");
|
|
4992
4746
|
var injectedContexts = /* @__PURE__ */ new WeakSet();
|
|
4993
4747
|
var browserMajorVersionCache = /* @__PURE__ */ new Map();
|
|
4994
4748
|
var DEFAULT_BROWSER_PROFILE_SCHEMA_VERSION = 1;
|
|
@@ -5000,6 +4754,16 @@ var DEFAULT_CRAWLER_BASE_OPTIONS = Object.freeze({
|
|
|
5000
4754
|
navigationTimeoutSecs: 120
|
|
5001
4755
|
});
|
|
5002
4756
|
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
|
+
};
|
|
5003
4767
|
var parseChromeMajorVersion = (rawValue = "") => {
|
|
5004
4768
|
const match = String(rawValue || "").match(/(?:Chrome|Chromium)(?:\/|\s+(?:for Testing\s+)?)(\d+)/i);
|
|
5005
4769
|
return match ? Number(match[1] || 0) : 0;
|
|
@@ -5043,7 +4807,7 @@ var resolveCoreDevice = (core = {}) => {
|
|
|
5043
4807
|
};
|
|
5044
4808
|
var buildFingerprintGenerator = ({ locale, browserMajorVersion, device }) => {
|
|
5045
4809
|
return new import_fingerprint_generator.FingerprintGenerator(
|
|
5046
|
-
|
|
4810
|
+
AntiCheat.getFingerprintGeneratorOptions({
|
|
5047
4811
|
locale,
|
|
5048
4812
|
browserMajorVersion,
|
|
5049
4813
|
device
|
|
@@ -5087,7 +4851,7 @@ var buildReplayableBrowserProfile = (runtimeState, launcher) => {
|
|
|
5087
4851
|
}
|
|
5088
4852
|
let nextState = RuntimeEnv.rememberState(runtimeState);
|
|
5089
4853
|
let browserProfileCore = RuntimeEnv.getBrowserProfileCore(nextState);
|
|
5090
|
-
const timezoneId = String(browserProfileCore?.timezone_id || "").trim() ||
|
|
4854
|
+
const timezoneId = String(browserProfileCore?.timezone_id || "").trim() || AntiCheat.getBaseConfig().timezoneId;
|
|
5091
4855
|
const locale = DEFAULT_LOCALE;
|
|
5092
4856
|
const currentBrowserMajorVersion = detectBrowserMajorVersion(launcher);
|
|
5093
4857
|
const storedBrowserMajorVersion = Number(browserProfileCore?.browser_major_version || 0);
|
|
@@ -5166,7 +4930,7 @@ var applyFingerprintPageOptions = (pageOptions = {}, { fingerprintWithHeaders =
|
|
|
5166
4930
|
pageOptions.timezoneId = timezoneId;
|
|
5167
4931
|
}
|
|
5168
4932
|
};
|
|
5169
|
-
var buildReplayBrowserPoolOptions = (browserProfileCore) => {
|
|
4933
|
+
var buildReplayBrowserPoolOptions = (browserProfileCore, modifyPageOptions = null) => {
|
|
5170
4934
|
const fingerprintWithHeaders = browserProfileCore?.fingerprint;
|
|
5171
4935
|
const fingerprint = fingerprintWithHeaders?.fingerprint;
|
|
5172
4936
|
if (!fingerprintWithHeaders || !fingerprint) {
|
|
@@ -5175,13 +4939,16 @@ var buildReplayBrowserPoolOptions = (browserProfileCore) => {
|
|
|
5175
4939
|
return {
|
|
5176
4940
|
useFingerprints: false,
|
|
5177
4941
|
prePageCreateHooks: [
|
|
5178
|
-
(
|
|
4942
|
+
async (pageId, browserController, pageOptions = {}) => {
|
|
5179
4943
|
if (!pageOptions || typeof pageOptions !== "object") return;
|
|
5180
4944
|
applyFingerprintPageOptions(pageOptions, {
|
|
5181
4945
|
fingerprintWithHeaders,
|
|
5182
4946
|
locale: browserProfileCore.locale,
|
|
5183
4947
|
timezoneId: browserProfileCore.timezone_id
|
|
5184
4948
|
});
|
|
4949
|
+
if (modifyPageOptions) {
|
|
4950
|
+
await modifyPageOptions(pageOptions, { pageId, browserController });
|
|
4951
|
+
}
|
|
5185
4952
|
}
|
|
5186
4953
|
],
|
|
5187
4954
|
postPageCreateHooks: [
|
|
@@ -5196,7 +4963,7 @@ var buildReplayBrowserPoolOptions = (browserProfileCore) => {
|
|
|
5196
4963
|
]
|
|
5197
4964
|
};
|
|
5198
4965
|
};
|
|
5199
|
-
var
|
|
4966
|
+
var Launch = {
|
|
5200
4967
|
getPlaywrightCrawlerOptions(options = {}) {
|
|
5201
4968
|
const normalizedOptions = Array.isArray(options) ? { customArgs: options } : options || {};
|
|
5202
4969
|
const {
|
|
@@ -5207,35 +4974,54 @@ var DefaultLaunch = {
|
|
|
5207
4974
|
debugMode = false,
|
|
5208
4975
|
isRunningOnApify = false,
|
|
5209
4976
|
launcher = null,
|
|
4977
|
+
hooks = {},
|
|
5210
4978
|
preNavigationHooks = [],
|
|
5211
4979
|
postNavigationHooks = [],
|
|
5212
4980
|
runtimeState = null
|
|
5213
4981
|
} = normalizedOptions;
|
|
5214
4982
|
const device = resolveRuntimeDevice(runtimeState);
|
|
5215
|
-
const
|
|
5216
|
-
const
|
|
5217
|
-
const
|
|
5218
|
-
|
|
5219
|
-
|
|
5220
|
-
|
|
4983
|
+
const modifyPageOptions = typeof hooks?.modifyPageOptions === "function" ? hooks.modifyPageOptions : null;
|
|
4984
|
+
const { byPassDomains, enableProxy, proxyUrl } = resolveProxyLaunchOptions(proxyConfiguration);
|
|
4985
|
+
const byPassRules = ByPass.buildByPassDomainRules(byPassDomains);
|
|
4986
|
+
const proxyMeter = enableProxy && proxyUrl ? ProxyMeterRuntime.startProxyMeter({ proxyUrl, debugMode }) : null;
|
|
4987
|
+
const launchProxy = proxyMeter ? { server: proxyMeter.server } : null;
|
|
4988
|
+
if (launchProxy && byPassDomains.length > 0) {
|
|
4989
|
+
launchProxy.bypass = byPassDomains.join(",");
|
|
4990
|
+
}
|
|
5221
4991
|
const replayContext = buildReplayableBrowserProfile(runtimeState, launcher);
|
|
5222
|
-
const replayBrowserPoolOptions = buildReplayBrowserPoolOptions(replayContext.browserProfileCore);
|
|
4992
|
+
const replayBrowserPoolOptions = buildReplayBrowserPoolOptions(replayContext.browserProfileCore, modifyPageOptions);
|
|
5223
4993
|
const launchLocale = String(replayContext.browserProfileCore?.locale || DEFAULT_LOCALE).trim() || DEFAULT_LOCALE;
|
|
5224
4994
|
const launchOptions = {
|
|
5225
4995
|
args: [
|
|
5226
|
-
...
|
|
4996
|
+
...AntiCheat.getLaunchArgs({ locale: launchLocale }),
|
|
5227
4997
|
...customArgs
|
|
5228
4998
|
],
|
|
5229
4999
|
ignoreDefaultArgs: ["--enable-automation"]
|
|
5230
5000
|
};
|
|
5231
|
-
if (
|
|
5232
|
-
launchOptions.proxy =
|
|
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`);
|
|
5233
5024
|
}
|
|
5234
|
-
logLaunchTraffic({
|
|
5235
|
-
...traffic,
|
|
5236
|
-
debugMode,
|
|
5237
|
-
enabled: enableByPassLogger
|
|
5238
|
-
});
|
|
5239
5025
|
const onPageCreated = (page) => {
|
|
5240
5026
|
const recommendedGotoOptions = {
|
|
5241
5027
|
waitUntil: "commit"
|
|
@@ -5243,7 +5029,22 @@ var DefaultLaunch = {
|
|
|
5243
5029
|
if (!page || typeof page.on !== "function") {
|
|
5244
5030
|
return recommendedGotoOptions;
|
|
5245
5031
|
}
|
|
5246
|
-
|
|
5032
|
+
if (page[REQUEST_HOOK_FLAG]) {
|
|
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);
|
|
5247
5048
|
return recommendedGotoOptions;
|
|
5248
5049
|
};
|
|
5249
5050
|
const launchContext = {
|
|
@@ -5260,20 +5061,23 @@ var DefaultLaunch = {
|
|
|
5260
5061
|
browserPoolOptions: replayBrowserPoolOptions || {
|
|
5261
5062
|
useFingerprints: true,
|
|
5262
5063
|
fingerprintOptions: {
|
|
5263
|
-
fingerprintGeneratorOptions:
|
|
5064
|
+
fingerprintGeneratorOptions: AntiCheat.getFingerprintGeneratorOptions({
|
|
5264
5065
|
locale: launchLocale,
|
|
5265
5066
|
device
|
|
5266
5067
|
})
|
|
5267
5068
|
},
|
|
5268
5069
|
prePageCreateHooks: [
|
|
5269
|
-
(
|
|
5070
|
+
async (pageId, browserController, pageOptions = {}) => {
|
|
5270
5071
|
const fingerprintWithHeaders = browserController?.launchContext?.fingerprint;
|
|
5271
|
-
const timezoneId =
|
|
5072
|
+
const timezoneId = AntiCheat.getBaseConfig().timezoneId;
|
|
5272
5073
|
applyFingerprintPageOptions(pageOptions, {
|
|
5273
5074
|
fingerprintWithHeaders,
|
|
5274
5075
|
locale: launchLocale,
|
|
5275
5076
|
timezoneId
|
|
5276
5077
|
});
|
|
5078
|
+
if (modifyPageOptions) {
|
|
5079
|
+
await modifyPageOptions(pageOptions, { pageId, browserController });
|
|
5080
|
+
}
|
|
5277
5081
|
}
|
|
5278
5082
|
]
|
|
5279
5083
|
},
|
|
@@ -5295,303 +5099,10 @@ var DefaultLaunch = {
|
|
|
5295
5099
|
}
|
|
5296
5100
|
};
|
|
5297
5101
|
|
|
5298
|
-
// src/internals/launch/cloak.js
|
|
5299
|
-
var import_node_child_process2 = require("node:child_process");
|
|
5300
|
-
var import_node_util = require("node:util");
|
|
5301
|
-
var logger9 = createInternalLogger("Launch");
|
|
5302
|
-
var execFileAsync = (0, import_node_util.promisify)(import_node_child_process2.execFile);
|
|
5303
|
-
var DEFAULT_CLOAK_CRAWLER_BASE_OPTIONS = Object.freeze({
|
|
5304
|
-
maxConcurrency: 1,
|
|
5305
|
-
maxRequestRetries: 0,
|
|
5306
|
-
requestHandlerTimeoutSecs: 240,
|
|
5307
|
-
navigationTimeoutSecs: 120
|
|
5308
|
-
});
|
|
5309
|
-
var DEFAULT_CLOAK_HUMANIZE_OPTIONS = Object.freeze({
|
|
5310
|
-
humanize: true
|
|
5311
|
-
});
|
|
5312
|
-
var DEFAULT_CLOAK_GOTO_OPTIONS = Object.freeze({
|
|
5313
|
-
waitUntil: "commit"
|
|
5314
|
-
});
|
|
5315
|
-
var DEFAULT_CLOAK_FINGERPRINT_PLATFORM = "linux";
|
|
5316
|
-
var CLOAK_FINGERPRINT_PLATFORM_ARG_PREFIX = "--fingerprint-platform=";
|
|
5317
|
-
var SUPPORTED_CLOAK_FINGERPRINT_PLATFORMS = /* @__PURE__ */ new Set(["linux", "macos", "windows"]);
|
|
5318
|
-
var cachedCloakModulePromise = null;
|
|
5319
|
-
var hasOwn = (target, key) => Object.prototype.hasOwnProperty.call(target, key);
|
|
5320
|
-
var loadCloakModule = async () => {
|
|
5321
|
-
if (!cachedCloakModulePromise) {
|
|
5322
|
-
cachedCloakModulePromise = import("cloakbrowser").catch((error) => {
|
|
5323
|
-
cachedCloakModulePromise = null;
|
|
5324
|
-
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", {
|
|
5325
|
-
cause: error
|
|
5326
|
-
});
|
|
5327
|
-
});
|
|
5328
|
-
}
|
|
5329
|
-
return cachedCloakModulePromise;
|
|
5330
|
-
};
|
|
5331
|
-
var buildCloakLaunchOptions = async (options = {}) => {
|
|
5332
|
-
const { buildLaunchOptions } = await loadCloakModule();
|
|
5333
|
-
return await buildLaunchOptions(normalizeObject2(options));
|
|
5334
|
-
};
|
|
5335
|
-
var normalizeObject2 = (value) => {
|
|
5336
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
5337
|
-
return {};
|
|
5338
|
-
}
|
|
5339
|
-
return value;
|
|
5340
|
-
};
|
|
5341
|
-
var normalizeStringArray = (value) => {
|
|
5342
|
-
if (!Array.isArray(value)) {
|
|
5343
|
-
return [];
|
|
5344
|
-
}
|
|
5345
|
-
return value.map((item) => String(item || "").trim()).filter(Boolean);
|
|
5346
|
-
};
|
|
5347
|
-
var resolveCloakFingerprintPlatformArg = (fingerprintPlatform = "", args = []) => {
|
|
5348
|
-
const normalizedFingerprintPlatform = String(fingerprintPlatform || "").trim().toLowerCase();
|
|
5349
|
-
if (SUPPORTED_CLOAK_FINGERPRINT_PLATFORMS.has(normalizedFingerprintPlatform)) {
|
|
5350
|
-
return `${CLOAK_FINGERPRINT_PLATFORM_ARG_PREFIX}${normalizedFingerprintPlatform}`;
|
|
5351
|
-
}
|
|
5352
|
-
const existingArg = normalizeStringArray(args).find((value) => value.startsWith(CLOAK_FINGERPRINT_PLATFORM_ARG_PREFIX));
|
|
5353
|
-
if (existingArg) {
|
|
5354
|
-
return existingArg;
|
|
5355
|
-
}
|
|
5356
|
-
return `${CLOAK_FINGERPRINT_PLATFORM_ARG_PREFIX}${DEFAULT_CLOAK_FINGERPRINT_PLATFORM}`;
|
|
5357
|
-
};
|
|
5358
|
-
var resolveCloakProxy = (proxyConfiguration = {}) => {
|
|
5359
|
-
const config = normalizeObject2(proxyConfiguration);
|
|
5360
|
-
const proxyUrl = String(config.proxy_url || "").trim();
|
|
5361
|
-
const enableProxy = typeof config.enable_proxy === "boolean" ? config.enable_proxy : proxyUrl !== "";
|
|
5362
|
-
if (!enableProxy || !proxyUrl) {
|
|
5363
|
-
return null;
|
|
5364
|
-
}
|
|
5365
|
-
const byPassDomains = ByPass.normalizeByPassDomains(config.by_pass_domains);
|
|
5366
|
-
if (byPassDomains.length === 0) {
|
|
5367
|
-
return proxyUrl;
|
|
5368
|
-
}
|
|
5369
|
-
const parsedProxyUrl = new URL(proxyUrl.includes("://") ? proxyUrl : `http://${proxyUrl}`);
|
|
5370
|
-
return {
|
|
5371
|
-
server: `${parsedProxyUrl.protocol}//${parsedProxyUrl.host}`,
|
|
5372
|
-
username: decodeURIComponent(parsedProxyUrl.username || ""),
|
|
5373
|
-
password: decodeURIComponent(parsedProxyUrl.password || ""),
|
|
5374
|
-
bypass: byPassDomains.join(",")
|
|
5375
|
-
};
|
|
5376
|
-
};
|
|
5377
|
-
var extractFingerprintArg = (launchOptions = {}) => {
|
|
5378
|
-
const args = Array.isArray(launchOptions?.args) ? launchOptions.args : [];
|
|
5379
|
-
return args.find((value) => String(value || "").startsWith("--fingerprint=")) || "";
|
|
5380
|
-
};
|
|
5381
|
-
var createStableGotoHook = (recommendedGotoOptions = DEFAULT_CLOAK_GOTO_OPTIONS) => {
|
|
5382
|
-
const normalizedRecommendedGotoOptions = normalizeObject2(recommendedGotoOptions);
|
|
5383
|
-
const fallbackGotoOptions = Object.keys(normalizedRecommendedGotoOptions).length > 0 ? normalizedRecommendedGotoOptions : DEFAULT_CLOAK_GOTO_OPTIONS;
|
|
5384
|
-
return async (_crawlingContext, gotoOptions = {}) => {
|
|
5385
|
-
for (const [key, value] of Object.entries(fallbackGotoOptions)) {
|
|
5386
|
-
if (gotoOptions[key] == null) {
|
|
5387
|
-
gotoOptions[key] = value;
|
|
5388
|
-
}
|
|
5389
|
-
}
|
|
5390
|
-
};
|
|
5391
|
-
};
|
|
5392
|
-
var attachCloakHumanizeHook = ({
|
|
5393
|
-
browserPoolOptions = {},
|
|
5394
|
-
activeBrowsers,
|
|
5395
|
-
patchedBrowsers,
|
|
5396
|
-
humanizeOptions = DEFAULT_CLOAK_HUMANIZE_OPTIONS
|
|
5397
|
-
} = {}) => {
|
|
5398
|
-
const normalizedBrowserPoolOptions = normalizeObject2(browserPoolOptions);
|
|
5399
|
-
const shouldHumanize = humanizeOptions !== false;
|
|
5400
|
-
const normalizedHumanizeOptions = shouldHumanize ? {
|
|
5401
|
-
...DEFAULT_CLOAK_HUMANIZE_OPTIONS,
|
|
5402
|
-
...normalizeObject2(humanizeOptions)
|
|
5403
|
-
} : null;
|
|
5404
|
-
return {
|
|
5405
|
-
...normalizedBrowserPoolOptions,
|
|
5406
|
-
useFingerprints: false,
|
|
5407
|
-
postLaunchHooks: [
|
|
5408
|
-
...Array.isArray(normalizedBrowserPoolOptions.postLaunchHooks) ? normalizedBrowserPoolOptions.postLaunchHooks : [],
|
|
5409
|
-
async (_pageId, browserController) => {
|
|
5410
|
-
const browser = browserController?.browser;
|
|
5411
|
-
if (!browser || typeof browser.contexts !== "function") {
|
|
5412
|
-
return;
|
|
5413
|
-
}
|
|
5414
|
-
activeBrowsers.add(browser);
|
|
5415
|
-
if (typeof browser.once === "function") {
|
|
5416
|
-
browser.once("disconnected", () => {
|
|
5417
|
-
activeBrowsers.delete(browser);
|
|
5418
|
-
});
|
|
5419
|
-
}
|
|
5420
|
-
if (!shouldHumanize || patchedBrowsers.has(browser)) {
|
|
5421
|
-
return;
|
|
5422
|
-
}
|
|
5423
|
-
const { humanizeBrowser } = await loadCloakModule();
|
|
5424
|
-
await humanizeBrowser(browser, normalizedHumanizeOptions);
|
|
5425
|
-
patchedBrowsers.add(browser);
|
|
5426
|
-
}
|
|
5427
|
-
]
|
|
5428
|
-
};
|
|
5429
|
-
};
|
|
5430
|
-
var closeTrackedBrowsers = async (activeBrowsers) => {
|
|
5431
|
-
const browsers = Array.from(activeBrowsers || []);
|
|
5432
|
-
activeBrowsers?.clear?.();
|
|
5433
|
-
await Promise.allSettled(
|
|
5434
|
-
browsers.map(async (browser) => {
|
|
5435
|
-
if (!browser || typeof browser.isConnected !== "function" || !browser.isConnected()) {
|
|
5436
|
-
return;
|
|
5437
|
-
}
|
|
5438
|
-
await browser.close().catch(() => {
|
|
5439
|
-
});
|
|
5440
|
-
})
|
|
5441
|
-
);
|
|
5442
|
-
};
|
|
5443
|
-
var forceTerminateBrowsersByFingerprintArg = async (fingerprintArg) => {
|
|
5444
|
-
if (!fingerprintArg) {
|
|
5445
|
-
return;
|
|
5446
|
-
}
|
|
5447
|
-
await execFileAsync("pkill", ["-f", "--", fingerprintArg]).catch((error) => {
|
|
5448
|
-
if (error?.code === 1 || error?.code === "ENOENT") {
|
|
5449
|
-
return;
|
|
5450
|
-
}
|
|
5451
|
-
logger9.info(`\u5F3A\u5236\u5173\u95ED Cloak \u8FDB\u7A0B\u5931\u8D25\uFF08\u5FFD\u7565\uFF09: ${error?.message || String(error)}`);
|
|
5452
|
-
});
|
|
5453
|
-
};
|
|
5454
|
-
var CloakLaunch = {
|
|
5455
|
-
resolveProxyConfiguration(proxyConfiguration = {}) {
|
|
5456
|
-
return resolveCloakProxy(proxyConfiguration);
|
|
5457
|
-
},
|
|
5458
|
-
extractFingerprintArg(launchOptions = {}) {
|
|
5459
|
-
return extractFingerprintArg(launchOptions);
|
|
5460
|
-
},
|
|
5461
|
-
createStableGotoHook(recommendedGotoOptions = DEFAULT_CLOAK_GOTO_OPTIONS) {
|
|
5462
|
-
return createStableGotoHook(recommendedGotoOptions);
|
|
5463
|
-
},
|
|
5464
|
-
async getPlaywrightCrawlerOptions(options = {}) {
|
|
5465
|
-
const runtime2 = await CloakLaunch.createPlaywrightCrawlerRuntime(options);
|
|
5466
|
-
return Object.defineProperties(runtime2.crawlerOptions, {
|
|
5467
|
-
cleanup: {
|
|
5468
|
-
enumerable: false,
|
|
5469
|
-
value: runtime2.cleanup
|
|
5470
|
-
},
|
|
5471
|
-
closeActiveBrowsers: {
|
|
5472
|
-
enumerable: false,
|
|
5473
|
-
value: runtime2.closeActiveBrowsers
|
|
5474
|
-
},
|
|
5475
|
-
forceTerminateActiveProcesses: {
|
|
5476
|
-
enumerable: false,
|
|
5477
|
-
value: runtime2.forceTerminateActiveProcesses
|
|
5478
|
-
}
|
|
5479
|
-
});
|
|
5480
|
-
},
|
|
5481
|
-
async buildLaunchOptions(options = {}) {
|
|
5482
|
-
return await buildCloakLaunchOptions(options);
|
|
5483
|
-
},
|
|
5484
|
-
async createPlaywrightCrawlerRuntime(options = {}) {
|
|
5485
|
-
const normalizedOptions = normalizeObject2(options);
|
|
5486
|
-
const {
|
|
5487
|
-
proxyConfiguration = {},
|
|
5488
|
-
log: logOptions = null,
|
|
5489
|
-
debugMode = false,
|
|
5490
|
-
runInHeadfulMode = false,
|
|
5491
|
-
isRunningOnApify = false,
|
|
5492
|
-
launcher = null,
|
|
5493
|
-
fingerprintPlatform = "",
|
|
5494
|
-
cloakOptions = {},
|
|
5495
|
-
humanizeOptions = DEFAULT_CLOAK_HUMANIZE_OPTIONS,
|
|
5496
|
-
crawlerBaseOptions = {},
|
|
5497
|
-
browserPoolOptions = {},
|
|
5498
|
-
launchContext = {},
|
|
5499
|
-
preNavigationHooks = [],
|
|
5500
|
-
postNavigationHooks = [],
|
|
5501
|
-
recommendedGotoOptions = DEFAULT_CLOAK_GOTO_OPTIONS
|
|
5502
|
-
} = normalizedOptions;
|
|
5503
|
-
const normalizedCloakOptions = normalizeObject2(cloakOptions);
|
|
5504
|
-
const activeBrowsers = /* @__PURE__ */ new Set();
|
|
5505
|
-
const patchedBrowsers = /* @__PURE__ */ new WeakSet();
|
|
5506
|
-
const defaultArgs = isRunningOnApify ? ["--no-sandbox", "--disable-setuid-sandbox"] : [];
|
|
5507
|
-
const fingerprintPlatformArg = resolveCloakFingerprintPlatformArg(fingerprintPlatform, normalizedCloakOptions.args);
|
|
5508
|
-
const extraArgs = normalizeStringArray(normalizedCloakOptions.args).filter((value) => !value.startsWith(CLOAK_FINGERPRINT_PLATFORM_ARG_PREFIX));
|
|
5509
|
-
const hasExplicitProxy = hasOwn(normalizedCloakOptions, "proxy");
|
|
5510
|
-
const proxyLaunchState = hasExplicitProxy ? resolveLaunchTraffic({ proxyConfiguration, debugMode, useMeter: false }) : resolveLaunchTraffic({ proxyConfiguration, debugMode });
|
|
5511
|
-
const proxy = hasExplicitProxy ? normalizedCloakOptions.proxy : proxyLaunchState.launchProxy;
|
|
5512
|
-
const headless = hasOwn(normalizedCloakOptions, "headless") ? normalizedCloakOptions.headless : !runInHeadfulMode || isRunningOnApify;
|
|
5513
|
-
const enableByPassLogger = Boolean(logOptions && logOptions.enable);
|
|
5514
|
-
const mergedCloakOptions = {
|
|
5515
|
-
...normalizedCloakOptions,
|
|
5516
|
-
headless,
|
|
5517
|
-
proxy,
|
|
5518
|
-
args: [...defaultArgs, ...extraArgs, fingerprintPlatformArg]
|
|
5519
|
-
};
|
|
5520
|
-
const launchOptions = await buildCloakLaunchOptions(mergedCloakOptions);
|
|
5521
|
-
const fingerprintArg = extractFingerprintArg(launchOptions);
|
|
5522
|
-
const internalPreNavigationHook = createStableGotoHook(recommendedGotoOptions);
|
|
5523
|
-
const trafficHook = createLaunchTrafficHook({
|
|
5524
|
-
byPassDomains: proxyLaunchState.byPassDomains,
|
|
5525
|
-
byPassRules: proxyLaunchState.byPassRules,
|
|
5526
|
-
enabled: enableByPassLogger,
|
|
5527
|
-
launchProxy: proxyLaunchState.launchProxy
|
|
5528
|
-
});
|
|
5529
|
-
const normalizedPreNavigationHooks = Array.isArray(preNavigationHooks) ? preNavigationHooks : [];
|
|
5530
|
-
const normalizedPostNavigationHooks = Array.isArray(postNavigationHooks) ? postNavigationHooks : [];
|
|
5531
|
-
logLaunchTraffic({
|
|
5532
|
-
...proxyLaunchState,
|
|
5533
|
-
debugMode,
|
|
5534
|
-
enabled: enableByPassLogger,
|
|
5535
|
-
explicitProxy: hasExplicitProxy
|
|
5536
|
-
});
|
|
5537
|
-
const crawlerOptions = {
|
|
5538
|
-
...DEFAULT_CLOAK_CRAWLER_BASE_OPTIONS,
|
|
5539
|
-
...normalizeObject2(crawlerBaseOptions),
|
|
5540
|
-
headless,
|
|
5541
|
-
launchContext: {
|
|
5542
|
-
useIncognitoPages: true,
|
|
5543
|
-
...normalizeObject2(launchContext),
|
|
5544
|
-
...launcher ? { launcher } : {},
|
|
5545
|
-
launchOptions
|
|
5546
|
-
},
|
|
5547
|
-
browserPoolOptions: attachCloakHumanizeHook({
|
|
5548
|
-
browserPoolOptions,
|
|
5549
|
-
activeBrowsers,
|
|
5550
|
-
patchedBrowsers,
|
|
5551
|
-
humanizeOptions
|
|
5552
|
-
}),
|
|
5553
|
-
preNavigationHooks: [
|
|
5554
|
-
async (crawlingContext, gotoOptions = {}) => {
|
|
5555
|
-
trafficHook(crawlingContext?.page);
|
|
5556
|
-
await internalPreNavigationHook(crawlingContext, gotoOptions);
|
|
5557
|
-
},
|
|
5558
|
-
...normalizedPreNavigationHooks
|
|
5559
|
-
],
|
|
5560
|
-
...normalizedPostNavigationHooks.length > 0 ? { postNavigationHooks: normalizedPostNavigationHooks } : {}
|
|
5561
|
-
};
|
|
5562
|
-
const closeActiveBrowsers = async () => {
|
|
5563
|
-
await closeTrackedBrowsers(activeBrowsers);
|
|
5564
|
-
};
|
|
5565
|
-
const forceTerminateActiveProcesses = async () => {
|
|
5566
|
-
await forceTerminateBrowsersByFingerprintArg(fingerprintArg);
|
|
5567
|
-
};
|
|
5568
|
-
const cleanup = async () => {
|
|
5569
|
-
await closeActiveBrowsers();
|
|
5570
|
-
await forceTerminateActiveProcesses();
|
|
5571
|
-
};
|
|
5572
|
-
return {
|
|
5573
|
-
headless,
|
|
5574
|
-
launchOptions,
|
|
5575
|
-
fingerprintArg,
|
|
5576
|
-
crawlerOptions,
|
|
5577
|
-
closeActiveBrowsers,
|
|
5578
|
-
forceTerminateActiveProcesses,
|
|
5579
|
-
cleanup
|
|
5580
|
-
};
|
|
5581
|
-
}
|
|
5582
|
-
};
|
|
5583
|
-
|
|
5584
|
-
// src/launch.js
|
|
5585
|
-
var launchStrategies = {
|
|
5586
|
-
[Mode.Default]: DefaultLaunch,
|
|
5587
|
-
[Mode.Cloak]: CloakLaunch
|
|
5588
|
-
};
|
|
5589
|
-
var Launch = withModeReflect("Launch", launchStrategies);
|
|
5590
|
-
|
|
5591
5102
|
// src/live-view.js
|
|
5592
5103
|
var import_express = __toESM(require("express"), 1);
|
|
5593
5104
|
var import_apify = require("apify");
|
|
5594
|
-
var
|
|
5105
|
+
var logger9 = createInternalLogger("LiveView");
|
|
5595
5106
|
async function startLiveViewServer(liveViewKey) {
|
|
5596
5107
|
const app = (0, import_express.default)();
|
|
5597
5108
|
app.get("/", async (req, res) => {
|
|
@@ -5616,13 +5127,13 @@ async function startLiveViewServer(liveViewKey) {
|
|
|
5616
5127
|
</html>
|
|
5617
5128
|
`);
|
|
5618
5129
|
} catch (error) {
|
|
5619
|
-
|
|
5130
|
+
logger9.fail("Live View Server", error);
|
|
5620
5131
|
res.status(500).send(`\u65E0\u6CD5\u52A0\u8F7D\u5C4F\u5E55\u622A\u56FE: ${error.message}`);
|
|
5621
5132
|
}
|
|
5622
5133
|
});
|
|
5623
5134
|
const port = process.env.APIFY_CONTAINER_PORT || 4321;
|
|
5624
5135
|
app.listen(port, () => {
|
|
5625
|
-
|
|
5136
|
+
logger9.success("startLiveViewServer", `\u76D1\u542C\u7AEF\u53E3 ${port}`);
|
|
5626
5137
|
});
|
|
5627
5138
|
}
|
|
5628
5139
|
async function takeLiveScreenshot(liveViewKey, page, logMessage) {
|
|
@@ -5630,10 +5141,10 @@ async function takeLiveScreenshot(liveViewKey, page, logMessage) {
|
|
|
5630
5141
|
const buffer = await capturePageScreenshot(page, { type: "png" });
|
|
5631
5142
|
await import_apify.Actor.setValue(liveViewKey, buffer, { contentType: "image/png" });
|
|
5632
5143
|
if (logMessage) {
|
|
5633
|
-
|
|
5144
|
+
logger9.info(`(\u622A\u56FE): ${logMessage}`);
|
|
5634
5145
|
}
|
|
5635
5146
|
} catch (e) {
|
|
5636
|
-
|
|
5147
|
+
logger9.warn(`\u65E0\u6CD5\u6355\u83B7 Live View \u5C4F\u5E55\u622A\u56FE: ${e.message}`);
|
|
5637
5148
|
}
|
|
5638
5149
|
}
|
|
5639
5150
|
var useLiveView = (liveViewKey = PresetOfLiveViewKey) => {
|
|
@@ -5650,6 +5161,9 @@ var LiveView = {
|
|
|
5650
5161
|
useLiveView
|
|
5651
5162
|
};
|
|
5652
5163
|
|
|
5164
|
+
// src/chaptcha.js
|
|
5165
|
+
var import_uuid = require("uuid");
|
|
5166
|
+
|
|
5653
5167
|
// src/internals/captcha/bytedance.js
|
|
5654
5168
|
var import_promises = require("fs/promises");
|
|
5655
5169
|
var import_path2 = __toESM(require("path"), 1);
|
|
@@ -5739,7 +5253,7 @@ var dragCaptchaAction = async (page, sourceLocator, targetLocator, options = {})
|
|
|
5739
5253
|
};
|
|
5740
5254
|
|
|
5741
5255
|
// src/internals/captcha/bytedance.js
|
|
5742
|
-
var
|
|
5256
|
+
var logger10 = createInternalLogger("Captcha");
|
|
5743
5257
|
var DEFAULT_BYTEDANCE_CAPTCHA_OPTIONS = Object.freeze({
|
|
5744
5258
|
apiType: "31234",
|
|
5745
5259
|
maxRetries: 3,
|
|
@@ -5871,7 +5385,7 @@ var collectCaptchaDebugInfo = async (page, frame, iframeLocator, attempt, phase,
|
|
|
5871
5385
|
}
|
|
5872
5386
|
await (0, import_promises.writeFile)(infoPath, JSON.stringify(payload, null, 2), "utf8");
|
|
5873
5387
|
}
|
|
5874
|
-
|
|
5388
|
+
logger10.info(`\u5DF2\u5199\u51FA\u9A8C\u8BC1\u7801\u8C03\u8BD5\u4EA7\u7269\uFF1A${debugDir}`);
|
|
5875
5389
|
};
|
|
5876
5390
|
var maybeCollectCaptchaDebugInfo = async (page, frame, iframeLocator, attempt, phase, options, extra = null) => {
|
|
5877
5391
|
if (!options.debugArtifacts) {
|
|
@@ -5908,14 +5422,14 @@ var getVerifycenterCaptchaContext = async (page, options) => {
|
|
|
5908
5422
|
if (!isContainerVisible) {
|
|
5909
5423
|
return null;
|
|
5910
5424
|
}
|
|
5911
|
-
|
|
5425
|
+
logger10.info("\u68C0\u6D4B\u5230\u9A8C\u8BC1\u7801\u5BB9\u5668\uFF0C\u5F00\u59CB\u7B49\u5F85 iframe \u52A0\u8F7D\u3002");
|
|
5912
5426
|
let iframeLocator = page.locator(options.iframeSelector).first();
|
|
5913
5427
|
let isIframeVisible = await waitForVisible(
|
|
5914
5428
|
iframeLocator,
|
|
5915
5429
|
options.iframeVisibleTimeoutMs
|
|
5916
5430
|
);
|
|
5917
5431
|
if (!isIframeVisible) {
|
|
5918
|
-
|
|
5432
|
+
logger10.warn("\u672A\u5728\u9884\u671F\u9009\u62E9\u5668\u4E2D\u627E\u5230 verifycenter iframe\uFF0C\u5C1D\u8BD5\u5BB9\u5668\u5185\u4EFB\u610F iframe\u3002");
|
|
5919
5433
|
iframeLocator = captchaContainer.locator(options.iframeFallbackSelector).first();
|
|
5920
5434
|
isIframeVisible = await waitForVisible(
|
|
5921
5435
|
iframeLocator,
|
|
@@ -5925,7 +5439,7 @@ var getVerifycenterCaptchaContext = async (page, options) => {
|
|
|
5925
5439
|
if (!isIframeVisible) {
|
|
5926
5440
|
throw new Error("verifycenter iframe not found inside captcha container.");
|
|
5927
5441
|
}
|
|
5928
|
-
|
|
5442
|
+
logger10.info("\u9A8C\u8BC1\u7801 iframe \u5DF2\u53EF\u89C1\uFF0C\u5F00\u59CB\u89E3\u6790\u5185\u5BB9 frame\u3002");
|
|
5929
5443
|
const frame = await resolveContentFrame(page, iframeLocator, options);
|
|
5930
5444
|
if (!frame) {
|
|
5931
5445
|
throw new Error("Failed to resolve verifycenter iframe content frame.");
|
|
@@ -6041,11 +5555,11 @@ var refreshCaptcha = async (page, frame, options) => {
|
|
|
6041
5555
|
const clicked = await clickCaptchaAction(frame, options.refreshTexts, {
|
|
6042
5556
|
...options,
|
|
6043
5557
|
page,
|
|
6044
|
-
logger:
|
|
5558
|
+
logger: logger10,
|
|
6045
5559
|
forceMouse: true
|
|
6046
5560
|
}).catch(() => false);
|
|
6047
5561
|
if (!clicked) {
|
|
6048
|
-
|
|
5562
|
+
logger10.warn("Refresh button not found.");
|
|
6049
5563
|
return false;
|
|
6050
5564
|
}
|
|
6051
5565
|
await page.waitForTimeout(options.refreshWaitMs);
|
|
@@ -6076,24 +5590,24 @@ var waitForCaptchaChallengeReady = async (page, frame, options) => {
|
|
|
6076
5590
|
const hasGuideMaskVisible = options.guideMaskSelector ? await frame.locator(options.guideMaskSelector).first().isVisible({ timeout: options.loadingIndicatorVisibleTimeoutMs }).catch(() => false) : false;
|
|
6077
5591
|
hasSeenGuideMask = hasSeenGuideMask || hasGuideMaskVisible;
|
|
6078
5592
|
if (hasGuideMaskVisible && !hasLoggedGuideMask) {
|
|
6079
|
-
|
|
5593
|
+
logger10.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");
|
|
6080
5594
|
hasLoggedGuideMask = true;
|
|
6081
5595
|
}
|
|
6082
5596
|
if (!isLoadingVisible && hasVisibleSourceImage && hasVisibleDropTarget && !hasGuideMaskVisible) {
|
|
6083
|
-
|
|
5597
|
+
logger10.info(
|
|
6084
5598
|
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"
|
|
6085
5599
|
);
|
|
6086
5600
|
return;
|
|
6087
5601
|
}
|
|
6088
5602
|
if (hasErrorTextVisible) {
|
|
6089
|
-
|
|
5603
|
+
logger10.warn("\u9A8C\u8BC1\u7801\u9762\u677F\u51FA\u73B0\u7F51\u7EDC\u5F02\u5E38\u6587\u6848\uFF0C\u5C1D\u8BD5\u7ACB\u5373\u5237\u65B0\u9898\u76EE\u3002");
|
|
6090
5604
|
await refreshCaptcha(page, frame, options);
|
|
6091
5605
|
refreshDeadline = Date.now() + options.challengeReadyRefreshTimeoutMs;
|
|
6092
5606
|
hasSeenLoading = false;
|
|
6093
5607
|
continue;
|
|
6094
5608
|
}
|
|
6095
5609
|
if ((!hasVisibleSourceImage || !hasVisibleDropTarget) && Date.now() >= refreshDeadline) {
|
|
6096
|
-
|
|
5610
|
+
logger10.warn(`\u9A8C\u8BC1\u7801\u9898\u76EE\u8D85\u8FC7 ${options.challengeReadyRefreshTimeoutMs}ms \u4ECD\u672A\u51C6\u5907\u597D\uFF0C\u5C1D\u8BD5\u5237\u65B0\u9898\u76EE\u3002`);
|
|
6097
5611
|
await refreshCaptcha(page, frame, options);
|
|
6098
5612
|
refreshDeadline = Date.now() + options.challengeReadyRefreshTimeoutMs;
|
|
6099
5613
|
hasSeenLoading = false;
|
|
@@ -6141,7 +5655,7 @@ var dragPromptCaptchaImage = async (page, frame, iframeLocator, sourceLocator, d
|
|
|
6141
5655
|
accepted
|
|
6142
5656
|
};
|
|
6143
5657
|
dragAttempts.push(attemptInfo);
|
|
6144
|
-
|
|
5658
|
+
logger10.info(
|
|
6145
5659
|
`\u9A8C\u8BC1\u7801\u62D6\u62FD\u7B2C ${visualIndex + 1} \u5F20\uFF0C\u65B9\u6848 ${plan.name}\uFF0Cbadge ${baselineState.badgeCount} -> ${afterState.badgeCount}\uFF0Cselected ${baselineState.selectedCount} -> ${afterState.selectedCount}`
|
|
6146
5660
|
);
|
|
6147
5661
|
if (accepted) {
|
|
@@ -6159,7 +5673,7 @@ var dragPromptCaptchaImage = async (page, frame, iframeLocator, sourceLocator, d
|
|
|
6159
5673
|
dragAttempts,
|
|
6160
5674
|
finalState: await readPromptCaptchaState(frame, options)
|
|
6161
5675
|
}).catch((error) => {
|
|
6162
|
-
|
|
5676
|
+
logger10.warn(`\u9A8C\u8BC1\u7801\u62D6\u62FD\u5931\u8D25\u8C03\u8BD5\u6293\u53D6\u5931\u8D25\uFF1A${error?.message || error}`);
|
|
6163
5677
|
});
|
|
6164
5678
|
return {
|
|
6165
5679
|
accepted: false,
|
|
@@ -6176,16 +5690,16 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
|
|
|
6176
5690
|
...options
|
|
6177
5691
|
};
|
|
6178
5692
|
if (!config.token) {
|
|
6179
|
-
|
|
5693
|
+
logger10.warn("\u7F3A\u5C11\u9A8C\u8BC1\u7801 token\uFF0C\u8DF3\u8FC7\u81EA\u52A8\u8BC6\u522B\u3002");
|
|
6180
5694
|
return false;
|
|
6181
5695
|
}
|
|
6182
|
-
|
|
5696
|
+
logger10.info("\u5F53\u524D\u4F7F\u7528\u672Ctool\u2014\u2014\u6D4B\u8BD5\u7248\u672C");
|
|
6183
5697
|
for (let attempt = 1; attempt <= config.maxRetries; attempt += 1) {
|
|
6184
|
-
|
|
5698
|
+
logger10.info(`\u5F00\u59CB\u7B2C ${attempt}/${config.maxRetries} \u6B21 verifycenter \u9A8C\u8BC1\u7801\u8BC6\u522B\u3002`);
|
|
6185
5699
|
try {
|
|
6186
5700
|
const captchaContext = await getVerifycenterCaptchaContext(page, config);
|
|
6187
5701
|
if (!captchaContext) {
|
|
6188
|
-
|
|
5702
|
+
logger10.info("Captcha container is not visible anymore.");
|
|
6189
5703
|
return true;
|
|
6190
5704
|
}
|
|
6191
5705
|
const { iframeLocator, frame } = captchaContext;
|
|
@@ -6198,7 +5712,7 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
|
|
|
6198
5712
|
"ready",
|
|
6199
5713
|
config
|
|
6200
5714
|
).catch((error) => {
|
|
6201
|
-
|
|
5715
|
+
logger10.warn(`\u9A8C\u8BC1\u7801\u8C03\u8BD5\u6293\u53D6\u5931\u8D25\uFF1A${error?.message || error}`);
|
|
6202
5716
|
});
|
|
6203
5717
|
await page.waitForTimeout(config.recognitionDelayMs);
|
|
6204
5718
|
const screenshotBuffer = await iframeLocator.screenshot();
|
|
@@ -6210,16 +5724,16 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
|
|
|
6210
5724
|
});
|
|
6211
5725
|
const serialNumbers = extractCaptchaSerialNumbers(apiResponse);
|
|
6212
5726
|
if (apiResponse?.code !== config.recognitionSuccessCode || serialNumbers.length === 0) {
|
|
6213
|
-
|
|
5727
|
+
logger10.warn(
|
|
6214
5728
|
`\u9A8C\u8BC1\u7801\u8BC6\u522B\u5931\u8D25\u3002code=${apiResponse?.code}, msg=${apiResponse?.msg || "unknown"}`
|
|
6215
5729
|
);
|
|
6216
5730
|
await refreshCaptcha(page, frame, config);
|
|
6217
5731
|
continue;
|
|
6218
5732
|
}
|
|
6219
|
-
|
|
5733
|
+
logger10.info(`\u9A8C\u8BC1\u7801\u8BC6\u522B\u6210\u529F\uFF0C\u5E8F\u53F7\uFF1A${serialNumbers.join(", ")}`);
|
|
6220
5734
|
const dropTarget = await findCaptchaDropTarget(frame, config);
|
|
6221
5735
|
if (!dropTarget) {
|
|
6222
|
-
|
|
5736
|
+
logger10.warn("\u672A\u627E\u5230\u9A8C\u8BC1\u7801\u62D6\u62FD\u76EE\u6807\u533A\u57DF\u3002");
|
|
6223
5737
|
await refreshCaptcha(page, frame, config);
|
|
6224
5738
|
continue;
|
|
6225
5739
|
}
|
|
@@ -6230,7 +5744,7 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
|
|
|
6230
5744
|
`Captcha image indexes could not be normalized. raw=${serialNumbers.join(", ")}, count=${orderedSourceImages.length}`
|
|
6231
5745
|
);
|
|
6232
5746
|
}
|
|
6233
|
-
|
|
5747
|
+
logger10.info(`\u9A8C\u8BC1\u7801\u89C6\u89C9\u4F4D\u5E8F\u6620\u5C04\uFF1A${normalizedIndexes.map((index) => index + 1).join(", ")}`);
|
|
6234
5748
|
for (const imageIndex of normalizedIndexes) {
|
|
6235
5749
|
if (imageIndex < 0 || imageIndex >= orderedSourceImages.length) {
|
|
6236
5750
|
throw new Error(
|
|
@@ -6262,55 +5776,52 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
|
|
|
6262
5776
|
}
|
|
6263
5777
|
}
|
|
6264
5778
|
const beforeSubmitState = await readPromptCaptchaState(frame, config);
|
|
6265
|
-
|
|
5779
|
+
logger10.info(
|
|
6266
5780
|
`\u63D0\u4EA4\u524D\u9A8C\u8BC1\u7801\u72B6\u6001\uFF1Abadge=${beforeSubmitState.badgeCount}, selected=${beforeSubmitState.selectedCount}, submitDisabled=${beforeSubmitState.submitDisabled}`
|
|
6267
5781
|
);
|
|
6268
5782
|
const submitted = await clickCaptchaAction(frame, config.submitTexts, {
|
|
6269
5783
|
...config,
|
|
6270
5784
|
page,
|
|
6271
|
-
logger:
|
|
5785
|
+
logger: logger10,
|
|
6272
5786
|
forceMouse: true,
|
|
6273
5787
|
actionVisibleTimeoutMs: config.submitReadyTimeoutMs
|
|
6274
5788
|
}).catch(() => false);
|
|
6275
5789
|
if (!submitted) {
|
|
6276
|
-
|
|
5790
|
+
logger10.warn("\u672A\u627E\u5230\u63D0\u4EA4\u6309\u94AE\uFF0C\u53EF\u80FD\u4F1A\u81EA\u52A8\u63D0\u4EA4\u3002");
|
|
6277
5791
|
}
|
|
6278
5792
|
await page.waitForTimeout(config.submitWaitMs);
|
|
6279
5793
|
const afterSubmitState = await readPromptCaptchaState(frame, config);
|
|
6280
|
-
|
|
5794
|
+
logger10.info(
|
|
6281
5795
|
`\u63D0\u4EA4\u540E\u9A8C\u8BC1\u7801\u72B6\u6001\uFF1Abadge=${afterSubmitState.badgeCount}, selected=${afterSubmitState.selectedCount}, submitDisabled=${afterSubmitState.submitDisabled}`
|
|
6282
5796
|
);
|
|
6283
5797
|
const stillVisible = await iframeLocator.isVisible({ timeout: config.containerVisibleTimeoutMs }).catch(() => false);
|
|
6284
5798
|
if (!stillVisible) {
|
|
6285
|
-
|
|
5799
|
+
logger10.info("\u9A8C\u8BC1\u7801\u8BC6\u522B\u5E76\u63D0\u4EA4\u6210\u529F\u3002");
|
|
6286
5800
|
return true;
|
|
6287
5801
|
}
|
|
6288
5802
|
await maybeCollectCaptchaDebugInfo(page, frame, iframeLocator, attempt, "submit-still-visible", config, {
|
|
6289
5803
|
beforeSubmitState,
|
|
6290
5804
|
afterSubmitState
|
|
6291
5805
|
}).catch((error) => {
|
|
6292
|
-
|
|
5806
|
+
logger10.warn(`\u63D0\u4EA4\u540E\u9A8C\u8BC1\u7801\u8C03\u8BD5\u6293\u53D6\u5931\u8D25\uFF1A${error?.message || error}`);
|
|
6293
5807
|
});
|
|
6294
|
-
|
|
5808
|
+
logger10.warn("\u63D0\u4EA4\u540E\u9A8C\u8BC1\u7801 iframe \u4ECD\u7136\u53EF\u89C1\uFF0C\u51C6\u5907\u5237\u65B0\u540E\u91CD\u8BD5\u3002");
|
|
6295
5809
|
await page.waitForTimeout(2e3);
|
|
6296
5810
|
await refreshCaptcha(page, frame, config);
|
|
6297
5811
|
} catch (error) {
|
|
6298
|
-
|
|
5812
|
+
logger10.error(`\u7B2C ${attempt}/${config.maxRetries} \u6B21\u9A8C\u8BC1\u7801\u8BC6\u522B\u5931\u8D25\uFF1A${error?.message || error}`);
|
|
6299
5813
|
}
|
|
6300
5814
|
if (attempt < config.maxRetries) {
|
|
6301
5815
|
await page.waitForTimeout(config.retryDelayBaseMs + attempt * config.retryDelayStepMs);
|
|
6302
5816
|
}
|
|
6303
5817
|
}
|
|
6304
|
-
|
|
5818
|
+
logger10.error(`\u91CD\u8BD5 ${config.maxRetries} \u6B21\u540E\uFF0C\u9A8C\u8BC1\u7801\u4ECD\u672A\u8BC6\u522B\u6210\u529F\u3002`);
|
|
6305
5819
|
return false;
|
|
6306
5820
|
}
|
|
6307
5821
|
var sloveCaptcha = solveCaptcha;
|
|
6308
5822
|
|
|
6309
5823
|
// src/chaptcha.js
|
|
6310
|
-
var
|
|
6311
|
-
var DOM_MONITOR_WAIT_TIMEOUT_MS = 1e3;
|
|
6312
|
-
var DOM_MONITOR_POST_DETECT_HIDDEN_WAIT_MS = 300;
|
|
6313
|
-
var DOM_MONITOR_RECOVERY_WAIT_MS = 100;
|
|
5824
|
+
var logger11 = createInternalLogger("Captcha");
|
|
6314
5825
|
var DEFAULT_CAPTCHA_RECOGNITION_OPTIONS = Object.freeze({
|
|
6315
5826
|
token: "eKJvBfwfN0YRav0-VD_44E2VBSfm7l0YtddUQ7cFySI",
|
|
6316
5827
|
apiUrl: "https://api.jfbym.com/api/YmServer/customApi"
|
|
@@ -6331,15 +5842,6 @@ var mergeDefinedOptions = (...sources) => {
|
|
|
6331
5842
|
}
|
|
6332
5843
|
return merged;
|
|
6333
5844
|
};
|
|
6334
|
-
var sleep = (ms) => new Promise((resolve) => {
|
|
6335
|
-
setTimeout(resolve, ms);
|
|
6336
|
-
});
|
|
6337
|
-
var getErrorMessage = (error) => String(error?.message || error || "");
|
|
6338
|
-
var isTimeoutError = (error) => error?.name === "TimeoutError" || getErrorMessage(error).includes("Timeout");
|
|
6339
|
-
var isPageLifecycleError = (error) => {
|
|
6340
|
-
const message = getErrorMessage(error);
|
|
6341
|
-
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");
|
|
6342
|
-
};
|
|
6343
5845
|
function useCaptchaMonitor(page, options) {
|
|
6344
5846
|
const { domSelector, urlPattern, onDetected } = options;
|
|
6345
5847
|
if (!domSelector && !urlPattern) {
|
|
@@ -6351,13 +5853,10 @@ function useCaptchaMonitor(page, options) {
|
|
|
6351
5853
|
let isStopped = false;
|
|
6352
5854
|
let isHandling = false;
|
|
6353
5855
|
let frameHandler = null;
|
|
6354
|
-
let
|
|
6355
|
-
let lastTriggeredAt = 0;
|
|
5856
|
+
let exposedFunctionName = null;
|
|
6356
5857
|
const triggerDetected = async () => {
|
|
6357
|
-
|
|
6358
|
-
if (isStopped || isHandling || now - lastTriggeredAt < 250) return;
|
|
5858
|
+
if (isStopped || isHandling) return;
|
|
6359
5859
|
isHandling = true;
|
|
6360
|
-
lastTriggeredAt = now;
|
|
6361
5860
|
try {
|
|
6362
5861
|
await onDetected();
|
|
6363
5862
|
} finally {
|
|
@@ -6366,38 +5865,60 @@ function useCaptchaMonitor(page, options) {
|
|
|
6366
5865
|
};
|
|
6367
5866
|
const cleanupFns = [];
|
|
6368
5867
|
if (domSelector) {
|
|
6369
|
-
|
|
6370
|
-
|
|
6371
|
-
|
|
6372
|
-
|
|
6373
|
-
|
|
6374
|
-
|
|
6375
|
-
|
|
6376
|
-
|
|
6377
|
-
|
|
6378
|
-
|
|
6379
|
-
|
|
6380
|
-
}).catch(() => {
|
|
6381
|
-
});
|
|
6382
|
-
} catch (error) {
|
|
6383
|
-
if (isStopped) break;
|
|
6384
|
-
if (page?.isClosed?.() && isPageLifecycleError(error)) break;
|
|
6385
|
-
if (isTimeoutError(error) || isPageLifecycleError(error)) {
|
|
6386
|
-
await sleep(DOM_MONITOR_RECOVERY_WAIT_MS);
|
|
6387
|
-
continue;
|
|
5868
|
+
exposedFunctionName = `__c_d_${(0, import_uuid.v4)().replace(/-/g, "_")}`;
|
|
5869
|
+
const cleanerName = `__c_cleaner_${(0, import_uuid.v4)().replace(/-/g, "_")}`;
|
|
5870
|
+
page.exposeFunction(exposedFunctionName, triggerDetected).catch(() => {
|
|
5871
|
+
});
|
|
5872
|
+
page.addInitScript(({ selector, callbackName, cleanerName: cleanupName }) => {
|
|
5873
|
+
(() => {
|
|
5874
|
+
let observer = null;
|
|
5875
|
+
const checkAndReport = () => {
|
|
5876
|
+
const element = document.querySelector(selector);
|
|
5877
|
+
if (!element) {
|
|
5878
|
+
return false;
|
|
6388
5879
|
}
|
|
6389
|
-
|
|
6390
|
-
|
|
6391
|
-
|
|
6392
|
-
|
|
6393
|
-
|
|
5880
|
+
if (window[callbackName]) {
|
|
5881
|
+
window[callbackName]();
|
|
5882
|
+
}
|
|
5883
|
+
return true;
|
|
5884
|
+
};
|
|
5885
|
+
checkAndReport();
|
|
5886
|
+
observer = new MutationObserver((mutations) => {
|
|
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 });
|
|
5896
|
+
}
|
|
5897
|
+
};
|
|
5898
|
+
if (document.readyState === "loading") {
|
|
5899
|
+
window.addEventListener("DOMContentLoaded", mountObserver);
|
|
5900
|
+
} else {
|
|
5901
|
+
mountObserver();
|
|
6394
5902
|
}
|
|
6395
|
-
|
|
6396
|
-
|
|
6397
|
-
|
|
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}`);
|
|
6398
5912
|
cleanupFns.push(async () => {
|
|
6399
|
-
|
|
6400
|
-
|
|
5913
|
+
try {
|
|
5914
|
+
await page.evaluate((name) => {
|
|
5915
|
+
if (window[name]) {
|
|
5916
|
+
window[name]();
|
|
5917
|
+
delete window[name];
|
|
5918
|
+
}
|
|
5919
|
+
}, cleanerName);
|
|
5920
|
+
} catch {
|
|
5921
|
+
}
|
|
6401
5922
|
});
|
|
6402
5923
|
}
|
|
6403
5924
|
if (urlPattern) {
|
|
@@ -6411,24 +5932,18 @@ function useCaptchaMonitor(page, options) {
|
|
|
6411
5932
|
}
|
|
6412
5933
|
};
|
|
6413
5934
|
page.on("framenavigated", frameHandler);
|
|
6414
|
-
|
|
6415
|
-
Promise.resolve().then(async () => {
|
|
6416
|
-
if (!isStopped && page.url().includes(urlPattern)) {
|
|
6417
|
-
await triggerDetected();
|
|
6418
|
-
}
|
|
6419
|
-
}).catch(() => {
|
|
6420
|
-
});
|
|
5935
|
+
logger11.success("useCaptchaMonitor", `URL \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${urlPattern}`);
|
|
6421
5936
|
cleanupFns.push(async () => {
|
|
6422
5937
|
page.off("framenavigated", frameHandler);
|
|
6423
5938
|
});
|
|
6424
5939
|
}
|
|
6425
5940
|
return {
|
|
6426
5941
|
stop: async () => {
|
|
6427
|
-
|
|
6428
|
-
isStopped = true;
|
|
5942
|
+
logger11.info("\u6B63\u5728\u505C\u6B62\u9A8C\u8BC1\u7801\u76D1\u63A7...");
|
|
6429
5943
|
for (const fn of cleanupFns) {
|
|
6430
5944
|
await fn();
|
|
6431
5945
|
}
|
|
5946
|
+
isStopped = true;
|
|
6432
5947
|
}
|
|
6433
5948
|
};
|
|
6434
5949
|
}
|
|
@@ -6463,7 +5978,7 @@ async function solveCaptchaWithStrategy(strategyName, page, options = {}) {
|
|
|
6463
5978
|
);
|
|
6464
5979
|
return strategy.sloveCaptcha(page, resolvedOptions, {
|
|
6465
5980
|
callCaptchaRecognitionApi,
|
|
6466
|
-
logger:
|
|
5981
|
+
logger: logger11
|
|
6467
5982
|
});
|
|
6468
5983
|
}
|
|
6469
5984
|
var Captcha = {
|
|
@@ -6473,15 +5988,15 @@ var Captcha = {
|
|
|
6473
5988
|
|
|
6474
5989
|
// src/mutation.js
|
|
6475
5990
|
var import_node_crypto = require("node:crypto");
|
|
6476
|
-
var
|
|
6477
|
-
var
|
|
5991
|
+
var import_uuid2 = require("uuid");
|
|
5992
|
+
var logger12 = createInternalLogger("Mutation");
|
|
6478
5993
|
var MUTATION_MONITOR_MODE = Object.freeze({
|
|
6479
5994
|
Added: "added",
|
|
6480
5995
|
Changed: "changed",
|
|
6481
5996
|
All: "all"
|
|
6482
5997
|
});
|
|
6483
5998
|
function generateKey(prefix) {
|
|
6484
|
-
return `__${prefix}_${(0,
|
|
5999
|
+
return `__${prefix}_${(0, import_uuid2.v4)().replace(/-/g, "_")}`;
|
|
6485
6000
|
}
|
|
6486
6001
|
var Mutation = {
|
|
6487
6002
|
Mode: MUTATION_MONITOR_MODE,
|
|
@@ -6507,14 +6022,14 @@ var Mutation = {
|
|
|
6507
6022
|
const stableTime = options.stableTime ?? 5 * 1e3;
|
|
6508
6023
|
const timeout = options.timeout ?? 120 * 1e3;
|
|
6509
6024
|
const onMutation = options.onMutation;
|
|
6510
|
-
|
|
6025
|
+
logger12.start("waitForStable", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, \u7A33\u5B9A\u65F6\u95F4=${stableTime}ms`);
|
|
6511
6026
|
if (initialTimeout > 0) {
|
|
6512
6027
|
const selectorQuery = selectorList.join(",");
|
|
6513
6028
|
try {
|
|
6514
6029
|
await page.waitForSelector(selectorQuery, { timeout: initialTimeout });
|
|
6515
|
-
|
|
6030
|
+
logger12.info(`waitForStable \u5DF2\u68C0\u6D4B\u5230\u5143\u7D20: ${selectorQuery}`);
|
|
6516
6031
|
} catch (e) {
|
|
6517
|
-
|
|
6032
|
+
logger12.warning(`waitForStable \u521D\u59CB\u7B49\u5F85\u8D85\u65F6 (${initialTimeout}ms): ${selectorQuery}`);
|
|
6518
6033
|
throw e;
|
|
6519
6034
|
}
|
|
6520
6035
|
}
|
|
@@ -6530,7 +6045,7 @@ var Mutation = {
|
|
|
6530
6045
|
return "__CONTINUE__";
|
|
6531
6046
|
}
|
|
6532
6047
|
});
|
|
6533
|
-
|
|
6048
|
+
logger12.info("waitForStable \u5DF2\u542F\u7528 onMutation \u56DE\u8C03");
|
|
6534
6049
|
} catch (e) {
|
|
6535
6050
|
}
|
|
6536
6051
|
}
|
|
@@ -6645,9 +6160,9 @@ var Mutation = {
|
|
|
6645
6160
|
{ selectorList, stableTime, timeout, callbackName, hasCallback: !!onMutation }
|
|
6646
6161
|
);
|
|
6647
6162
|
if (result.mutationCount === 0 && result.stableTime === 0) {
|
|
6648
|
-
|
|
6163
|
+
logger12.warning("waitForStable \u672A\u627E\u5230\u53EF\u76D1\u63A7\u7684\u5143\u7D20");
|
|
6649
6164
|
}
|
|
6650
|
-
|
|
6165
|
+
logger12.success("waitForStable", `DOM \u7A33\u5B9A, \u603B\u5171 ${result.mutationCount} \u6B21\u53D8\u5316${result.wasPaused ? ", \u66FE\u6682\u505C\u8BA1\u65F6" : ""}`);
|
|
6651
6166
|
return result;
|
|
6652
6167
|
},
|
|
6653
6168
|
/**
|
|
@@ -6671,7 +6186,7 @@ var Mutation = {
|
|
|
6671
6186
|
const overallTimeout = options.timeout ?? 180 * 1e3;
|
|
6672
6187
|
const onMutation = options.onMutation;
|
|
6673
6188
|
const pollInterval = 500;
|
|
6674
|
-
const
|
|
6189
|
+
const sleep = (ms) => new Promise((resolve) => {
|
|
6675
6190
|
setTimeout(resolve, ms);
|
|
6676
6191
|
});
|
|
6677
6192
|
const truncate = (value, max = 800) => {
|
|
@@ -6819,29 +6334,29 @@ var Mutation = {
|
|
|
6819
6334
|
return "__CONTINUE__";
|
|
6820
6335
|
}
|
|
6821
6336
|
};
|
|
6822
|
-
|
|
6337
|
+
logger12.start(
|
|
6823
6338
|
"waitForStableAcrossRoots",
|
|
6824
6339
|
`\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668(\u8DE8 root), \u7A33\u5B9A\u65F6\u95F4=${waitForStableTime}ms`
|
|
6825
6340
|
);
|
|
6826
6341
|
if (initialTimeout > 0) {
|
|
6827
6342
|
try {
|
|
6828
6343
|
await page.waitForSelector(selectorQuery, { timeout: initialTimeout });
|
|
6829
|
-
|
|
6344
|
+
logger12.info(`waitForStableAcrossRoots \u5DF2\u68C0\u6D4B\u5230\u5143\u7D20: ${selectorQuery}`);
|
|
6830
6345
|
} catch (e) {
|
|
6831
|
-
|
|
6346
|
+
logger12.warning(`waitForStableAcrossRoots \u521D\u59CB\u7B49\u5F85\u8D85\u65F6 (${initialTimeout}ms): ${selectorQuery}`);
|
|
6832
6347
|
throw e;
|
|
6833
6348
|
}
|
|
6834
6349
|
}
|
|
6835
|
-
let
|
|
6836
|
-
if (!
|
|
6837
|
-
|
|
6350
|
+
let state = await buildState();
|
|
6351
|
+
if (!state?.hasMatched) {
|
|
6352
|
+
logger12.warning("waitForStableAcrossRoots \u672A\u627E\u5230\u53EF\u76D1\u63A7\u7684\u5143\u7D20");
|
|
6838
6353
|
return { mutationCount: 0, stableTime: 0, wasPaused: false };
|
|
6839
6354
|
}
|
|
6840
6355
|
let mutationCount = 0;
|
|
6841
6356
|
let stableSince = 0;
|
|
6842
6357
|
let isPaused = false;
|
|
6843
6358
|
let wasPaused = false;
|
|
6844
|
-
let lastSnapshotKey =
|
|
6359
|
+
let lastSnapshotKey = state.snapshotKey;
|
|
6845
6360
|
const applyPauseSignal = (signal) => {
|
|
6846
6361
|
const nextPaused = signal === "__PAUSE__";
|
|
6847
6362
|
if (nextPaused) {
|
|
@@ -6855,15 +6370,15 @@ var Mutation = {
|
|
|
6855
6370
|
};
|
|
6856
6371
|
const initialSignal = await invokeMutationCallback({
|
|
6857
6372
|
mutationCount: 0,
|
|
6858
|
-
html:
|
|
6859
|
-
text:
|
|
6860
|
-
mutationNodes:
|
|
6373
|
+
html: state.html || "",
|
|
6374
|
+
text: state.text || "",
|
|
6375
|
+
mutationNodes: state.mutationNodes || []
|
|
6861
6376
|
});
|
|
6862
6377
|
applyPauseSignal(initialSignal);
|
|
6863
6378
|
const deadline = Date.now() + overallTimeout;
|
|
6864
|
-
let lastState =
|
|
6379
|
+
let lastState = state;
|
|
6865
6380
|
while (Date.now() < deadline) {
|
|
6866
|
-
await
|
|
6381
|
+
await sleep(pollInterval);
|
|
6867
6382
|
lastState = await buildState();
|
|
6868
6383
|
if (!lastState?.hasMatched) {
|
|
6869
6384
|
continue;
|
|
@@ -6871,7 +6386,7 @@ var Mutation = {
|
|
|
6871
6386
|
if (lastState.snapshotKey !== lastSnapshotKey) {
|
|
6872
6387
|
lastSnapshotKey = lastState.snapshotKey;
|
|
6873
6388
|
mutationCount += 1;
|
|
6874
|
-
|
|
6389
|
+
logger12.info(
|
|
6875
6390
|
`waitForStableAcrossRoots \u53D8\u5316#${mutationCount}, len=${lastState.snapshotLength}, path=${lastState.primaryPath || "unknown"}, preview="${truncate(lastState.text, 120)}"`
|
|
6876
6391
|
);
|
|
6877
6392
|
const signal = await invokeMutationCallback({
|
|
@@ -6884,7 +6399,7 @@ var Mutation = {
|
|
|
6884
6399
|
continue;
|
|
6885
6400
|
}
|
|
6886
6401
|
if (!isPaused && stableSince > 0 && Date.now() - stableSince >= waitForStableTime) {
|
|
6887
|
-
|
|
6402
|
+
logger12.success("waitForStableAcrossRoots", `DOM \u7A33\u5B9A, \u603B\u5171 ${mutationCount} \u6B21\u53D8\u5316${wasPaused ? ", \u66FE\u6682\u505C\u8BA1\u65F6" : ""}`);
|
|
6888
6403
|
return {
|
|
6889
6404
|
mutationCount,
|
|
6890
6405
|
stableTime: waitForStableTime,
|
|
@@ -6911,7 +6426,7 @@ var Mutation = {
|
|
|
6911
6426
|
const onMutation = options.onMutation;
|
|
6912
6427
|
const rawMode = String(options.mode || MUTATION_MONITOR_MODE.Added).toLowerCase();
|
|
6913
6428
|
const mode = [MUTATION_MONITOR_MODE.Added, MUTATION_MONITOR_MODE.Changed, MUTATION_MONITOR_MODE.All].includes(rawMode) ? rawMode : MUTATION_MONITOR_MODE.Added;
|
|
6914
|
-
|
|
6429
|
+
logger12.start("useMonitor", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, mode=${mode}`);
|
|
6915
6430
|
const monitorKey = generateKey("pk_mon");
|
|
6916
6431
|
const callbackName = generateKey("pk_mon_cb");
|
|
6917
6432
|
const cleanerName = generateKey("pk_mon_clean");
|
|
@@ -7054,7 +6569,7 @@ var Mutation = {
|
|
|
7054
6569
|
return total;
|
|
7055
6570
|
};
|
|
7056
6571
|
}, { selectorList, monitorKey, callbackName, cleanerName, hasCallback: !!onMutation, mode });
|
|
7057
|
-
|
|
6572
|
+
logger12.success("useMonitor", "\u76D1\u63A7\u5668\u5DF2\u542F\u52A8");
|
|
7058
6573
|
return {
|
|
7059
6574
|
stop: async () => {
|
|
7060
6575
|
let totalMutations = 0;
|
|
@@ -7067,7 +6582,7 @@ var Mutation = {
|
|
|
7067
6582
|
}, cleanerName);
|
|
7068
6583
|
} catch (e) {
|
|
7069
6584
|
}
|
|
7070
|
-
|
|
6585
|
+
logger12.success("useMonitor.stop", `\u76D1\u63A7\u5DF2\u505C\u6B62, \u5171 ${totalMutations} \u6B21\u53D8\u5316`);
|
|
7071
6586
|
return { totalMutations };
|
|
7072
6587
|
}
|
|
7073
6588
|
};
|
|
@@ -7936,7 +7451,7 @@ var createTemplateLogger = (baseLogger = createBaseLogger()) => {
|
|
|
7936
7451
|
};
|
|
7937
7452
|
var getDefaultBaseLogger = () => createBaseLogger("");
|
|
7938
7453
|
var Logger = {
|
|
7939
|
-
setLogger: (
|
|
7454
|
+
setLogger: (logger16) => setDefaultLogger(logger16),
|
|
7940
7455
|
info: (message) => getDefaultBaseLogger().info(message),
|
|
7941
7456
|
success: (message) => getDefaultBaseLogger().success(message),
|
|
7942
7457
|
warning: (message) => getDefaultBaseLogger().warning(message),
|
|
@@ -7944,14 +7459,14 @@ var Logger = {
|
|
|
7944
7459
|
error: (message) => getDefaultBaseLogger().error(message),
|
|
7945
7460
|
debug: (message) => getDefaultBaseLogger().debug(message),
|
|
7946
7461
|
start: (message) => getDefaultBaseLogger().start(message),
|
|
7947
|
-
useTemplate: (
|
|
7948
|
-
if (
|
|
7462
|
+
useTemplate: (logger16) => {
|
|
7463
|
+
if (logger16) return createTemplateLogger(createBaseLogger("", logger16));
|
|
7949
7464
|
return createTemplateLogger();
|
|
7950
7465
|
}
|
|
7951
7466
|
};
|
|
7952
7467
|
|
|
7953
7468
|
// src/share.js
|
|
7954
|
-
var
|
|
7469
|
+
var import_delay4 = __toESM(require("delay"), 1);
|
|
7955
7470
|
|
|
7956
7471
|
// src/internals/watermarkify.js
|
|
7957
7472
|
var DEFAULT_TIMEZONE_OFFSET = 8;
|
|
@@ -8019,7 +7534,7 @@ var LOCATION_NETWORK_SUFFIX_PATTERNS = [
|
|
|
8019
7534
|
];
|
|
8020
7535
|
var cachedStripLogoSrcPromise = null;
|
|
8021
7536
|
var cachedEnrichmentByContext = /* @__PURE__ */ new WeakMap();
|
|
8022
|
-
var
|
|
7537
|
+
var logger13 = createInternalLogger("Watermarkify");
|
|
8023
7538
|
var normalizeText = (value) => String(value || "").trim();
|
|
8024
7539
|
var toInline = (value, maxLen = 200) => {
|
|
8025
7540
|
const text = normalizeText(value);
|
|
@@ -8261,9 +7776,9 @@ var resolveWithCustomResolver = async (page, baseMeta, options = {}) => {
|
|
|
8261
7776
|
location: toInline(resolved.location, 80)
|
|
8262
7777
|
};
|
|
8263
7778
|
if (enrichment.ip || enrichment.location) {
|
|
8264
|
-
|
|
7779
|
+
logger13.info(`\u81EA\u5B9A\u4E49 resolver \u547D\u4E2D: ip=${enrichment.ip || "-"}, loc=${enrichment.location || "-"}`);
|
|
8265
7780
|
} else {
|
|
8266
|
-
|
|
7781
|
+
logger13.warning("\u81EA\u5B9A\u4E49 resolver \u5DF2\u6267\u884C\uFF0C\u4F46\u672A\u8FD4\u56DE IP/Loc");
|
|
8267
7782
|
}
|
|
8268
7783
|
return enrichment;
|
|
8269
7784
|
} finally {
|
|
@@ -8447,17 +7962,14 @@ var buildWatermarkifyRenderHtml = ({ imageSrc, overlaySvg, width, height, imageH
|
|
|
8447
7962
|
</html>
|
|
8448
7963
|
`;
|
|
8449
7964
|
};
|
|
8450
|
-
var
|
|
8451
|
-
return String(value || "default").trim().toLowerCase() === "cloak" ? "cloak" : "default";
|
|
8452
|
-
};
|
|
8453
|
-
var composeScreenshotBufferWithBrowser = async (page, buffer, overlaySvg, imageInfo = {}, options = {}) => {
|
|
7965
|
+
var composeScreenshotBufferWithBrowser = async (page, buffer, overlaySvg, imageInfo = {}) => {
|
|
8454
7966
|
if (!page || typeof page.context !== "function") {
|
|
8455
|
-
|
|
7967
|
+
logger13.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u8DF3\u8FC7: \u7F3A\u5C11\u53EF\u7528 page");
|
|
8456
7968
|
return buffer;
|
|
8457
7969
|
}
|
|
8458
7970
|
const renderScope = await openProbePage(page);
|
|
8459
7971
|
if (!renderScope?.page) {
|
|
8460
|
-
|
|
7972
|
+
logger13.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u8DF3\u8FC7: \u65E0\u6CD5\u521B\u5EFA render page");
|
|
8461
7973
|
return buffer;
|
|
8462
7974
|
}
|
|
8463
7975
|
try {
|
|
@@ -8474,35 +7986,15 @@ var composeScreenshotBufferWithBrowser = async (page, buffer, overlaySvg, imageI
|
|
|
8474
7986
|
height: viewportHeight
|
|
8475
7987
|
}).catch(() => {
|
|
8476
7988
|
});
|
|
8477
|
-
|
|
8478
|
-
|
|
8479
|
-
|
|
8480
|
-
|
|
8481
|
-
|
|
8482
|
-
|
|
8483
|
-
|
|
8484
|
-
|
|
8485
|
-
|
|
8486
|
-
await renderPage.goto("about:blank", {
|
|
8487
|
-
waitUntil: "commit"
|
|
8488
|
-
}).catch(() => {
|
|
8489
|
-
});
|
|
8490
|
-
await renderPage.evaluate((html) => {
|
|
8491
|
-
document.open();
|
|
8492
|
-
document.write(html);
|
|
8493
|
-
document.close();
|
|
8494
|
-
}, renderHtml);
|
|
8495
|
-
} else {
|
|
8496
|
-
await renderPage.setContent(buildWatermarkifyRenderHtml({
|
|
8497
|
-
imageSrc: `data:${imageInfo.mimeType || "image/png"};base64,${buffer.toString("base64")}`,
|
|
8498
|
-
overlaySvg,
|
|
8499
|
-
width: safeWidth,
|
|
8500
|
-
height: safeHeight,
|
|
8501
|
-
imageHeight: safeImageHeight
|
|
8502
|
-
}), {
|
|
8503
|
-
waitUntil: "load"
|
|
8504
|
-
});
|
|
8505
|
-
}
|
|
7989
|
+
await renderPage.setContent(buildWatermarkifyRenderHtml({
|
|
7990
|
+
imageSrc: `data:${imageInfo.mimeType || "image/png"};base64,${buffer.toString("base64")}`,
|
|
7991
|
+
overlaySvg,
|
|
7992
|
+
width: safeWidth,
|
|
7993
|
+
height: safeHeight,
|
|
7994
|
+
imageHeight: safeImageHeight
|
|
7995
|
+
}), {
|
|
7996
|
+
waitUntil: "load"
|
|
7997
|
+
});
|
|
8506
7998
|
await renderPage.waitForFunction(() => {
|
|
8507
7999
|
const image = document.getElementById("pk-base-image");
|
|
8508
8000
|
return image instanceof HTMLImageElement && image.complete && image.naturalWidth > 0 && image.naturalHeight > 0;
|
|
@@ -8522,13 +8014,13 @@ var composeScreenshotBufferWithBrowser = async (page, buffer, overlaySvg, imageI
|
|
|
8522
8014
|
fullPage: true,
|
|
8523
8015
|
animations: "disabled"
|
|
8524
8016
|
}).catch((error) => {
|
|
8525
|
-
|
|
8017
|
+
logger13.warning(`watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
|
|
8526
8018
|
return null;
|
|
8527
8019
|
});
|
|
8528
8020
|
if (Buffer.isBuffer(composed) && composed.length > 0) {
|
|
8529
8021
|
return composed;
|
|
8530
8022
|
}
|
|
8531
|
-
|
|
8023
|
+
logger13.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u5931\u8D25: \u672A\u5F97\u5230\u6709\u6548\u622A\u56FE\u7ED3\u679C");
|
|
8532
8024
|
return buffer;
|
|
8533
8025
|
} finally {
|
|
8534
8026
|
await renderScope.close().catch(() => {
|
|
@@ -8541,7 +8033,7 @@ var resolveWithIpLookup = async (page, options = {}) => {
|
|
|
8541
8033
|
}
|
|
8542
8034
|
const probeScope = await openProbePage(page);
|
|
8543
8035
|
if (!probeScope?.page) {
|
|
8544
|
-
|
|
8036
|
+
logger13.warning("ipLookup \u8DF3\u8FC7: \u65E0\u6CD5\u521B\u5EFA probe page");
|
|
8545
8037
|
return null;
|
|
8546
8038
|
}
|
|
8547
8039
|
const timeoutMs = Math.max(
|
|
@@ -8550,12 +8042,12 @@ var resolveWithIpLookup = async (page, options = {}) => {
|
|
|
8550
8042
|
);
|
|
8551
8043
|
try {
|
|
8552
8044
|
const probePage = probeScope.page;
|
|
8553
|
-
|
|
8045
|
+
logger13.info(`ipLookup \u5C1D\u8BD5: url=${DEFAULT_IP_LOOKUP_URL}, timeoutMs=${timeoutMs}`);
|
|
8554
8046
|
const response = await probePage.goto(DEFAULT_IP_LOOKUP_URL, {
|
|
8555
8047
|
waitUntil: "commit",
|
|
8556
8048
|
timeout: timeoutMs
|
|
8557
8049
|
}).catch((error) => {
|
|
8558
|
-
|
|
8050
|
+
logger13.warning(`ipLookup \u8BF7\u6C42\u5931\u8D25: url=${DEFAULT_IP_LOOKUP_URL}, error=${error instanceof Error ? error.message : String(error)}`);
|
|
8559
8051
|
return null;
|
|
8560
8052
|
});
|
|
8561
8053
|
const status = response && typeof response.status === "function" ? response.status() : 0;
|
|
@@ -8577,13 +8069,13 @@ var resolveWithIpLookup = async (page, options = {}) => {
|
|
|
8577
8069
|
}
|
|
8578
8070
|
const parsed = parseIpIpJsonResponse(rawText);
|
|
8579
8071
|
if (parsed?.ip || parsed?.location) {
|
|
8580
|
-
|
|
8072
|
+
logger13.info(`ipLookup \u6210\u529F: url=${DEFAULT_IP_LOOKUP_URL}, status=${status || "-"}, contentType=${contentType || "-"}, ip=${parsed.ip || "-"}, loc=${parsed.location || "-"}`);
|
|
8581
8073
|
return parsed;
|
|
8582
8074
|
}
|
|
8583
|
-
|
|
8075
|
+
logger13.warning(`ipLookup \u672A\u89E3\u6790\u51FA IP/Loc: url=${DEFAULT_IP_LOOKUP_URL}, status=${status || "-"}, contentType=${contentType || "-"}, preview=${shortenTail(rawText, 120) || "[empty]"}`);
|
|
8584
8076
|
return null;
|
|
8585
8077
|
} catch (error) {
|
|
8586
|
-
|
|
8078
|
+
logger13.warning(`ipLookup \u6267\u884C\u5F02\u5E38\uFF0C\u672A\u83B7\u5F97 IP/Loc: ${error instanceof Error ? error.message : String(error)}`);
|
|
8587
8079
|
return null;
|
|
8588
8080
|
} finally {
|
|
8589
8081
|
await probeScope.close().catch(() => {
|
|
@@ -8597,10 +8089,10 @@ var resolveEnrichment = async (page, baseMeta, options) => {
|
|
|
8597
8089
|
ip: toInline(options.ip, 80),
|
|
8598
8090
|
location: toInline(options.location, 80)
|
|
8599
8091
|
};
|
|
8600
|
-
|
|
8092
|
+
logger13.info(`enrichment \u5F00\u59CB: host=${baseMeta.hostname || "-"}, hasPresetIp=${Boolean(merged.ip)}, hasPresetLoc=${Boolean(merged.location)}, ipLookup=${options.ipLookup !== false}`);
|
|
8601
8093
|
if (!merged.ip || !merged.location) {
|
|
8602
8094
|
if (cached?.ip || cached?.location) {
|
|
8603
|
-
|
|
8095
|
+
logger13.info(`enrichment \u547D\u4E2D\u4E0A\u4E0B\u6587\u7F13\u5B58: ip=${cached.ip || "-"}, loc=${cached.location || "-"}`);
|
|
8604
8096
|
}
|
|
8605
8097
|
fillEnrichment(merged, cached);
|
|
8606
8098
|
}
|
|
@@ -8624,15 +8116,15 @@ var resolveEnrichment = async (page, baseMeta, options) => {
|
|
|
8624
8116
|
"x-geo-country"
|
|
8625
8117
|
]), 80);
|
|
8626
8118
|
if (!merged.location || isWeakLocationValue(merged.location) && headerLocation) {
|
|
8627
|
-
|
|
8119
|
+
logger13.info(`enrichment \u4F7F\u7528\u54CD\u5E94\u5934\u8865\u5145 Loc: ${headerLocation || "-"}`);
|
|
8628
8120
|
merged.location = headerLocation || merged.location;
|
|
8629
8121
|
}
|
|
8630
8122
|
}
|
|
8631
8123
|
writeCachedEnrichment(page, merged);
|
|
8632
8124
|
if (merged.ip || merged.location) {
|
|
8633
|
-
|
|
8125
|
+
logger13.info(`enrichment \u5B8C\u6210: ip=${merged.ip || "-"}, loc=${merged.location || "-"}`);
|
|
8634
8126
|
} else {
|
|
8635
|
-
|
|
8127
|
+
logger13.warning("enrichment \u5B8C\u6210: \u672A\u83B7\u5F97 IP/Loc");
|
|
8636
8128
|
}
|
|
8637
8129
|
return merged;
|
|
8638
8130
|
};
|
|
@@ -9437,7 +8929,7 @@ var buildWatermarkifySvg = (meta, imageWidth, imageHeight) => {
|
|
|
9437
8929
|
</svg>
|
|
9438
8930
|
`;
|
|
9439
8931
|
};
|
|
9440
|
-
var watermarkifyScreenshotBuffer = async (buffer, meta, page = null
|
|
8932
|
+
var watermarkifyScreenshotBuffer = async (buffer, meta, page = null) => {
|
|
9441
8933
|
const hasWatermark = meta?.watermark?.enabled !== false && normalizeText(meta?.watermarkText);
|
|
9442
8934
|
const hasStrip = meta?.strip?.enabled !== false && Array.isArray(meta?.stripSegments) && meta.stripSegments.length > 0;
|
|
9443
8935
|
if (!Buffer.isBuffer(buffer) || !meta || !hasWatermark && !hasStrip) {
|
|
@@ -9445,7 +8937,7 @@ var watermarkifyScreenshotBuffer = async (buffer, meta, page = null, options = {
|
|
|
9445
8937
|
}
|
|
9446
8938
|
const imageInfo = readImageInfo(buffer);
|
|
9447
8939
|
if (!imageInfo.width || !imageInfo.height || !imageInfo.mimeType) {
|
|
9448
|
-
|
|
8940
|
+
logger13.warning("watermarkify \u8DF3\u8FC7: \u65E0\u6CD5\u89E3\u6790\u622A\u56FE\u5C3A\u5BF8\u6216\u683C\u5F0F");
|
|
9449
8941
|
return buffer;
|
|
9450
8942
|
}
|
|
9451
8943
|
const isMobileStrip = normalizeDevice(meta.device) === Device.Mobile && hasStrip;
|
|
@@ -9458,12 +8950,12 @@ var watermarkifyScreenshotBuffer = async (buffer, meta, page = null, options = {
|
|
|
9458
8950
|
if (!overlaySvg) {
|
|
9459
8951
|
return buffer;
|
|
9460
8952
|
}
|
|
9461
|
-
return await composeScreenshotBufferWithBrowser(page, buffer, overlaySvg, outputImageInfo
|
|
8953
|
+
return await composeScreenshotBufferWithBrowser(page, buffer, overlaySvg, outputImageInfo);
|
|
9462
8954
|
};
|
|
9463
8955
|
|
|
9464
8956
|
// src/internals/compression.js
|
|
9465
8957
|
var import_jimp = require("jimp");
|
|
9466
|
-
var
|
|
8958
|
+
var logger14 = createInternalLogger("Compression");
|
|
9467
8959
|
var DEFAULT_SCREENSHOT_MAX_BYTES = 5 * 1024 * 1024;
|
|
9468
8960
|
var DEFAULT_SCREENSHOT_OUTPUT_TYPE = "jpeg";
|
|
9469
8961
|
var DEFAULT_SCREENSHOT_QUALITY = 0.72;
|
|
@@ -9582,18 +9074,18 @@ var compressImageBufferToBase64 = async (buffer, compression) => {
|
|
|
9582
9074
|
return buffer.toString("base64");
|
|
9583
9075
|
}
|
|
9584
9076
|
const result = await compressImageBuffer(buffer, compression).catch((error) => {
|
|
9585
|
-
|
|
9077
|
+
logger14.warning(`captureScreen \u538B\u7F29\u5931\u8D25\uFF0C\u8FD4\u56DE\u539F\u56FE: ${error instanceof Error ? error.message : String(error)}`);
|
|
9586
9078
|
return null;
|
|
9587
9079
|
});
|
|
9588
9080
|
if (!result?.buffer) {
|
|
9589
9081
|
return buffer.toString("base64");
|
|
9590
9082
|
}
|
|
9591
9083
|
if (result.withinLimit) {
|
|
9592
|
-
|
|
9084
|
+
logger14.info(
|
|
9593
9085
|
`captureScreen \u5DF2\u538B\u7F29: ${originalBytes} -> ${result.bytes} bytes, format=${result.format}, quality=${result.quality}, scale=${result.scale}, size=${result.width}x${result.height}`
|
|
9594
9086
|
);
|
|
9595
9087
|
} else {
|
|
9596
|
-
|
|
9088
|
+
logger14.warning(
|
|
9597
9089
|
`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}`
|
|
9598
9090
|
);
|
|
9599
9091
|
}
|
|
@@ -9601,7 +9093,7 @@ var compressImageBufferToBase64 = async (buffer, compression) => {
|
|
|
9601
9093
|
};
|
|
9602
9094
|
|
|
9603
9095
|
// src/share.js
|
|
9604
|
-
var
|
|
9096
|
+
var logger15 = createInternalLogger("Share");
|
|
9605
9097
|
var DEFAULT_TIMEOUT_MS2 = 50 * 1e3;
|
|
9606
9098
|
var DEFAULT_PAYLOAD_SNAPSHOT_MAX_LEN = 500;
|
|
9607
9099
|
var DEFAULT_POLL_INTERVAL_MS = 120;
|
|
@@ -9738,7 +9230,7 @@ var createDomShareMonitor = async (page, options = {}) => {
|
|
|
9738
9230
|
const onMatch = typeof options.onMatch === "function" ? options.onMatch : null;
|
|
9739
9231
|
const onTelemetry = typeof options.onTelemetry === "function" ? options.onTelemetry : null;
|
|
9740
9232
|
let matched = false;
|
|
9741
|
-
|
|
9233
|
+
logger15.info(`DOM \u76D1\u542C\u51C6\u5907\u6302\u8F7D: selectors=${toJsonInline(selectors, 120)}, mode=${mode}`);
|
|
9742
9234
|
const monitor = await Mutation.useMonitor(page, selectors, {
|
|
9743
9235
|
mode,
|
|
9744
9236
|
onMutation: (context = {}) => {
|
|
@@ -9756,12 +9248,12 @@ ${text}`;
|
|
|
9756
9248
|
});
|
|
9757
9249
|
}
|
|
9758
9250
|
if (mutationCount <= 5 || mutationCount % 50 === 0) {
|
|
9759
|
-
|
|
9251
|
+
logger15.info(`DOM \u53D8\u5316\u5DF2\u6355\u83B7: mutationCount=${mutationCount}, mutationNodes=${mutationNodes.length}`);
|
|
9760
9252
|
}
|
|
9761
9253
|
const [candidate] = Utils.parseLinks(rawDom, { prefix }) || [];
|
|
9762
9254
|
if (!candidate) return;
|
|
9763
9255
|
matched = true;
|
|
9764
|
-
|
|
9256
|
+
logger15.success("captureLink.domHit", `DOM \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: mutationCount=${mutationCount}, link=${candidate}`);
|
|
9765
9257
|
if (onMatch) {
|
|
9766
9258
|
onMatch({
|
|
9767
9259
|
link: candidate,
|
|
@@ -9777,7 +9269,7 @@ ${text}`;
|
|
|
9777
9269
|
return {
|
|
9778
9270
|
stop: async () => {
|
|
9779
9271
|
const result = await monitor.stop();
|
|
9780
|
-
|
|
9272
|
+
logger15.info(`DOM \u76D1\u542C\u5DF2\u505C\u6B62: totalMutations=${result?.totalMutations || 0}`);
|
|
9781
9273
|
return result;
|
|
9782
9274
|
}
|
|
9783
9275
|
};
|
|
@@ -9826,8 +9318,8 @@ var Share = {
|
|
|
9826
9318
|
if (share.mode === "response" && apiMatchers.length === 0) {
|
|
9827
9319
|
throw new Error("Share.captureLink requires share.xurl[0] api matcher when mode=response");
|
|
9828
9320
|
}
|
|
9829
|
-
|
|
9830
|
-
|
|
9321
|
+
logger15.start("captureLink", `mode=${share.mode}, timeoutMs=${timeoutDisabled ? "disabled" : timeoutMs}, prefix=${share.prefix}`);
|
|
9322
|
+
logger15.info(`captureLink \u914D\u7F6E: xurl=${toJsonInline(share.xurl)}, domMode=${domMode}, domSelectors=${toJsonInline(domSelectors, 120)}`);
|
|
9831
9323
|
const stats = {
|
|
9832
9324
|
actionTimedOut: false,
|
|
9833
9325
|
domMutationCount: 0,
|
|
@@ -9839,7 +9331,7 @@ var Share = {
|
|
|
9839
9331
|
responseSampleUrls: []
|
|
9840
9332
|
};
|
|
9841
9333
|
if (isAborted()) {
|
|
9842
|
-
|
|
9334
|
+
logger15.warning(`captureLink \u5DF2\u53D6\u6D88: ${abortReason()}`);
|
|
9843
9335
|
return {
|
|
9844
9336
|
link: null,
|
|
9845
9337
|
payloadText: "",
|
|
@@ -9862,7 +9354,7 @@ var Share = {
|
|
|
9862
9354
|
link: validated,
|
|
9863
9355
|
payloadText: String(payloadText || "")
|
|
9864
9356
|
};
|
|
9865
|
-
|
|
9357
|
+
logger15.info(`\u5019\u9009\u94FE\u63A5\u5DF2\u786E\u8BA4: source=${source}, link=${validated}`);
|
|
9866
9358
|
return true;
|
|
9867
9359
|
};
|
|
9868
9360
|
const resolveResponseCandidate = (responseText) => {
|
|
@@ -9897,7 +9389,7 @@ var Share = {
|
|
|
9897
9389
|
try {
|
|
9898
9390
|
await monitor.stop();
|
|
9899
9391
|
} catch (error) {
|
|
9900
|
-
|
|
9392
|
+
logger15.warning(`\u505C\u6B62 DOM \u76D1\u542C\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
|
|
9901
9393
|
}
|
|
9902
9394
|
};
|
|
9903
9395
|
const onResponse = async (response) => {
|
|
@@ -9911,29 +9403,29 @@ var Share = {
|
|
|
9911
9403
|
stats.responseSampleUrls.push(url);
|
|
9912
9404
|
}
|
|
9913
9405
|
if (stats.responseObserved <= 5) {
|
|
9914
|
-
|
|
9406
|
+
logger15.info(`\u63A5\u53E3\u54CD\u5E94\u91C7\u6837(${stats.responseObserved}): ${url}`);
|
|
9915
9407
|
}
|
|
9916
9408
|
if (!apiMatchers.some((matcher) => url.includes(matcher))) return;
|
|
9917
9409
|
stats.responseMatched += 1;
|
|
9918
9410
|
stats.lastMatchedUrl = url;
|
|
9919
|
-
|
|
9411
|
+
logger15.info(`\u63A5\u53E3\u547D\u4E2D\u5339\u914D(${stats.responseMatched}): ${url}`);
|
|
9920
9412
|
const text = await response.text();
|
|
9921
9413
|
const hit = resolveResponseCandidate(text);
|
|
9922
9414
|
if (!hit?.link) {
|
|
9923
9415
|
if (stats.responseMatched <= 3) {
|
|
9924
|
-
|
|
9416
|
+
logger15.info(`\u63A5\u53E3\u89E3\u6790\u5B8C\u6210\u4F46\u672A\u63D0\u53D6\u5230\u5206\u4EAB\u94FE\u63A5: payloadSize=${text.length}`);
|
|
9925
9417
|
}
|
|
9926
9418
|
return;
|
|
9927
9419
|
}
|
|
9928
9420
|
stats.responseResolved += 1;
|
|
9929
|
-
|
|
9421
|
+
logger15.success("captureLink.responseHit", `\u63A5\u53E3\u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: url=${url}, link=${hit.link}`);
|
|
9930
9422
|
setCandidate("response", hit.link, hit.payloadText);
|
|
9931
9423
|
} catch (error) {
|
|
9932
|
-
|
|
9424
|
+
logger15.warning(`\u63A5\u53E3\u54CD\u5E94\u5904\u7406\u5F02\u5E38: ${error instanceof Error ? error.message : String(error)}`);
|
|
9933
9425
|
}
|
|
9934
9426
|
};
|
|
9935
9427
|
if (share.mode === "dom") {
|
|
9936
|
-
|
|
9428
|
+
logger15.info("\u5F53\u524D\u4E3A DOM \u6A21\u5F0F\uFF0C\u4EC5\u542F\u7528 DOM \u76D1\u542C");
|
|
9937
9429
|
domMonitor = await createDomShareMonitor(page, {
|
|
9938
9430
|
prefix: share.prefix,
|
|
9939
9431
|
selectors: domSelectors,
|
|
@@ -9948,17 +9440,17 @@ var Share = {
|
|
|
9948
9440
|
});
|
|
9949
9441
|
}
|
|
9950
9442
|
if (share.mode === "response") {
|
|
9951
|
-
|
|
9443
|
+
logger15.info(`\u5F53\u524D\u4E3A\u63A5\u53E3\u6A21\u5F0F\uFF0C\u6302\u8F7D response \u76D1\u542C: apiMatchers=${toJsonInline(apiMatchers, 160)}`);
|
|
9952
9444
|
page.on("response", onResponse);
|
|
9953
9445
|
}
|
|
9954
9446
|
if (share.mode === "custom") {
|
|
9955
|
-
|
|
9447
|
+
logger15.info("\u5F53\u524D\u4E3A custom \u6A21\u5F0F\uFF0C\u5C06\u4F7F\u7528 performActions \u8FD4\u56DE\u503C");
|
|
9956
9448
|
}
|
|
9957
9449
|
const deadline = timeoutDisabled ? Infinity : Date.now() + timeoutMs;
|
|
9958
9450
|
const getRemainingMs = () => timeoutDisabled ? Infinity : Math.max(0, deadline - Date.now());
|
|
9959
9451
|
try {
|
|
9960
9452
|
const actionTimeout = getRemainingMs();
|
|
9961
|
-
|
|
9453
|
+
logger15.start("captureLink.performActions", `\u6267\u884C\u52A8\u4F5C\u9884\u7B97=${timeoutDisabled ? "disabled" : `${actionTimeout}ms`}`);
|
|
9962
9454
|
let actionValue;
|
|
9963
9455
|
if (!isAborted() && actionTimeout > 0) {
|
|
9964
9456
|
let timer = null;
|
|
@@ -9971,30 +9463,30 @@ var Share = {
|
|
|
9971
9463
|
]);
|
|
9972
9464
|
if (timer) clearTimeout(timer);
|
|
9973
9465
|
if (actionResult.type === "error") {
|
|
9974
|
-
|
|
9466
|
+
logger15.fail("captureLink.performActions", actionResult.error);
|
|
9975
9467
|
throw actionResult.error;
|
|
9976
9468
|
}
|
|
9977
9469
|
if (actionResult.type === "timeout") {
|
|
9978
9470
|
stats.actionTimedOut = true;
|
|
9979
|
-
|
|
9471
|
+
logger15.warning(`performActions \u5DF2\u8D85\u65F6 (${actionTimeout}ms)\uFF0C\u52A8\u4F5C\u53EF\u80FD\u4ECD\u5728\u5F02\u6B65\u6267\u884C`);
|
|
9980
9472
|
} else {
|
|
9981
9473
|
actionValue = actionResult.result;
|
|
9982
|
-
|
|
9474
|
+
logger15.success("captureLink.performActions", "\u6267\u884C\u52A8\u4F5C\u5B8C\u6210");
|
|
9983
9475
|
}
|
|
9984
9476
|
}
|
|
9985
9477
|
if (share.mode === "custom") {
|
|
9986
9478
|
const customLink = typeof actionValue === "string" ? actionValue : actionValue?.link || actionValue?.payloadText;
|
|
9987
9479
|
const customPayloadText = typeof actionValue === "string" ? actionValue : actionValue?.payloadText;
|
|
9988
9480
|
if (setCandidate("custom", customLink, customPayloadText)) {
|
|
9989
|
-
|
|
9481
|
+
logger15.success("captureLink.customResult", `custom \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: link=${candidates.custom.link}`);
|
|
9990
9482
|
} else {
|
|
9991
|
-
|
|
9483
|
+
logger15.warning("performActions \u6267\u884C\u5B8C\u6210\u4F46\u672A\u8FD4\u56DE\u6709\u6548\u5206\u4EAB\u94FE\u63A5");
|
|
9992
9484
|
}
|
|
9993
9485
|
}
|
|
9994
9486
|
let nextProgressLogTs = Date.now() + 3e3;
|
|
9995
9487
|
while (true) {
|
|
9996
9488
|
if (isAborted()) {
|
|
9997
|
-
|
|
9489
|
+
logger15.warning(`captureLink \u5DF2\u53D6\u6D88: ${abortReason()}`);
|
|
9998
9490
|
return {
|
|
9999
9491
|
link: null,
|
|
10000
9492
|
payloadText: "",
|
|
@@ -10004,7 +9496,7 @@ var Share = {
|
|
|
10004
9496
|
}
|
|
10005
9497
|
const selected = candidates[share.mode];
|
|
10006
9498
|
if (selected?.link) {
|
|
10007
|
-
|
|
9499
|
+
logger15.success("captureLink", `\u6355\u83B7\u6210\u529F: source=${share.mode}, link=${selected.link}`);
|
|
10008
9500
|
return {
|
|
10009
9501
|
link: selected.link,
|
|
10010
9502
|
payloadText: selected.payloadText,
|
|
@@ -10017,19 +9509,19 @@ var Share = {
|
|
|
10017
9509
|
if (remaining <= 0) break;
|
|
10018
9510
|
const now = Date.now();
|
|
10019
9511
|
if (now >= nextProgressLogTs) {
|
|
10020
|
-
|
|
9512
|
+
logger15.info(
|
|
10021
9513
|
`captureLink \u7B49\u5F85\u4E2D: remaining=${timeoutDisabled ? "disabled" : `${remaining}ms`}, domMutationCount=${stats.domMutationCount}, responseMatched=${stats.responseMatched}`
|
|
10022
9514
|
);
|
|
10023
9515
|
nextProgressLogTs = now + 5e3;
|
|
10024
9516
|
}
|
|
10025
|
-
await (0,
|
|
9517
|
+
await (0, import_delay4.default)(Math.max(0, Math.min(DEFAULT_POLL_INTERVAL_MS, remaining)));
|
|
10026
9518
|
}
|
|
10027
9519
|
if (!timeoutDisabled && share.mode === "response" && stats.responseMatched === 0) {
|
|
10028
|
-
|
|
9520
|
+
logger15.warning(
|
|
10029
9521
|
`\u63A5\u53E3\u76D1\u542C\u672A\u547D\u4E2D: apiMatchers=${toJsonInline(apiMatchers, 220)}, \u54CD\u5E94\u6837\u672CURLs=${toJsonInline(stats.responseSampleUrls, 420)}`
|
|
10030
9522
|
);
|
|
10031
9523
|
}
|
|
10032
|
-
|
|
9524
|
+
logger15.warning(
|
|
10033
9525
|
`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"}`
|
|
10034
9526
|
);
|
|
10035
9527
|
return {
|
|
@@ -10041,7 +9533,7 @@ var Share = {
|
|
|
10041
9533
|
} finally {
|
|
10042
9534
|
if (share.mode === "response") {
|
|
10043
9535
|
page.off("response", onResponse);
|
|
10044
|
-
|
|
9536
|
+
logger15.info("response \u76D1\u542C\u5DF2\u5378\u8F7D");
|
|
10045
9537
|
}
|
|
10046
9538
|
await stopDomMonitor();
|
|
10047
9539
|
}
|
|
@@ -10056,7 +9548,6 @@ var Share = {
|
|
|
10056
9548
|
* @param {number} [options.maxBytes] 默认 5MiB,返回 base64 超过后会压缩
|
|
10057
9549
|
* @param {'jpeg'|'jpg'} [options.type] 压缩输出格式,默认 jpeg
|
|
10058
9550
|
* @param {boolean|Object} [options.compression] 传 false 可关闭压缩
|
|
10059
|
-
* @param {'default'|'cloak'} [options.mode] 截图水印合成模式,默认 default
|
|
10060
9551
|
* @returns {Promise<string>} base64 image
|
|
10061
9552
|
*/
|
|
10062
9553
|
async captureScreen(page, options = {}) {
|
|
@@ -10077,9 +9568,7 @@ var Share = {
|
|
|
10077
9568
|
...screenshotWatermarkify,
|
|
10078
9569
|
capturedAt
|
|
10079
9570
|
});
|
|
10080
|
-
outputBuffer = await watermarkifyScreenshotBuffer(rawBuffer, watermarkifyMeta, page
|
|
10081
|
-
mode: options.mode
|
|
10082
|
-
});
|
|
9571
|
+
outputBuffer = await watermarkifyScreenshotBuffer(rawBuffer, watermarkifyMeta, page);
|
|
10083
9572
|
}
|
|
10084
9573
|
return await compressImageBufferToBase64(outputBuffer, compression);
|
|
10085
9574
|
}
|
|
@@ -10087,9 +9576,8 @@ var Share = {
|
|
|
10087
9576
|
|
|
10088
9577
|
// entrys/node.js
|
|
10089
9578
|
Logger.setLogger(import_crawlee.log);
|
|
10090
|
-
var usePlaywrightToolKit = (
|
|
10091
|
-
|
|
10092
|
-
const toolkit = {
|
|
9579
|
+
var usePlaywrightToolKit = () => {
|
|
9580
|
+
return {
|
|
10093
9581
|
ApifyKit,
|
|
10094
9582
|
AntiCheat,
|
|
10095
9583
|
DeviceInput,
|
|
@@ -10109,7 +9597,6 @@ var usePlaywrightToolKit = (mode = "default") => {
|
|
|
10109
9597
|
ByPass,
|
|
10110
9598
|
$Internals: { LOG_TEMPLATES, stripAnsi }
|
|
10111
9599
|
};
|
|
10112
|
-
return toolkit;
|
|
10113
9600
|
};
|
|
10114
9601
|
// Annotate the CommonJS export names for ESM import in node:
|
|
10115
9602
|
0 && (module.exports = {
|