@skrillex1224/playwright-toolkit 3.0.15 → 3.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/browser.d.ts +6 -0
- package/dist/browser.js +446 -163
- package/dist/browser.js.map +4 -4
- package/dist/index.cjs +1224 -517
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +1222 -515
- package/dist/index.js.map +4 -4
- package/index.d.ts +49 -9
- package/package.json +9 -1
- package/scripts/postinstall.js +203 -0
package/dist/index.cjs
CHANGED
|
@@ -40,9 +40,12 @@ __export(constants_exports, {
|
|
|
40
40
|
ActorInfo: () => ActorInfo,
|
|
41
41
|
Code: () => Code,
|
|
42
42
|
Device: () => Device,
|
|
43
|
+
Mode: () => Mode,
|
|
43
44
|
PresetOfLiveViewKey: () => PresetOfLiveViewKey,
|
|
44
45
|
Status: () => Status,
|
|
45
|
-
|
|
46
|
+
mode: () => mode,
|
|
47
|
+
normalizeDevice: () => normalizeDevice,
|
|
48
|
+
normalizeMode: () => normalizeMode
|
|
46
49
|
});
|
|
47
50
|
var Code = {
|
|
48
51
|
Success: 0,
|
|
@@ -62,6 +65,14 @@ var Device = Object.freeze({
|
|
|
62
65
|
Desktop: "desktop",
|
|
63
66
|
Mobile: "mobile"
|
|
64
67
|
});
|
|
68
|
+
var Mode = Object.freeze({
|
|
69
|
+
Default: "default",
|
|
70
|
+
Cloak: "cloak"
|
|
71
|
+
});
|
|
72
|
+
var mode = Object.freeze({
|
|
73
|
+
default: Mode.Default,
|
|
74
|
+
cloak: Mode.Cloak
|
|
75
|
+
});
|
|
65
76
|
var normalizeDevice = (value, fallback = Device.Desktop) => {
|
|
66
77
|
const normalizedFallback = String(fallback || "").trim().toLowerCase() === Device.Mobile ? Device.Mobile : Device.Desktop;
|
|
67
78
|
const raw = String(value || "").trim().toLowerCase();
|
|
@@ -69,6 +80,13 @@ var normalizeDevice = (value, fallback = Device.Desktop) => {
|
|
|
69
80
|
if (raw === Device.Desktop) return Device.Desktop;
|
|
70
81
|
return normalizedFallback;
|
|
71
82
|
};
|
|
83
|
+
var normalizeMode = (value, fallback = Mode.Default) => {
|
|
84
|
+
const normalizedFallback = String(fallback || "").trim().toLowerCase() === Mode.Cloak ? Mode.Cloak : Mode.Default;
|
|
85
|
+
const raw = String(value || "").trim().toLowerCase();
|
|
86
|
+
if (raw === Mode.Cloak) return Mode.Cloak;
|
|
87
|
+
if (raw === Mode.Default) return Mode.Default;
|
|
88
|
+
return normalizedFallback;
|
|
89
|
+
};
|
|
72
90
|
var createActorInfo = (info) => {
|
|
73
91
|
const normalizeDomain = (value) => {
|
|
74
92
|
if (!value) return "";
|
|
@@ -83,7 +101,7 @@ var createActorInfo = (info) => {
|
|
|
83
101
|
const normalizeShare2 = (value) => {
|
|
84
102
|
const raw = value && typeof value === "object" ? value : {};
|
|
85
103
|
const modeRaw = String(raw.mode || "dom").trim().toLowerCase();
|
|
86
|
-
const
|
|
104
|
+
const mode2 = ["dom", "response", "custom"].includes(modeRaw) ? modeRaw : "dom";
|
|
87
105
|
const prefix = String(raw.prefix || "").trim();
|
|
88
106
|
const rawXurl = Array.isArray(raw.xurl) ? raw.xurl : [];
|
|
89
107
|
const normalizeMatcherList = (input) => {
|
|
@@ -128,7 +146,7 @@ var createActorInfo = (info) => {
|
|
|
128
146
|
xurl.push(...extraPaths);
|
|
129
147
|
}
|
|
130
148
|
return {
|
|
131
|
-
mode,
|
|
149
|
+
mode: mode2,
|
|
132
150
|
prefix,
|
|
133
151
|
xurl
|
|
134
152
|
};
|
|
@@ -136,7 +154,6 @@ var createActorInfo = (info) => {
|
|
|
136
154
|
const buildLandingUrl = ({ protocol: protocol2, domain: domain2, path: path4 }) => {
|
|
137
155
|
const safeProtocol = String(protocol2).trim();
|
|
138
156
|
const safeDomain = normalizeDomain(domain2);
|
|
139
|
-
if (!safeDomain) return "";
|
|
140
157
|
const safePath = normalizePath(path4);
|
|
141
158
|
return `${safeProtocol}://${safeDomain}${safePath}`;
|
|
142
159
|
};
|
|
@@ -344,18 +361,6 @@ var ActorInfo = {
|
|
|
344
361
|
prefix: "",
|
|
345
362
|
xurl: []
|
|
346
363
|
}
|
|
347
|
-
}),
|
|
348
|
-
// 通用网页抓取 Actor:入口 URL 来自 query,因此这里只声明统一的 Actor 元信息。
|
|
349
|
-
webpage: createActorInfo({
|
|
350
|
-
key: "webpage",
|
|
351
|
-
name: "\u901A\u7528\u7F51\u9875",
|
|
352
|
-
domain: "",
|
|
353
|
-
path: "/",
|
|
354
|
-
share: {
|
|
355
|
-
mode: "dom",
|
|
356
|
-
prefix: "",
|
|
357
|
-
xurl: []
|
|
358
|
-
}
|
|
359
364
|
})
|
|
360
365
|
};
|
|
361
366
|
|
|
@@ -387,18 +392,18 @@ var fallbackLog = {
|
|
|
387
392
|
error: (...args) => console.error(...args),
|
|
388
393
|
debug: (...args) => console.debug ? console.debug(...args) : console.log(...args)
|
|
389
394
|
};
|
|
390
|
-
var resolveLogMethod = (
|
|
391
|
-
if (
|
|
392
|
-
return
|
|
395
|
+
var resolveLogMethod = (logger17, name) => {
|
|
396
|
+
if (logger17 && typeof logger17[name] === "function") {
|
|
397
|
+
return logger17[name].bind(logger17);
|
|
393
398
|
}
|
|
394
|
-
if (name === "warning" &&
|
|
395
|
-
return
|
|
399
|
+
if (name === "warning" && logger17 && typeof logger17.warn === "function") {
|
|
400
|
+
return logger17.warn.bind(logger17);
|
|
396
401
|
}
|
|
397
402
|
return fallbackLog[name];
|
|
398
403
|
};
|
|
399
404
|
var defaultLogger = null;
|
|
400
|
-
var setDefaultLogger = (
|
|
401
|
-
defaultLogger =
|
|
405
|
+
var setDefaultLogger = (logger17) => {
|
|
406
|
+
defaultLogger = logger17;
|
|
402
407
|
};
|
|
403
408
|
var resolveLogger = (explicitLogger) => {
|
|
404
409
|
if (explicitLogger && typeof explicitLogger.info === "function") {
|
|
@@ -425,8 +430,8 @@ var colorize = (text, color) => {
|
|
|
425
430
|
var createBaseLogger = (prefix = "", explicitLogger) => {
|
|
426
431
|
const name = prefix ? String(prefix) : "";
|
|
427
432
|
const dispatch = (methodName, icon, message, color) => {
|
|
428
|
-
const
|
|
429
|
-
const logFn = resolveLogMethod(
|
|
433
|
+
const logger17 = resolveLogger(explicitLogger);
|
|
434
|
+
const logFn = resolveLogMethod(logger17, methodName);
|
|
430
435
|
const timestamp = colorize(`[${formatTimestamp()}]`, ANSI.gray);
|
|
431
436
|
const line = formatLine(name, icon, message);
|
|
432
437
|
const coloredLine = colorize(line, color);
|
|
@@ -780,7 +785,7 @@ var adjustAffixedElementsForExpandedScreenshot = async (page, options = {}) => {
|
|
|
780
785
|
if (safeTargetHeight <= viewportHeight + 1) {
|
|
781
786
|
return 0;
|
|
782
787
|
}
|
|
783
|
-
const
|
|
788
|
+
const hasOwn2 = (source, key) => Object.prototype.hasOwnProperty.call(source, key);
|
|
784
789
|
const isVisible = (el, style, rect) => {
|
|
785
790
|
if (!el || !style || !rect) return false;
|
|
786
791
|
if (style.display === "none" || style.visibility === "hidden" || style.visibility === "collapse") {
|
|
@@ -820,7 +825,7 @@ var adjustAffixedElementsForExpandedScreenshot = async (page, options = {}) => {
|
|
|
820
825
|
return true;
|
|
821
826
|
});
|
|
822
827
|
topLevelCandidates.forEach(({ el, position, edge }) => {
|
|
823
|
-
if (!
|
|
828
|
+
if (!hasOwn2(el.dataset, "pkAffixedAdjusted")) {
|
|
824
829
|
el.dataset.pkAffixedAdjusted = "1";
|
|
825
830
|
el.dataset.pkOrigPosition = el.style.getPropertyValue("position") || "";
|
|
826
831
|
el.dataset.pkOrigPositionPriority = el.style.getPropertyPriority("position") || "";
|
|
@@ -851,7 +856,7 @@ var adjustAffixedElementsForExpandedScreenshot = async (page, options = {}) => {
|
|
|
851
856
|
};
|
|
852
857
|
var restoreAffixedElementsForExpandedScreenshot = async (page) => {
|
|
853
858
|
await page.evaluate((className) => {
|
|
854
|
-
const
|
|
859
|
+
const hasOwn2 = (source, key) => Object.prototype.hasOwnProperty.call(source, key);
|
|
855
860
|
const expansionKeys = [
|
|
856
861
|
"pkOrigOverflow",
|
|
857
862
|
"pkOrigHeight",
|
|
@@ -859,28 +864,28 @@ var restoreAffixedElementsForExpandedScreenshot = async (page) => {
|
|
|
859
864
|
"pkOrigMaxHeight"
|
|
860
865
|
];
|
|
861
866
|
document.querySelectorAll('[data-pk-affixed-adjusted="1"]').forEach((el) => {
|
|
862
|
-
if (
|
|
867
|
+
if (hasOwn2(el.dataset, "pkOrigPosition")) {
|
|
863
868
|
el.style.setProperty("position", el.dataset.pkOrigPosition || "", el.dataset.pkOrigPositionPriority || "");
|
|
864
869
|
delete el.dataset.pkOrigPosition;
|
|
865
870
|
delete el.dataset.pkOrigPositionPriority;
|
|
866
871
|
}
|
|
867
|
-
if (
|
|
872
|
+
if (hasOwn2(el.dataset, "pkOrigTop")) {
|
|
868
873
|
el.style.setProperty("top", el.dataset.pkOrigTop || "", el.dataset.pkOrigTopPriority || "");
|
|
869
874
|
delete el.dataset.pkOrigTop;
|
|
870
875
|
delete el.dataset.pkOrigTopPriority;
|
|
871
876
|
}
|
|
872
|
-
if (
|
|
877
|
+
if (hasOwn2(el.dataset, "pkOrigBottom")) {
|
|
873
878
|
el.style.setProperty("bottom", el.dataset.pkOrigBottom || "", el.dataset.pkOrigBottomPriority || "");
|
|
874
879
|
delete el.dataset.pkOrigBottom;
|
|
875
880
|
delete el.dataset.pkOrigBottomPriority;
|
|
876
881
|
}
|
|
877
|
-
if (
|
|
882
|
+
if (hasOwn2(el.dataset, "pkOrigTranslate")) {
|
|
878
883
|
el.style.setProperty("translate", el.dataset.pkOrigTranslate || "", el.dataset.pkOrigTranslatePriority || "");
|
|
879
884
|
delete el.dataset.pkOrigTranslate;
|
|
880
885
|
delete el.dataset.pkOrigTranslatePriority;
|
|
881
886
|
}
|
|
882
887
|
delete el.dataset.pkAffixedAdjusted;
|
|
883
|
-
const stillExpanded = expansionKeys.some((key) =>
|
|
888
|
+
const stillExpanded = expansionKeys.some((key) => hasOwn2(el.dataset, key));
|
|
884
889
|
if (!stillExpanded) {
|
|
885
890
|
el.classList.remove(className);
|
|
886
891
|
}
|
|
@@ -923,7 +928,7 @@ var prepareExpandedFullPageScreenshot = async (page, options = {}) => {
|
|
|
923
928
|
viewportResized
|
|
924
929
|
};
|
|
925
930
|
};
|
|
926
|
-
var restoreExpandedFullPageScreenshot = async (page,
|
|
931
|
+
var restoreExpandedFullPageScreenshot = async (page, state2 = {}) => {
|
|
927
932
|
await page.evaluate((className) => {
|
|
928
933
|
const targets = new Set([
|
|
929
934
|
...document.querySelectorAll(`.${className}`),
|
|
@@ -947,8 +952,8 @@ var restoreExpandedFullPageScreenshot = async (page, state = {}) => {
|
|
|
947
952
|
el.classList.remove(className);
|
|
948
953
|
});
|
|
949
954
|
}, EXPANDED_SCROLLABLE_CLASS);
|
|
950
|
-
if (
|
|
951
|
-
await page.setViewportSize(
|
|
955
|
+
if (state2?.originalViewport && state2?.viewportResized) {
|
|
956
|
+
await page.setViewportSize(state2.originalViewport);
|
|
952
957
|
}
|
|
953
958
|
};
|
|
954
959
|
var capturePageScreenshot = async (page, options = {}) => {
|
|
@@ -1005,21 +1010,21 @@ var capturePageScreenshot = async (page, options = {}) => {
|
|
|
1005
1010
|
}
|
|
1006
1011
|
};
|
|
1007
1012
|
var captureExpandedFullPageScreenshot = async (page, options = {}) => {
|
|
1008
|
-
const
|
|
1013
|
+
const state2 = await prepareExpandedFullPageScreenshot(page, options);
|
|
1009
1014
|
try {
|
|
1010
1015
|
return await capturePageScreenshot(page, {
|
|
1011
1016
|
fullPage: true,
|
|
1012
1017
|
type: options.type || "png",
|
|
1013
1018
|
quality: options.quality,
|
|
1014
1019
|
timeout: options.timeout,
|
|
1015
|
-
maxClipHeight:
|
|
1020
|
+
maxClipHeight: state2.targetHeight
|
|
1016
1021
|
});
|
|
1017
1022
|
} finally {
|
|
1018
1023
|
await restoreAffixedElementsForExpandedScreenshot(page).catch((error) => {
|
|
1019
1024
|
logger.warning(`\u79FB\u52A8\u7AEF\u5438\u9644\u5143\u7D20\u6062\u590D\u5931\u8D25: ${error?.message || error}`);
|
|
1020
1025
|
});
|
|
1021
1026
|
if (options.restore) {
|
|
1022
|
-
await restoreExpandedFullPageScreenshot(page,
|
|
1027
|
+
await restoreExpandedFullPageScreenshot(page, state2);
|
|
1023
1028
|
}
|
|
1024
1029
|
}
|
|
1025
1030
|
};
|
|
@@ -1473,6 +1478,7 @@ var ProxyMeterRuntime = {
|
|
|
1473
1478
|
|
|
1474
1479
|
// src/runtime-env.js
|
|
1475
1480
|
var BROWSER_PROFILE_SCHEMA_VERSION = 1;
|
|
1481
|
+
var SUPPORTED_CLOAK_FINGERPRINT_PLATFORMS = /* @__PURE__ */ new Set(["linux", "macos", "windows"]);
|
|
1476
1482
|
var rememberedRuntimeState = null;
|
|
1477
1483
|
var isPlainObject = (value) => value && typeof value === "object" && !Array.isArray(value);
|
|
1478
1484
|
var normalizeKnownDevice = (value) => {
|
|
@@ -1481,6 +1487,22 @@ var normalizeKnownDevice = (value) => {
|
|
|
1481
1487
|
if (raw === Device.Desktop) return Device.Desktop;
|
|
1482
1488
|
return "";
|
|
1483
1489
|
};
|
|
1490
|
+
var normalizeCloakSeed = (value) => {
|
|
1491
|
+
const numericSeed = Number(value);
|
|
1492
|
+
if (Number.isSafeInteger(numericSeed) && numericSeed > 0) {
|
|
1493
|
+
return numericSeed;
|
|
1494
|
+
}
|
|
1495
|
+
const raw = String(value || "").trim();
|
|
1496
|
+
if (!/^\d+$/.test(raw)) {
|
|
1497
|
+
return 0;
|
|
1498
|
+
}
|
|
1499
|
+
const parsedSeed = Number(raw);
|
|
1500
|
+
return Number.isSafeInteger(parsedSeed) && parsedSeed > 0 ? parsedSeed : 0;
|
|
1501
|
+
};
|
|
1502
|
+
var normalizeCloakFingerprintPlatform = (value) => {
|
|
1503
|
+
const raw = String(value || "").trim().toLowerCase();
|
|
1504
|
+
return SUPPORTED_CLOAK_FINGERPRINT_PLATFORMS.has(raw) ? raw : "";
|
|
1505
|
+
};
|
|
1484
1506
|
var deepClone = (value) => {
|
|
1485
1507
|
if (value == null) return value;
|
|
1486
1508
|
try {
|
|
@@ -1851,6 +1873,14 @@ var normalizeBrowserProfileCore = (value) => {
|
|
|
1851
1873
|
if (Number.isFinite(browserMajorVersion) && browserMajorVersion > 0) {
|
|
1852
1874
|
profile.browser_major_version = browserMajorVersion;
|
|
1853
1875
|
}
|
|
1876
|
+
const cloakSeed = normalizeCloakSeed(source.cloak_seed);
|
|
1877
|
+
if (cloakSeed > 0) {
|
|
1878
|
+
profile.cloak_seed = cloakSeed;
|
|
1879
|
+
}
|
|
1880
|
+
const cloakFingerprintPlatform = normalizeCloakFingerprintPlatform(source.cloak_fingerprint_platform);
|
|
1881
|
+
if (cloakFingerprintPlatform) {
|
|
1882
|
+
profile.cloak_fingerprint_platform = cloakFingerprintPlatform;
|
|
1883
|
+
}
|
|
1854
1884
|
const schemaVersion = Number(source.schema_version || 0);
|
|
1855
1885
|
if (Number.isFinite(schemaVersion) && schemaVersion > 0) {
|
|
1856
1886
|
profile.schema_version = schemaVersion;
|
|
@@ -1938,8 +1968,8 @@ var normalizeBrowserProfile = (value) => {
|
|
|
1938
1968
|
payload: buildBrowserProfilePayload(core, observed)
|
|
1939
1969
|
};
|
|
1940
1970
|
};
|
|
1941
|
-
var rememberRuntimeState = (
|
|
1942
|
-
rememberedRuntimeState = deepClone(
|
|
1971
|
+
var rememberRuntimeState = (state2) => {
|
|
1972
|
+
rememberedRuntimeState = deepClone(state2);
|
|
1943
1973
|
return rememberedRuntimeState;
|
|
1944
1974
|
};
|
|
1945
1975
|
var normalizeRuntimeState = (source = {}, actor = "") => {
|
|
@@ -1998,7 +2028,7 @@ var RuntimeEnv = {
|
|
|
1998
2028
|
} else {
|
|
1999
2029
|
delete normalizedRuntime.browser_profile;
|
|
2000
2030
|
}
|
|
2001
|
-
const
|
|
2031
|
+
const state2 = {
|
|
2002
2032
|
actor: resolvedActor,
|
|
2003
2033
|
device,
|
|
2004
2034
|
runtime: normalizedRuntime,
|
|
@@ -2012,73 +2042,73 @@ var RuntimeEnv = {
|
|
|
2012
2042
|
browserProfileCore: browserProfile.core,
|
|
2013
2043
|
browserProfileObserved: browserProfile.observed
|
|
2014
2044
|
};
|
|
2015
|
-
rememberRuntimeState(
|
|
2016
|
-
return
|
|
2045
|
+
rememberRuntimeState(state2);
|
|
2046
|
+
return state2;
|
|
2017
2047
|
},
|
|
2018
2048
|
// buildEnvPatch 只构造允许回写到后端 env 的字段集合。
|
|
2019
2049
|
buildEnvPatch(source = {}, actor = "") {
|
|
2020
|
-
const
|
|
2021
|
-
const browserProfile = buildBrowserProfilePayload(
|
|
2050
|
+
const state2 = normalizeRuntimeState(source, actor);
|
|
2051
|
+
const browserProfile = buildBrowserProfilePayload(state2.browserProfileCore, state2.browserProfileObserved);
|
|
2022
2052
|
const envPatch = {
|
|
2023
|
-
...Array.isArray(
|
|
2024
|
-
...Object.keys(
|
|
2025
|
-
...Object.keys(
|
|
2053
|
+
...Array.isArray(state2.cookies) && state2.cookies.length > 0 ? { cookies: state2.cookies } : {},
|
|
2054
|
+
...Object.keys(state2.localStorage || {}).length > 0 ? { local_storage: state2.localStorage } : {},
|
|
2055
|
+
...Object.keys(state2.sessionStorage || {}).length > 0 ? { session_storage: state2.sessionStorage } : {},
|
|
2026
2056
|
...Object.keys(browserProfile).length > 0 ? { browser_profile: browserProfile } : {}
|
|
2027
2057
|
};
|
|
2028
2058
|
return Object.keys(envPatch).length > 0 ? envPatch : null;
|
|
2029
2059
|
},
|
|
2030
2060
|
// hasLoginState 只判断 runtime 是否存在有效载荷,不再区分具体字段来源。
|
|
2031
2061
|
hasLoginState(source = {}, actor = "") {
|
|
2032
|
-
const
|
|
2033
|
-
return isPlainObject(
|
|
2062
|
+
const state2 = normalizeRuntimeState(source, actor);
|
|
2063
|
+
return isPlainObject(state2.runtime) && Object.keys(state2.runtime || {}).length > 0;
|
|
2034
2064
|
},
|
|
2035
2065
|
rememberState(source = {}) {
|
|
2036
|
-
const
|
|
2037
|
-
rememberRuntimeState(
|
|
2066
|
+
const state2 = normalizeRuntimeState(source);
|
|
2067
|
+
rememberRuntimeState(state2);
|
|
2038
2068
|
return RuntimeEnv.peekRememberedState();
|
|
2039
2069
|
},
|
|
2040
2070
|
peekRememberedState() {
|
|
2041
2071
|
return rememberedRuntimeState ? deepClone(rememberedRuntimeState) : null;
|
|
2042
2072
|
},
|
|
2043
2073
|
getBrowserProfileCore(source = {}, actor = "") {
|
|
2044
|
-
const
|
|
2045
|
-
return deepClone(
|
|
2074
|
+
const state2 = normalizeRuntimeState(source, actor);
|
|
2075
|
+
return deepClone(state2.browserProfileCore || {});
|
|
2046
2076
|
},
|
|
2047
2077
|
setBrowserProfileCore(source = {}, core = {}, actor = "") {
|
|
2048
|
-
const
|
|
2078
|
+
const state2 = normalizeRuntimeState(source, actor);
|
|
2049
2079
|
const normalizedCore = normalizeBrowserProfileCore({
|
|
2050
2080
|
...core,
|
|
2051
|
-
device: normalizeKnownDevice(core?.device) ||
|
|
2081
|
+
device: normalizeKnownDevice(core?.device) || state2.device
|
|
2052
2082
|
});
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
if (Object.keys(
|
|
2056
|
-
|
|
2083
|
+
state2.browserProfileCore = normalizedCore;
|
|
2084
|
+
state2.browserProfile = buildBrowserProfilePayload(normalizedCore, state2.browserProfileObserved);
|
|
2085
|
+
if (Object.keys(state2.browserProfile).length > 0) {
|
|
2086
|
+
state2.runtime.browser_profile = state2.browserProfile;
|
|
2057
2087
|
} else {
|
|
2058
|
-
delete
|
|
2088
|
+
delete state2.runtime.browser_profile;
|
|
2059
2089
|
}
|
|
2060
|
-
rememberRuntimeState(
|
|
2061
|
-
return
|
|
2090
|
+
rememberRuntimeState(state2);
|
|
2091
|
+
return state2;
|
|
2062
2092
|
},
|
|
2063
2093
|
// applyToPage 只负责把登录态相关字段注入页面:
|
|
2064
2094
|
// cookies / localStorage / sessionStorage。
|
|
2065
2095
|
// 指纹、时区、UA、viewport 的回放发生在 launch.js 启动阶段,不在这里做。
|
|
2066
2096
|
async applyToPage(page, source = {}, options = {}) {
|
|
2067
2097
|
if (!page) return;
|
|
2068
|
-
let
|
|
2098
|
+
let state2 = normalizeRuntimeState(source, options?.actor || "");
|
|
2069
2099
|
if (typeof options?.preapply === "function") {
|
|
2070
|
-
|
|
2071
|
-
rememberRuntimeState(
|
|
2100
|
+
state2 = await options.preapply(state2) || state2;
|
|
2101
|
+
rememberRuntimeState(state2);
|
|
2072
2102
|
}
|
|
2073
2103
|
Object.defineProperty(page, PageRuntimeStateKey, {
|
|
2074
2104
|
configurable: true,
|
|
2075
2105
|
enumerable: false,
|
|
2076
2106
|
writable: true,
|
|
2077
|
-
value:
|
|
2107
|
+
value: state2
|
|
2078
2108
|
});
|
|
2079
|
-
const localStorage =
|
|
2080
|
-
const sessionStorage =
|
|
2081
|
-
const cookies = (
|
|
2109
|
+
const localStorage = state2.localStorage || {};
|
|
2110
|
+
const sessionStorage = state2.sessionStorage || {};
|
|
2111
|
+
const cookies = (state2.cookies || []).map((cookie) => {
|
|
2082
2112
|
const normalized = { ...cookie };
|
|
2083
2113
|
if (!normalized.path) {
|
|
2084
2114
|
normalized.path = "/";
|
|
@@ -2116,8 +2146,8 @@ var RuntimeEnv = {
|
|
|
2116
2146
|
},
|
|
2117
2147
|
// captureEnvPatch 在任务结束时采集最新环境快照,用于 pushSuccess / pushFailed 自动回写。
|
|
2118
2148
|
async captureEnvPatch(page, source = {}, options = {}) {
|
|
2119
|
-
const
|
|
2120
|
-
const baseline = RuntimeEnv.buildEnvPatch(
|
|
2149
|
+
const state2 = normalizeRuntimeState(source, options?.actor || "");
|
|
2150
|
+
const baseline = RuntimeEnv.buildEnvPatch(state2) || {};
|
|
2121
2151
|
if (!page || typeof page.evaluate !== "function" || typeof page.context !== "function") {
|
|
2122
2152
|
return Object.keys(baseline).length > 0 ? baseline : null;
|
|
2123
2153
|
}
|
|
@@ -2136,7 +2166,7 @@ var RuntimeEnv = {
|
|
|
2136
2166
|
cookies
|
|
2137
2167
|
},
|
|
2138
2168
|
{
|
|
2139
|
-
browserProfileCore:
|
|
2169
|
+
browserProfileCore: state2.browserProfileCore
|
|
2140
2170
|
}
|
|
2141
2171
|
);
|
|
2142
2172
|
return RuntimeEnv.mergeEnvPatches(baseline, capturedPatch);
|
|
@@ -2150,11 +2180,11 @@ var RuntimeEnv = {
|
|
|
2150
2180
|
var logger3 = createInternalLogger("ApifyKit");
|
|
2151
2181
|
var resolveRuntimeContext = (input) => {
|
|
2152
2182
|
const rememberedState = RuntimeEnv.peekRememberedState();
|
|
2153
|
-
const
|
|
2154
|
-
const envPatch = RuntimeEnv.buildEnvPatch(
|
|
2183
|
+
const state2 = rememberedState || RuntimeEnv.parseInput(input || {});
|
|
2184
|
+
const envPatch = RuntimeEnv.buildEnvPatch(state2) || null;
|
|
2155
2185
|
return {
|
|
2156
|
-
actor:
|
|
2157
|
-
runtime:
|
|
2186
|
+
actor: state2.actor,
|
|
2187
|
+
runtime: state2.runtime,
|
|
2158
2188
|
envPatch
|
|
2159
2189
|
};
|
|
2160
2190
|
};
|
|
@@ -2513,8 +2543,82 @@ var Utils = {
|
|
|
2513
2543
|
}
|
|
2514
2544
|
};
|
|
2515
2545
|
|
|
2516
|
-
// src/
|
|
2517
|
-
var
|
|
2546
|
+
// src/internals/context.js
|
|
2547
|
+
var state = {
|
|
2548
|
+
mode: Mode.Default
|
|
2549
|
+
};
|
|
2550
|
+
var normalizeStrategies = (strategies) => strategies && typeof strategies === "object" ? strategies : {};
|
|
2551
|
+
var ToolkitContext = {
|
|
2552
|
+
get mode() {
|
|
2553
|
+
return state.mode;
|
|
2554
|
+
},
|
|
2555
|
+
setMode(mode2 = Mode.Default) {
|
|
2556
|
+
state.mode = normalizeMode(mode2, Mode.Default);
|
|
2557
|
+
return state.mode;
|
|
2558
|
+
}
|
|
2559
|
+
};
|
|
2560
|
+
var getToolkitMode = () => state.mode;
|
|
2561
|
+
var setToolkitMode = (mode2 = Mode.Default) => ToolkitContext.setMode(mode2);
|
|
2562
|
+
var resolveModeStrategy = (strategies = {}, mode2 = getToolkitMode(), fallbackMode = Mode.Default) => {
|
|
2563
|
+
const normalizedStrategies = normalizeStrategies(strategies);
|
|
2564
|
+
const normalizedMode = normalizeMode(mode2, fallbackMode);
|
|
2565
|
+
const strategy = normalizedStrategies[normalizedMode] ?? normalizedStrategies[fallbackMode] ?? Object.values(normalizedStrategies).find(Boolean) ?? null;
|
|
2566
|
+
return {
|
|
2567
|
+
mode: normalizedMode,
|
|
2568
|
+
strategy
|
|
2569
|
+
};
|
|
2570
|
+
};
|
|
2571
|
+
|
|
2572
|
+
// src/internals/reflect.js
|
|
2573
|
+
var normalizeStrategies2 = (strategies) => strategies && typeof strategies === "object" ? strategies : {};
|
|
2574
|
+
var collectFunctionNames = (strategies = []) => {
|
|
2575
|
+
const names = /* @__PURE__ */ new Set();
|
|
2576
|
+
for (const strategy of strategies) {
|
|
2577
|
+
if (!strategy || typeof strategy !== "object") continue;
|
|
2578
|
+
for (const name of Reflect.ownKeys(strategy)) {
|
|
2579
|
+
if (typeof name === "string" && typeof strategy[name] === "function") {
|
|
2580
|
+
names.add(name);
|
|
2581
|
+
}
|
|
2582
|
+
}
|
|
2583
|
+
}
|
|
2584
|
+
return names;
|
|
2585
|
+
};
|
|
2586
|
+
var methodDescriptor = (namespace, name, resolveTarget) => ({
|
|
2587
|
+
enumerable: true,
|
|
2588
|
+
configurable: true,
|
|
2589
|
+
writable: true,
|
|
2590
|
+
value: (...args) => {
|
|
2591
|
+
const { mode: mode2, strategy } = resolveTarget(args);
|
|
2592
|
+
const method = strategy?.[name];
|
|
2593
|
+
if (typeof method !== "function") {
|
|
2594
|
+
throw new Error(`${namespace}.${name} is not available in ${mode2} mode`);
|
|
2595
|
+
}
|
|
2596
|
+
return method.apply(strategy, args);
|
|
2597
|
+
}
|
|
2598
|
+
});
|
|
2599
|
+
var withModeReflect = (namespace, strategies = {}) => {
|
|
2600
|
+
const normalizedStrategies = normalizeStrategies2(strategies);
|
|
2601
|
+
const baseStrategy = normalizedStrategies.default ?? Object.values(normalizedStrategies).find(Boolean);
|
|
2602
|
+
const names = collectFunctionNames([baseStrategy]);
|
|
2603
|
+
const descriptors = {};
|
|
2604
|
+
for (const name of names) {
|
|
2605
|
+
descriptors[name] = methodDescriptor(namespace, name, () => resolveModeStrategy(normalizedStrategies));
|
|
2606
|
+
}
|
|
2607
|
+
return Object.defineProperties({}, descriptors);
|
|
2608
|
+
};
|
|
2609
|
+
var withPageReflect = (namespace, resolveStrategy, strategies = []) => {
|
|
2610
|
+
const names = collectFunctionNames(strategies);
|
|
2611
|
+
const descriptors = {};
|
|
2612
|
+
for (const name of names) {
|
|
2613
|
+
descriptors[name] = methodDescriptor(namespace, name, ([page]) => ({
|
|
2614
|
+
mode: "page",
|
|
2615
|
+
strategy: resolveStrategy(page)
|
|
2616
|
+
}));
|
|
2617
|
+
}
|
|
2618
|
+
return Object.defineProperties({}, descriptors);
|
|
2619
|
+
};
|
|
2620
|
+
|
|
2621
|
+
// src/internals/anti-cheat/default.js
|
|
2518
2622
|
var BASE_CONFIG = Object.freeze({
|
|
2519
2623
|
locale: "zh-CN",
|
|
2520
2624
|
acceptLanguage: "zh-CN,zh;q=0.9",
|
|
@@ -2549,7 +2653,7 @@ function buildFingerprintOptions({ locale = BASE_CONFIG.locale, browserMajorVers
|
|
|
2549
2653
|
}
|
|
2550
2654
|
return options;
|
|
2551
2655
|
}
|
|
2552
|
-
var
|
|
2656
|
+
var DefaultAntiCheat = {
|
|
2553
2657
|
/**
|
|
2554
2658
|
* 获取统一的基础配置
|
|
2555
2659
|
*/
|
|
@@ -2586,6 +2690,47 @@ var AntiCheat = {
|
|
|
2586
2690
|
}
|
|
2587
2691
|
};
|
|
2588
2692
|
|
|
2693
|
+
// src/internals/anti-cheat/cloak.js
|
|
2694
|
+
var CLOAK_BASE_CONFIG = Object.freeze({
|
|
2695
|
+
locale: "",
|
|
2696
|
+
acceptLanguage: "",
|
|
2697
|
+
timezoneId: "",
|
|
2698
|
+
timezoneOffset: null,
|
|
2699
|
+
geolocation: null
|
|
2700
|
+
});
|
|
2701
|
+
var normalizeHeaders = (headers) => headers && typeof headers === "object" ? headers : {};
|
|
2702
|
+
var CloakAntiCheat = {
|
|
2703
|
+
/**
|
|
2704
|
+
* Cloak 自身会负责浏览器指纹,toolkit 在该模式下尽量不再注入额外反检测配置。
|
|
2705
|
+
*/
|
|
2706
|
+
getBaseConfig() {
|
|
2707
|
+
return { ...CLOAK_BASE_CONFIG };
|
|
2708
|
+
},
|
|
2709
|
+
getFingerprintGeneratorOptions() {
|
|
2710
|
+
return {};
|
|
2711
|
+
},
|
|
2712
|
+
getLaunchArgs() {
|
|
2713
|
+
return [];
|
|
2714
|
+
},
|
|
2715
|
+
getTlsFingerprintOptions() {
|
|
2716
|
+
return {};
|
|
2717
|
+
},
|
|
2718
|
+
applyLocaleHeaders(headers, acceptLanguage = "") {
|
|
2719
|
+
const normalizedHeaders = normalizeHeaders(headers);
|
|
2720
|
+
if (acceptLanguage && !normalizedHeaders["accept-language"]) {
|
|
2721
|
+
normalizedHeaders["accept-language"] = acceptLanguage;
|
|
2722
|
+
}
|
|
2723
|
+
return normalizedHeaders;
|
|
2724
|
+
}
|
|
2725
|
+
};
|
|
2726
|
+
|
|
2727
|
+
// src/anti-cheat.js
|
|
2728
|
+
var antiCheatStrategies = {
|
|
2729
|
+
[Mode.Default]: DefaultAntiCheat,
|
|
2730
|
+
[Mode.Cloak]: CloakAntiCheat
|
|
2731
|
+
};
|
|
2732
|
+
var AntiCheat = withModeReflect("AntiCheat", antiCheatStrategies);
|
|
2733
|
+
|
|
2589
2734
|
// src/device-input.js
|
|
2590
2735
|
var resolveDeviceFromPage = (page) => normalizeDevice(page?.[PageRuntimeStateKey]?.device);
|
|
2591
2736
|
var assertPage = (page, method) => {
|
|
@@ -2985,12 +3130,12 @@ var resolveDescriptor = (descriptor, device) => {
|
|
|
2985
3130
|
}
|
|
2986
3131
|
return resolved;
|
|
2987
3132
|
};
|
|
2988
|
-
var attachRuntimeState = (page,
|
|
3133
|
+
var attachRuntimeState = (page, state2) => {
|
|
2989
3134
|
Object.defineProperty(page, PageRuntimeStateKey, {
|
|
2990
3135
|
configurable: true,
|
|
2991
3136
|
enumerable: false,
|
|
2992
3137
|
writable: true,
|
|
2993
|
-
value:
|
|
3138
|
+
value: state2
|
|
2994
3139
|
});
|
|
2995
3140
|
};
|
|
2996
3141
|
var restoreRuntimeState = (page, snapshot) => {
|
|
@@ -3136,10 +3281,13 @@ var DeviceView = {
|
|
|
3136
3281
|
}
|
|
3137
3282
|
};
|
|
3138
3283
|
|
|
3284
|
+
// src/internals/humanize/index.js
|
|
3285
|
+
var import_delay4 = __toESM(require("delay"), 1);
|
|
3286
|
+
|
|
3139
3287
|
// src/internals/humanize/desktop.js
|
|
3140
3288
|
var import_delay2 = __toESM(require("delay"), 1);
|
|
3141
3289
|
var import_ghost_cursor_playwright = require("ghost-cursor-playwright");
|
|
3142
|
-
var
|
|
3290
|
+
var logger5 = createInternalLogger("Humanize");
|
|
3143
3291
|
var $CursorWeakMap = /* @__PURE__ */ new WeakMap();
|
|
3144
3292
|
function $GetCursor(page) {
|
|
3145
3293
|
const cursor = $CursorWeakMap.get(page);
|
|
@@ -3167,13 +3315,13 @@ var Humanize = {
|
|
|
3167
3315
|
*/
|
|
3168
3316
|
async initializeCursor(page) {
|
|
3169
3317
|
if ($CursorWeakMap.has(page)) {
|
|
3170
|
-
|
|
3318
|
+
logger5.debug("initializeCursor: cursor already exists, skipping");
|
|
3171
3319
|
return;
|
|
3172
3320
|
}
|
|
3173
|
-
|
|
3321
|
+
logger5.start("initializeCursor", "creating cursor");
|
|
3174
3322
|
const cursor = await (0, import_ghost_cursor_playwright.createCursor)(page);
|
|
3175
3323
|
$CursorWeakMap.set(page, cursor);
|
|
3176
|
-
|
|
3324
|
+
logger5.success("initializeCursor", "cursor initialized");
|
|
3177
3325
|
},
|
|
3178
3326
|
/**
|
|
3179
3327
|
* 人类化鼠标移动 - 使用 ghost-cursor 移动到指定位置或元素
|
|
@@ -3183,17 +3331,17 @@ var Humanize = {
|
|
|
3183
3331
|
*/
|
|
3184
3332
|
async humanMove(page, target) {
|
|
3185
3333
|
const cursor = $GetCursor(page);
|
|
3186
|
-
|
|
3334
|
+
logger5.start("humanMove", `target=${typeof target === "string" ? target : "element/coords"}`);
|
|
3187
3335
|
try {
|
|
3188
3336
|
if (typeof target === "string") {
|
|
3189
3337
|
const element = await page.$(target);
|
|
3190
3338
|
if (!element) {
|
|
3191
|
-
|
|
3339
|
+
logger5.warn(`humanMove: \u5143\u7D20\u4E0D\u5B58\u5728 ${target}`);
|
|
3192
3340
|
return false;
|
|
3193
3341
|
}
|
|
3194
3342
|
const box = await element.boundingBox();
|
|
3195
3343
|
if (!box) {
|
|
3196
|
-
|
|
3344
|
+
logger5.warn(`humanMove: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E ${target}`);
|
|
3197
3345
|
return false;
|
|
3198
3346
|
}
|
|
3199
3347
|
const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.2;
|
|
@@ -3209,10 +3357,10 @@ var Humanize = {
|
|
|
3209
3357
|
await cursor.actions.move({ x, y });
|
|
3210
3358
|
}
|
|
3211
3359
|
}
|
|
3212
|
-
|
|
3360
|
+
logger5.success("humanMove");
|
|
3213
3361
|
return true;
|
|
3214
3362
|
} catch (error) {
|
|
3215
|
-
|
|
3363
|
+
logger5.fail("humanMove", error);
|
|
3216
3364
|
throw error;
|
|
3217
3365
|
}
|
|
3218
3366
|
},
|
|
@@ -3236,12 +3384,12 @@ var Humanize = {
|
|
|
3236
3384
|
maxDurationMs = maxSteps * 220 + 800
|
|
3237
3385
|
} = options;
|
|
3238
3386
|
const targetDesc = typeof target === "string" ? target : "ElementHandle";
|
|
3239
|
-
|
|
3387
|
+
logger5.start("humanScroll", `target=${targetDesc}`);
|
|
3240
3388
|
let element;
|
|
3241
3389
|
if (typeof target === "string") {
|
|
3242
3390
|
element = await page.$(target);
|
|
3243
3391
|
if (!element) {
|
|
3244
|
-
|
|
3392
|
+
logger5.warn(`humanScroll | \u5143\u7D20\u672A\u627E\u5230: ${target}`);
|
|
3245
3393
|
return { element: null, didScroll: false };
|
|
3246
3394
|
}
|
|
3247
3395
|
} else {
|
|
@@ -3316,26 +3464,26 @@ var Humanize = {
|
|
|
3316
3464
|
try {
|
|
3317
3465
|
for (let i = 0; i < maxSteps; i++) {
|
|
3318
3466
|
if (Date.now() - startTime > maxDurationMs) {
|
|
3319
|
-
|
|
3467
|
+
logger5.warn(`humanScroll | \u8D85\u65F6\u4FDD\u62A4\u89E6\u53D1 (${maxDurationMs}ms)`);
|
|
3320
3468
|
return { element, didScroll };
|
|
3321
3469
|
}
|
|
3322
3470
|
const status = await checkVisibility();
|
|
3323
3471
|
if (status.code === "VISIBLE") {
|
|
3324
3472
|
if (status.isFixed) {
|
|
3325
|
-
|
|
3473
|
+
logger5.info("humanScroll | fixed \u5BB9\u5668\u5185\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
|
|
3326
3474
|
} else {
|
|
3327
|
-
|
|
3475
|
+
logger5.debug("humanScroll | \u5143\u7D20\u53EF\u89C1\u4E14\u65E0\u906E\u6321");
|
|
3328
3476
|
}
|
|
3329
|
-
|
|
3477
|
+
logger5.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
|
|
3330
3478
|
return { element, didScroll };
|
|
3331
3479
|
}
|
|
3332
|
-
|
|
3480
|
+
logger5.debug(`humanScroll | \u6B65\u9AA4 ${i + 1}/${maxSteps}: ${status.reason} ${status.direction ? `(${status.direction})` : ""}`);
|
|
3333
3481
|
if (status.code === "OBSTRUCTED" && status.obstruction) {
|
|
3334
|
-
|
|
3482
|
+
logger5.debug(`humanScroll | \u88AB\u4EE5\u4E0B\u5143\u7D20\u906E\u6321 <${status.obstruction.tag} id="${status.obstruction.id}">`);
|
|
3335
3483
|
}
|
|
3336
3484
|
const scrollRect = await getScrollableRect2();
|
|
3337
3485
|
if (!scrollRect && status.isFixed) {
|
|
3338
|
-
|
|
3486
|
+
logger5.warn("humanScroll | fixed \u5BB9\u5668\u5185\u4E14\u65E0\u53EF\u6EDA\u52A8\u7956\u5148\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
|
|
3339
3487
|
return { element, didScroll };
|
|
3340
3488
|
}
|
|
3341
3489
|
const stepMin = scrollRect ? Math.min(minStep, Math.max(60, scrollRect.height * 0.4)) : minStep;
|
|
@@ -3371,10 +3519,10 @@ var Humanize = {
|
|
|
3371
3519
|
didScroll = true;
|
|
3372
3520
|
await (0, import_delay2.default)(this.jitterMs(20 + Math.random() * 40, 0.2));
|
|
3373
3521
|
}
|
|
3374
|
-
|
|
3522
|
+
logger5.warn(`humanScroll | \u5728 ${maxSteps} \u6B65\u540E\u65E0\u6CD5\u786E\u4FDD\u53EF\u89C1\u6027`);
|
|
3375
3523
|
return { element, didScroll };
|
|
3376
3524
|
} catch (error) {
|
|
3377
|
-
|
|
3525
|
+
logger5.fail("humanScroll", error);
|
|
3378
3526
|
throw error;
|
|
3379
3527
|
}
|
|
3380
3528
|
},
|
|
@@ -3392,7 +3540,7 @@ var Humanize = {
|
|
|
3392
3540
|
const cursor = $GetCursor(page);
|
|
3393
3541
|
const { reactionDelay = 250, throwOnMissing = true, scrollIfNeeded = true, restore = false } = options;
|
|
3394
3542
|
const targetDesc = target == null ? "Current Position" : typeof target === "string" ? target : "ElementHandle";
|
|
3395
|
-
|
|
3543
|
+
logger5.start("humanClick", `target=${targetDesc}`);
|
|
3396
3544
|
const restoreOnce = async () => {
|
|
3397
3545
|
if (restoreOnce.restored) return;
|
|
3398
3546
|
restoreOnce.restored = true;
|
|
@@ -3401,14 +3549,14 @@ var Humanize = {
|
|
|
3401
3549
|
await (0, import_delay2.default)(this.jitterMs(1e3));
|
|
3402
3550
|
await restoreOnce.do();
|
|
3403
3551
|
} catch (restoreError) {
|
|
3404
|
-
|
|
3552
|
+
logger5.warn(`humanClick: \u6062\u590D\u6EDA\u52A8\u4F4D\u7F6E\u5931\u8D25: ${restoreError.message}`);
|
|
3405
3553
|
}
|
|
3406
3554
|
};
|
|
3407
3555
|
try {
|
|
3408
3556
|
if (target == null) {
|
|
3409
3557
|
await (0, import_delay2.default)(this.jitterMs(reactionDelay, 0.4));
|
|
3410
3558
|
await cursor.actions.click();
|
|
3411
|
-
|
|
3559
|
+
logger5.success("humanClick", "Clicked current position");
|
|
3412
3560
|
return true;
|
|
3413
3561
|
}
|
|
3414
3562
|
let element;
|
|
@@ -3418,7 +3566,7 @@ var Humanize = {
|
|
|
3418
3566
|
if (throwOnMissing) {
|
|
3419
3567
|
throw new Error(`\u627E\u4E0D\u5230\u5143\u7D20 ${target}`);
|
|
3420
3568
|
}
|
|
3421
|
-
|
|
3569
|
+
logger5.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${target}`);
|
|
3422
3570
|
return false;
|
|
3423
3571
|
}
|
|
3424
3572
|
} else {
|
|
@@ -3434,7 +3582,7 @@ var Humanize = {
|
|
|
3434
3582
|
if (throwOnMissing) {
|
|
3435
3583
|
throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5143\u7D20\u4F4D\u7F6E");
|
|
3436
3584
|
}
|
|
3437
|
-
|
|
3585
|
+
logger5.warn("humanClick: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E\uFF0C\u8DF3\u8FC7\u70B9\u51FB");
|
|
3438
3586
|
return false;
|
|
3439
3587
|
}
|
|
3440
3588
|
const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.3;
|
|
@@ -3443,11 +3591,11 @@ var Humanize = {
|
|
|
3443
3591
|
await (0, import_delay2.default)(this.jitterMs(reactionDelay, 0.4));
|
|
3444
3592
|
await cursor.actions.click();
|
|
3445
3593
|
await restoreOnce();
|
|
3446
|
-
|
|
3594
|
+
logger5.success("humanClick");
|
|
3447
3595
|
return true;
|
|
3448
3596
|
} catch (error) {
|
|
3449
3597
|
await restoreOnce();
|
|
3450
|
-
|
|
3598
|
+
logger5.fail("humanClick", error);
|
|
3451
3599
|
throw error;
|
|
3452
3600
|
}
|
|
3453
3601
|
},
|
|
@@ -3458,9 +3606,9 @@ var Humanize = {
|
|
|
3458
3606
|
*/
|
|
3459
3607
|
async randomSleep(baseMs, jitterPercent = 0.3) {
|
|
3460
3608
|
const ms = this.jitterMs(baseMs, jitterPercent);
|
|
3461
|
-
|
|
3609
|
+
logger5.start("randomSleep", `base=${baseMs}, actual=${ms}ms`);
|
|
3462
3610
|
await (0, import_delay2.default)(ms);
|
|
3463
|
-
|
|
3611
|
+
logger5.success("randomSleep");
|
|
3464
3612
|
},
|
|
3465
3613
|
/**
|
|
3466
3614
|
* 模拟人类"注视"或"阅读"行为:鼠标在页面上随机微动
|
|
@@ -3470,7 +3618,7 @@ var Humanize = {
|
|
|
3470
3618
|
async simulateGaze(page, baseDurationMs = 2500) {
|
|
3471
3619
|
const cursor = $GetCursor(page);
|
|
3472
3620
|
const durationMs = this.jitterMs(baseDurationMs, 0.4);
|
|
3473
|
-
|
|
3621
|
+
logger5.start("simulateGaze", `duration=${durationMs}ms`);
|
|
3474
3622
|
const startTime = Date.now();
|
|
3475
3623
|
const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };
|
|
3476
3624
|
while (Date.now() - startTime < durationMs) {
|
|
@@ -3479,7 +3627,7 @@ var Humanize = {
|
|
|
3479
3627
|
await cursor.actions.move({ x, y });
|
|
3480
3628
|
await (0, import_delay2.default)(this.jitterMs(600, 0.5));
|
|
3481
3629
|
}
|
|
3482
|
-
|
|
3630
|
+
logger5.success("simulateGaze");
|
|
3483
3631
|
},
|
|
3484
3632
|
/**
|
|
3485
3633
|
* 人类化输入 - 带节奏变化(快-慢-停顿-偶尔加速)
|
|
@@ -3492,7 +3640,7 @@ var Humanize = {
|
|
|
3492
3640
|
* @param {number} [options.pauseBase=800] - 停顿时长基础值 (ms),实际 ±50% 抖动
|
|
3493
3641
|
*/
|
|
3494
3642
|
async humanType(page, selector, text, options = {}) {
|
|
3495
|
-
|
|
3643
|
+
logger5.start("humanType", `selector=${selector}, textLen=${text.length}`);
|
|
3496
3644
|
const {
|
|
3497
3645
|
baseDelay = 180,
|
|
3498
3646
|
pauseProbability = 0.08,
|
|
@@ -3516,13 +3664,13 @@ var Humanize = {
|
|
|
3516
3664
|
await (0, import_delay2.default)(charDelay);
|
|
3517
3665
|
if (Math.random() < pauseProbability && i < text.length - 1) {
|
|
3518
3666
|
const pauseTime = this.jitterMs(pauseBase, 0.5);
|
|
3519
|
-
|
|
3667
|
+
logger5.debug(`\u505C\u987F ${pauseTime}ms...`);
|
|
3520
3668
|
await (0, import_delay2.default)(pauseTime);
|
|
3521
3669
|
}
|
|
3522
3670
|
}
|
|
3523
|
-
|
|
3671
|
+
logger5.success("humanType");
|
|
3524
3672
|
} catch (error) {
|
|
3525
|
-
|
|
3673
|
+
logger5.fail("humanType", error);
|
|
3526
3674
|
throw error;
|
|
3527
3675
|
}
|
|
3528
3676
|
},
|
|
@@ -3546,7 +3694,7 @@ var Humanize = {
|
|
|
3546
3694
|
keyboardOptions = {}
|
|
3547
3695
|
} = pressOptions || {};
|
|
3548
3696
|
const targetDesc = hasTarget ? typeof targetOrKey === "string" ? targetOrKey : "ElementHandle" : "current focus";
|
|
3549
|
-
|
|
3697
|
+
logger5.start("humanPress", `key=${key}, target=${targetDesc}`);
|
|
3550
3698
|
try {
|
|
3551
3699
|
if (hasTarget) {
|
|
3552
3700
|
await this.humanClick(page, targetOrKey, { reactionDelay: focusDelay, scrollIfNeeded, throwOnMissing });
|
|
@@ -3556,10 +3704,10 @@ var Humanize = {
|
|
|
3556
3704
|
...keyboardOptions,
|
|
3557
3705
|
delay: this.jitterMs(holdDelay, 0.5)
|
|
3558
3706
|
});
|
|
3559
|
-
|
|
3707
|
+
logger5.success("humanPress");
|
|
3560
3708
|
return true;
|
|
3561
3709
|
} catch (error) {
|
|
3562
|
-
|
|
3710
|
+
logger5.fail("humanPress", error);
|
|
3563
3711
|
throw error;
|
|
3564
3712
|
}
|
|
3565
3713
|
},
|
|
@@ -3569,22 +3717,22 @@ var Humanize = {
|
|
|
3569
3717
|
* @param {string} selector - 输入框选择器
|
|
3570
3718
|
*/
|
|
3571
3719
|
async humanClear(page, selector) {
|
|
3572
|
-
|
|
3720
|
+
logger5.start("humanClear", `selector=${selector}`);
|
|
3573
3721
|
try {
|
|
3574
3722
|
const locator = page.locator(selector);
|
|
3575
3723
|
await locator.click();
|
|
3576
3724
|
await (0, import_delay2.default)(this.jitterMs(200, 0.4));
|
|
3577
3725
|
const currentValue = await locator.inputValue();
|
|
3578
3726
|
if (!currentValue || currentValue.length === 0) {
|
|
3579
|
-
|
|
3727
|
+
logger5.success("humanClear", "already empty");
|
|
3580
3728
|
return;
|
|
3581
3729
|
}
|
|
3582
3730
|
await page.keyboard.press("Meta+A");
|
|
3583
3731
|
await (0, import_delay2.default)(this.jitterMs(100, 0.4));
|
|
3584
3732
|
await page.keyboard.press("Backspace");
|
|
3585
|
-
|
|
3733
|
+
logger5.success("humanClear");
|
|
3586
3734
|
} catch (error) {
|
|
3587
|
-
|
|
3735
|
+
logger5.fail("humanClear", error);
|
|
3588
3736
|
throw error;
|
|
3589
3737
|
}
|
|
3590
3738
|
},
|
|
@@ -3596,7 +3744,7 @@ var Humanize = {
|
|
|
3596
3744
|
async warmUpBrowsing(page, baseDuration = 3500) {
|
|
3597
3745
|
const cursor = $GetCursor(page);
|
|
3598
3746
|
const durationMs = this.jitterMs(baseDuration, 0.4);
|
|
3599
|
-
|
|
3747
|
+
logger5.start("warmUpBrowsing", `duration=${durationMs}ms`);
|
|
3600
3748
|
const startTime = Date.now();
|
|
3601
3749
|
const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };
|
|
3602
3750
|
try {
|
|
@@ -3615,9 +3763,9 @@ var Humanize = {
|
|
|
3615
3763
|
await (0, import_delay2.default)(this.jitterMs(800, 0.5));
|
|
3616
3764
|
}
|
|
3617
3765
|
}
|
|
3618
|
-
|
|
3766
|
+
logger5.success("warmUpBrowsing");
|
|
3619
3767
|
} catch (error) {
|
|
3620
|
-
|
|
3768
|
+
logger5.fail("warmUpBrowsing", error);
|
|
3621
3769
|
throw error;
|
|
3622
3770
|
}
|
|
3623
3771
|
},
|
|
@@ -3631,7 +3779,7 @@ var Humanize = {
|
|
|
3631
3779
|
async naturalScroll(page, direction = "down", distance = 300, baseSteps = 5) {
|
|
3632
3780
|
const steps = Math.max(3, baseSteps + Math.floor(Math.random() * 3) - 1);
|
|
3633
3781
|
const actualDistance = this.jitterMs(distance, 0.15);
|
|
3634
|
-
|
|
3782
|
+
logger5.start("naturalScroll", `dir=${direction}, dist=${actualDistance}, steps=${steps}`);
|
|
3635
3783
|
const sign = direction === "down" ? 1 : -1;
|
|
3636
3784
|
const stepDistance = actualDistance / steps;
|
|
3637
3785
|
try {
|
|
@@ -3643,9 +3791,9 @@ var Humanize = {
|
|
|
3643
3791
|
const baseDelay = 60 + i * 25;
|
|
3644
3792
|
await (0, import_delay2.default)(this.jitterMs(baseDelay, 0.3));
|
|
3645
3793
|
}
|
|
3646
|
-
|
|
3794
|
+
logger5.success("naturalScroll");
|
|
3647
3795
|
} catch (error) {
|
|
3648
|
-
|
|
3796
|
+
logger5.fail("naturalScroll", error);
|
|
3649
3797
|
throw error;
|
|
3650
3798
|
}
|
|
3651
3799
|
}
|
|
@@ -3674,7 +3822,7 @@ var resolveElement = async (page, target, { throwOnMissing = true } = {}) => {
|
|
|
3674
3822
|
var waitJitter = (base, jitterPercent = 0.3) => (0, import_delay3.default)(jitterMs(base, jitterPercent));
|
|
3675
3823
|
|
|
3676
3824
|
// src/internals/humanize/mobile.js
|
|
3677
|
-
var
|
|
3825
|
+
var logger6 = createInternalLogger("Humanize.Mobile");
|
|
3678
3826
|
var initializedPages = /* @__PURE__ */ new WeakSet();
|
|
3679
3827
|
var DEFAULT_TAP_TIMEOUT_MS = 2500;
|
|
3680
3828
|
var DEFAULT_MOUSE_TAP_FALLBACK_TIMEOUT_MS = 1200;
|
|
@@ -4044,7 +4192,7 @@ var restoreWindowFromSnapshot = async (page, before, after) => {
|
|
|
4044
4192
|
return;
|
|
4045
4193
|
}
|
|
4046
4194
|
await page.evaluate(
|
|
4047
|
-
(
|
|
4195
|
+
(state2) => window.scrollTo(state2.x, state2.y),
|
|
4048
4196
|
{ x: Number(before.scrollX || 0), y: Number(before.scrollY || 0) }
|
|
4049
4197
|
).catch(() => {
|
|
4050
4198
|
});
|
|
@@ -4131,7 +4279,7 @@ var dispatchTouchSwipe = async (page, deltaY, options = {}) => {
|
|
|
4131
4279
|
}
|
|
4132
4280
|
return true;
|
|
4133
4281
|
} catch (error) {
|
|
4134
|
-
|
|
4282
|
+
logger6.debug(`touch swipe fallback: ${error?.message || error}`);
|
|
4135
4283
|
try {
|
|
4136
4284
|
await page.evaluate((amount) => window.scrollBy(0, amount), deltaY);
|
|
4137
4285
|
await waitJitter(120, 0.35);
|
|
@@ -4165,7 +4313,7 @@ var tapPoint = async (page, point, options = {}) => {
|
|
|
4165
4313
|
);
|
|
4166
4314
|
return { method: "touchscreen" };
|
|
4167
4315
|
} catch (error) {
|
|
4168
|
-
|
|
4316
|
+
logger6.warn(`tapPoint | touchscreen.tap \u5931\u8D25\u6216\u8D85\u65F6\uFF0C\u5C1D\u8BD5\u9F20\u6807\u515C\u5E95: ${error?.message || error}`);
|
|
4169
4317
|
if (!allowMouseFallback) throw error;
|
|
4170
4318
|
}
|
|
4171
4319
|
}
|
|
@@ -4181,10 +4329,10 @@ var MobileHumanize = {
|
|
|
4181
4329
|
async initializeCursor(page) {
|
|
4182
4330
|
if (initializedPages.has(page)) return;
|
|
4183
4331
|
initializedPages.add(page);
|
|
4184
|
-
|
|
4332
|
+
logger6.debug("initializeCursor: mobile mode uses touch gestures, cursor init skipped");
|
|
4185
4333
|
},
|
|
4186
4334
|
async humanMove(page, target) {
|
|
4187
|
-
|
|
4335
|
+
logger6.debug(`humanMove: mobile no-op target=${typeof target === "string" ? target : "element/coords"}`);
|
|
4188
4336
|
if (typeof target === "string" || target && typeof target.boundingBox === "function") {
|
|
4189
4337
|
const element = await resolveElement(page, target, { throwOnMissing: false });
|
|
4190
4338
|
if (!element) {
|
|
@@ -4203,10 +4351,10 @@ var MobileHumanize = {
|
|
|
4203
4351
|
throwOnMissing = false
|
|
4204
4352
|
} = options;
|
|
4205
4353
|
const targetDesc = describeTarget(target);
|
|
4206
|
-
|
|
4354
|
+
logger6.start("humanScroll", `target=${targetDesc}`);
|
|
4207
4355
|
const element = await resolveElement(page, target, { throwOnMissing });
|
|
4208
4356
|
if (!element) {
|
|
4209
|
-
|
|
4357
|
+
logger6.warn(`humanScroll | \u5143\u7D20\u672A\u627E\u5230: ${targetDesc}`);
|
|
4210
4358
|
return { element: null, didScroll: false, restore: null };
|
|
4211
4359
|
}
|
|
4212
4360
|
const startTime = Date.now();
|
|
@@ -4215,42 +4363,42 @@ var MobileHumanize = {
|
|
|
4215
4363
|
const status = await checkElementVisibility(element);
|
|
4216
4364
|
if (status.code === "VISIBLE") {
|
|
4217
4365
|
if (status.isFixed) {
|
|
4218
|
-
|
|
4366
|
+
logger6.info("humanScroll | fixed/sticky \u5BB9\u5668\u5185\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
|
|
4219
4367
|
} else {
|
|
4220
|
-
|
|
4368
|
+
logger6.debug("humanScroll | \u5143\u7D20\u53EF\u89C1\u4E14\u65E0\u906E\u6321");
|
|
4221
4369
|
}
|
|
4222
|
-
|
|
4370
|
+
logger6.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
|
|
4223
4371
|
return { element, didScroll, restore: null };
|
|
4224
4372
|
}
|
|
4225
4373
|
if (status.code === "ZERO_DIMENSIONS" || status.code === "NOT_INTERACTABLE") {
|
|
4226
|
-
|
|
4374
|
+
logger6.warn(`humanScroll | \u5143\u7D20\u4E0D\u53EF\u6EDA\u52A8\u81F3\u53EF\u70B9\u51FB\u72B6\u6001: ${status.reason || status.code}`);
|
|
4227
4375
|
return { element, didScroll, restore: null };
|
|
4228
4376
|
}
|
|
4229
4377
|
const scrollRect = await getScrollableRect(element);
|
|
4230
4378
|
if (!scrollRect && status.isFixed && status.code === "OUT_OF_VIEWPORT") {
|
|
4231
|
-
|
|
4379
|
+
logger6.warn(`humanScroll | fixed/sticky \u76EE\u6807\u4E0D\u5728\u89C6\u53E3\u5185\uFF0C\u9875\u9762\u6EDA\u52A8\u65E0\u6CD5\u6539\u53D8\u5176\u4F4D\u7F6E (direction=${status.direction || "unknown"})`);
|
|
4232
4380
|
return { element, didScroll, restore: null, unscrollable: true };
|
|
4233
4381
|
}
|
|
4234
4382
|
if (!scrollRect && status.isFixed && status.code === "OBSTRUCTED") {
|
|
4235
|
-
|
|
4383
|
+
logger6.warn(`humanScroll | fixed/sticky \u76EE\u6807\u88AB\u906E\u6321\uFF0C\u6EDA\u52A8\u65E0\u6CD5\u89E3\u9664 (${status.obstruction?.tag || "unknown"})`);
|
|
4236
4384
|
return { element, didScroll, restore: null, unscrollable: true };
|
|
4237
4385
|
}
|
|
4238
4386
|
if (scrollRect && status.code === "OBSTRUCTED" && status.obstruction?.isFixed) {
|
|
4239
4387
|
const moved = await scrollAwayFromObstruction(element, status);
|
|
4240
4388
|
if (moved.moved) {
|
|
4241
|
-
|
|
4389
|
+
logger6.debug(`humanScroll | sticky/fixed \u906E\u6321\u8865\u507F\u6EDA\u52A8 top=${Math.round(moved.scrollTop || 0)}`);
|
|
4242
4390
|
await waitJitter(90, 0.3);
|
|
4243
4391
|
didScroll = true;
|
|
4244
4392
|
continue;
|
|
4245
4393
|
}
|
|
4246
4394
|
}
|
|
4247
4395
|
if (Date.now() - startTime > maxDurationMs) {
|
|
4248
|
-
|
|
4396
|
+
logger6.warn(`humanScroll | mobile timeout (${maxDurationMs}ms, status=${status.code}, direction=${status.direction || "unknown"}, fixed=${Boolean(status.isFixed)})`);
|
|
4249
4397
|
return { element, didScroll, restore: null };
|
|
4250
4398
|
}
|
|
4251
4399
|
const stepMin = scrollRect ? Math.min(minStep, Math.max(60, scrollRect.height * 0.4)) : minStep;
|
|
4252
4400
|
const stepMax = scrollRect ? Math.min(maxStep, Math.max(stepMin + 40, scrollRect.height * 0.8)) : maxStep;
|
|
4253
|
-
|
|
4401
|
+
logger6.debug(`humanScroll | \u6B65\u9AA4 ${i + 1}/${maxSteps}: ${status.reason || status.code} ${status.direction ? `(${status.direction})` : ""}`);
|
|
4254
4402
|
const distance = stepMin + Math.random() * Math.max(1, stepMax - stepMin);
|
|
4255
4403
|
let deltaY = status.direction === "up" ? -distance : distance;
|
|
4256
4404
|
if (status.code === "OBSTRUCTED") {
|
|
@@ -4290,8 +4438,8 @@ var MobileHumanize = {
|
|
|
4290
4438
|
if (scrollRect && beforeWindowState) {
|
|
4291
4439
|
const afterWindowState = await page.evaluate(() => ({ x: window.scrollX, y: window.scrollY }));
|
|
4292
4440
|
if (Math.abs(afterWindowState.x - beforeWindowState.x) > 2 || Math.abs(afterWindowState.y - beforeWindowState.y) > 2) {
|
|
4293
|
-
await page.evaluate((
|
|
4294
|
-
|
|
4441
|
+
await page.evaluate((state2) => window.scrollTo(state2.x, state2.y), beforeWindowState);
|
|
4442
|
+
logger6.debug(`humanScroll | \u7A97\u53E3\u6EDA\u52A8\u56DE\u6536 from=${Math.round(afterWindowState.y)} to=${Math.round(beforeWindowState.y)}`);
|
|
4295
4443
|
}
|
|
4296
4444
|
}
|
|
4297
4445
|
let afterElementSnapshot = null;
|
|
@@ -4305,7 +4453,7 @@ var MobileHumanize = {
|
|
|
4305
4453
|
const afterSnapshot = await readAfterElementSnapshot();
|
|
4306
4454
|
if (isTargetImmobileAfterScroll(beforeElementSnapshot, afterSnapshot)) {
|
|
4307
4455
|
await restoreWindowFromSnapshot(page, beforeElementSnapshot, afterSnapshot);
|
|
4308
|
-
|
|
4456
|
+
logger6.warn(`humanScroll | \u76EE\u6807\u4E0D\u968F\u9875\u9762\u6EDA\u52A8\u79FB\u52A8\uFF0C\u9875\u9762\u6EDA\u52A8\u65E0\u6CD5\u6539\u53D8\u5176\u4F4D\u7F6E (status=${status.code}, direction=${status.direction || "unknown"})`);
|
|
4309
4457
|
return { element, didScroll, restore: null, unscrollable: true };
|
|
4310
4458
|
}
|
|
4311
4459
|
}
|
|
@@ -4337,12 +4485,12 @@ var MobileHumanize = {
|
|
|
4337
4485
|
const moved = beforeState.kind !== afterState.kind || Math.abs(topDelta) > 2 || Math.abs(leftDelta) > 2;
|
|
4338
4486
|
if (!moved) {
|
|
4339
4487
|
const fallback = await scrollScrollableAncestor(element, deltaY);
|
|
4340
|
-
|
|
4488
|
+
logger6.debug(`humanScroll | \u5BB9\u5668\u89E6\u6478\u65E0\u6548\uFF0C\u76F4\u63A5\u6EDA\u52A8 fallback=${fallback.scroller ? "ancestor" : "window"} top=${Math.round(fallback.scrollTop || 0)}`);
|
|
4341
4489
|
} else if (beforeState.kind === afterState.kind && Math.abs(expectedDelta) > 24 && Math.sign(topDelta || expectedDelta) === Math.sign(expectedDelta) && Math.abs(topDelta) < Math.min(Math.abs(expectedDelta) * 0.45, 96)) {
|
|
4342
4490
|
const residualDelta = expectedDelta - topDelta;
|
|
4343
4491
|
if (Math.sign(residualDelta) === Math.sign(expectedDelta) && Math.abs(residualDelta) > 24) {
|
|
4344
4492
|
const fallback = await scrollScrollableAncestor(element, residualDelta);
|
|
4345
|
-
|
|
4493
|
+
logger6.debug(`humanScroll | \u5BB9\u5668\u89E6\u6478\u8DDD\u79BB\u4E0D\u8DB3\uFF0C\u8865\u507F\u6EDA\u52A8 fallback=${fallback.scroller ? "ancestor" : "window"} top=${Math.round(fallback.scrollTop || 0)}`);
|
|
4346
4494
|
}
|
|
4347
4495
|
}
|
|
4348
4496
|
}
|
|
@@ -4350,7 +4498,7 @@ var MobileHumanize = {
|
|
|
4350
4498
|
const afterSnapshot = await getElementViewportSnapshot(element).catch(() => null);
|
|
4351
4499
|
if (isTargetImmobileAfterScroll(beforeElementSnapshot, afterSnapshot)) {
|
|
4352
4500
|
await restoreWindowFromSnapshot(page, beforeElementSnapshot, afterSnapshot);
|
|
4353
|
-
|
|
4501
|
+
logger6.warn(`humanScroll | \u76EE\u6807\u4E0D\u968F\u6EDA\u52A8\u5BB9\u5668\u79FB\u52A8\uFF0C\u6EDA\u52A8\u65E0\u6CD5\u6539\u53D8\u5176\u4F4D\u7F6E (status=${status.code}, direction=${status.direction || "unknown"})`);
|
|
4354
4502
|
return { element, didScroll, restore: null, unscrollable: true };
|
|
4355
4503
|
}
|
|
4356
4504
|
}
|
|
@@ -4361,14 +4509,14 @@ var MobileHumanize = {
|
|
|
4361
4509
|
await waitJitter(80, 0.3);
|
|
4362
4510
|
const finalStatus = await checkElementVisibility(element);
|
|
4363
4511
|
if (finalStatus.code === "VISIBLE") {
|
|
4364
|
-
|
|
4365
|
-
|
|
4512
|
+
logger6.info("humanScroll | \u539F\u751F scrollIntoViewIfNeeded \u515C\u5E95\u6210\u529F");
|
|
4513
|
+
logger6.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
|
|
4366
4514
|
return { element, didScroll: true, restore: null };
|
|
4367
4515
|
}
|
|
4368
4516
|
} catch (fallbackError) {
|
|
4369
|
-
|
|
4517
|
+
logger6.debug(`humanScroll | native fallback failed: ${fallbackError?.message || fallbackError}`);
|
|
4370
4518
|
}
|
|
4371
|
-
|
|
4519
|
+
logger6.warn(`humanScroll | \u5728 ${maxSteps} \u6B65\u540E\u65E0\u6CD5\u786E\u4FDD\u53EF\u89C1\u6027`);
|
|
4372
4520
|
return { element, didScroll, restore: null };
|
|
4373
4521
|
},
|
|
4374
4522
|
async humanClick(page, target, options = {}) {
|
|
@@ -4383,7 +4531,7 @@ var MobileHumanize = {
|
|
|
4383
4531
|
fallbackDomClickOnTapError = true
|
|
4384
4532
|
} = options;
|
|
4385
4533
|
const targetDesc = describeTarget(target);
|
|
4386
|
-
|
|
4534
|
+
logger6.start("humanClick", `target=${targetDesc}`);
|
|
4387
4535
|
try {
|
|
4388
4536
|
if (target == null) {
|
|
4389
4537
|
const viewport = resolveViewport(page);
|
|
@@ -4395,12 +4543,12 @@ var MobileHumanize = {
|
|
|
4395
4543
|
timeoutMs: tapTimeoutMs,
|
|
4396
4544
|
mouseFallbackTimeoutMs
|
|
4397
4545
|
});
|
|
4398
|
-
|
|
4546
|
+
logger6.success("humanClick", "Tapped current position");
|
|
4399
4547
|
return true;
|
|
4400
4548
|
}
|
|
4401
4549
|
const element = await resolveElement(page, target, { throwOnMissing });
|
|
4402
4550
|
if (!element) {
|
|
4403
|
-
|
|
4551
|
+
logger6.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${targetDesc}`);
|
|
4404
4552
|
return false;
|
|
4405
4553
|
}
|
|
4406
4554
|
const scrollResult = scrollIfNeeded ? await MobileHumanize.humanScroll(page, element, { throwOnMissing }) : null;
|
|
@@ -4424,19 +4572,19 @@ var MobileHumanize = {
|
|
|
4424
4572
|
).catch(() => null);
|
|
4425
4573
|
}
|
|
4426
4574
|
if (fallback?.activated) {
|
|
4427
|
-
|
|
4575
|
+
logger6.warn(`humanClick: \u4E0D\u53EF\u6EDA\u52A8\u76EE\u6807\u4E0D\u53EF\u7269\u7406\u70B9\u51FB\uFF0C\u5DF2\u7528 ${fallback.method} \u6FC0\u6D3B`);
|
|
4428
4576
|
return true;
|
|
4429
4577
|
}
|
|
4430
4578
|
}
|
|
4431
4579
|
const message = `\u5143\u7D20\u4E0D\u53EF\u70B9\u51FB: ${status.reason || status.code}`;
|
|
4432
4580
|
if (throwOnMissing) throw new Error(message);
|
|
4433
|
-
|
|
4581
|
+
logger6.warn(`humanClick: ${message}\uFF0C\u8DF3\u8FC7\u70B9\u51FB`);
|
|
4434
4582
|
return false;
|
|
4435
4583
|
}
|
|
4436
4584
|
const box = await element.boundingBox();
|
|
4437
4585
|
if (!box) {
|
|
4438
4586
|
if (throwOnMissing) throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5143\u7D20\u4F4D\u7F6E");
|
|
4439
|
-
|
|
4587
|
+
logger6.warn("humanClick: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E\uFF0C\u8DF3\u8FC7\u70B9\u51FB");
|
|
4440
4588
|
return false;
|
|
4441
4589
|
}
|
|
4442
4590
|
await waitJitter(reactionDelay, 0.45);
|
|
@@ -4457,13 +4605,13 @@ var MobileHumanize = {
|
|
|
4457
4605
|
"activation fallback"
|
|
4458
4606
|
).catch(() => null);
|
|
4459
4607
|
if (!fallback?.activated) throw tapError;
|
|
4460
|
-
|
|
4608
|
+
logger6.warn(`humanClick: tap \u5931\u8D25\u540E\u5DF2\u7528 ${fallback.method} \u515C\u5E95: ${tapError?.message || tapError}`);
|
|
4461
4609
|
}
|
|
4462
4610
|
await waitJitter(120, 0.35);
|
|
4463
|
-
|
|
4611
|
+
logger6.success("humanClick");
|
|
4464
4612
|
return true;
|
|
4465
4613
|
} catch (error) {
|
|
4466
|
-
|
|
4614
|
+
logger6.fail("humanClick", error);
|
|
4467
4615
|
throw error;
|
|
4468
4616
|
}
|
|
4469
4617
|
},
|
|
@@ -4516,7 +4664,7 @@ var MobileHumanize = {
|
|
|
4516
4664
|
keyboardOptions = {}
|
|
4517
4665
|
} = pressOptions || {};
|
|
4518
4666
|
const targetDesc = hasTarget ? describeTarget(targetOrKey) : "current focus";
|
|
4519
|
-
|
|
4667
|
+
logger6.start("humanPress", `key=${key}, target=${targetDesc}`);
|
|
4520
4668
|
try {
|
|
4521
4669
|
if (hasTarget) {
|
|
4522
4670
|
await MobileHumanize.humanClick(page, targetOrKey, {
|
|
@@ -4530,10 +4678,10 @@ var MobileHumanize = {
|
|
|
4530
4678
|
...keyboardOptions,
|
|
4531
4679
|
delay: jitterMs(holdDelay, 0.5)
|
|
4532
4680
|
});
|
|
4533
|
-
|
|
4681
|
+
logger6.success("humanPress");
|
|
4534
4682
|
return true;
|
|
4535
4683
|
} catch (error) {
|
|
4536
|
-
|
|
4684
|
+
logger6.fail("humanPress", error);
|
|
4537
4685
|
throw error;
|
|
4538
4686
|
}
|
|
4539
4687
|
},
|
|
@@ -4600,65 +4748,96 @@ var MobileHumanize = {
|
|
|
4600
4748
|
}
|
|
4601
4749
|
};
|
|
4602
4750
|
|
|
4603
|
-
// src/humanize.js
|
|
4751
|
+
// src/internals/humanize/default.js
|
|
4604
4752
|
var resolveDeviceFromPage2 = (page) => normalizeDevice(page?.[PageRuntimeStateKey]?.device);
|
|
4605
4753
|
var resolveDelegate = (page) => {
|
|
4606
4754
|
return resolveDeviceFromPage2(page) === Device.Mobile ? MobileHumanize : Humanize;
|
|
4607
4755
|
};
|
|
4608
|
-
var
|
|
4609
|
-
|
|
4610
|
-
|
|
4756
|
+
var DefaultHumanizeDevice = withPageReflect(
|
|
4757
|
+
"DefaultHumanize",
|
|
4758
|
+
resolveDelegate,
|
|
4759
|
+
[Humanize, MobileHumanize]
|
|
4760
|
+
);
|
|
4761
|
+
|
|
4762
|
+
// src/internals/humanize/cloak.js
|
|
4763
|
+
var FORCE_CLICK = Object.freeze({
|
|
4764
|
+
forceClick: true,
|
|
4765
|
+
clickOptions: { force: true }
|
|
4766
|
+
});
|
|
4767
|
+
var pointOrNull = async (target) => {
|
|
4768
|
+
if (!target || typeof target.boundingBox !== "function") return null;
|
|
4769
|
+
const box = await target.boundingBox().catch(() => null);
|
|
4770
|
+
return box ? { x: box.x + box.width / 2, y: box.y + box.height / 2 } : null;
|
|
4611
4771
|
};
|
|
4612
|
-
var
|
|
4613
|
-
|
|
4614
|
-
return
|
|
4615
|
-
},
|
|
4616
|
-
initializeCursor(page) {
|
|
4617
|
-
return callDelegate("initializeCursor", page, []);
|
|
4772
|
+
var CloakHumanizeInput = {
|
|
4773
|
+
async initializeCursor(page) {
|
|
4774
|
+
return Boolean(page);
|
|
4618
4775
|
},
|
|
4619
|
-
humanMove(page, target) {
|
|
4620
|
-
|
|
4776
|
+
async humanMove(page, target) {
|
|
4777
|
+
const point = target?.x != null && target?.y != null ? target : await pointOrNull(typeof target === "string" ? page.locator(target).first() : target);
|
|
4778
|
+
return point ? await DeviceInput.move(page, point, { forceMouse: true }) : false;
|
|
4621
4779
|
},
|
|
4622
|
-
humanScroll(page, target
|
|
4623
|
-
|
|
4780
|
+
async humanScroll(page, target) {
|
|
4781
|
+
const element = typeof target === "string" ? page.locator(target).first() : target;
|
|
4782
|
+
if (!element) return { element: null, didScroll: false, restore: null };
|
|
4783
|
+
await element.scrollIntoViewIfNeeded?.();
|
|
4784
|
+
return { element, didScroll: true, restore: null };
|
|
4624
4785
|
},
|
|
4625
|
-
humanClick(page, target
|
|
4626
|
-
return
|
|
4786
|
+
async humanClick(page, target) {
|
|
4787
|
+
return await DeviceInput.click(page, target, FORCE_CLICK);
|
|
4627
4788
|
},
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
return delegate.randomSleep(maybeBaseMs, maybeJitterPercent);
|
|
4632
|
-
}
|
|
4633
|
-
return Humanize.randomSleep(pageOrBaseMs, maybeBaseMs);
|
|
4789
|
+
async humanType(page, selector, text) {
|
|
4790
|
+
await DeviceInput.click(page, selector, FORCE_CLICK);
|
|
4791
|
+
return await DeviceInput.keyboardType(page, text);
|
|
4634
4792
|
},
|
|
4635
|
-
|
|
4636
|
-
return
|
|
4793
|
+
async humanPress(page, targetOrKey, maybeKey) {
|
|
4794
|
+
return await DeviceInput.press(page, targetOrKey, maybeKey, {
|
|
4795
|
+
clickOptions: FORCE_CLICK,
|
|
4796
|
+
keyboardOptions: {}
|
|
4797
|
+
});
|
|
4637
4798
|
},
|
|
4638
|
-
|
|
4639
|
-
return
|
|
4799
|
+
async humanClear(page, selector) {
|
|
4800
|
+
return await DeviceInput.fill(page, selector, "", { force: true });
|
|
4640
4801
|
},
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
return callDelegate("humanPress", page, [targetOrKey, maybeKey, options]);
|
|
4644
|
-
}
|
|
4645
|
-
return callDelegate("humanPress", page, [targetOrKey, maybeKey || options]);
|
|
4802
|
+
async simulateGaze(page) {
|
|
4803
|
+
return await DeviceInput.move(page, { x: 0, y: 0 }, { forceMouse: true });
|
|
4646
4804
|
},
|
|
4647
|
-
|
|
4648
|
-
return
|
|
4805
|
+
async warmUpBrowsing(page) {
|
|
4806
|
+
return await this.simulateGaze(page);
|
|
4649
4807
|
},
|
|
4650
|
-
|
|
4651
|
-
|
|
4808
|
+
async naturalScroll(page, direction = "down", distance = 300) {
|
|
4809
|
+
const sign = direction === "down" ? 1 : -1;
|
|
4810
|
+
await page.mouse.wheel(0, Number(distance || 0) * sign);
|
|
4811
|
+
}
|
|
4812
|
+
};
|
|
4813
|
+
|
|
4814
|
+
// src/internals/humanize/index.js
|
|
4815
|
+
var HumanizeCommon = {
|
|
4816
|
+
jitterMs(base, jitterPercent = 0.3) {
|
|
4817
|
+
return jitterMs(base, jitterPercent);
|
|
4652
4818
|
},
|
|
4653
|
-
|
|
4654
|
-
|
|
4819
|
+
async randomSleep(pageOrBaseMs, maybeBaseMs, maybeJitterPercent) {
|
|
4820
|
+
const hasPage = pageOrBaseMs && typeof pageOrBaseMs === "object" && typeof pageOrBaseMs.evaluate === "function";
|
|
4821
|
+
const baseMs = hasPage ? maybeBaseMs : pageOrBaseMs;
|
|
4822
|
+
const jitterPercent = hasPage ? maybeJitterPercent : maybeBaseMs;
|
|
4823
|
+
await (0, import_delay4.default)(jitterMs(baseMs, jitterPercent ?? 0.3));
|
|
4655
4824
|
}
|
|
4656
4825
|
};
|
|
4826
|
+
var DefaultHumanize = Object.assign({}, DefaultHumanizeDevice, HumanizeCommon);
|
|
4827
|
+
var CloakHumanize = Object.assign({}, CloakHumanizeInput, HumanizeCommon);
|
|
4657
4828
|
|
|
4658
|
-
// src/
|
|
4829
|
+
// src/humanize.js
|
|
4830
|
+
var humanizeStrategies = {
|
|
4831
|
+
[Mode.Default]: DefaultHumanize,
|
|
4832
|
+
[Mode.Cloak]: CloakHumanize
|
|
4833
|
+
};
|
|
4834
|
+
var Humanize2 = withModeReflect("Humanize", humanizeStrategies);
|
|
4835
|
+
|
|
4836
|
+
// src/internals/launch/default.js
|
|
4659
4837
|
var import_node_child_process = require("node:child_process");
|
|
4660
4838
|
var import_fingerprint_generator = require("fingerprint-generator");
|
|
4661
4839
|
var import_fingerprint_injector = require("fingerprint-injector");
|
|
4840
|
+
var import_playwright2 = require("playwright");
|
|
4662
4841
|
|
|
4663
4842
|
// src/proxy-bypass.js
|
|
4664
4843
|
var import_picomatch = __toESM(require("picomatch"), 1);
|
|
@@ -4740,9 +4919,107 @@ var ByPass = {
|
|
|
4740
4919
|
resolveRouteByProxy
|
|
4741
4920
|
};
|
|
4742
4921
|
|
|
4743
|
-
// src/launch.js
|
|
4922
|
+
// src/internals/launch/traffic.js
|
|
4923
|
+
var logger7 = createInternalLogger("Launch");
|
|
4924
|
+
var normalizeObject = (value) => {
|
|
4925
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
4926
|
+
return {};
|
|
4927
|
+
}
|
|
4928
|
+
return value;
|
|
4929
|
+
};
|
|
4930
|
+
var parseProxyConfiguration = (proxyConfiguration = {}) => {
|
|
4931
|
+
const config = normalizeObject(proxyConfiguration);
|
|
4932
|
+
const proxyUrl = String(config.proxy_url || "").trim();
|
|
4933
|
+
const enableProxy = typeof config.enable_proxy === "boolean" ? config.enable_proxy : proxyUrl !== "";
|
|
4934
|
+
const byPassDomains = enableProxy && proxyUrl ? ByPass.normalizeByPassDomains(config.by_pass_domains) : [];
|
|
4935
|
+
return {
|
|
4936
|
+
byPassDomains,
|
|
4937
|
+
enableProxy,
|
|
4938
|
+
proxyUrl
|
|
4939
|
+
};
|
|
4940
|
+
};
|
|
4941
|
+
var resolveLaunchTraffic = ({
|
|
4942
|
+
proxyConfiguration = {},
|
|
4943
|
+
debugMode = false,
|
|
4944
|
+
useMeter = true
|
|
4945
|
+
} = {}) => {
|
|
4946
|
+
const { byPassDomains, enableProxy, proxyUrl } = parseProxyConfiguration(proxyConfiguration);
|
|
4947
|
+
const byPassRules = ByPass.buildByPassDomainRules(byPassDomains);
|
|
4948
|
+
const proxyMeter = useMeter && enableProxy && proxyUrl ? ProxyMeterRuntime.startProxyMeter({ proxyUrl, debugMode }) : null;
|
|
4949
|
+
const launchProxy = proxyMeter ? { server: proxyMeter.server } : null;
|
|
4950
|
+
if (launchProxy && byPassDomains.length > 0) {
|
|
4951
|
+
launchProxy.bypass = byPassDomains.join(",");
|
|
4952
|
+
}
|
|
4953
|
+
return {
|
|
4954
|
+
byPassDomains,
|
|
4955
|
+
byPassRules,
|
|
4956
|
+
enableProxy,
|
|
4957
|
+
proxyUrl,
|
|
4958
|
+
launchProxy
|
|
4959
|
+
};
|
|
4960
|
+
};
|
|
4961
|
+
var logLaunchTraffic = ({
|
|
4962
|
+
byPassDomains = [],
|
|
4963
|
+
debugMode = false,
|
|
4964
|
+
enabled = false,
|
|
4965
|
+
enableProxy = false,
|
|
4966
|
+
explicitProxy = false,
|
|
4967
|
+
launchProxy = null,
|
|
4968
|
+
proxyUrl = ""
|
|
4969
|
+
} = {}) => {
|
|
4970
|
+
if (!enabled) return;
|
|
4971
|
+
if (explicitProxy) {
|
|
4972
|
+
logger7.info("[\u4EE3\u7406\u5DF2\u542F\u7528] \u4F7F\u7528\u663E\u5F0F proxy \u914D\u7F6E\uFF0C\u8DF3\u8FC7 toolkit \u672C\u5730\u6D41\u91CF\u89C2\u6D4B");
|
|
4973
|
+
return;
|
|
4974
|
+
}
|
|
4975
|
+
if (launchProxy) {
|
|
4976
|
+
let upstreamLabel = "";
|
|
4977
|
+
try {
|
|
4978
|
+
const parsedProxyUrl = new URL(proxyUrl.includes("://") ? proxyUrl : `http://${proxyUrl}`);
|
|
4979
|
+
upstreamLabel = `${parsedProxyUrl.protocol}//${parsedProxyUrl.host}`;
|
|
4980
|
+
} catch {
|
|
4981
|
+
}
|
|
4982
|
+
logger7.info(
|
|
4983
|
+
`[\u4EE3\u7406\u5DF2\u542F\u7528] \u672C\u5730=${launchProxy.server} \u4E0A\u6E38=${upstreamLabel || "-"} \u76F4\u8FDE\u57DF\u540D=${byPassDomains.join(",")}`
|
|
4984
|
+
);
|
|
4985
|
+
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`);
|
|
4986
|
+
return;
|
|
4987
|
+
}
|
|
4988
|
+
if (enableProxy) {
|
|
4989
|
+
logger7.info("[\u4EE3\u7406\u672A\u542F\u7528] enable_proxy=true \u4F46 proxy_url \u4E3A\u7A7A");
|
|
4990
|
+
} else if (proxyUrl) {
|
|
4991
|
+
logger7.info("[\u4EE3\u7406\u672A\u542F\u7528] enable_proxy=false \u4E14 proxy_url \u5DF2\u914D\u7F6E");
|
|
4992
|
+
}
|
|
4993
|
+
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`);
|
|
4994
|
+
};
|
|
4995
|
+
var createLaunchTrafficHook = ({
|
|
4996
|
+
byPassDomains = [],
|
|
4997
|
+
byPassRules = [],
|
|
4998
|
+
enabled = false,
|
|
4999
|
+
launchProxy = null
|
|
5000
|
+
} = {}) => {
|
|
5001
|
+
const patchedPages = /* @__PURE__ */ new WeakSet();
|
|
5002
|
+
return (page) => {
|
|
5003
|
+
if (!page || typeof page.on !== "function" || patchedPages.has(page)) {
|
|
5004
|
+
return;
|
|
5005
|
+
}
|
|
5006
|
+
patchedPages.add(page);
|
|
5007
|
+
page.on("request", (req) => {
|
|
5008
|
+
const requestUrl = req.url();
|
|
5009
|
+
const resourceType = req.resourceType();
|
|
5010
|
+
const matched = byPassDomains.length > 0 ? ByPass.findMatchedByPassRule(byPassRules, requestUrl) : null;
|
|
5011
|
+
if (launchProxy) {
|
|
5012
|
+
ProxyMeterRuntime.recordProxyMeterResourceType(requestUrl, resourceType);
|
|
5013
|
+
}
|
|
5014
|
+
if (!enabled || byPassDomains.length === 0) return;
|
|
5015
|
+
if (!matched || !matched.rule) return;
|
|
5016
|
+
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}`);
|
|
5017
|
+
});
|
|
5018
|
+
};
|
|
5019
|
+
};
|
|
5020
|
+
|
|
5021
|
+
// src/internals/launch/default.js
|
|
4744
5022
|
var logger8 = createInternalLogger("Launch");
|
|
4745
|
-
var REQUEST_HOOK_FLAG = Symbol("playwright-toolkit-request-hook");
|
|
4746
5023
|
var injectedContexts = /* @__PURE__ */ new WeakSet();
|
|
4747
5024
|
var browserMajorVersionCache = /* @__PURE__ */ new Map();
|
|
4748
5025
|
var DEFAULT_BROWSER_PROFILE_SCHEMA_VERSION = 1;
|
|
@@ -4754,16 +5031,6 @@ var DEFAULT_CRAWLER_BASE_OPTIONS = Object.freeze({
|
|
|
4754
5031
|
navigationTimeoutSecs: 120
|
|
4755
5032
|
});
|
|
4756
5033
|
var fingerprintInjector = new import_fingerprint_injector.FingerprintInjector();
|
|
4757
|
-
var resolveProxyLaunchOptions = (proxyConfiguration = {}) => {
|
|
4758
|
-
const config = proxyConfiguration && typeof proxyConfiguration === "object" && !Array.isArray(proxyConfiguration) ? proxyConfiguration : {};
|
|
4759
|
-
const proxyUrl = String(config.proxy_url || "").trim();
|
|
4760
|
-
const enableProxy = typeof config.enable_proxy === "boolean" ? config.enable_proxy : proxyUrl !== "";
|
|
4761
|
-
if (!enableProxy || !proxyUrl) {
|
|
4762
|
-
return { byPassDomains: [], enableProxy, proxyUrl };
|
|
4763
|
-
}
|
|
4764
|
-
const byPassDomains = ByPass.normalizeByPassDomains(config.by_pass_domains);
|
|
4765
|
-
return { byPassDomains, enableProxy, proxyUrl };
|
|
4766
|
-
};
|
|
4767
5034
|
var parseChromeMajorVersion = (rawValue = "") => {
|
|
4768
5035
|
const match = String(rawValue || "").match(/(?:Chrome|Chromium)(?:\/|\s+(?:for Testing\s+)?)(\d+)/i);
|
|
4769
5036
|
return match ? Number(match[1] || 0) : 0;
|
|
@@ -4807,7 +5074,7 @@ var resolveCoreDevice = (core = {}) => {
|
|
|
4807
5074
|
};
|
|
4808
5075
|
var buildFingerprintGenerator = ({ locale, browserMajorVersion, device }) => {
|
|
4809
5076
|
return new import_fingerprint_generator.FingerprintGenerator(
|
|
4810
|
-
|
|
5077
|
+
DefaultAntiCheat.getFingerprintGeneratorOptions({
|
|
4811
5078
|
locale,
|
|
4812
5079
|
browserMajorVersion,
|
|
4813
5080
|
device
|
|
@@ -4851,7 +5118,7 @@ var buildReplayableBrowserProfile = (runtimeState, launcher) => {
|
|
|
4851
5118
|
}
|
|
4852
5119
|
let nextState = RuntimeEnv.rememberState(runtimeState);
|
|
4853
5120
|
let browserProfileCore = RuntimeEnv.getBrowserProfileCore(nextState);
|
|
4854
|
-
const timezoneId = String(browserProfileCore?.timezone_id || "").trim() ||
|
|
5121
|
+
const timezoneId = String(browserProfileCore?.timezone_id || "").trim() || DefaultAntiCheat.getBaseConfig().timezoneId;
|
|
4855
5122
|
const locale = DEFAULT_LOCALE;
|
|
4856
5123
|
const currentBrowserMajorVersion = detectBrowserMajorVersion(launcher);
|
|
4857
5124
|
const storedBrowserMajorVersion = Number(browserProfileCore?.browser_major_version || 0);
|
|
@@ -4867,6 +5134,7 @@ var buildReplayableBrowserProfile = (runtimeState, launcher) => {
|
|
|
4867
5134
|
const fingerprint = generated.fingerprint;
|
|
4868
5135
|
const fingerprintBrowserMajorVersion = parseChromeMajorVersion(fingerprint?.fingerprint?.navigator?.userAgent || "");
|
|
4869
5136
|
browserProfileCore = {
|
|
5137
|
+
...browserProfileCore,
|
|
4870
5138
|
fingerprint,
|
|
4871
5139
|
device,
|
|
4872
5140
|
timezone_id: timezoneId,
|
|
@@ -4930,7 +5198,7 @@ var applyFingerprintPageOptions = (pageOptions = {}, { fingerprintWithHeaders =
|
|
|
4930
5198
|
pageOptions.timezoneId = timezoneId;
|
|
4931
5199
|
}
|
|
4932
5200
|
};
|
|
4933
|
-
var buildReplayBrowserPoolOptions = (browserProfileCore
|
|
5201
|
+
var buildReplayBrowserPoolOptions = (browserProfileCore) => {
|
|
4934
5202
|
const fingerprintWithHeaders = browserProfileCore?.fingerprint;
|
|
4935
5203
|
const fingerprint = fingerprintWithHeaders?.fingerprint;
|
|
4936
5204
|
if (!fingerprintWithHeaders || !fingerprint) {
|
|
@@ -4939,16 +5207,13 @@ var buildReplayBrowserPoolOptions = (browserProfileCore, modifyPageOptions = nul
|
|
|
4939
5207
|
return {
|
|
4940
5208
|
useFingerprints: false,
|
|
4941
5209
|
prePageCreateHooks: [
|
|
4942
|
-
|
|
5210
|
+
(_pageId, _browserController, pageOptions = {}) => {
|
|
4943
5211
|
if (!pageOptions || typeof pageOptions !== "object") return;
|
|
4944
5212
|
applyFingerprintPageOptions(pageOptions, {
|
|
4945
5213
|
fingerprintWithHeaders,
|
|
4946
5214
|
locale: browserProfileCore.locale,
|
|
4947
5215
|
timezoneId: browserProfileCore.timezone_id
|
|
4948
5216
|
});
|
|
4949
|
-
if (modifyPageOptions) {
|
|
4950
|
-
await modifyPageOptions(pageOptions, { pageId, browserController });
|
|
4951
|
-
}
|
|
4952
5217
|
}
|
|
4953
5218
|
],
|
|
4954
5219
|
postPageCreateHooks: [
|
|
@@ -4963,7 +5228,7 @@ var buildReplayBrowserPoolOptions = (browserProfileCore, modifyPageOptions = nul
|
|
|
4963
5228
|
]
|
|
4964
5229
|
};
|
|
4965
5230
|
};
|
|
4966
|
-
var
|
|
5231
|
+
var DefaultLaunch = {
|
|
4967
5232
|
getPlaywrightCrawlerOptions(options = {}) {
|
|
4968
5233
|
const normalizedOptions = Array.isArray(options) ? { customArgs: options } : options || {};
|
|
4969
5234
|
const {
|
|
@@ -4974,54 +5239,36 @@ var Launch = {
|
|
|
4974
5239
|
debugMode = false,
|
|
4975
5240
|
isRunningOnApify = false,
|
|
4976
5241
|
launcher = null,
|
|
4977
|
-
hooks = {},
|
|
4978
5242
|
preNavigationHooks = [],
|
|
4979
5243
|
postNavigationHooks = [],
|
|
4980
5244
|
runtimeState = null
|
|
4981
5245
|
} = normalizedOptions;
|
|
4982
5246
|
const device = resolveRuntimeDevice(runtimeState);
|
|
4983
|
-
const
|
|
4984
|
-
const
|
|
4985
|
-
const
|
|
4986
|
-
const
|
|
4987
|
-
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
|
|
4991
|
-
const
|
|
4992
|
-
const replayBrowserPoolOptions = buildReplayBrowserPoolOptions(replayContext.browserProfileCore, modifyPageOptions);
|
|
5247
|
+
const effectiveLauncher = launcher || import_playwright2.chromium;
|
|
5248
|
+
const enableByPassLogger = Boolean(logOptions && logOptions.enable);
|
|
5249
|
+
const traffic = resolveLaunchTraffic({ proxyConfiguration, debugMode });
|
|
5250
|
+
const trafficHook = createLaunchTrafficHook({
|
|
5251
|
+
...traffic,
|
|
5252
|
+
enabled: enableByPassLogger
|
|
5253
|
+
});
|
|
5254
|
+
const replayContext = buildReplayableBrowserProfile(runtimeState, effectiveLauncher);
|
|
5255
|
+
const replayBrowserPoolOptions = buildReplayBrowserPoolOptions(replayContext.browserProfileCore);
|
|
4993
5256
|
const launchLocale = String(replayContext.browserProfileCore?.locale || DEFAULT_LOCALE).trim() || DEFAULT_LOCALE;
|
|
4994
5257
|
const launchOptions = {
|
|
4995
5258
|
args: [
|
|
4996
|
-
...
|
|
5259
|
+
...DefaultAntiCheat.getLaunchArgs({ locale: launchLocale }),
|
|
4997
5260
|
...customArgs
|
|
4998
5261
|
],
|
|
4999
5262
|
ignoreDefaultArgs: ["--enable-automation"]
|
|
5000
5263
|
};
|
|
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`);
|
|
5264
|
+
if (traffic.launchProxy) {
|
|
5265
|
+
launchOptions.proxy = traffic.launchProxy;
|
|
5024
5266
|
}
|
|
5267
|
+
logLaunchTraffic({
|
|
5268
|
+
...traffic,
|
|
5269
|
+
debugMode,
|
|
5270
|
+
enabled: enableByPassLogger
|
|
5271
|
+
});
|
|
5025
5272
|
const onPageCreated = (page) => {
|
|
5026
5273
|
const recommendedGotoOptions = {
|
|
5027
5274
|
waitUntil: "commit"
|
|
@@ -5029,31 +5276,14 @@ var Launch = {
|
|
|
5029
5276
|
if (!page || typeof page.on !== "function") {
|
|
5030
5277
|
return recommendedGotoOptions;
|
|
5031
5278
|
}
|
|
5032
|
-
|
|
5033
|
-
return recommendedGotoOptions;
|
|
5034
|
-
}
|
|
5035
|
-
page[REQUEST_HOOK_FLAG] = true;
|
|
5036
|
-
const requestHandler = (req) => {
|
|
5037
|
-
const requestUrl = req.url();
|
|
5038
|
-
const resourceType = req.resourceType();
|
|
5039
|
-
const matched = byPassDomains.length > 0 ? ByPass.findMatchedByPassRule(byPassRules, requestUrl) : null;
|
|
5040
|
-
if (launchProxy) {
|
|
5041
|
-
ProxyMeterRuntime.recordProxyMeterResourceType(requestUrl, resourceType);
|
|
5042
|
-
}
|
|
5043
|
-
if (!enableByPassLogger || byPassDomains.length === 0) return;
|
|
5044
|
-
if (!matched || !matched.rule) return;
|
|
5045
|
-
logger8.info(`[\u76F4\u8FDE\u547D\u4E2D] \u89C4\u5219=${matched.rule.pattern} \u57DF\u540D=${matched.hostname} \u8D44\u6E90\u7C7B\u578B=${resourceType} \u65B9\u6CD5=${req.method()} \u5730\u5740=${requestUrl}`);
|
|
5046
|
-
};
|
|
5047
|
-
page.on("request", requestHandler);
|
|
5279
|
+
trafficHook(page);
|
|
5048
5280
|
return recommendedGotoOptions;
|
|
5049
5281
|
};
|
|
5050
5282
|
const launchContext = {
|
|
5051
5283
|
useIncognitoPages: true,
|
|
5052
|
-
launchOptions
|
|
5284
|
+
launchOptions,
|
|
5285
|
+
launcher: effectiveLauncher
|
|
5053
5286
|
};
|
|
5054
|
-
if (launcher) {
|
|
5055
|
-
launchContext.launcher = launcher;
|
|
5056
|
-
}
|
|
5057
5287
|
const crawlerBaseOptions = {
|
|
5058
5288
|
...DEFAULT_CRAWLER_BASE_OPTIONS,
|
|
5059
5289
|
headless: !runInHeadfulMode || isRunningOnApify,
|
|
@@ -5061,23 +5291,20 @@ var Launch = {
|
|
|
5061
5291
|
browserPoolOptions: replayBrowserPoolOptions || {
|
|
5062
5292
|
useFingerprints: true,
|
|
5063
5293
|
fingerprintOptions: {
|
|
5064
|
-
fingerprintGeneratorOptions:
|
|
5294
|
+
fingerprintGeneratorOptions: DefaultAntiCheat.getFingerprintGeneratorOptions({
|
|
5065
5295
|
locale: launchLocale,
|
|
5066
5296
|
device
|
|
5067
5297
|
})
|
|
5068
5298
|
},
|
|
5069
5299
|
prePageCreateHooks: [
|
|
5070
|
-
|
|
5300
|
+
(_pageId, browserController, pageOptions = {}) => {
|
|
5071
5301
|
const fingerprintWithHeaders = browserController?.launchContext?.fingerprint;
|
|
5072
|
-
const timezoneId =
|
|
5302
|
+
const timezoneId = DefaultAntiCheat.getBaseConfig().timezoneId;
|
|
5073
5303
|
applyFingerprintPageOptions(pageOptions, {
|
|
5074
5304
|
fingerprintWithHeaders,
|
|
5075
5305
|
locale: launchLocale,
|
|
5076
5306
|
timezoneId
|
|
5077
5307
|
});
|
|
5078
|
-
if (modifyPageOptions) {
|
|
5079
|
-
await modifyPageOptions(pageOptions, { pageId, browserController });
|
|
5080
|
-
}
|
|
5081
5308
|
}
|
|
5082
5309
|
]
|
|
5083
5310
|
},
|
|
@@ -5099,10 +5326,464 @@ var Launch = {
|
|
|
5099
5326
|
}
|
|
5100
5327
|
};
|
|
5101
5328
|
|
|
5329
|
+
// src/internals/launch/cloak.js
|
|
5330
|
+
var import_node_child_process2 = require("node:child_process");
|
|
5331
|
+
var import_node_crypto = require("node:crypto");
|
|
5332
|
+
var import_node_util = require("node:util");
|
|
5333
|
+
var logger9 = createInternalLogger("Launch");
|
|
5334
|
+
var execFileAsync = (0, import_node_util.promisify)(import_node_child_process2.execFile);
|
|
5335
|
+
var DEFAULT_CLOAK_CRAWLER_BASE_OPTIONS = Object.freeze({
|
|
5336
|
+
maxConcurrency: 1,
|
|
5337
|
+
maxRequestRetries: 0,
|
|
5338
|
+
requestHandlerTimeoutSecs: 240,
|
|
5339
|
+
navigationTimeoutSecs: 120
|
|
5340
|
+
});
|
|
5341
|
+
var DEFAULT_CLOAK_HUMANIZE_OPTIONS = Object.freeze({
|
|
5342
|
+
humanize: true
|
|
5343
|
+
});
|
|
5344
|
+
var DEFAULT_CLOAK_GOTO_OPTIONS = Object.freeze({
|
|
5345
|
+
waitUntil: "commit"
|
|
5346
|
+
});
|
|
5347
|
+
var DEFAULT_CLOAK_SEED_MIN = 1e4;
|
|
5348
|
+
var DEFAULT_CLOAK_SEED_MAX = 99999;
|
|
5349
|
+
var DEFAULT_CLOAK_FINGERPRINT_PLATFORM = "linux";
|
|
5350
|
+
var CLOAK_FINGERPRINT_ARG_PREFIX = "--fingerprint=";
|
|
5351
|
+
var CLOAK_FINGERPRINT_PLATFORM_ARG_PREFIX = "--fingerprint-platform=";
|
|
5352
|
+
var CLOAK_FINGERPRINT_TIMEZONE_ARG_PREFIX = "--fingerprint-timezone=";
|
|
5353
|
+
var CLOAK_FINGERPRINT_LOCALE_ARG_PREFIX = "--fingerprint-locale=";
|
|
5354
|
+
var CLOAK_LANG_ARG_PREFIX = "--lang=";
|
|
5355
|
+
var SUPPORTED_CLOAK_FINGERPRINT_PLATFORMS2 = /* @__PURE__ */ new Set(["linux", "macos", "windows"]);
|
|
5356
|
+
var cachedCloakModulePromise = null;
|
|
5357
|
+
var hasOwn = (target, key) => Object.prototype.hasOwnProperty.call(target, key);
|
|
5358
|
+
var loadCloakModule = async () => {
|
|
5359
|
+
if (!cachedCloakModulePromise) {
|
|
5360
|
+
cachedCloakModulePromise = import("cloakbrowser").catch((error) => {
|
|
5361
|
+
cachedCloakModulePromise = null;
|
|
5362
|
+
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", {
|
|
5363
|
+
cause: error
|
|
5364
|
+
});
|
|
5365
|
+
});
|
|
5366
|
+
}
|
|
5367
|
+
return cachedCloakModulePromise;
|
|
5368
|
+
};
|
|
5369
|
+
var buildCloakLaunchOptions = async (options = {}) => {
|
|
5370
|
+
const { buildLaunchOptions } = await loadCloakModule();
|
|
5371
|
+
return await buildLaunchOptions(normalizeObject2(options));
|
|
5372
|
+
};
|
|
5373
|
+
var normalizeObject2 = (value) => {
|
|
5374
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
5375
|
+
return {};
|
|
5376
|
+
}
|
|
5377
|
+
return value;
|
|
5378
|
+
};
|
|
5379
|
+
var normalizeStringArray = (value) => {
|
|
5380
|
+
if (!Array.isArray(value)) {
|
|
5381
|
+
return [];
|
|
5382
|
+
}
|
|
5383
|
+
return value.map((item) => String(item || "").trim()).filter(Boolean);
|
|
5384
|
+
};
|
|
5385
|
+
var normalizeText = (value) => String(value || "").trim();
|
|
5386
|
+
var normalizePositiveInteger = (value) => {
|
|
5387
|
+
const numericValue = Number(value);
|
|
5388
|
+
if (Number.isSafeInteger(numericValue) && numericValue > 0) {
|
|
5389
|
+
return numericValue;
|
|
5390
|
+
}
|
|
5391
|
+
const raw = normalizeText(value);
|
|
5392
|
+
if (!/^\d+$/.test(raw)) {
|
|
5393
|
+
return 0;
|
|
5394
|
+
}
|
|
5395
|
+
const parsedValue = Number(raw);
|
|
5396
|
+
return Number.isSafeInteger(parsedValue) && parsedValue > 0 ? parsedValue : 0;
|
|
5397
|
+
};
|
|
5398
|
+
var normalizeCloakFingerprintPlatform2 = (value) => {
|
|
5399
|
+
const normalizedFingerprintPlatform = String(value || "").trim().toLowerCase();
|
|
5400
|
+
return SUPPORTED_CLOAK_FINGERPRINT_PLATFORMS2.has(normalizedFingerprintPlatform) ? normalizedFingerprintPlatform : "";
|
|
5401
|
+
};
|
|
5402
|
+
var buildCloakFingerprintPlatformArg = (fingerprintPlatform = DEFAULT_CLOAK_FINGERPRINT_PLATFORM) => `${CLOAK_FINGERPRINT_PLATFORM_ARG_PREFIX}${fingerprintPlatform}`;
|
|
5403
|
+
var resolveCloakFingerprintPlatformArg = (fingerprintPlatform = "", args = []) => {
|
|
5404
|
+
const normalizedFingerprintPlatform = normalizeCloakFingerprintPlatform2(fingerprintPlatform);
|
|
5405
|
+
if (normalizedFingerprintPlatform) {
|
|
5406
|
+
return buildCloakFingerprintPlatformArg(normalizedFingerprintPlatform);
|
|
5407
|
+
}
|
|
5408
|
+
const existingFingerprintPlatform = normalizeCloakFingerprintPlatform2(
|
|
5409
|
+
extractArgValue(args, CLOAK_FINGERPRINT_PLATFORM_ARG_PREFIX)
|
|
5410
|
+
);
|
|
5411
|
+
if (existingFingerprintPlatform) {
|
|
5412
|
+
return buildCloakFingerprintPlatformArg(existingFingerprintPlatform);
|
|
5413
|
+
}
|
|
5414
|
+
return buildCloakFingerprintPlatformArg(DEFAULT_CLOAK_FINGERPRINT_PLATFORM);
|
|
5415
|
+
};
|
|
5416
|
+
var resolveCloakProxy = (proxyConfiguration = {}) => {
|
|
5417
|
+
const config = normalizeObject2(proxyConfiguration);
|
|
5418
|
+
const proxyUrl = String(config.proxy_url || "").trim();
|
|
5419
|
+
const enableProxy = typeof config.enable_proxy === "boolean" ? config.enable_proxy : proxyUrl !== "";
|
|
5420
|
+
if (!enableProxy || !proxyUrl) {
|
|
5421
|
+
return null;
|
|
5422
|
+
}
|
|
5423
|
+
const byPassDomains = ByPass.normalizeByPassDomains(config.by_pass_domains);
|
|
5424
|
+
if (byPassDomains.length === 0) {
|
|
5425
|
+
return proxyUrl;
|
|
5426
|
+
}
|
|
5427
|
+
const parsedProxyUrl = new URL(proxyUrl.includes("://") ? proxyUrl : `http://${proxyUrl}`);
|
|
5428
|
+
return {
|
|
5429
|
+
server: `${parsedProxyUrl.protocol}//${parsedProxyUrl.host}`,
|
|
5430
|
+
username: decodeURIComponent(parsedProxyUrl.username || ""),
|
|
5431
|
+
password: decodeURIComponent(parsedProxyUrl.password || ""),
|
|
5432
|
+
bypass: byPassDomains.join(",")
|
|
5433
|
+
};
|
|
5434
|
+
};
|
|
5435
|
+
var extractFingerprintArg = (launchOptions = {}) => {
|
|
5436
|
+
const args = Array.isArray(launchOptions?.args) ? launchOptions.args : [];
|
|
5437
|
+
return args.find((value) => String(value || "").startsWith(CLOAK_FINGERPRINT_ARG_PREFIX)) || "";
|
|
5438
|
+
};
|
|
5439
|
+
var buildFingerprintArg = (seed) => `${CLOAK_FINGERPRINT_ARG_PREFIX}${seed}`;
|
|
5440
|
+
var extractArgValue = (args = [], prefix = "") => {
|
|
5441
|
+
const matchedArg = normalizeStringArray(args).find((value) => value.startsWith(prefix));
|
|
5442
|
+
if (!matchedArg) {
|
|
5443
|
+
return "";
|
|
5444
|
+
}
|
|
5445
|
+
return normalizeText(matchedArg.slice(prefix.length));
|
|
5446
|
+
};
|
|
5447
|
+
var extractFingerprintSeedFromArgs = (args = []) => normalizePositiveInteger(
|
|
5448
|
+
extractArgValue(args, CLOAK_FINGERPRINT_ARG_PREFIX)
|
|
5449
|
+
);
|
|
5450
|
+
var extractLocaleFromArgs = (args = []) => extractArgValue(args, CLOAK_LANG_ARG_PREFIX) || extractArgValue(args, CLOAK_FINGERPRINT_LOCALE_ARG_PREFIX);
|
|
5451
|
+
var extractTimezoneFromArgs = (args = []) => extractArgValue(args, CLOAK_FINGERPRINT_TIMEZONE_ARG_PREFIX);
|
|
5452
|
+
var hashStringToSeed = (value = "") => {
|
|
5453
|
+
let hash = 2166136261;
|
|
5454
|
+
const text = normalizeText(value);
|
|
5455
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
5456
|
+
hash ^= text.charCodeAt(index);
|
|
5457
|
+
hash = Math.imul(hash, 16777619);
|
|
5458
|
+
}
|
|
5459
|
+
const numericHash = hash >>> 0;
|
|
5460
|
+
const seedRange = DEFAULT_CLOAK_SEED_MAX - DEFAULT_CLOAK_SEED_MIN + 1;
|
|
5461
|
+
return DEFAULT_CLOAK_SEED_MIN + numericHash % seedRange;
|
|
5462
|
+
};
|
|
5463
|
+
var buildCloakSeedIdentity = (runtimeState = {}) => {
|
|
5464
|
+
const normalizedRuntimeState = normalizeObject2(runtimeState);
|
|
5465
|
+
const normalizedEnvId = normalizeText(normalizedRuntimeState.envId);
|
|
5466
|
+
if (normalizedEnvId) {
|
|
5467
|
+
return `env:${normalizedEnvId}`;
|
|
5468
|
+
}
|
|
5469
|
+
const runtimePayload = normalizeObject2(normalizedRuntimeState.runtime);
|
|
5470
|
+
if (Object.keys(runtimePayload).length === 0) {
|
|
5471
|
+
return "";
|
|
5472
|
+
}
|
|
5473
|
+
return JSON.stringify({
|
|
5474
|
+
actor: normalizeText(normalizedRuntimeState.actor),
|
|
5475
|
+
device: normalizeText(normalizedRuntimeState.device),
|
|
5476
|
+
runtime: runtimePayload
|
|
5477
|
+
});
|
|
5478
|
+
};
|
|
5479
|
+
var generateCloakSeed = (runtimeState = {}) => {
|
|
5480
|
+
const identity = buildCloakSeedIdentity(runtimeState);
|
|
5481
|
+
if (identity) {
|
|
5482
|
+
return hashStringToSeed(`cloak:${identity}`);
|
|
5483
|
+
}
|
|
5484
|
+
return (0, import_node_crypto.randomInt)(DEFAULT_CLOAK_SEED_MIN, DEFAULT_CLOAK_SEED_MAX + 1);
|
|
5485
|
+
};
|
|
5486
|
+
var resolveReplayableCloakProfile = (runtimeState, { fingerprintPlatform = "", cloakOptions = {} } = {}) => {
|
|
5487
|
+
const normalizedCloakOptions = normalizeObject2(cloakOptions);
|
|
5488
|
+
const normalizedArgs = normalizeStringArray(normalizedCloakOptions.args);
|
|
5489
|
+
const explicitFingerprintSeed = extractFingerprintSeedFromArgs(normalizedArgs);
|
|
5490
|
+
const explicitFingerprintPlatform = normalizeCloakFingerprintPlatform2(fingerprintPlatform) || normalizeCloakFingerprintPlatform2(
|
|
5491
|
+
extractArgValue(normalizedArgs, CLOAK_FINGERPRINT_PLATFORM_ARG_PREFIX)
|
|
5492
|
+
);
|
|
5493
|
+
const explicitTimezone = normalizeText(
|
|
5494
|
+
normalizedCloakOptions.timezone || normalizedCloakOptions.timezoneId || extractTimezoneFromArgs(normalizedArgs)
|
|
5495
|
+
);
|
|
5496
|
+
const explicitLocale = normalizeText(
|
|
5497
|
+
normalizedCloakOptions.locale || extractLocaleFromArgs(normalizedArgs)
|
|
5498
|
+
);
|
|
5499
|
+
if (!runtimeState || !RuntimeEnv.hasLoginState(runtimeState)) {
|
|
5500
|
+
return {
|
|
5501
|
+
runtimeState,
|
|
5502
|
+
browserProfileCore: null,
|
|
5503
|
+
fingerprintSeed: explicitFingerprintSeed,
|
|
5504
|
+
fingerprintPlatform: explicitFingerprintPlatform,
|
|
5505
|
+
locale: explicitLocale,
|
|
5506
|
+
timezone: explicitTimezone,
|
|
5507
|
+
hasExplicitFingerprintSeed: explicitFingerprintSeed > 0,
|
|
5508
|
+
hasExplicitLocale: Boolean(explicitLocale),
|
|
5509
|
+
hasExplicitTimezone: Boolean(explicitTimezone)
|
|
5510
|
+
};
|
|
5511
|
+
}
|
|
5512
|
+
let nextState = RuntimeEnv.rememberState(runtimeState);
|
|
5513
|
+
const currentBrowserProfileCore = RuntimeEnv.getBrowserProfileCore(nextState);
|
|
5514
|
+
const storedFingerprintSeed = normalizePositiveInteger(currentBrowserProfileCore?.cloak_seed);
|
|
5515
|
+
const storedFingerprintPlatform = normalizeCloakFingerprintPlatform2(
|
|
5516
|
+
currentBrowserProfileCore?.cloak_fingerprint_platform
|
|
5517
|
+
);
|
|
5518
|
+
const storedLocale = normalizeText(currentBrowserProfileCore?.locale);
|
|
5519
|
+
const storedTimezone = normalizeText(currentBrowserProfileCore?.timezone_id);
|
|
5520
|
+
const fingerprintSeed = explicitFingerprintSeed || storedFingerprintSeed || generateCloakSeed(nextState);
|
|
5521
|
+
const resolvedFingerprintPlatform = explicitFingerprintPlatform || storedFingerprintPlatform || DEFAULT_CLOAK_FINGERPRINT_PLATFORM;
|
|
5522
|
+
const locale = explicitLocale || storedLocale;
|
|
5523
|
+
const timezone = explicitTimezone || storedTimezone;
|
|
5524
|
+
const nextBrowserProfileCore = {
|
|
5525
|
+
...currentBrowserProfileCore,
|
|
5526
|
+
cloak_seed: fingerprintSeed,
|
|
5527
|
+
cloak_fingerprint_platform: resolvedFingerprintPlatform
|
|
5528
|
+
};
|
|
5529
|
+
if (locale) {
|
|
5530
|
+
nextBrowserProfileCore.locale = locale;
|
|
5531
|
+
}
|
|
5532
|
+
if (timezone) {
|
|
5533
|
+
nextBrowserProfileCore.timezone_id = timezone;
|
|
5534
|
+
}
|
|
5535
|
+
const currentCoreRaw = JSON.stringify(currentBrowserProfileCore || {});
|
|
5536
|
+
const nextCoreRaw = JSON.stringify(nextBrowserProfileCore);
|
|
5537
|
+
if (currentCoreRaw !== nextCoreRaw) {
|
|
5538
|
+
nextState = RuntimeEnv.setBrowserProfileCore(nextState, nextBrowserProfileCore);
|
|
5539
|
+
logger9.info(
|
|
5540
|
+
`\u5DF2\u540C\u6B65 Cloak \u6307\u7EB9\u771F\u6E90 | env=${String(nextState.envId || "-")} | seed=${fingerprintSeed} | platform=${resolvedFingerprintPlatform} | timezone=${timezone || "-"} | locale=${locale || "-"}`
|
|
5541
|
+
);
|
|
5542
|
+
}
|
|
5543
|
+
const rememberedBrowserProfileCore = RuntimeEnv.getBrowserProfileCore(nextState);
|
|
5544
|
+
return {
|
|
5545
|
+
runtimeState: nextState,
|
|
5546
|
+
browserProfileCore: rememberedBrowserProfileCore,
|
|
5547
|
+
fingerprintSeed,
|
|
5548
|
+
fingerprintPlatform: resolvedFingerprintPlatform,
|
|
5549
|
+
locale,
|
|
5550
|
+
timezone,
|
|
5551
|
+
hasExplicitFingerprintSeed: explicitFingerprintSeed > 0,
|
|
5552
|
+
hasExplicitLocale: Boolean(explicitLocale),
|
|
5553
|
+
hasExplicitTimezone: Boolean(explicitTimezone)
|
|
5554
|
+
};
|
|
5555
|
+
};
|
|
5556
|
+
var createStableGotoHook = (recommendedGotoOptions = DEFAULT_CLOAK_GOTO_OPTIONS) => {
|
|
5557
|
+
const normalizedRecommendedGotoOptions = normalizeObject2(recommendedGotoOptions);
|
|
5558
|
+
const fallbackGotoOptions = Object.keys(normalizedRecommendedGotoOptions).length > 0 ? normalizedRecommendedGotoOptions : DEFAULT_CLOAK_GOTO_OPTIONS;
|
|
5559
|
+
return async (_crawlingContext, gotoOptions = {}) => {
|
|
5560
|
+
for (const [key, value] of Object.entries(fallbackGotoOptions)) {
|
|
5561
|
+
if (gotoOptions[key] == null) {
|
|
5562
|
+
gotoOptions[key] = value;
|
|
5563
|
+
}
|
|
5564
|
+
}
|
|
5565
|
+
};
|
|
5566
|
+
};
|
|
5567
|
+
var attachCloakHumanizeHook = ({
|
|
5568
|
+
browserPoolOptions = {},
|
|
5569
|
+
activeBrowsers,
|
|
5570
|
+
patchedBrowsers,
|
|
5571
|
+
humanizeOptions = DEFAULT_CLOAK_HUMANIZE_OPTIONS
|
|
5572
|
+
} = {}) => {
|
|
5573
|
+
const normalizedBrowserPoolOptions = normalizeObject2(browserPoolOptions);
|
|
5574
|
+
const shouldHumanize = humanizeOptions !== false;
|
|
5575
|
+
const normalizedHumanizeOptions = shouldHumanize ? {
|
|
5576
|
+
...DEFAULT_CLOAK_HUMANIZE_OPTIONS,
|
|
5577
|
+
...normalizeObject2(humanizeOptions)
|
|
5578
|
+
} : null;
|
|
5579
|
+
return {
|
|
5580
|
+
...normalizedBrowserPoolOptions,
|
|
5581
|
+
useFingerprints: false,
|
|
5582
|
+
postLaunchHooks: [
|
|
5583
|
+
...Array.isArray(normalizedBrowserPoolOptions.postLaunchHooks) ? normalizedBrowserPoolOptions.postLaunchHooks : [],
|
|
5584
|
+
async (_pageId, browserController) => {
|
|
5585
|
+
const browser = browserController?.browser;
|
|
5586
|
+
if (!browser || typeof browser.contexts !== "function") {
|
|
5587
|
+
return;
|
|
5588
|
+
}
|
|
5589
|
+
activeBrowsers.add(browser);
|
|
5590
|
+
if (typeof browser.once === "function") {
|
|
5591
|
+
browser.once("disconnected", () => {
|
|
5592
|
+
activeBrowsers.delete(browser);
|
|
5593
|
+
});
|
|
5594
|
+
}
|
|
5595
|
+
if (!shouldHumanize || patchedBrowsers.has(browser)) {
|
|
5596
|
+
return;
|
|
5597
|
+
}
|
|
5598
|
+
const { humanizeBrowser } = await loadCloakModule();
|
|
5599
|
+
await humanizeBrowser(browser, normalizedHumanizeOptions);
|
|
5600
|
+
patchedBrowsers.add(browser);
|
|
5601
|
+
}
|
|
5602
|
+
]
|
|
5603
|
+
};
|
|
5604
|
+
};
|
|
5605
|
+
var closeTrackedBrowsers = async (activeBrowsers) => {
|
|
5606
|
+
const browsers = Array.from(activeBrowsers || []);
|
|
5607
|
+
activeBrowsers?.clear?.();
|
|
5608
|
+
await Promise.allSettled(
|
|
5609
|
+
browsers.map(async (browser) => {
|
|
5610
|
+
if (!browser || typeof browser.isConnected !== "function" || !browser.isConnected()) {
|
|
5611
|
+
return;
|
|
5612
|
+
}
|
|
5613
|
+
await browser.close().catch(() => {
|
|
5614
|
+
});
|
|
5615
|
+
})
|
|
5616
|
+
);
|
|
5617
|
+
};
|
|
5618
|
+
var forceTerminateBrowsersByFingerprintArg = async (fingerprintArg) => {
|
|
5619
|
+
if (!fingerprintArg) {
|
|
5620
|
+
return;
|
|
5621
|
+
}
|
|
5622
|
+
await execFileAsync("pkill", ["-f", "--", fingerprintArg]).catch((error) => {
|
|
5623
|
+
if (error?.code === 1 || error?.code === "ENOENT") {
|
|
5624
|
+
return;
|
|
5625
|
+
}
|
|
5626
|
+
logger9.info(`\u5F3A\u5236\u5173\u95ED Cloak \u8FDB\u7A0B\u5931\u8D25\uFF08\u5FFD\u7565\uFF09: ${error?.message || String(error)}`);
|
|
5627
|
+
});
|
|
5628
|
+
};
|
|
5629
|
+
var CloakLaunch = {
|
|
5630
|
+
resolveProxyConfiguration(proxyConfiguration = {}) {
|
|
5631
|
+
return resolveCloakProxy(proxyConfiguration);
|
|
5632
|
+
},
|
|
5633
|
+
extractFingerprintArg(launchOptions = {}) {
|
|
5634
|
+
return extractFingerprintArg(launchOptions);
|
|
5635
|
+
},
|
|
5636
|
+
createStableGotoHook(recommendedGotoOptions = DEFAULT_CLOAK_GOTO_OPTIONS) {
|
|
5637
|
+
return createStableGotoHook(recommendedGotoOptions);
|
|
5638
|
+
},
|
|
5639
|
+
async getPlaywrightCrawlerOptions(options = {}) {
|
|
5640
|
+
const runtime2 = await CloakLaunch.createPlaywrightCrawlerRuntime(options);
|
|
5641
|
+
return Object.defineProperties(runtime2.crawlerOptions, {
|
|
5642
|
+
cleanup: {
|
|
5643
|
+
enumerable: false,
|
|
5644
|
+
value: runtime2.cleanup
|
|
5645
|
+
},
|
|
5646
|
+
closeActiveBrowsers: {
|
|
5647
|
+
enumerable: false,
|
|
5648
|
+
value: runtime2.closeActiveBrowsers
|
|
5649
|
+
},
|
|
5650
|
+
forceTerminateActiveProcesses: {
|
|
5651
|
+
enumerable: false,
|
|
5652
|
+
value: runtime2.forceTerminateActiveProcesses
|
|
5653
|
+
}
|
|
5654
|
+
});
|
|
5655
|
+
},
|
|
5656
|
+
async buildLaunchOptions(options = {}) {
|
|
5657
|
+
return await buildCloakLaunchOptions(options);
|
|
5658
|
+
},
|
|
5659
|
+
async createPlaywrightCrawlerRuntime(options = {}) {
|
|
5660
|
+
const normalizedOptions = normalizeObject2(options);
|
|
5661
|
+
const {
|
|
5662
|
+
proxyConfiguration = {},
|
|
5663
|
+
log: logOptions = null,
|
|
5664
|
+
debugMode = false,
|
|
5665
|
+
runInHeadfulMode = false,
|
|
5666
|
+
isRunningOnApify = false,
|
|
5667
|
+
launcher = null,
|
|
5668
|
+
runtimeState = null,
|
|
5669
|
+
fingerprintPlatform = "",
|
|
5670
|
+
cloakOptions = {},
|
|
5671
|
+
humanizeOptions = DEFAULT_CLOAK_HUMANIZE_OPTIONS,
|
|
5672
|
+
crawlerBaseOptions = {},
|
|
5673
|
+
browserPoolOptions = {},
|
|
5674
|
+
launchContext = {},
|
|
5675
|
+
preNavigationHooks = [],
|
|
5676
|
+
postNavigationHooks = [],
|
|
5677
|
+
recommendedGotoOptions = DEFAULT_CLOAK_GOTO_OPTIONS
|
|
5678
|
+
} = normalizedOptions;
|
|
5679
|
+
const normalizedCloakOptions = normalizeObject2(cloakOptions);
|
|
5680
|
+
const activeBrowsers = /* @__PURE__ */ new Set();
|
|
5681
|
+
const patchedBrowsers = /* @__PURE__ */ new WeakSet();
|
|
5682
|
+
const defaultArgs = isRunningOnApify ? ["--no-sandbox", "--disable-setuid-sandbox"] : [];
|
|
5683
|
+
const replayContext = resolveReplayableCloakProfile(runtimeState, {
|
|
5684
|
+
fingerprintPlatform,
|
|
5685
|
+
cloakOptions: normalizedCloakOptions
|
|
5686
|
+
});
|
|
5687
|
+
const fingerprintPlatformArg = resolveCloakFingerprintPlatformArg(
|
|
5688
|
+
replayContext.fingerprintPlatform,
|
|
5689
|
+
normalizedCloakOptions.args
|
|
5690
|
+
);
|
|
5691
|
+
const extraArgs = normalizeStringArray(normalizedCloakOptions.args).filter((value) => !value.startsWith(CLOAK_FINGERPRINT_PLATFORM_ARG_PREFIX));
|
|
5692
|
+
const replayFingerprintArg = !replayContext.hasExplicitFingerprintSeed && replayContext.fingerprintSeed > 0 ? buildFingerprintArg(replayContext.fingerprintSeed) : "";
|
|
5693
|
+
const hasExplicitProxy = hasOwn(normalizedCloakOptions, "proxy");
|
|
5694
|
+
const proxyLaunchState = hasExplicitProxy ? resolveLaunchTraffic({ proxyConfiguration, debugMode, useMeter: false }) : resolveLaunchTraffic({ proxyConfiguration, debugMode });
|
|
5695
|
+
const proxy = hasExplicitProxy ? normalizedCloakOptions.proxy : proxyLaunchState.launchProxy;
|
|
5696
|
+
const headless = hasOwn(normalizedCloakOptions, "headless") ? normalizedCloakOptions.headless : !runInHeadfulMode || isRunningOnApify;
|
|
5697
|
+
const enableByPassLogger = Boolean(logOptions && logOptions.enable);
|
|
5698
|
+
const mergedCloakOptions = {
|
|
5699
|
+
...normalizedCloakOptions,
|
|
5700
|
+
headless,
|
|
5701
|
+
proxy,
|
|
5702
|
+
...normalizedCloakOptions.timezoneId && !hasOwn(normalizedCloakOptions, "timezone") ? { timezone: normalizedCloakOptions.timezoneId } : {},
|
|
5703
|
+
...replayContext.timezone && !replayContext.hasExplicitTimezone ? { timezone: replayContext.timezone } : {},
|
|
5704
|
+
...replayContext.locale && !replayContext.hasExplicitLocale ? { locale: replayContext.locale } : {},
|
|
5705
|
+
args: [
|
|
5706
|
+
...defaultArgs,
|
|
5707
|
+
...replayFingerprintArg ? [replayFingerprintArg] : [],
|
|
5708
|
+
...extraArgs,
|
|
5709
|
+
fingerprintPlatformArg
|
|
5710
|
+
]
|
|
5711
|
+
};
|
|
5712
|
+
const launchOptions = await buildCloakLaunchOptions(mergedCloakOptions);
|
|
5713
|
+
const fingerprintArg = extractFingerprintArg(launchOptions);
|
|
5714
|
+
const internalPreNavigationHook = createStableGotoHook(recommendedGotoOptions);
|
|
5715
|
+
const trafficHook = createLaunchTrafficHook({
|
|
5716
|
+
byPassDomains: proxyLaunchState.byPassDomains,
|
|
5717
|
+
byPassRules: proxyLaunchState.byPassRules,
|
|
5718
|
+
enabled: enableByPassLogger,
|
|
5719
|
+
launchProxy: proxyLaunchState.launchProxy
|
|
5720
|
+
});
|
|
5721
|
+
const normalizedPreNavigationHooks = Array.isArray(preNavigationHooks) ? preNavigationHooks : [];
|
|
5722
|
+
const normalizedPostNavigationHooks = Array.isArray(postNavigationHooks) ? postNavigationHooks : [];
|
|
5723
|
+
logLaunchTraffic({
|
|
5724
|
+
...proxyLaunchState,
|
|
5725
|
+
debugMode,
|
|
5726
|
+
enabled: enableByPassLogger,
|
|
5727
|
+
explicitProxy: hasExplicitProxy
|
|
5728
|
+
});
|
|
5729
|
+
const crawlerOptions = {
|
|
5730
|
+
...DEFAULT_CLOAK_CRAWLER_BASE_OPTIONS,
|
|
5731
|
+
...normalizeObject2(crawlerBaseOptions),
|
|
5732
|
+
headless,
|
|
5733
|
+
launchContext: {
|
|
5734
|
+
useIncognitoPages: true,
|
|
5735
|
+
...normalizeObject2(launchContext),
|
|
5736
|
+
...launcher ? { launcher } : {},
|
|
5737
|
+
launchOptions
|
|
5738
|
+
},
|
|
5739
|
+
browserPoolOptions: attachCloakHumanizeHook({
|
|
5740
|
+
browserPoolOptions,
|
|
5741
|
+
activeBrowsers,
|
|
5742
|
+
patchedBrowsers,
|
|
5743
|
+
humanizeOptions
|
|
5744
|
+
}),
|
|
5745
|
+
preNavigationHooks: [
|
|
5746
|
+
async (crawlingContext, gotoOptions = {}) => {
|
|
5747
|
+
trafficHook(crawlingContext?.page);
|
|
5748
|
+
await internalPreNavigationHook(crawlingContext, gotoOptions);
|
|
5749
|
+
},
|
|
5750
|
+
...normalizedPreNavigationHooks
|
|
5751
|
+
],
|
|
5752
|
+
...normalizedPostNavigationHooks.length > 0 ? { postNavigationHooks: normalizedPostNavigationHooks } : {}
|
|
5753
|
+
};
|
|
5754
|
+
const closeActiveBrowsers = async () => {
|
|
5755
|
+
await closeTrackedBrowsers(activeBrowsers);
|
|
5756
|
+
};
|
|
5757
|
+
const forceTerminateActiveProcesses = async () => {
|
|
5758
|
+
await forceTerminateBrowsersByFingerprintArg(fingerprintArg);
|
|
5759
|
+
};
|
|
5760
|
+
const cleanup = async () => {
|
|
5761
|
+
await closeActiveBrowsers();
|
|
5762
|
+
await forceTerminateActiveProcesses();
|
|
5763
|
+
};
|
|
5764
|
+
return {
|
|
5765
|
+
headless,
|
|
5766
|
+
launchOptions,
|
|
5767
|
+
fingerprintArg,
|
|
5768
|
+
crawlerOptions,
|
|
5769
|
+
closeActiveBrowsers,
|
|
5770
|
+
forceTerminateActiveProcesses,
|
|
5771
|
+
cleanup
|
|
5772
|
+
};
|
|
5773
|
+
}
|
|
5774
|
+
};
|
|
5775
|
+
|
|
5776
|
+
// src/launch.js
|
|
5777
|
+
var launchStrategies = {
|
|
5778
|
+
[Mode.Default]: DefaultLaunch,
|
|
5779
|
+
[Mode.Cloak]: CloakLaunch
|
|
5780
|
+
};
|
|
5781
|
+
var Launch = withModeReflect("Launch", launchStrategies);
|
|
5782
|
+
|
|
5102
5783
|
// src/live-view.js
|
|
5103
5784
|
var import_express = __toESM(require("express"), 1);
|
|
5104
5785
|
var import_apify = require("apify");
|
|
5105
|
-
var
|
|
5786
|
+
var logger10 = createInternalLogger("LiveView");
|
|
5106
5787
|
async function startLiveViewServer(liveViewKey) {
|
|
5107
5788
|
const app = (0, import_express.default)();
|
|
5108
5789
|
app.get("/", async (req, res) => {
|
|
@@ -5127,13 +5808,13 @@ async function startLiveViewServer(liveViewKey) {
|
|
|
5127
5808
|
</html>
|
|
5128
5809
|
`);
|
|
5129
5810
|
} catch (error) {
|
|
5130
|
-
|
|
5811
|
+
logger10.fail("Live View Server", error);
|
|
5131
5812
|
res.status(500).send(`\u65E0\u6CD5\u52A0\u8F7D\u5C4F\u5E55\u622A\u56FE: ${error.message}`);
|
|
5132
5813
|
}
|
|
5133
5814
|
});
|
|
5134
5815
|
const port = process.env.APIFY_CONTAINER_PORT || 4321;
|
|
5135
5816
|
app.listen(port, () => {
|
|
5136
|
-
|
|
5817
|
+
logger10.success("startLiveViewServer", `\u76D1\u542C\u7AEF\u53E3 ${port}`);
|
|
5137
5818
|
});
|
|
5138
5819
|
}
|
|
5139
5820
|
async function takeLiveScreenshot(liveViewKey, page, logMessage) {
|
|
@@ -5141,10 +5822,10 @@ async function takeLiveScreenshot(liveViewKey, page, logMessage) {
|
|
|
5141
5822
|
const buffer = await capturePageScreenshot(page, { type: "png" });
|
|
5142
5823
|
await import_apify.Actor.setValue(liveViewKey, buffer, { contentType: "image/png" });
|
|
5143
5824
|
if (logMessage) {
|
|
5144
|
-
|
|
5825
|
+
logger10.info(`(\u622A\u56FE): ${logMessage}`);
|
|
5145
5826
|
}
|
|
5146
5827
|
} catch (e) {
|
|
5147
|
-
|
|
5828
|
+
logger10.warn(`\u65E0\u6CD5\u6355\u83B7 Live View \u5C4F\u5E55\u622A\u56FE: ${e.message}`);
|
|
5148
5829
|
}
|
|
5149
5830
|
}
|
|
5150
5831
|
var useLiveView = (liveViewKey = PresetOfLiveViewKey) => {
|
|
@@ -5161,9 +5842,6 @@ var LiveView = {
|
|
|
5161
5842
|
useLiveView
|
|
5162
5843
|
};
|
|
5163
5844
|
|
|
5164
|
-
// src/chaptcha.js
|
|
5165
|
-
var import_uuid = require("uuid");
|
|
5166
|
-
|
|
5167
5845
|
// src/internals/captcha/bytedance.js
|
|
5168
5846
|
var import_promises = require("fs/promises");
|
|
5169
5847
|
var import_path2 = __toESM(require("path"), 1);
|
|
@@ -5253,7 +5931,7 @@ var dragCaptchaAction = async (page, sourceLocator, targetLocator, options = {})
|
|
|
5253
5931
|
};
|
|
5254
5932
|
|
|
5255
5933
|
// src/internals/captcha/bytedance.js
|
|
5256
|
-
var
|
|
5934
|
+
var logger11 = createInternalLogger("Captcha");
|
|
5257
5935
|
var DEFAULT_BYTEDANCE_CAPTCHA_OPTIONS = Object.freeze({
|
|
5258
5936
|
apiType: "31234",
|
|
5259
5937
|
maxRetries: 3,
|
|
@@ -5385,7 +6063,7 @@ var collectCaptchaDebugInfo = async (page, frame, iframeLocator, attempt, phase,
|
|
|
5385
6063
|
}
|
|
5386
6064
|
await (0, import_promises.writeFile)(infoPath, JSON.stringify(payload, null, 2), "utf8");
|
|
5387
6065
|
}
|
|
5388
|
-
|
|
6066
|
+
logger11.info(`\u5DF2\u5199\u51FA\u9A8C\u8BC1\u7801\u8C03\u8BD5\u4EA7\u7269\uFF1A${debugDir}`);
|
|
5389
6067
|
};
|
|
5390
6068
|
var maybeCollectCaptchaDebugInfo = async (page, frame, iframeLocator, attempt, phase, options, extra = null) => {
|
|
5391
6069
|
if (!options.debugArtifacts) {
|
|
@@ -5422,14 +6100,14 @@ var getVerifycenterCaptchaContext = async (page, options) => {
|
|
|
5422
6100
|
if (!isContainerVisible) {
|
|
5423
6101
|
return null;
|
|
5424
6102
|
}
|
|
5425
|
-
|
|
6103
|
+
logger11.info("\u68C0\u6D4B\u5230\u9A8C\u8BC1\u7801\u5BB9\u5668\uFF0C\u5F00\u59CB\u7B49\u5F85 iframe \u52A0\u8F7D\u3002");
|
|
5426
6104
|
let iframeLocator = page.locator(options.iframeSelector).first();
|
|
5427
6105
|
let isIframeVisible = await waitForVisible(
|
|
5428
6106
|
iframeLocator,
|
|
5429
6107
|
options.iframeVisibleTimeoutMs
|
|
5430
6108
|
);
|
|
5431
6109
|
if (!isIframeVisible) {
|
|
5432
|
-
|
|
6110
|
+
logger11.warn("\u672A\u5728\u9884\u671F\u9009\u62E9\u5668\u4E2D\u627E\u5230 verifycenter iframe\uFF0C\u5C1D\u8BD5\u5BB9\u5668\u5185\u4EFB\u610F iframe\u3002");
|
|
5433
6111
|
iframeLocator = captchaContainer.locator(options.iframeFallbackSelector).first();
|
|
5434
6112
|
isIframeVisible = await waitForVisible(
|
|
5435
6113
|
iframeLocator,
|
|
@@ -5439,7 +6117,7 @@ var getVerifycenterCaptchaContext = async (page, options) => {
|
|
|
5439
6117
|
if (!isIframeVisible) {
|
|
5440
6118
|
throw new Error("verifycenter iframe not found inside captcha container.");
|
|
5441
6119
|
}
|
|
5442
|
-
|
|
6120
|
+
logger11.info("\u9A8C\u8BC1\u7801 iframe \u5DF2\u53EF\u89C1\uFF0C\u5F00\u59CB\u89E3\u6790\u5185\u5BB9 frame\u3002");
|
|
5443
6121
|
const frame = await resolveContentFrame(page, iframeLocator, options);
|
|
5444
6122
|
if (!frame) {
|
|
5445
6123
|
throw new Error("Failed to resolve verifycenter iframe content frame.");
|
|
@@ -5555,11 +6233,11 @@ var refreshCaptcha = async (page, frame, options) => {
|
|
|
5555
6233
|
const clicked = await clickCaptchaAction(frame, options.refreshTexts, {
|
|
5556
6234
|
...options,
|
|
5557
6235
|
page,
|
|
5558
|
-
logger:
|
|
6236
|
+
logger: logger11,
|
|
5559
6237
|
forceMouse: true
|
|
5560
6238
|
}).catch(() => false);
|
|
5561
6239
|
if (!clicked) {
|
|
5562
|
-
|
|
6240
|
+
logger11.warn("Refresh button not found.");
|
|
5563
6241
|
return false;
|
|
5564
6242
|
}
|
|
5565
6243
|
await page.waitForTimeout(options.refreshWaitMs);
|
|
@@ -5590,24 +6268,24 @@ var waitForCaptchaChallengeReady = async (page, frame, options) => {
|
|
|
5590
6268
|
const hasGuideMaskVisible = options.guideMaskSelector ? await frame.locator(options.guideMaskSelector).first().isVisible({ timeout: options.loadingIndicatorVisibleTimeoutMs }).catch(() => false) : false;
|
|
5591
6269
|
hasSeenGuideMask = hasSeenGuideMask || hasGuideMaskVisible;
|
|
5592
6270
|
if (hasGuideMaskVisible && !hasLoggedGuideMask) {
|
|
5593
|
-
|
|
6271
|
+
logger11.info("\u68C0\u6D4B\u5230\u9A8C\u8BC1\u7801\u64CD\u4F5C\u5F15\u5BFC\u5C42\uFF0C\u7B49\u5F85\u5176\u6D88\u5931\u540E\u518D\u5F00\u59CB\u8BC6\u522B\u3002");
|
|
5594
6272
|
hasLoggedGuideMask = true;
|
|
5595
6273
|
}
|
|
5596
6274
|
if (!isLoadingVisible && hasVisibleSourceImage && hasVisibleDropTarget && !hasGuideMaskVisible) {
|
|
5597
|
-
|
|
6275
|
+
logger11.info(
|
|
5598
6276
|
hasSeenGuideMask ? "\u9A8C\u8BC1\u7801\u56FE\u7247\u548C\u62D6\u62FD\u533A\u57DF\u5DF2\u5C31\u7EEA\uFF0C\u5F15\u5BFC\u5C42\u5DF2\u6D88\u5931\u3002" : hasSeenLoading ? "\u9A8C\u8BC1\u7801\u56FE\u7247\u5DF2\u52A0\u8F7D\u5B8C\u6210\u3002" : "\u9A8C\u8BC1\u7801\u56FE\u7247\u5DF2\u5C31\u7EEA\u3002"
|
|
5599
6277
|
);
|
|
5600
6278
|
return;
|
|
5601
6279
|
}
|
|
5602
6280
|
if (hasErrorTextVisible) {
|
|
5603
|
-
|
|
6281
|
+
logger11.warn("\u9A8C\u8BC1\u7801\u9762\u677F\u51FA\u73B0\u7F51\u7EDC\u5F02\u5E38\u6587\u6848\uFF0C\u5C1D\u8BD5\u7ACB\u5373\u5237\u65B0\u9898\u76EE\u3002");
|
|
5604
6282
|
await refreshCaptcha(page, frame, options);
|
|
5605
6283
|
refreshDeadline = Date.now() + options.challengeReadyRefreshTimeoutMs;
|
|
5606
6284
|
hasSeenLoading = false;
|
|
5607
6285
|
continue;
|
|
5608
6286
|
}
|
|
5609
6287
|
if ((!hasVisibleSourceImage || !hasVisibleDropTarget) && Date.now() >= refreshDeadline) {
|
|
5610
|
-
|
|
6288
|
+
logger11.warn(`\u9A8C\u8BC1\u7801\u9898\u76EE\u8D85\u8FC7 ${options.challengeReadyRefreshTimeoutMs}ms \u4ECD\u672A\u51C6\u5907\u597D\uFF0C\u5C1D\u8BD5\u5237\u65B0\u9898\u76EE\u3002`);
|
|
5611
6289
|
await refreshCaptcha(page, frame, options);
|
|
5612
6290
|
refreshDeadline = Date.now() + options.challengeReadyRefreshTimeoutMs;
|
|
5613
6291
|
hasSeenLoading = false;
|
|
@@ -5655,7 +6333,7 @@ var dragPromptCaptchaImage = async (page, frame, iframeLocator, sourceLocator, d
|
|
|
5655
6333
|
accepted
|
|
5656
6334
|
};
|
|
5657
6335
|
dragAttempts.push(attemptInfo);
|
|
5658
|
-
|
|
6336
|
+
logger11.info(
|
|
5659
6337
|
`\u9A8C\u8BC1\u7801\u62D6\u62FD\u7B2C ${visualIndex + 1} \u5F20\uFF0C\u65B9\u6848 ${plan.name}\uFF0Cbadge ${baselineState.badgeCount} -> ${afterState.badgeCount}\uFF0Cselected ${baselineState.selectedCount} -> ${afterState.selectedCount}`
|
|
5660
6338
|
);
|
|
5661
6339
|
if (accepted) {
|
|
@@ -5673,7 +6351,7 @@ var dragPromptCaptchaImage = async (page, frame, iframeLocator, sourceLocator, d
|
|
|
5673
6351
|
dragAttempts,
|
|
5674
6352
|
finalState: await readPromptCaptchaState(frame, options)
|
|
5675
6353
|
}).catch((error) => {
|
|
5676
|
-
|
|
6354
|
+
logger11.warn(`\u9A8C\u8BC1\u7801\u62D6\u62FD\u5931\u8D25\u8C03\u8BD5\u6293\u53D6\u5931\u8D25\uFF1A${error?.message || error}`);
|
|
5677
6355
|
});
|
|
5678
6356
|
return {
|
|
5679
6357
|
accepted: false,
|
|
@@ -5690,16 +6368,16 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
|
|
|
5690
6368
|
...options
|
|
5691
6369
|
};
|
|
5692
6370
|
if (!config.token) {
|
|
5693
|
-
|
|
6371
|
+
logger11.warn("\u7F3A\u5C11\u9A8C\u8BC1\u7801 token\uFF0C\u8DF3\u8FC7\u81EA\u52A8\u8BC6\u522B\u3002");
|
|
5694
6372
|
return false;
|
|
5695
6373
|
}
|
|
5696
|
-
|
|
6374
|
+
logger11.info("\u5F53\u524D\u4F7F\u7528\u672Ctool\u2014\u2014\u6D4B\u8BD5\u7248\u672C");
|
|
5697
6375
|
for (let attempt = 1; attempt <= config.maxRetries; attempt += 1) {
|
|
5698
|
-
|
|
6376
|
+
logger11.info(`\u5F00\u59CB\u7B2C ${attempt}/${config.maxRetries} \u6B21 verifycenter \u9A8C\u8BC1\u7801\u8BC6\u522B\u3002`);
|
|
5699
6377
|
try {
|
|
5700
6378
|
const captchaContext = await getVerifycenterCaptchaContext(page, config);
|
|
5701
6379
|
if (!captchaContext) {
|
|
5702
|
-
|
|
6380
|
+
logger11.info("Captcha container is not visible anymore.");
|
|
5703
6381
|
return true;
|
|
5704
6382
|
}
|
|
5705
6383
|
const { iframeLocator, frame } = captchaContext;
|
|
@@ -5712,7 +6390,7 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
|
|
|
5712
6390
|
"ready",
|
|
5713
6391
|
config
|
|
5714
6392
|
).catch((error) => {
|
|
5715
|
-
|
|
6393
|
+
logger11.warn(`\u9A8C\u8BC1\u7801\u8C03\u8BD5\u6293\u53D6\u5931\u8D25\uFF1A${error?.message || error}`);
|
|
5716
6394
|
});
|
|
5717
6395
|
await page.waitForTimeout(config.recognitionDelayMs);
|
|
5718
6396
|
const screenshotBuffer = await iframeLocator.screenshot();
|
|
@@ -5724,16 +6402,16 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
|
|
|
5724
6402
|
});
|
|
5725
6403
|
const serialNumbers = extractCaptchaSerialNumbers(apiResponse);
|
|
5726
6404
|
if (apiResponse?.code !== config.recognitionSuccessCode || serialNumbers.length === 0) {
|
|
5727
|
-
|
|
6405
|
+
logger11.warn(
|
|
5728
6406
|
`\u9A8C\u8BC1\u7801\u8BC6\u522B\u5931\u8D25\u3002code=${apiResponse?.code}, msg=${apiResponse?.msg || "unknown"}`
|
|
5729
6407
|
);
|
|
5730
6408
|
await refreshCaptcha(page, frame, config);
|
|
5731
6409
|
continue;
|
|
5732
6410
|
}
|
|
5733
|
-
|
|
6411
|
+
logger11.info(`\u9A8C\u8BC1\u7801\u8BC6\u522B\u6210\u529F\uFF0C\u5E8F\u53F7\uFF1A${serialNumbers.join(", ")}`);
|
|
5734
6412
|
const dropTarget = await findCaptchaDropTarget(frame, config);
|
|
5735
6413
|
if (!dropTarget) {
|
|
5736
|
-
|
|
6414
|
+
logger11.warn("\u672A\u627E\u5230\u9A8C\u8BC1\u7801\u62D6\u62FD\u76EE\u6807\u533A\u57DF\u3002");
|
|
5737
6415
|
await refreshCaptcha(page, frame, config);
|
|
5738
6416
|
continue;
|
|
5739
6417
|
}
|
|
@@ -5744,7 +6422,7 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
|
|
|
5744
6422
|
`Captcha image indexes could not be normalized. raw=${serialNumbers.join(", ")}, count=${orderedSourceImages.length}`
|
|
5745
6423
|
);
|
|
5746
6424
|
}
|
|
5747
|
-
|
|
6425
|
+
logger11.info(`\u9A8C\u8BC1\u7801\u89C6\u89C9\u4F4D\u5E8F\u6620\u5C04\uFF1A${normalizedIndexes.map((index) => index + 1).join(", ")}`);
|
|
5748
6426
|
for (const imageIndex of normalizedIndexes) {
|
|
5749
6427
|
if (imageIndex < 0 || imageIndex >= orderedSourceImages.length) {
|
|
5750
6428
|
throw new Error(
|
|
@@ -5776,52 +6454,55 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
|
|
|
5776
6454
|
}
|
|
5777
6455
|
}
|
|
5778
6456
|
const beforeSubmitState = await readPromptCaptchaState(frame, config);
|
|
5779
|
-
|
|
6457
|
+
logger11.info(
|
|
5780
6458
|
`\u63D0\u4EA4\u524D\u9A8C\u8BC1\u7801\u72B6\u6001\uFF1Abadge=${beforeSubmitState.badgeCount}, selected=${beforeSubmitState.selectedCount}, submitDisabled=${beforeSubmitState.submitDisabled}`
|
|
5781
6459
|
);
|
|
5782
6460
|
const submitted = await clickCaptchaAction(frame, config.submitTexts, {
|
|
5783
6461
|
...config,
|
|
5784
6462
|
page,
|
|
5785
|
-
logger:
|
|
6463
|
+
logger: logger11,
|
|
5786
6464
|
forceMouse: true,
|
|
5787
6465
|
actionVisibleTimeoutMs: config.submitReadyTimeoutMs
|
|
5788
6466
|
}).catch(() => false);
|
|
5789
6467
|
if (!submitted) {
|
|
5790
|
-
|
|
6468
|
+
logger11.warn("\u672A\u627E\u5230\u63D0\u4EA4\u6309\u94AE\uFF0C\u53EF\u80FD\u4F1A\u81EA\u52A8\u63D0\u4EA4\u3002");
|
|
5791
6469
|
}
|
|
5792
6470
|
await page.waitForTimeout(config.submitWaitMs);
|
|
5793
6471
|
const afterSubmitState = await readPromptCaptchaState(frame, config);
|
|
5794
|
-
|
|
6472
|
+
logger11.info(
|
|
5795
6473
|
`\u63D0\u4EA4\u540E\u9A8C\u8BC1\u7801\u72B6\u6001\uFF1Abadge=${afterSubmitState.badgeCount}, selected=${afterSubmitState.selectedCount}, submitDisabled=${afterSubmitState.submitDisabled}`
|
|
5796
6474
|
);
|
|
5797
6475
|
const stillVisible = await iframeLocator.isVisible({ timeout: config.containerVisibleTimeoutMs }).catch(() => false);
|
|
5798
6476
|
if (!stillVisible) {
|
|
5799
|
-
|
|
6477
|
+
logger11.info("\u9A8C\u8BC1\u7801\u8BC6\u522B\u5E76\u63D0\u4EA4\u6210\u529F\u3002");
|
|
5800
6478
|
return true;
|
|
5801
6479
|
}
|
|
5802
6480
|
await maybeCollectCaptchaDebugInfo(page, frame, iframeLocator, attempt, "submit-still-visible", config, {
|
|
5803
6481
|
beforeSubmitState,
|
|
5804
6482
|
afterSubmitState
|
|
5805
6483
|
}).catch((error) => {
|
|
5806
|
-
|
|
6484
|
+
logger11.warn(`\u63D0\u4EA4\u540E\u9A8C\u8BC1\u7801\u8C03\u8BD5\u6293\u53D6\u5931\u8D25\uFF1A${error?.message || error}`);
|
|
5807
6485
|
});
|
|
5808
|
-
|
|
6486
|
+
logger11.warn("\u63D0\u4EA4\u540E\u9A8C\u8BC1\u7801 iframe \u4ECD\u7136\u53EF\u89C1\uFF0C\u51C6\u5907\u5237\u65B0\u540E\u91CD\u8BD5\u3002");
|
|
5809
6487
|
await page.waitForTimeout(2e3);
|
|
5810
6488
|
await refreshCaptcha(page, frame, config);
|
|
5811
6489
|
} catch (error) {
|
|
5812
|
-
|
|
6490
|
+
logger11.error(`\u7B2C ${attempt}/${config.maxRetries} \u6B21\u9A8C\u8BC1\u7801\u8BC6\u522B\u5931\u8D25\uFF1A${error?.message || error}`);
|
|
5813
6491
|
}
|
|
5814
6492
|
if (attempt < config.maxRetries) {
|
|
5815
6493
|
await page.waitForTimeout(config.retryDelayBaseMs + attempt * config.retryDelayStepMs);
|
|
5816
6494
|
}
|
|
5817
6495
|
}
|
|
5818
|
-
|
|
6496
|
+
logger11.error(`\u91CD\u8BD5 ${config.maxRetries} \u6B21\u540E\uFF0C\u9A8C\u8BC1\u7801\u4ECD\u672A\u8BC6\u522B\u6210\u529F\u3002`);
|
|
5819
6497
|
return false;
|
|
5820
6498
|
}
|
|
5821
6499
|
var sloveCaptcha = solveCaptcha;
|
|
5822
6500
|
|
|
5823
6501
|
// src/chaptcha.js
|
|
5824
|
-
var
|
|
6502
|
+
var logger12 = createInternalLogger("Captcha");
|
|
6503
|
+
var DOM_MONITOR_WAIT_TIMEOUT_MS = 1e3;
|
|
6504
|
+
var DOM_MONITOR_POST_DETECT_HIDDEN_WAIT_MS = 300;
|
|
6505
|
+
var DOM_MONITOR_RECOVERY_WAIT_MS = 100;
|
|
5825
6506
|
var DEFAULT_CAPTCHA_RECOGNITION_OPTIONS = Object.freeze({
|
|
5826
6507
|
token: "eKJvBfwfN0YRav0-VD_44E2VBSfm7l0YtddUQ7cFySI",
|
|
5827
6508
|
apiUrl: "https://api.jfbym.com/api/YmServer/customApi"
|
|
@@ -5842,6 +6523,11 @@ var mergeDefinedOptions = (...sources) => {
|
|
|
5842
6523
|
}
|
|
5843
6524
|
return merged;
|
|
5844
6525
|
};
|
|
6526
|
+
var sleep = (ms) => new Promise((resolve) => {
|
|
6527
|
+
setTimeout(resolve, ms);
|
|
6528
|
+
});
|
|
6529
|
+
var getErrorMessage = (error) => String(error?.message || error || "");
|
|
6530
|
+
var isTimeoutError = (error) => error?.name === "TimeoutError" || getErrorMessage(error).includes("Timeout");
|
|
5845
6531
|
function useCaptchaMonitor(page, options) {
|
|
5846
6532
|
const { domSelector, urlPattern, onDetected } = options;
|
|
5847
6533
|
if (!domSelector && !urlPattern) {
|
|
@@ -5853,10 +6539,13 @@ function useCaptchaMonitor(page, options) {
|
|
|
5853
6539
|
let isStopped = false;
|
|
5854
6540
|
let isHandling = false;
|
|
5855
6541
|
let frameHandler = null;
|
|
5856
|
-
let
|
|
6542
|
+
let domMonitorTask = null;
|
|
6543
|
+
let lastTriggeredAt = 0;
|
|
5857
6544
|
const triggerDetected = async () => {
|
|
5858
|
-
|
|
6545
|
+
const now = Date.now();
|
|
6546
|
+
if (isStopped || isHandling || now - lastTriggeredAt < 250) return;
|
|
5859
6547
|
isHandling = true;
|
|
6548
|
+
lastTriggeredAt = now;
|
|
5860
6549
|
try {
|
|
5861
6550
|
await onDetected();
|
|
5862
6551
|
} finally {
|
|
@@ -5865,60 +6554,38 @@ function useCaptchaMonitor(page, options) {
|
|
|
5865
6554
|
};
|
|
5866
6555
|
const cleanupFns = [];
|
|
5867
6556
|
if (domSelector) {
|
|
5868
|
-
|
|
5869
|
-
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
|
|
5873
|
-
|
|
5874
|
-
|
|
5875
|
-
|
|
5876
|
-
|
|
5877
|
-
|
|
5878
|
-
|
|
5879
|
-
}
|
|
5880
|
-
|
|
5881
|
-
|
|
5882
|
-
|
|
5883
|
-
|
|
5884
|
-
|
|
5885
|
-
|
|
5886
|
-
|
|
5887
|
-
const shouldCheck = mutations.some((mutation) => mutation.addedNodes.length > 0);
|
|
5888
|
-
if (shouldCheck && observer) {
|
|
5889
|
-
checkAndReport();
|
|
5890
|
-
}
|
|
5891
|
-
});
|
|
5892
|
-
const mountObserver = () => {
|
|
5893
|
-
const target = document.documentElement;
|
|
5894
|
-
if (target && observer) {
|
|
5895
|
-
observer.observe(target, { childList: true, subtree: true });
|
|
6557
|
+
domMonitorTask = (async () => {
|
|
6558
|
+
const locator = page.locator(domSelector).first();
|
|
6559
|
+
while (!isStopped) {
|
|
6560
|
+
try {
|
|
6561
|
+
await locator.waitFor({ state: "visible", timeout: DOM_MONITOR_WAIT_TIMEOUT_MS });
|
|
6562
|
+
if (isStopped) break;
|
|
6563
|
+
await triggerDetected();
|
|
6564
|
+
if (isStopped) break;
|
|
6565
|
+
await locator.waitFor({
|
|
6566
|
+
state: "hidden",
|
|
6567
|
+
timeout: DOM_MONITOR_POST_DETECT_HIDDEN_WAIT_MS
|
|
6568
|
+
}).catch(() => {
|
|
6569
|
+
});
|
|
6570
|
+
} catch (error) {
|
|
6571
|
+
if (isStopped) break;
|
|
6572
|
+
if (page?.isClosed?.()) break;
|
|
6573
|
+
if (isTimeoutError(error)) {
|
|
6574
|
+
await sleep(DOM_MONITOR_RECOVERY_WAIT_MS);
|
|
6575
|
+
continue;
|
|
5896
6576
|
}
|
|
5897
|
-
|
|
5898
|
-
|
|
5899
|
-
|
|
5900
|
-
|
|
5901
|
-
|
|
6577
|
+
logger12.warning(
|
|
6578
|
+
"useCaptchaMonitor",
|
|
6579
|
+
`DOM \u76D1\u63A7\u51FA\u73B0\u5F02\u5E38\uFF08\u7EE7\u7EED\u91CD\u8BD5\uFF09: selector=${domSelector}, error=${getErrorMessage(error)}`
|
|
6580
|
+
);
|
|
6581
|
+
await sleep(DOM_MONITOR_RECOVERY_WAIT_MS);
|
|
5902
6582
|
}
|
|
5903
|
-
window[cleanupName] = () => {
|
|
5904
|
-
if (observer) {
|
|
5905
|
-
observer.disconnect();
|
|
5906
|
-
observer = null;
|
|
5907
|
-
}
|
|
5908
|
-
};
|
|
5909
|
-
})();
|
|
5910
|
-
}, { selector: domSelector, callbackName: exposedFunctionName, cleanerName });
|
|
5911
|
-
logger11.success("useCaptchaMonitor", `DOM \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${domSelector}`);
|
|
5912
|
-
cleanupFns.push(async () => {
|
|
5913
|
-
try {
|
|
5914
|
-
await page.evaluate((name) => {
|
|
5915
|
-
if (window[name]) {
|
|
5916
|
-
window[name]();
|
|
5917
|
-
delete window[name];
|
|
5918
|
-
}
|
|
5919
|
-
}, cleanerName);
|
|
5920
|
-
} catch {
|
|
5921
6583
|
}
|
|
6584
|
+
})();
|
|
6585
|
+
logger12.success("useCaptchaMonitor", `DOM \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${domSelector}`);
|
|
6586
|
+
cleanupFns.push(async () => {
|
|
6587
|
+
await domMonitorTask?.catch(() => {
|
|
6588
|
+
});
|
|
5922
6589
|
});
|
|
5923
6590
|
}
|
|
5924
6591
|
if (urlPattern) {
|
|
@@ -5932,18 +6599,24 @@ function useCaptchaMonitor(page, options) {
|
|
|
5932
6599
|
}
|
|
5933
6600
|
};
|
|
5934
6601
|
page.on("framenavigated", frameHandler);
|
|
5935
|
-
|
|
6602
|
+
logger12.success("useCaptchaMonitor", `URL \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${urlPattern}`);
|
|
6603
|
+
Promise.resolve().then(async () => {
|
|
6604
|
+
if (!isStopped && page.url().includes(urlPattern)) {
|
|
6605
|
+
await triggerDetected();
|
|
6606
|
+
}
|
|
6607
|
+
}).catch(() => {
|
|
6608
|
+
});
|
|
5936
6609
|
cleanupFns.push(async () => {
|
|
5937
6610
|
page.off("framenavigated", frameHandler);
|
|
5938
6611
|
});
|
|
5939
6612
|
}
|
|
5940
6613
|
return {
|
|
5941
6614
|
stop: async () => {
|
|
5942
|
-
|
|
6615
|
+
logger12.info("\u6B63\u5728\u505C\u6B62\u9A8C\u8BC1\u7801\u76D1\u63A7...");
|
|
6616
|
+
isStopped = true;
|
|
5943
6617
|
for (const fn of cleanupFns) {
|
|
5944
6618
|
await fn();
|
|
5945
6619
|
}
|
|
5946
|
-
isStopped = true;
|
|
5947
6620
|
}
|
|
5948
6621
|
};
|
|
5949
6622
|
}
|
|
@@ -5978,7 +6651,7 @@ async function solveCaptchaWithStrategy(strategyName, page, options = {}) {
|
|
|
5978
6651
|
);
|
|
5979
6652
|
return strategy.sloveCaptcha(page, resolvedOptions, {
|
|
5980
6653
|
callCaptchaRecognitionApi,
|
|
5981
|
-
logger:
|
|
6654
|
+
logger: logger12
|
|
5982
6655
|
});
|
|
5983
6656
|
}
|
|
5984
6657
|
var Captcha = {
|
|
@@ -5987,16 +6660,16 @@ var Captcha = {
|
|
|
5987
6660
|
};
|
|
5988
6661
|
|
|
5989
6662
|
// src/mutation.js
|
|
5990
|
-
var
|
|
5991
|
-
var
|
|
5992
|
-
var
|
|
6663
|
+
var import_node_crypto2 = require("node:crypto");
|
|
6664
|
+
var import_uuid = require("uuid");
|
|
6665
|
+
var logger13 = createInternalLogger("Mutation");
|
|
5993
6666
|
var MUTATION_MONITOR_MODE = Object.freeze({
|
|
5994
6667
|
Added: "added",
|
|
5995
6668
|
Changed: "changed",
|
|
5996
6669
|
All: "all"
|
|
5997
6670
|
});
|
|
5998
6671
|
function generateKey(prefix) {
|
|
5999
|
-
return `__${prefix}_${(0,
|
|
6672
|
+
return `__${prefix}_${(0, import_uuid.v4)().replace(/-/g, "_")}`;
|
|
6000
6673
|
}
|
|
6001
6674
|
var Mutation = {
|
|
6002
6675
|
Mode: MUTATION_MONITOR_MODE,
|
|
@@ -6022,14 +6695,14 @@ var Mutation = {
|
|
|
6022
6695
|
const stableTime = options.stableTime ?? 5 * 1e3;
|
|
6023
6696
|
const timeout = options.timeout ?? 120 * 1e3;
|
|
6024
6697
|
const onMutation = options.onMutation;
|
|
6025
|
-
|
|
6698
|
+
logger13.start("waitForStable", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, \u7A33\u5B9A\u65F6\u95F4=${stableTime}ms`);
|
|
6026
6699
|
if (initialTimeout > 0) {
|
|
6027
6700
|
const selectorQuery = selectorList.join(",");
|
|
6028
6701
|
try {
|
|
6029
6702
|
await page.waitForSelector(selectorQuery, { timeout: initialTimeout });
|
|
6030
|
-
|
|
6703
|
+
logger13.info(`waitForStable \u5DF2\u68C0\u6D4B\u5230\u5143\u7D20: ${selectorQuery}`);
|
|
6031
6704
|
} catch (e) {
|
|
6032
|
-
|
|
6705
|
+
logger13.warning(`waitForStable \u521D\u59CB\u7B49\u5F85\u8D85\u65F6 (${initialTimeout}ms): ${selectorQuery}`);
|
|
6033
6706
|
throw e;
|
|
6034
6707
|
}
|
|
6035
6708
|
}
|
|
@@ -6045,7 +6718,7 @@ var Mutation = {
|
|
|
6045
6718
|
return "__CONTINUE__";
|
|
6046
6719
|
}
|
|
6047
6720
|
});
|
|
6048
|
-
|
|
6721
|
+
logger13.info("waitForStable \u5DF2\u542F\u7528 onMutation \u56DE\u8C03");
|
|
6049
6722
|
} catch (e) {
|
|
6050
6723
|
}
|
|
6051
6724
|
}
|
|
@@ -6160,9 +6833,9 @@ var Mutation = {
|
|
|
6160
6833
|
{ selectorList, stableTime, timeout, callbackName, hasCallback: !!onMutation }
|
|
6161
6834
|
);
|
|
6162
6835
|
if (result.mutationCount === 0 && result.stableTime === 0) {
|
|
6163
|
-
|
|
6836
|
+
logger13.warning("waitForStable \u672A\u627E\u5230\u53EF\u76D1\u63A7\u7684\u5143\u7D20");
|
|
6164
6837
|
}
|
|
6165
|
-
|
|
6838
|
+
logger13.success("waitForStable", `DOM \u7A33\u5B9A, \u603B\u5171 ${result.mutationCount} \u6B21\u53D8\u5316${result.wasPaused ? ", \u66FE\u6682\u505C\u8BA1\u65F6" : ""}`);
|
|
6166
6839
|
return result;
|
|
6167
6840
|
},
|
|
6168
6841
|
/**
|
|
@@ -6186,7 +6859,7 @@ var Mutation = {
|
|
|
6186
6859
|
const overallTimeout = options.timeout ?? 180 * 1e3;
|
|
6187
6860
|
const onMutation = options.onMutation;
|
|
6188
6861
|
const pollInterval = 500;
|
|
6189
|
-
const
|
|
6862
|
+
const sleep2 = (ms) => new Promise((resolve) => {
|
|
6190
6863
|
setTimeout(resolve, ms);
|
|
6191
6864
|
});
|
|
6192
6865
|
const truncate = (value, max = 800) => {
|
|
@@ -6194,9 +6867,9 @@ var Mutation = {
|
|
|
6194
6867
|
if (text.length <= max) return text;
|
|
6195
6868
|
return `${text.slice(0, max)}...`;
|
|
6196
6869
|
};
|
|
6197
|
-
const
|
|
6870
|
+
const normalizeText3 = (value) => String(value || "").replace(/\s+/g, " ").trim();
|
|
6198
6871
|
const normalizeHtml = (value) => String(value || "").trim();
|
|
6199
|
-
const hashSnapshot = (value) => (0,
|
|
6872
|
+
const hashSnapshot = (value) => (0, import_node_crypto2.createHash)("sha256").update(String(value || "")).digest("hex");
|
|
6200
6873
|
const buildState = async () => {
|
|
6201
6874
|
const items = [];
|
|
6202
6875
|
const describeElement = async (elementHandle) => {
|
|
@@ -6259,7 +6932,7 @@ var Mutation = {
|
|
|
6259
6932
|
if (frame) {
|
|
6260
6933
|
try {
|
|
6261
6934
|
const frameSnapshot = await readFrameSnapshot(frame);
|
|
6262
|
-
text =
|
|
6935
|
+
text = normalizeText3(frameSnapshot?.text || "");
|
|
6263
6936
|
html = normalizeHtml(frameSnapshot?.html || "");
|
|
6264
6937
|
frameUrl = String(frameSnapshot?.url || "").trim();
|
|
6265
6938
|
readyState = String(frameSnapshot?.readyState || "").trim();
|
|
@@ -6273,7 +6946,7 @@ var Mutation = {
|
|
|
6273
6946
|
} else {
|
|
6274
6947
|
try {
|
|
6275
6948
|
const elementSnapshot = await readElementSnapshot(handle);
|
|
6276
|
-
text =
|
|
6949
|
+
text = normalizeText3(elementSnapshot?.text || "");
|
|
6277
6950
|
html = normalizeHtml(elementSnapshot?.html || "");
|
|
6278
6951
|
} catch (error) {
|
|
6279
6952
|
source = "main-unreadable";
|
|
@@ -6334,29 +7007,29 @@ var Mutation = {
|
|
|
6334
7007
|
return "__CONTINUE__";
|
|
6335
7008
|
}
|
|
6336
7009
|
};
|
|
6337
|
-
|
|
7010
|
+
logger13.start(
|
|
6338
7011
|
"waitForStableAcrossRoots",
|
|
6339
7012
|
`\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668(\u8DE8 root), \u7A33\u5B9A\u65F6\u95F4=${waitForStableTime}ms`
|
|
6340
7013
|
);
|
|
6341
7014
|
if (initialTimeout > 0) {
|
|
6342
7015
|
try {
|
|
6343
7016
|
await page.waitForSelector(selectorQuery, { timeout: initialTimeout });
|
|
6344
|
-
|
|
7017
|
+
logger13.info(`waitForStableAcrossRoots \u5DF2\u68C0\u6D4B\u5230\u5143\u7D20: ${selectorQuery}`);
|
|
6345
7018
|
} catch (e) {
|
|
6346
|
-
|
|
7019
|
+
logger13.warning(`waitForStableAcrossRoots \u521D\u59CB\u7B49\u5F85\u8D85\u65F6 (${initialTimeout}ms): ${selectorQuery}`);
|
|
6347
7020
|
throw e;
|
|
6348
7021
|
}
|
|
6349
7022
|
}
|
|
6350
|
-
let
|
|
6351
|
-
if (!
|
|
6352
|
-
|
|
7023
|
+
let state2 = await buildState();
|
|
7024
|
+
if (!state2?.hasMatched) {
|
|
7025
|
+
logger13.warning("waitForStableAcrossRoots \u672A\u627E\u5230\u53EF\u76D1\u63A7\u7684\u5143\u7D20");
|
|
6353
7026
|
return { mutationCount: 0, stableTime: 0, wasPaused: false };
|
|
6354
7027
|
}
|
|
6355
7028
|
let mutationCount = 0;
|
|
6356
7029
|
let stableSince = 0;
|
|
6357
7030
|
let isPaused = false;
|
|
6358
7031
|
let wasPaused = false;
|
|
6359
|
-
let lastSnapshotKey =
|
|
7032
|
+
let lastSnapshotKey = state2.snapshotKey;
|
|
6360
7033
|
const applyPauseSignal = (signal) => {
|
|
6361
7034
|
const nextPaused = signal === "__PAUSE__";
|
|
6362
7035
|
if (nextPaused) {
|
|
@@ -6370,15 +7043,15 @@ var Mutation = {
|
|
|
6370
7043
|
};
|
|
6371
7044
|
const initialSignal = await invokeMutationCallback({
|
|
6372
7045
|
mutationCount: 0,
|
|
6373
|
-
html:
|
|
6374
|
-
text:
|
|
6375
|
-
mutationNodes:
|
|
7046
|
+
html: state2.html || "",
|
|
7047
|
+
text: state2.text || "",
|
|
7048
|
+
mutationNodes: state2.mutationNodes || []
|
|
6376
7049
|
});
|
|
6377
7050
|
applyPauseSignal(initialSignal);
|
|
6378
7051
|
const deadline = Date.now() + overallTimeout;
|
|
6379
|
-
let lastState =
|
|
7052
|
+
let lastState = state2;
|
|
6380
7053
|
while (Date.now() < deadline) {
|
|
6381
|
-
await
|
|
7054
|
+
await sleep2(pollInterval);
|
|
6382
7055
|
lastState = await buildState();
|
|
6383
7056
|
if (!lastState?.hasMatched) {
|
|
6384
7057
|
continue;
|
|
@@ -6386,7 +7059,7 @@ var Mutation = {
|
|
|
6386
7059
|
if (lastState.snapshotKey !== lastSnapshotKey) {
|
|
6387
7060
|
lastSnapshotKey = lastState.snapshotKey;
|
|
6388
7061
|
mutationCount += 1;
|
|
6389
|
-
|
|
7062
|
+
logger13.info(
|
|
6390
7063
|
`waitForStableAcrossRoots \u53D8\u5316#${mutationCount}, len=${lastState.snapshotLength}, path=${lastState.primaryPath || "unknown"}, preview="${truncate(lastState.text, 120)}"`
|
|
6391
7064
|
);
|
|
6392
7065
|
const signal = await invokeMutationCallback({
|
|
@@ -6399,7 +7072,7 @@ var Mutation = {
|
|
|
6399
7072
|
continue;
|
|
6400
7073
|
}
|
|
6401
7074
|
if (!isPaused && stableSince > 0 && Date.now() - stableSince >= waitForStableTime) {
|
|
6402
|
-
|
|
7075
|
+
logger13.success("waitForStableAcrossRoots", `DOM \u7A33\u5B9A, \u603B\u5171 ${mutationCount} \u6B21\u53D8\u5316${wasPaused ? ", \u66FE\u6682\u505C\u8BA1\u65F6" : ""}`);
|
|
6403
7076
|
return {
|
|
6404
7077
|
mutationCount,
|
|
6405
7078
|
stableTime: waitForStableTime,
|
|
@@ -6425,8 +7098,8 @@ var Mutation = {
|
|
|
6425
7098
|
const selectorList = Array.isArray(selectors) ? selectors : [selectors];
|
|
6426
7099
|
const onMutation = options.onMutation;
|
|
6427
7100
|
const rawMode = String(options.mode || MUTATION_MONITOR_MODE.Added).toLowerCase();
|
|
6428
|
-
const
|
|
6429
|
-
|
|
7101
|
+
const mode2 = [MUTATION_MONITOR_MODE.Added, MUTATION_MONITOR_MODE.Changed, MUTATION_MONITOR_MODE.All].includes(rawMode) ? rawMode : MUTATION_MONITOR_MODE.Added;
|
|
7102
|
+
logger13.start("useMonitor", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, mode=${mode2}`);
|
|
6430
7103
|
const monitorKey = generateKey("pk_mon");
|
|
6431
7104
|
const callbackName = generateKey("pk_mon_cb");
|
|
6432
7105
|
const cleanerName = generateKey("pk_mon_clean");
|
|
@@ -6441,7 +7114,7 @@ var Mutation = {
|
|
|
6441
7114
|
} catch (e) {
|
|
6442
7115
|
}
|
|
6443
7116
|
}
|
|
6444
|
-
await page.evaluate(({ selectorList: selectorList2, monitorKey: monitorKey2, callbackName: callbackName2, cleanerName: cleanerName2, hasCallback, mode:
|
|
7117
|
+
await page.evaluate(({ selectorList: selectorList2, monitorKey: monitorKey2, callbackName: callbackName2, cleanerName: cleanerName2, hasCallback, mode: mode3 }) => {
|
|
6445
7118
|
const monitor = {
|
|
6446
7119
|
observers: [],
|
|
6447
7120
|
totalMutations: 0,
|
|
@@ -6485,7 +7158,7 @@ var Mutation = {
|
|
|
6485
7158
|
const collectMutationNodes = (mutations) => {
|
|
6486
7159
|
const mutationNodes = [];
|
|
6487
7160
|
for (const mutation of mutations) {
|
|
6488
|
-
if (
|
|
7161
|
+
if (mode3 === "added") {
|
|
6489
7162
|
if (mutation.type !== "childList") continue;
|
|
6490
7163
|
const added = Array.from(mutation.addedNodes || []);
|
|
6491
7164
|
for (const node of added) {
|
|
@@ -6493,7 +7166,7 @@ var Mutation = {
|
|
|
6493
7166
|
}
|
|
6494
7167
|
continue;
|
|
6495
7168
|
}
|
|
6496
|
-
if (
|
|
7169
|
+
if (mode3 === "changed") {
|
|
6497
7170
|
if (mutation.type === "attributes" || mutation.type === "characterData") {
|
|
6498
7171
|
mutationNodes.push(serializeNode(mutation.target, mutation.type));
|
|
6499
7172
|
} else if (mutation.type === "childList") {
|
|
@@ -6553,8 +7226,8 @@ var Mutation = {
|
|
|
6553
7226
|
observer.observe(element, {
|
|
6554
7227
|
childList: true,
|
|
6555
7228
|
subtree: true,
|
|
6556
|
-
characterData:
|
|
6557
|
-
attributes:
|
|
7229
|
+
characterData: mode3 !== "added",
|
|
7230
|
+
attributes: mode3 !== "added"
|
|
6558
7231
|
});
|
|
6559
7232
|
monitor.observers.push(observer);
|
|
6560
7233
|
});
|
|
@@ -6568,8 +7241,8 @@ var Mutation = {
|
|
|
6568
7241
|
delete window[cleanerName2];
|
|
6569
7242
|
return total;
|
|
6570
7243
|
};
|
|
6571
|
-
}, { selectorList, monitorKey, callbackName, cleanerName, hasCallback: !!onMutation, mode });
|
|
6572
|
-
|
|
7244
|
+
}, { selectorList, monitorKey, callbackName, cleanerName, hasCallback: !!onMutation, mode: mode2 });
|
|
7245
|
+
logger13.success("useMonitor", "\u76D1\u63A7\u5668\u5DF2\u542F\u52A8");
|
|
6573
7246
|
return {
|
|
6574
7247
|
stop: async () => {
|
|
6575
7248
|
let totalMutations = 0;
|
|
@@ -6582,7 +7255,7 @@ var Mutation = {
|
|
|
6582
7255
|
}, cleanerName);
|
|
6583
7256
|
} catch (e) {
|
|
6584
7257
|
}
|
|
6585
|
-
|
|
7258
|
+
logger13.success("useMonitor.stop", `\u76D1\u63A7\u5DF2\u505C\u6B62, \u5171 ${totalMutations} \u6B21\u53D8\u5316`);
|
|
6586
7259
|
return { totalMutations };
|
|
6587
7260
|
}
|
|
6588
7261
|
};
|
|
@@ -7451,7 +8124,7 @@ var createTemplateLogger = (baseLogger = createBaseLogger()) => {
|
|
|
7451
8124
|
};
|
|
7452
8125
|
var getDefaultBaseLogger = () => createBaseLogger("");
|
|
7453
8126
|
var Logger = {
|
|
7454
|
-
setLogger: (
|
|
8127
|
+
setLogger: (logger17) => setDefaultLogger(logger17),
|
|
7455
8128
|
info: (message) => getDefaultBaseLogger().info(message),
|
|
7456
8129
|
success: (message) => getDefaultBaseLogger().success(message),
|
|
7457
8130
|
warning: (message) => getDefaultBaseLogger().warning(message),
|
|
@@ -7459,14 +8132,14 @@ var Logger = {
|
|
|
7459
8132
|
error: (message) => getDefaultBaseLogger().error(message),
|
|
7460
8133
|
debug: (message) => getDefaultBaseLogger().debug(message),
|
|
7461
8134
|
start: (message) => getDefaultBaseLogger().start(message),
|
|
7462
|
-
useTemplate: (
|
|
7463
|
-
if (
|
|
8135
|
+
useTemplate: (logger17) => {
|
|
8136
|
+
if (logger17) return createTemplateLogger(createBaseLogger("", logger17));
|
|
7464
8137
|
return createTemplateLogger();
|
|
7465
8138
|
}
|
|
7466
8139
|
};
|
|
7467
8140
|
|
|
7468
8141
|
// src/share.js
|
|
7469
|
-
var
|
|
8142
|
+
var import_delay5 = __toESM(require("delay"), 1);
|
|
7470
8143
|
|
|
7471
8144
|
// src/internals/watermarkify.js
|
|
7472
8145
|
var DEFAULT_TIMEZONE_OFFSET = 8;
|
|
@@ -7534,10 +8207,10 @@ var LOCATION_NETWORK_SUFFIX_PATTERNS = [
|
|
|
7534
8207
|
];
|
|
7535
8208
|
var cachedStripLogoSrcPromise = null;
|
|
7536
8209
|
var cachedEnrichmentByContext = /* @__PURE__ */ new WeakMap();
|
|
7537
|
-
var
|
|
7538
|
-
var
|
|
8210
|
+
var logger14 = createInternalLogger("Watermarkify");
|
|
8211
|
+
var normalizeText2 = (value) => String(value || "").trim();
|
|
7539
8212
|
var toInline = (value, maxLen = 200) => {
|
|
7540
|
-
const text =
|
|
8213
|
+
const text = normalizeText2(value);
|
|
7541
8214
|
if (!text) return "";
|
|
7542
8215
|
return text.replace(/\s+/g, " ").trim().slice(0, maxLen);
|
|
7543
8216
|
};
|
|
@@ -7597,7 +8270,7 @@ var pickHeaderValue = async (response, names = []) => {
|
|
|
7597
8270
|
if (!response || typeof response.headerValue !== "function") return "";
|
|
7598
8271
|
for (const name of names) {
|
|
7599
8272
|
const value = await response.headerValue(name).catch(() => null);
|
|
7600
|
-
const text =
|
|
8273
|
+
const text = normalizeText2(value);
|
|
7601
8274
|
if (text) return text;
|
|
7602
8275
|
}
|
|
7603
8276
|
return "";
|
|
@@ -7701,7 +8374,7 @@ var fetchAsDataUrl = async (url, timeoutMs = DEFAULT_LOGO_FETCH_TIMEOUT_MS) => {
|
|
|
7701
8374
|
if (!response?.ok) {
|
|
7702
8375
|
return "";
|
|
7703
8376
|
}
|
|
7704
|
-
const contentType =
|
|
8377
|
+
const contentType = normalizeText2(response.headers?.get?.("content-type")) || "image/png";
|
|
7705
8378
|
if (!/^image\//i.test(contentType)) {
|
|
7706
8379
|
return "";
|
|
7707
8380
|
}
|
|
@@ -7724,7 +8397,7 @@ var resolveStripLogoSrc = async () => {
|
|
|
7724
8397
|
})();
|
|
7725
8398
|
}
|
|
7726
8399
|
const resolved = await cachedStripLogoSrcPromise.catch(() => DEFAULT_STRIP_LOGO_URL);
|
|
7727
|
-
return
|
|
8400
|
+
return normalizeText2(resolved) || DEFAULT_STRIP_LOGO_URL;
|
|
7728
8401
|
};
|
|
7729
8402
|
var normalizeLayer = (value, defaults) => {
|
|
7730
8403
|
if (value === false) {
|
|
@@ -7776,9 +8449,9 @@ var resolveWithCustomResolver = async (page, baseMeta, options = {}) => {
|
|
|
7776
8449
|
location: toInline(resolved.location, 80)
|
|
7777
8450
|
};
|
|
7778
8451
|
if (enrichment.ip || enrichment.location) {
|
|
7779
|
-
|
|
8452
|
+
logger14.info(`\u81EA\u5B9A\u4E49 resolver \u547D\u4E2D: ip=${enrichment.ip || "-"}, loc=${enrichment.location || "-"}`);
|
|
7780
8453
|
} else {
|
|
7781
|
-
|
|
8454
|
+
logger14.warning("\u81EA\u5B9A\u4E49 resolver \u5DF2\u6267\u884C\uFF0C\u4F46\u672A\u8FD4\u56DE IP/Loc");
|
|
7782
8455
|
}
|
|
7783
8456
|
return enrichment;
|
|
7784
8457
|
} finally {
|
|
@@ -7962,14 +8635,17 @@ var buildWatermarkifyRenderHtml = ({ imageSrc, overlaySvg, width, height, imageH
|
|
|
7962
8635
|
</html>
|
|
7963
8636
|
`;
|
|
7964
8637
|
};
|
|
7965
|
-
var
|
|
8638
|
+
var normalizeWatermarkifyRenderMode = (value) => {
|
|
8639
|
+
return String(value || Mode.Default).trim().toLowerCase() === Mode.Cloak ? Mode.Cloak : Mode.Default;
|
|
8640
|
+
};
|
|
8641
|
+
var composeScreenshotBufferWithBrowser = async (page, buffer, overlaySvg, imageInfo = {}, options = {}) => {
|
|
7966
8642
|
if (!page || typeof page.context !== "function") {
|
|
7967
|
-
|
|
8643
|
+
logger14.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u8DF3\u8FC7: \u7F3A\u5C11\u53EF\u7528 page");
|
|
7968
8644
|
return buffer;
|
|
7969
8645
|
}
|
|
7970
8646
|
const renderScope = await openProbePage(page);
|
|
7971
8647
|
if (!renderScope?.page) {
|
|
7972
|
-
|
|
8648
|
+
logger14.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u8DF3\u8FC7: \u65E0\u6CD5\u521B\u5EFA render page");
|
|
7973
8649
|
return buffer;
|
|
7974
8650
|
}
|
|
7975
8651
|
try {
|
|
@@ -7986,15 +8662,35 @@ var composeScreenshotBufferWithBrowser = async (page, buffer, overlaySvg, imageI
|
|
|
7986
8662
|
height: viewportHeight
|
|
7987
8663
|
}).catch(() => {
|
|
7988
8664
|
});
|
|
7989
|
-
|
|
7990
|
-
|
|
7991
|
-
|
|
7992
|
-
|
|
7993
|
-
|
|
7994
|
-
|
|
7995
|
-
|
|
7996
|
-
|
|
7997
|
-
|
|
8665
|
+
const renderMode = normalizeWatermarkifyRenderMode(options.mode);
|
|
8666
|
+
if (renderMode === Mode.Cloak) {
|
|
8667
|
+
const renderHtml = buildWatermarkifyRenderHtml({
|
|
8668
|
+
imageSrc: `data:${imageInfo.mimeType || "image/png"};base64,${buffer.toString("base64")}`,
|
|
8669
|
+
overlaySvg,
|
|
8670
|
+
width: safeWidth,
|
|
8671
|
+
height: safeHeight,
|
|
8672
|
+
imageHeight: safeImageHeight
|
|
8673
|
+
});
|
|
8674
|
+
await renderPage.goto("about:blank", {
|
|
8675
|
+
waitUntil: "commit"
|
|
8676
|
+
}).catch(() => {
|
|
8677
|
+
});
|
|
8678
|
+
await renderPage.evaluate((html) => {
|
|
8679
|
+
document.open();
|
|
8680
|
+
document.write(html);
|
|
8681
|
+
document.close();
|
|
8682
|
+
}, renderHtml);
|
|
8683
|
+
} else {
|
|
8684
|
+
await renderPage.setContent(buildWatermarkifyRenderHtml({
|
|
8685
|
+
imageSrc: `data:${imageInfo.mimeType || "image/png"};base64,${buffer.toString("base64")}`,
|
|
8686
|
+
overlaySvg,
|
|
8687
|
+
width: safeWidth,
|
|
8688
|
+
height: safeHeight,
|
|
8689
|
+
imageHeight: safeImageHeight
|
|
8690
|
+
}), {
|
|
8691
|
+
waitUntil: "load"
|
|
8692
|
+
});
|
|
8693
|
+
}
|
|
7998
8694
|
await renderPage.waitForFunction(() => {
|
|
7999
8695
|
const image = document.getElementById("pk-base-image");
|
|
8000
8696
|
return image instanceof HTMLImageElement && image.complete && image.naturalWidth > 0 && image.naturalHeight > 0;
|
|
@@ -8014,13 +8710,13 @@ var composeScreenshotBufferWithBrowser = async (page, buffer, overlaySvg, imageI
|
|
|
8014
8710
|
fullPage: true,
|
|
8015
8711
|
animations: "disabled"
|
|
8016
8712
|
}).catch((error) => {
|
|
8017
|
-
|
|
8713
|
+
logger14.warning(`watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
|
|
8018
8714
|
return null;
|
|
8019
8715
|
});
|
|
8020
8716
|
if (Buffer.isBuffer(composed) && composed.length > 0) {
|
|
8021
8717
|
return composed;
|
|
8022
8718
|
}
|
|
8023
|
-
|
|
8719
|
+
logger14.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u5931\u8D25: \u672A\u5F97\u5230\u6709\u6548\u622A\u56FE\u7ED3\u679C");
|
|
8024
8720
|
return buffer;
|
|
8025
8721
|
} finally {
|
|
8026
8722
|
await renderScope.close().catch(() => {
|
|
@@ -8033,7 +8729,7 @@ var resolveWithIpLookup = async (page, options = {}) => {
|
|
|
8033
8729
|
}
|
|
8034
8730
|
const probeScope = await openProbePage(page);
|
|
8035
8731
|
if (!probeScope?.page) {
|
|
8036
|
-
|
|
8732
|
+
logger14.warning("ipLookup \u8DF3\u8FC7: \u65E0\u6CD5\u521B\u5EFA probe page");
|
|
8037
8733
|
return null;
|
|
8038
8734
|
}
|
|
8039
8735
|
const timeoutMs = Math.max(
|
|
@@ -8042,16 +8738,16 @@ var resolveWithIpLookup = async (page, options = {}) => {
|
|
|
8042
8738
|
);
|
|
8043
8739
|
try {
|
|
8044
8740
|
const probePage = probeScope.page;
|
|
8045
|
-
|
|
8741
|
+
logger14.info(`ipLookup \u5C1D\u8BD5: url=${DEFAULT_IP_LOOKUP_URL}, timeoutMs=${timeoutMs}`);
|
|
8046
8742
|
const response = await probePage.goto(DEFAULT_IP_LOOKUP_URL, {
|
|
8047
8743
|
waitUntil: "commit",
|
|
8048
8744
|
timeout: timeoutMs
|
|
8049
8745
|
}).catch((error) => {
|
|
8050
|
-
|
|
8746
|
+
logger14.warning(`ipLookup \u8BF7\u6C42\u5931\u8D25: url=${DEFAULT_IP_LOOKUP_URL}, error=${error instanceof Error ? error.message : String(error)}`);
|
|
8051
8747
|
return null;
|
|
8052
8748
|
});
|
|
8053
8749
|
const status = response && typeof response.status === "function" ? response.status() : 0;
|
|
8054
|
-
const contentType =
|
|
8750
|
+
const contentType = normalizeText2(await pickHeaderValue(response, ["content-type"]));
|
|
8055
8751
|
let rawText = "";
|
|
8056
8752
|
if (response && typeof response.text === "function") {
|
|
8057
8753
|
rawText = String(await withTimeout2(
|
|
@@ -8069,13 +8765,13 @@ var resolveWithIpLookup = async (page, options = {}) => {
|
|
|
8069
8765
|
}
|
|
8070
8766
|
const parsed = parseIpIpJsonResponse(rawText);
|
|
8071
8767
|
if (parsed?.ip || parsed?.location) {
|
|
8072
|
-
|
|
8768
|
+
logger14.info(`ipLookup \u6210\u529F: url=${DEFAULT_IP_LOOKUP_URL}, status=${status || "-"}, contentType=${contentType || "-"}, ip=${parsed.ip || "-"}, loc=${parsed.location || "-"}`);
|
|
8073
8769
|
return parsed;
|
|
8074
8770
|
}
|
|
8075
|
-
|
|
8771
|
+
logger14.warning(`ipLookup \u672A\u89E3\u6790\u51FA IP/Loc: url=${DEFAULT_IP_LOOKUP_URL}, status=${status || "-"}, contentType=${contentType || "-"}, preview=${shortenTail(rawText, 120) || "[empty]"}`);
|
|
8076
8772
|
return null;
|
|
8077
8773
|
} catch (error) {
|
|
8078
|
-
|
|
8774
|
+
logger14.warning(`ipLookup \u6267\u884C\u5F02\u5E38\uFF0C\u672A\u83B7\u5F97 IP/Loc: ${error instanceof Error ? error.message : String(error)}`);
|
|
8079
8775
|
return null;
|
|
8080
8776
|
} finally {
|
|
8081
8777
|
await probeScope.close().catch(() => {
|
|
@@ -8089,10 +8785,10 @@ var resolveEnrichment = async (page, baseMeta, options) => {
|
|
|
8089
8785
|
ip: toInline(options.ip, 80),
|
|
8090
8786
|
location: toInline(options.location, 80)
|
|
8091
8787
|
};
|
|
8092
|
-
|
|
8788
|
+
logger14.info(`enrichment \u5F00\u59CB: host=${baseMeta.hostname || "-"}, hasPresetIp=${Boolean(merged.ip)}, hasPresetLoc=${Boolean(merged.location)}, ipLookup=${options.ipLookup !== false}`);
|
|
8093
8789
|
if (!merged.ip || !merged.location) {
|
|
8094
8790
|
if (cached?.ip || cached?.location) {
|
|
8095
|
-
|
|
8791
|
+
logger14.info(`enrichment \u547D\u4E2D\u4E0A\u4E0B\u6587\u7F13\u5B58: ip=${cached.ip || "-"}, loc=${cached.location || "-"}`);
|
|
8096
8792
|
}
|
|
8097
8793
|
fillEnrichment(merged, cached);
|
|
8098
8794
|
}
|
|
@@ -8116,15 +8812,15 @@ var resolveEnrichment = async (page, baseMeta, options) => {
|
|
|
8116
8812
|
"x-geo-country"
|
|
8117
8813
|
]), 80);
|
|
8118
8814
|
if (!merged.location || isWeakLocationValue(merged.location) && headerLocation) {
|
|
8119
|
-
|
|
8815
|
+
logger14.info(`enrichment \u4F7F\u7528\u54CD\u5E94\u5934\u8865\u5145 Loc: ${headerLocation || "-"}`);
|
|
8120
8816
|
merged.location = headerLocation || merged.location;
|
|
8121
8817
|
}
|
|
8122
8818
|
}
|
|
8123
8819
|
writeCachedEnrichment(page, merged);
|
|
8124
8820
|
if (merged.ip || merged.location) {
|
|
8125
|
-
|
|
8821
|
+
logger14.info(`enrichment \u5B8C\u6210: ip=${merged.ip || "-"}, loc=${merged.location || "-"}`);
|
|
8126
8822
|
} else {
|
|
8127
|
-
|
|
8823
|
+
logger14.warning("enrichment \u5B8C\u6210: \u672A\u83B7\u5F97 IP/Loc");
|
|
8128
8824
|
}
|
|
8129
8825
|
return merged;
|
|
8130
8826
|
};
|
|
@@ -8190,8 +8886,8 @@ var estimateTextWidth = (value, fontSize = 16) => {
|
|
|
8190
8886
|
return Math.ceil(width);
|
|
8191
8887
|
};
|
|
8192
8888
|
var resolvePromptFields = (options = {}, fallbackTitle = "") => {
|
|
8193
|
-
const query =
|
|
8194
|
-
const prompt = query ||
|
|
8889
|
+
const query = normalizeText2(options.query);
|
|
8890
|
+
const prompt = query || normalizeText2(options.prompt) || normalizeText2(fallbackTitle) || "\u672A\u63D0\u4F9B Prompt";
|
|
8195
8891
|
return {
|
|
8196
8892
|
prompt,
|
|
8197
8893
|
query: query || prompt
|
|
@@ -8245,8 +8941,8 @@ var normalizeScreenshotWatermarkify = (value) => {
|
|
|
8245
8941
|
enabled: source.enabled !== false,
|
|
8246
8942
|
timezoneOffsetHours: Number.isFinite(timezoneOffsetHoursRaw) ? timezoneOffsetHoursRaw : DEFAULT_TIMEZONE_OFFSET,
|
|
8247
8943
|
response: source.response ?? null,
|
|
8248
|
-
ip:
|
|
8249
|
-
location:
|
|
8944
|
+
ip: normalizeText2(source.ip),
|
|
8945
|
+
location: normalizeText2(source.location),
|
|
8250
8946
|
prompt: normalizeWhitespace(source.prompt),
|
|
8251
8947
|
query: normalizeWhitespace(source.query),
|
|
8252
8948
|
ipLookup: source.ipLookup !== false,
|
|
@@ -8264,8 +8960,8 @@ var normalizeScreenshotWatermarkify = (value) => {
|
|
|
8264
8960
|
};
|
|
8265
8961
|
var resolveScreenshotWatermarkifyMeta = async (page, options = {}) => {
|
|
8266
8962
|
const timezoneOffsetHours = options.timezoneOffsetHours ?? DEFAULT_TIMEZONE_OFFSET;
|
|
8267
|
-
const url =
|
|
8268
|
-
const title =
|
|
8963
|
+
const url = normalizeText2(page?.url?.()) || "about:blank";
|
|
8964
|
+
const title = normalizeText2(await page.title().catch(() => "")) || "\u672A\u547D\u540D\u9875\u9762";
|
|
8269
8965
|
const hostname = getHostname(url);
|
|
8270
8966
|
const { prompt, query } = resolvePromptFields(options, title);
|
|
8271
8967
|
const capturedAt = options.capturedAt instanceof Date ? options.capturedAt : new Date(options.capturedAt || Date.now());
|
|
@@ -8752,7 +9448,7 @@ var renderMobileStrip = ({ meta, width, baseHeight, fontFamily }) => {
|
|
|
8752
9448
|
`;
|
|
8753
9449
|
};
|
|
8754
9450
|
var buildWatermarkifySvg = (meta, imageWidth, imageHeight) => {
|
|
8755
|
-
const hasWatermark = meta?.watermark?.enabled !== false &&
|
|
9451
|
+
const hasWatermark = meta?.watermark?.enabled !== false && normalizeText2(meta?.watermarkText);
|
|
8756
9452
|
const hasStrip = meta?.strip?.enabled !== false && Array.isArray(meta?.stripSegments) && meta.stripSegments.length > 0;
|
|
8757
9453
|
if (!hasWatermark && !hasStrip) {
|
|
8758
9454
|
return "";
|
|
@@ -8763,7 +9459,7 @@ var buildWatermarkifySvg = (meta, imageWidth, imageHeight) => {
|
|
|
8763
9459
|
const fontFamily = escapeXml(buildFontFamily());
|
|
8764
9460
|
const parts = [];
|
|
8765
9461
|
if (hasWatermark) {
|
|
8766
|
-
const stampText = escapeXml(
|
|
9462
|
+
const stampText = escapeXml(normalizeText2(meta.watermarkText));
|
|
8767
9463
|
const cellWidth = Math.max(680, Number(meta.watermark?.cellWidth) || DEFAULT_WATERMARK_CELL_WIDTH);
|
|
8768
9464
|
const cellHeight = Math.max(260, Number(meta.watermark?.cellHeight) || DEFAULT_WATERMARK_CELL_HEIGHT);
|
|
8769
9465
|
const rotateDeg = Number(meta.watermark?.rotateDeg) || DEFAULT_WATERMARK_ROTATE_DEG;
|
|
@@ -8929,15 +9625,15 @@ var buildWatermarkifySvg = (meta, imageWidth, imageHeight) => {
|
|
|
8929
9625
|
</svg>
|
|
8930
9626
|
`;
|
|
8931
9627
|
};
|
|
8932
|
-
var watermarkifyScreenshotBuffer = async (buffer, meta, page = null) => {
|
|
8933
|
-
const hasWatermark = meta?.watermark?.enabled !== false &&
|
|
9628
|
+
var watermarkifyScreenshotBuffer = async (buffer, meta, page = null, options = {}) => {
|
|
9629
|
+
const hasWatermark = meta?.watermark?.enabled !== false && normalizeText2(meta?.watermarkText);
|
|
8934
9630
|
const hasStrip = meta?.strip?.enabled !== false && Array.isArray(meta?.stripSegments) && meta.stripSegments.length > 0;
|
|
8935
9631
|
if (!Buffer.isBuffer(buffer) || !meta || !hasWatermark && !hasStrip) {
|
|
8936
9632
|
return buffer;
|
|
8937
9633
|
}
|
|
8938
9634
|
const imageInfo = readImageInfo(buffer);
|
|
8939
9635
|
if (!imageInfo.width || !imageInfo.height || !imageInfo.mimeType) {
|
|
8940
|
-
|
|
9636
|
+
logger14.warning("watermarkify \u8DF3\u8FC7: \u65E0\u6CD5\u89E3\u6790\u622A\u56FE\u5C3A\u5BF8\u6216\u683C\u5F0F");
|
|
8941
9637
|
return buffer;
|
|
8942
9638
|
}
|
|
8943
9639
|
const isMobileStrip = normalizeDevice(meta.device) === Device.Mobile && hasStrip;
|
|
@@ -8950,12 +9646,12 @@ var watermarkifyScreenshotBuffer = async (buffer, meta, page = null) => {
|
|
|
8950
9646
|
if (!overlaySvg) {
|
|
8951
9647
|
return buffer;
|
|
8952
9648
|
}
|
|
8953
|
-
return await composeScreenshotBufferWithBrowser(page, buffer, overlaySvg, outputImageInfo);
|
|
9649
|
+
return await composeScreenshotBufferWithBrowser(page, buffer, overlaySvg, outputImageInfo, options);
|
|
8954
9650
|
};
|
|
8955
9651
|
|
|
8956
9652
|
// src/internals/compression.js
|
|
8957
9653
|
var import_jimp = require("jimp");
|
|
8958
|
-
var
|
|
9654
|
+
var logger15 = createInternalLogger("Compression");
|
|
8959
9655
|
var DEFAULT_SCREENSHOT_MAX_BYTES = 5 * 1024 * 1024;
|
|
8960
9656
|
var DEFAULT_SCREENSHOT_OUTPUT_TYPE = "jpeg";
|
|
8961
9657
|
var DEFAULT_SCREENSHOT_QUALITY = 0.72;
|
|
@@ -9074,18 +9770,18 @@ var compressImageBufferToBase64 = async (buffer, compression) => {
|
|
|
9074
9770
|
return buffer.toString("base64");
|
|
9075
9771
|
}
|
|
9076
9772
|
const result = await compressImageBuffer(buffer, compression).catch((error) => {
|
|
9077
|
-
|
|
9773
|
+
logger15.warning(`captureScreen \u538B\u7F29\u5931\u8D25\uFF0C\u8FD4\u56DE\u539F\u56FE: ${error instanceof Error ? error.message : String(error)}`);
|
|
9078
9774
|
return null;
|
|
9079
9775
|
});
|
|
9080
9776
|
if (!result?.buffer) {
|
|
9081
9777
|
return buffer.toString("base64");
|
|
9082
9778
|
}
|
|
9083
9779
|
if (result.withinLimit) {
|
|
9084
|
-
|
|
9780
|
+
logger15.info(
|
|
9085
9781
|
`captureScreen \u5DF2\u538B\u7F29: ${originalBytes} -> ${result.bytes} bytes, format=${result.format}, quality=${result.quality}, scale=${result.scale}, size=${result.width}x${result.height}`
|
|
9086
9782
|
);
|
|
9087
9783
|
} else {
|
|
9088
|
-
|
|
9784
|
+
logger15.warning(
|
|
9089
9785
|
`captureScreen \u538B\u7F29\u540E\u4ECD\u8D85\u8FC7\u76EE\u6807: ${originalBytes} -> ${result.bytes} bytes, maxBytes=${compression.maxBytes}, format=${result.format}, quality=${result.quality}, scale=${result.scale}`
|
|
9090
9786
|
);
|
|
9091
9787
|
}
|
|
@@ -9093,7 +9789,7 @@ var compressImageBufferToBase64 = async (buffer, compression) => {
|
|
|
9093
9789
|
};
|
|
9094
9790
|
|
|
9095
9791
|
// src/share.js
|
|
9096
|
-
var
|
|
9792
|
+
var logger16 = createInternalLogger("Share");
|
|
9097
9793
|
var DEFAULT_TIMEOUT_MS2 = 50 * 1e3;
|
|
9098
9794
|
var DEFAULT_PAYLOAD_SNAPSHOT_MAX_LEN = 500;
|
|
9099
9795
|
var DEFAULT_POLL_INTERVAL_MS = 120;
|
|
@@ -9163,9 +9859,9 @@ var normalizeXurl = (value) => {
|
|
|
9163
9859
|
var normalizeShare = (share) => {
|
|
9164
9860
|
const source = share && typeof share === "object" ? share : {};
|
|
9165
9861
|
const modeRaw = String(source.mode || "dom").trim().toLowerCase();
|
|
9166
|
-
const
|
|
9862
|
+
const mode2 = ["dom", "response", "custom"].includes(modeRaw) ? modeRaw : "dom";
|
|
9167
9863
|
return {
|
|
9168
|
-
mode,
|
|
9864
|
+
mode: mode2,
|
|
9169
9865
|
prefix: normalizePrefix(source.prefix),
|
|
9170
9866
|
xurl: normalizeXurl(source.xurl)
|
|
9171
9867
|
};
|
|
@@ -9226,13 +9922,13 @@ var parseJsonSafely = (text) => {
|
|
|
9226
9922
|
var createDomShareMonitor = async (page, options = {}) => {
|
|
9227
9923
|
const prefix = normalizePrefix(options.prefix);
|
|
9228
9924
|
const selectors = options.selectors ?? "html";
|
|
9229
|
-
const
|
|
9925
|
+
const mode2 = options.mode ?? Mutation.Mode.All;
|
|
9230
9926
|
const onMatch = typeof options.onMatch === "function" ? options.onMatch : null;
|
|
9231
9927
|
const onTelemetry = typeof options.onTelemetry === "function" ? options.onTelemetry : null;
|
|
9232
9928
|
let matched = false;
|
|
9233
|
-
|
|
9929
|
+
logger16.info(`DOM \u76D1\u542C\u51C6\u5907\u6302\u8F7D: selectors=${toJsonInline(selectors, 120)}, mode=${mode2}`);
|
|
9234
9930
|
const monitor = await Mutation.useMonitor(page, selectors, {
|
|
9235
|
-
mode,
|
|
9931
|
+
mode: mode2,
|
|
9236
9932
|
onMutation: (context = {}) => {
|
|
9237
9933
|
if (matched) return;
|
|
9238
9934
|
const mutationCount = Number(context.mutationCount || 0);
|
|
@@ -9248,12 +9944,12 @@ ${text}`;
|
|
|
9248
9944
|
});
|
|
9249
9945
|
}
|
|
9250
9946
|
if (mutationCount <= 5 || mutationCount % 50 === 0) {
|
|
9251
|
-
|
|
9947
|
+
logger16.info(`DOM \u53D8\u5316\u5DF2\u6355\u83B7: mutationCount=${mutationCount}, mutationNodes=${mutationNodes.length}`);
|
|
9252
9948
|
}
|
|
9253
9949
|
const [candidate] = Utils.parseLinks(rawDom, { prefix }) || [];
|
|
9254
9950
|
if (!candidate) return;
|
|
9255
9951
|
matched = true;
|
|
9256
|
-
|
|
9952
|
+
logger16.success("captureLink.domHit", `DOM \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: mutationCount=${mutationCount}, link=${candidate}`);
|
|
9257
9953
|
if (onMatch) {
|
|
9258
9954
|
onMatch({
|
|
9259
9955
|
link: candidate,
|
|
@@ -9269,7 +9965,7 @@ ${text}`;
|
|
|
9269
9965
|
return {
|
|
9270
9966
|
stop: async () => {
|
|
9271
9967
|
const result = await monitor.stop();
|
|
9272
|
-
|
|
9968
|
+
logger16.info(`DOM \u76D1\u542C\u5DF2\u505C\u6B62: totalMutations=${result?.totalMutations || 0}`);
|
|
9273
9969
|
return result;
|
|
9274
9970
|
}
|
|
9275
9971
|
};
|
|
@@ -9318,8 +10014,8 @@ var Share = {
|
|
|
9318
10014
|
if (share.mode === "response" && apiMatchers.length === 0) {
|
|
9319
10015
|
throw new Error("Share.captureLink requires share.xurl[0] api matcher when mode=response");
|
|
9320
10016
|
}
|
|
9321
|
-
|
|
9322
|
-
|
|
10017
|
+
logger16.start("captureLink", `mode=${share.mode}, timeoutMs=${timeoutDisabled ? "disabled" : timeoutMs}, prefix=${share.prefix}`);
|
|
10018
|
+
logger16.info(`captureLink \u914D\u7F6E: xurl=${toJsonInline(share.xurl)}, domMode=${domMode}, domSelectors=${toJsonInline(domSelectors, 120)}`);
|
|
9323
10019
|
const stats = {
|
|
9324
10020
|
actionTimedOut: false,
|
|
9325
10021
|
domMutationCount: 0,
|
|
@@ -9331,7 +10027,7 @@ var Share = {
|
|
|
9331
10027
|
responseSampleUrls: []
|
|
9332
10028
|
};
|
|
9333
10029
|
if (isAborted()) {
|
|
9334
|
-
|
|
10030
|
+
logger16.warning(`captureLink \u5DF2\u53D6\u6D88: ${abortReason()}`);
|
|
9335
10031
|
return {
|
|
9336
10032
|
link: null,
|
|
9337
10033
|
payloadText: "",
|
|
@@ -9354,7 +10050,7 @@ var Share = {
|
|
|
9354
10050
|
link: validated,
|
|
9355
10051
|
payloadText: String(payloadText || "")
|
|
9356
10052
|
};
|
|
9357
|
-
|
|
10053
|
+
logger16.info(`\u5019\u9009\u94FE\u63A5\u5DF2\u786E\u8BA4: source=${source}, link=${validated}`);
|
|
9358
10054
|
return true;
|
|
9359
10055
|
};
|
|
9360
10056
|
const resolveResponseCandidate = (responseText) => {
|
|
@@ -9389,7 +10085,7 @@ var Share = {
|
|
|
9389
10085
|
try {
|
|
9390
10086
|
await monitor.stop();
|
|
9391
10087
|
} catch (error) {
|
|
9392
|
-
|
|
10088
|
+
logger16.warning(`\u505C\u6B62 DOM \u76D1\u542C\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
|
|
9393
10089
|
}
|
|
9394
10090
|
};
|
|
9395
10091
|
const onResponse = async (response) => {
|
|
@@ -9403,29 +10099,29 @@ var Share = {
|
|
|
9403
10099
|
stats.responseSampleUrls.push(url);
|
|
9404
10100
|
}
|
|
9405
10101
|
if (stats.responseObserved <= 5) {
|
|
9406
|
-
|
|
10102
|
+
logger16.info(`\u63A5\u53E3\u54CD\u5E94\u91C7\u6837(${stats.responseObserved}): ${url}`);
|
|
9407
10103
|
}
|
|
9408
10104
|
if (!apiMatchers.some((matcher) => url.includes(matcher))) return;
|
|
9409
10105
|
stats.responseMatched += 1;
|
|
9410
10106
|
stats.lastMatchedUrl = url;
|
|
9411
|
-
|
|
10107
|
+
logger16.info(`\u63A5\u53E3\u547D\u4E2D\u5339\u914D(${stats.responseMatched}): ${url}`);
|
|
9412
10108
|
const text = await response.text();
|
|
9413
10109
|
const hit = resolveResponseCandidate(text);
|
|
9414
10110
|
if (!hit?.link) {
|
|
9415
10111
|
if (stats.responseMatched <= 3) {
|
|
9416
|
-
|
|
10112
|
+
logger16.info(`\u63A5\u53E3\u89E3\u6790\u5B8C\u6210\u4F46\u672A\u63D0\u53D6\u5230\u5206\u4EAB\u94FE\u63A5: payloadSize=${text.length}`);
|
|
9417
10113
|
}
|
|
9418
10114
|
return;
|
|
9419
10115
|
}
|
|
9420
10116
|
stats.responseResolved += 1;
|
|
9421
|
-
|
|
10117
|
+
logger16.success("captureLink.responseHit", `\u63A5\u53E3\u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: url=${url}, link=${hit.link}`);
|
|
9422
10118
|
setCandidate("response", hit.link, hit.payloadText);
|
|
9423
10119
|
} catch (error) {
|
|
9424
|
-
|
|
10120
|
+
logger16.warning(`\u63A5\u53E3\u54CD\u5E94\u5904\u7406\u5F02\u5E38: ${error instanceof Error ? error.message : String(error)}`);
|
|
9425
10121
|
}
|
|
9426
10122
|
};
|
|
9427
10123
|
if (share.mode === "dom") {
|
|
9428
|
-
|
|
10124
|
+
logger16.info("\u5F53\u524D\u4E3A DOM \u6A21\u5F0F\uFF0C\u4EC5\u542F\u7528 DOM \u76D1\u542C");
|
|
9429
10125
|
domMonitor = await createDomShareMonitor(page, {
|
|
9430
10126
|
prefix: share.prefix,
|
|
9431
10127
|
selectors: domSelectors,
|
|
@@ -9440,17 +10136,17 @@ var Share = {
|
|
|
9440
10136
|
});
|
|
9441
10137
|
}
|
|
9442
10138
|
if (share.mode === "response") {
|
|
9443
|
-
|
|
10139
|
+
logger16.info(`\u5F53\u524D\u4E3A\u63A5\u53E3\u6A21\u5F0F\uFF0C\u6302\u8F7D response \u76D1\u542C: apiMatchers=${toJsonInline(apiMatchers, 160)}`);
|
|
9444
10140
|
page.on("response", onResponse);
|
|
9445
10141
|
}
|
|
9446
10142
|
if (share.mode === "custom") {
|
|
9447
|
-
|
|
10143
|
+
logger16.info("\u5F53\u524D\u4E3A custom \u6A21\u5F0F\uFF0C\u5C06\u4F7F\u7528 performActions \u8FD4\u56DE\u503C");
|
|
9448
10144
|
}
|
|
9449
10145
|
const deadline = timeoutDisabled ? Infinity : Date.now() + timeoutMs;
|
|
9450
10146
|
const getRemainingMs = () => timeoutDisabled ? Infinity : Math.max(0, deadline - Date.now());
|
|
9451
10147
|
try {
|
|
9452
10148
|
const actionTimeout = getRemainingMs();
|
|
9453
|
-
|
|
10149
|
+
logger16.start("captureLink.performActions", `\u6267\u884C\u52A8\u4F5C\u9884\u7B97=${timeoutDisabled ? "disabled" : `${actionTimeout}ms`}`);
|
|
9454
10150
|
let actionValue;
|
|
9455
10151
|
if (!isAborted() && actionTimeout > 0) {
|
|
9456
10152
|
let timer = null;
|
|
@@ -9463,30 +10159,30 @@ var Share = {
|
|
|
9463
10159
|
]);
|
|
9464
10160
|
if (timer) clearTimeout(timer);
|
|
9465
10161
|
if (actionResult.type === "error") {
|
|
9466
|
-
|
|
10162
|
+
logger16.fail("captureLink.performActions", actionResult.error);
|
|
9467
10163
|
throw actionResult.error;
|
|
9468
10164
|
}
|
|
9469
10165
|
if (actionResult.type === "timeout") {
|
|
9470
10166
|
stats.actionTimedOut = true;
|
|
9471
|
-
|
|
10167
|
+
logger16.warning(`performActions \u5DF2\u8D85\u65F6 (${actionTimeout}ms)\uFF0C\u52A8\u4F5C\u53EF\u80FD\u4ECD\u5728\u5F02\u6B65\u6267\u884C`);
|
|
9472
10168
|
} else {
|
|
9473
10169
|
actionValue = actionResult.result;
|
|
9474
|
-
|
|
10170
|
+
logger16.success("captureLink.performActions", "\u6267\u884C\u52A8\u4F5C\u5B8C\u6210");
|
|
9475
10171
|
}
|
|
9476
10172
|
}
|
|
9477
10173
|
if (share.mode === "custom") {
|
|
9478
10174
|
const customLink = typeof actionValue === "string" ? actionValue : actionValue?.link || actionValue?.payloadText;
|
|
9479
10175
|
const customPayloadText = typeof actionValue === "string" ? actionValue : actionValue?.payloadText;
|
|
9480
10176
|
if (setCandidate("custom", customLink, customPayloadText)) {
|
|
9481
|
-
|
|
10177
|
+
logger16.success("captureLink.customResult", `custom \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: link=${candidates.custom.link}`);
|
|
9482
10178
|
} else {
|
|
9483
|
-
|
|
10179
|
+
logger16.warning("performActions \u6267\u884C\u5B8C\u6210\u4F46\u672A\u8FD4\u56DE\u6709\u6548\u5206\u4EAB\u94FE\u63A5");
|
|
9484
10180
|
}
|
|
9485
10181
|
}
|
|
9486
10182
|
let nextProgressLogTs = Date.now() + 3e3;
|
|
9487
10183
|
while (true) {
|
|
9488
10184
|
if (isAborted()) {
|
|
9489
|
-
|
|
10185
|
+
logger16.warning(`captureLink \u5DF2\u53D6\u6D88: ${abortReason()}`);
|
|
9490
10186
|
return {
|
|
9491
10187
|
link: null,
|
|
9492
10188
|
payloadText: "",
|
|
@@ -9496,7 +10192,7 @@ var Share = {
|
|
|
9496
10192
|
}
|
|
9497
10193
|
const selected = candidates[share.mode];
|
|
9498
10194
|
if (selected?.link) {
|
|
9499
|
-
|
|
10195
|
+
logger16.success("captureLink", `\u6355\u83B7\u6210\u529F: source=${share.mode}, link=${selected.link}`);
|
|
9500
10196
|
return {
|
|
9501
10197
|
link: selected.link,
|
|
9502
10198
|
payloadText: selected.payloadText,
|
|
@@ -9509,19 +10205,19 @@ var Share = {
|
|
|
9509
10205
|
if (remaining <= 0) break;
|
|
9510
10206
|
const now = Date.now();
|
|
9511
10207
|
if (now >= nextProgressLogTs) {
|
|
9512
|
-
|
|
10208
|
+
logger16.info(
|
|
9513
10209
|
`captureLink \u7B49\u5F85\u4E2D: remaining=${timeoutDisabled ? "disabled" : `${remaining}ms`}, domMutationCount=${stats.domMutationCount}, responseMatched=${stats.responseMatched}`
|
|
9514
10210
|
);
|
|
9515
10211
|
nextProgressLogTs = now + 5e3;
|
|
9516
10212
|
}
|
|
9517
|
-
await (0,
|
|
10213
|
+
await (0, import_delay5.default)(Math.max(0, Math.min(DEFAULT_POLL_INTERVAL_MS, remaining)));
|
|
9518
10214
|
}
|
|
9519
10215
|
if (!timeoutDisabled && share.mode === "response" && stats.responseMatched === 0) {
|
|
9520
|
-
|
|
10216
|
+
logger16.warning(
|
|
9521
10217
|
`\u63A5\u53E3\u76D1\u542C\u672A\u547D\u4E2D: apiMatchers=${toJsonInline(apiMatchers, 220)}, \u54CD\u5E94\u6837\u672CURLs=${toJsonInline(stats.responseSampleUrls, 420)}`
|
|
9522
10218
|
);
|
|
9523
10219
|
}
|
|
9524
|
-
|
|
10220
|
+
logger16.warning(
|
|
9525
10221
|
`captureLink ${timeoutDisabled ? "\u672A\u62FF\u5230\u94FE\u63A5" : "\u8D85\u65F6\u672A\u62FF\u5230\u94FE\u63A5"}: mode=${share.mode}, actionTimedOut=${stats.actionTimedOut}, domMutationCount=${stats.domMutationCount}, responseObserved=${stats.responseObserved}, responseMatched=${stats.responseMatched}, lastMatchedUrl=${stats.lastMatchedUrl || "none"}`
|
|
9526
10222
|
);
|
|
9527
10223
|
return {
|
|
@@ -9533,7 +10229,7 @@ var Share = {
|
|
|
9533
10229
|
} finally {
|
|
9534
10230
|
if (share.mode === "response") {
|
|
9535
10231
|
page.off("response", onResponse);
|
|
9536
|
-
|
|
10232
|
+
logger16.info("response \u76D1\u542C\u5DF2\u5378\u8F7D");
|
|
9537
10233
|
}
|
|
9538
10234
|
await stopDomMonitor();
|
|
9539
10235
|
}
|
|
@@ -9548,12 +10244,14 @@ var Share = {
|
|
|
9548
10244
|
* @param {number} [options.maxBytes] 默认 5MiB,返回 base64 超过后会压缩
|
|
9549
10245
|
* @param {'jpeg'|'jpg'} [options.type] 压缩输出格式,默认 jpeg
|
|
9550
10246
|
* @param {boolean|Object} [options.compression] 传 false 可关闭压缩
|
|
10247
|
+
* @param {'default'|'cloak'} [options.mode] 截图水印合成模式,默认取当前 toolkit mode
|
|
9551
10248
|
* @returns {Promise<string>} base64 image
|
|
9552
10249
|
*/
|
|
9553
10250
|
async captureScreen(page, options = {}) {
|
|
9554
10251
|
const restore = options.restore ?? false;
|
|
9555
10252
|
const screenshotWatermarkify = resolveCaptureScreenWatermarkify(page, options.watermarkify);
|
|
9556
10253
|
const compression = resolveImageCompression(options);
|
|
10254
|
+
const screenshotMode = options.mode ?? getToolkitMode();
|
|
9557
10255
|
const captureOptions = {
|
|
9558
10256
|
restore,
|
|
9559
10257
|
maxHeight: options.maxHeight,
|
|
@@ -9568,7 +10266,9 @@ var Share = {
|
|
|
9568
10266
|
...screenshotWatermarkify,
|
|
9569
10267
|
capturedAt
|
|
9570
10268
|
});
|
|
9571
|
-
outputBuffer = await watermarkifyScreenshotBuffer(rawBuffer, watermarkifyMeta, page
|
|
10269
|
+
outputBuffer = await watermarkifyScreenshotBuffer(rawBuffer, watermarkifyMeta, page, {
|
|
10270
|
+
mode: screenshotMode
|
|
10271
|
+
});
|
|
9572
10272
|
}
|
|
9573
10273
|
return await compressImageBufferToBase64(outputBuffer, compression);
|
|
9574
10274
|
}
|
|
@@ -9576,8 +10276,13 @@ var Share = {
|
|
|
9576
10276
|
|
|
9577
10277
|
// entrys/node.js
|
|
9578
10278
|
Logger.setLogger(import_crawlee.log);
|
|
9579
|
-
var
|
|
9580
|
-
|
|
10279
|
+
var ToolkitMode = Object.freeze({
|
|
10280
|
+
default: Mode.Default,
|
|
10281
|
+
cloak: Mode.Cloak
|
|
10282
|
+
});
|
|
10283
|
+
var usePlaywrightToolKit = (mode2 = Mode.Default) => {
|
|
10284
|
+
setToolkitMode(mode2);
|
|
10285
|
+
const toolkit = {
|
|
9581
10286
|
ApifyKit,
|
|
9582
10287
|
AntiCheat,
|
|
9583
10288
|
DeviceInput,
|
|
@@ -9597,7 +10302,9 @@ var usePlaywrightToolKit = () => {
|
|
|
9597
10302
|
ByPass,
|
|
9598
10303
|
$Internals: { LOG_TEMPLATES, stripAnsi }
|
|
9599
10304
|
};
|
|
10305
|
+
return toolkit;
|
|
9600
10306
|
};
|
|
10307
|
+
usePlaywrightToolKit.Mode = ToolkitMode;
|
|
9601
10308
|
// Annotate the CommonJS export names for ESM import in node:
|
|
9602
10309
|
0 && (module.exports = {
|
|
9603
10310
|
usePlaywrightToolKit
|