@skrillex1224/playwright-toolkit 2.1.274 → 2.1.276
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +425 -146
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +425 -146
- package/dist/index.js.map +4 -4
- package/index.d.ts +48 -0
- package/package.json +7 -1
package/dist/index.js
CHANGED
|
@@ -347,18 +347,18 @@ var fallbackLog = {
|
|
|
347
347
|
error: (...args) => console.error(...args),
|
|
348
348
|
debug: (...args) => console.debug ? console.debug(...args) : console.log(...args)
|
|
349
349
|
};
|
|
350
|
-
var resolveLogMethod = (
|
|
351
|
-
if (
|
|
352
|
-
return
|
|
350
|
+
var resolveLogMethod = (logger17, name) => {
|
|
351
|
+
if (logger17 && typeof logger17[name] === "function") {
|
|
352
|
+
return logger17[name].bind(logger17);
|
|
353
353
|
}
|
|
354
|
-
if (name === "warning" &&
|
|
355
|
-
return
|
|
354
|
+
if (name === "warning" && logger17 && typeof logger17.warn === "function") {
|
|
355
|
+
return logger17.warn.bind(logger17);
|
|
356
356
|
}
|
|
357
357
|
return fallbackLog[name];
|
|
358
358
|
};
|
|
359
359
|
var defaultLogger = null;
|
|
360
|
-
var setDefaultLogger = (
|
|
361
|
-
defaultLogger =
|
|
360
|
+
var setDefaultLogger = (logger17) => {
|
|
361
|
+
defaultLogger = logger17;
|
|
362
362
|
};
|
|
363
363
|
var resolveLogger = (explicitLogger) => {
|
|
364
364
|
if (explicitLogger && typeof explicitLogger.info === "function") {
|
|
@@ -385,8 +385,8 @@ var colorize = (text, color) => {
|
|
|
385
385
|
var createBaseLogger = (prefix = "", explicitLogger) => {
|
|
386
386
|
const name = prefix ? String(prefix) : "";
|
|
387
387
|
const dispatch = (methodName, icon, message, color) => {
|
|
388
|
-
const
|
|
389
|
-
const logFn = resolveLogMethod(
|
|
388
|
+
const logger17 = resolveLogger(explicitLogger);
|
|
389
|
+
const logFn = resolveLogMethod(logger17, methodName);
|
|
390
390
|
const timestamp = colorize(`[${formatTimestamp()}]`, ANSI.gray);
|
|
391
391
|
const line = formatLine(name, icon, message);
|
|
392
392
|
const coloredLine = colorize(line, color);
|
|
@@ -740,7 +740,7 @@ var adjustAffixedElementsForExpandedScreenshot = async (page, options = {}) => {
|
|
|
740
740
|
if (safeTargetHeight <= viewportHeight + 1) {
|
|
741
741
|
return 0;
|
|
742
742
|
}
|
|
743
|
-
const
|
|
743
|
+
const hasOwn2 = (source, key) => Object.prototype.hasOwnProperty.call(source, key);
|
|
744
744
|
const isVisible = (el, style, rect) => {
|
|
745
745
|
if (!el || !style || !rect) return false;
|
|
746
746
|
if (style.display === "none" || style.visibility === "hidden" || style.visibility === "collapse") {
|
|
@@ -780,7 +780,7 @@ var adjustAffixedElementsForExpandedScreenshot = async (page, options = {}) => {
|
|
|
780
780
|
return true;
|
|
781
781
|
});
|
|
782
782
|
topLevelCandidates.forEach(({ el, position, edge }) => {
|
|
783
|
-
if (!
|
|
783
|
+
if (!hasOwn2(el.dataset, "pkAffixedAdjusted")) {
|
|
784
784
|
el.dataset.pkAffixedAdjusted = "1";
|
|
785
785
|
el.dataset.pkOrigPosition = el.style.getPropertyValue("position") || "";
|
|
786
786
|
el.dataset.pkOrigPositionPriority = el.style.getPropertyPriority("position") || "";
|
|
@@ -811,7 +811,7 @@ var adjustAffixedElementsForExpandedScreenshot = async (page, options = {}) => {
|
|
|
811
811
|
};
|
|
812
812
|
var restoreAffixedElementsForExpandedScreenshot = async (page) => {
|
|
813
813
|
await page.evaluate((className) => {
|
|
814
|
-
const
|
|
814
|
+
const hasOwn2 = (source, key) => Object.prototype.hasOwnProperty.call(source, key);
|
|
815
815
|
const expansionKeys = [
|
|
816
816
|
"pkOrigOverflow",
|
|
817
817
|
"pkOrigHeight",
|
|
@@ -819,28 +819,28 @@ var restoreAffixedElementsForExpandedScreenshot = async (page) => {
|
|
|
819
819
|
"pkOrigMaxHeight"
|
|
820
820
|
];
|
|
821
821
|
document.querySelectorAll('[data-pk-affixed-adjusted="1"]').forEach((el) => {
|
|
822
|
-
if (
|
|
822
|
+
if (hasOwn2(el.dataset, "pkOrigPosition")) {
|
|
823
823
|
el.style.setProperty("position", el.dataset.pkOrigPosition || "", el.dataset.pkOrigPositionPriority || "");
|
|
824
824
|
delete el.dataset.pkOrigPosition;
|
|
825
825
|
delete el.dataset.pkOrigPositionPriority;
|
|
826
826
|
}
|
|
827
|
-
if (
|
|
827
|
+
if (hasOwn2(el.dataset, "pkOrigTop")) {
|
|
828
828
|
el.style.setProperty("top", el.dataset.pkOrigTop || "", el.dataset.pkOrigTopPriority || "");
|
|
829
829
|
delete el.dataset.pkOrigTop;
|
|
830
830
|
delete el.dataset.pkOrigTopPriority;
|
|
831
831
|
}
|
|
832
|
-
if (
|
|
832
|
+
if (hasOwn2(el.dataset, "pkOrigBottom")) {
|
|
833
833
|
el.style.setProperty("bottom", el.dataset.pkOrigBottom || "", el.dataset.pkOrigBottomPriority || "");
|
|
834
834
|
delete el.dataset.pkOrigBottom;
|
|
835
835
|
delete el.dataset.pkOrigBottomPriority;
|
|
836
836
|
}
|
|
837
|
-
if (
|
|
837
|
+
if (hasOwn2(el.dataset, "pkOrigTranslate")) {
|
|
838
838
|
el.style.setProperty("translate", el.dataset.pkOrigTranslate || "", el.dataset.pkOrigTranslatePriority || "");
|
|
839
839
|
delete el.dataset.pkOrigTranslate;
|
|
840
840
|
delete el.dataset.pkOrigTranslatePriority;
|
|
841
841
|
}
|
|
842
842
|
delete el.dataset.pkAffixedAdjusted;
|
|
843
|
-
const stillExpanded = expansionKeys.some((key) =>
|
|
843
|
+
const stillExpanded = expansionKeys.some((key) => hasOwn2(el.dataset, key));
|
|
844
844
|
if (!stillExpanded) {
|
|
845
845
|
el.classList.remove(className);
|
|
846
846
|
}
|
|
@@ -5027,10 +5027,261 @@ var Launch = {
|
|
|
5027
5027
|
}
|
|
5028
5028
|
};
|
|
5029
5029
|
|
|
5030
|
+
// src/cloakbrowser.js
|
|
5031
|
+
import { execFile } from "node:child_process";
|
|
5032
|
+
import { promisify } from "node:util";
|
|
5033
|
+
var logger9 = createInternalLogger("CloakBrowser");
|
|
5034
|
+
var execFileAsync = promisify(execFile);
|
|
5035
|
+
var DEFAULT_CLOAK_CRAWLER_BASE_OPTIONS = Object.freeze({
|
|
5036
|
+
maxConcurrency: 1,
|
|
5037
|
+
maxRequestRetries: 0,
|
|
5038
|
+
requestHandlerTimeoutSecs: 240,
|
|
5039
|
+
navigationTimeoutSecs: 120
|
|
5040
|
+
});
|
|
5041
|
+
var DEFAULT_CLOAK_HUMANIZE_OPTIONS = Object.freeze({
|
|
5042
|
+
humanize: true
|
|
5043
|
+
});
|
|
5044
|
+
var DEFAULT_CLOAK_GOTO_OPTIONS = Object.freeze({
|
|
5045
|
+
waitUntil: "commit"
|
|
5046
|
+
});
|
|
5047
|
+
var cachedCloakBrowserModulePromise = null;
|
|
5048
|
+
var hasOwn = (target, key) => Object.prototype.hasOwnProperty.call(target, key);
|
|
5049
|
+
var loadCloakBrowserModule = async () => {
|
|
5050
|
+
if (!cachedCloakBrowserModulePromise) {
|
|
5051
|
+
cachedCloakBrowserModulePromise = import("cloakbrowser").catch((error) => {
|
|
5052
|
+
cachedCloakBrowserModulePromise = null;
|
|
5053
|
+
throw new Error("cloakbrowser \u6A21\u5757\u52A0\u8F7D\u5931\u8D25\uFF0C\u8BF7\u786E\u8BA4\u5F53\u524D\u8FD0\u884C\u73AF\u5883\u5DF2\u5B89\u88C5 cloakbrowser\u3002", {
|
|
5054
|
+
cause: error
|
|
5055
|
+
});
|
|
5056
|
+
});
|
|
5057
|
+
}
|
|
5058
|
+
return cachedCloakBrowserModulePromise;
|
|
5059
|
+
};
|
|
5060
|
+
var buildCloakLaunchOptions = async (options = {}) => {
|
|
5061
|
+
const { buildLaunchOptions } = await loadCloakBrowserModule();
|
|
5062
|
+
return await buildLaunchOptions(normalizeObject(options));
|
|
5063
|
+
};
|
|
5064
|
+
var normalizeObject = (value) => {
|
|
5065
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
5066
|
+
return {};
|
|
5067
|
+
}
|
|
5068
|
+
return value;
|
|
5069
|
+
};
|
|
5070
|
+
var normalizeStringArray = (value) => {
|
|
5071
|
+
if (!Array.isArray(value)) {
|
|
5072
|
+
return [];
|
|
5073
|
+
}
|
|
5074
|
+
return value.map((item) => String(item || "").trim()).filter(Boolean);
|
|
5075
|
+
};
|
|
5076
|
+
var resolveCloakBrowserProxy = (proxyConfiguration = {}) => {
|
|
5077
|
+
const config = normalizeObject(proxyConfiguration);
|
|
5078
|
+
const proxyUrl = String(config.proxy_url || "").trim();
|
|
5079
|
+
const enableProxy = typeof config.enable_proxy === "boolean" ? config.enable_proxy : proxyUrl !== "";
|
|
5080
|
+
if (!enableProxy || !proxyUrl) {
|
|
5081
|
+
return null;
|
|
5082
|
+
}
|
|
5083
|
+
const byPassDomains = ByPass.normalizeByPassDomains(config.by_pass_domains);
|
|
5084
|
+
if (byPassDomains.length === 0) {
|
|
5085
|
+
return proxyUrl;
|
|
5086
|
+
}
|
|
5087
|
+
const parsedProxyUrl = new URL(proxyUrl.includes("://") ? proxyUrl : `http://${proxyUrl}`);
|
|
5088
|
+
return {
|
|
5089
|
+
server: `${parsedProxyUrl.protocol}//${parsedProxyUrl.host}`,
|
|
5090
|
+
username: decodeURIComponent(parsedProxyUrl.username || ""),
|
|
5091
|
+
password: decodeURIComponent(parsedProxyUrl.password || ""),
|
|
5092
|
+
bypass: byPassDomains.join(",")
|
|
5093
|
+
};
|
|
5094
|
+
};
|
|
5095
|
+
var extractFingerprintArg = (launchOptions = {}) => {
|
|
5096
|
+
const args = Array.isArray(launchOptions?.args) ? launchOptions.args : [];
|
|
5097
|
+
return args.find((value) => String(value || "").startsWith("--fingerprint=")) || "";
|
|
5098
|
+
};
|
|
5099
|
+
var createStableGotoHook = (recommendedGotoOptions = DEFAULT_CLOAK_GOTO_OPTIONS) => {
|
|
5100
|
+
const normalizedRecommendedGotoOptions = normalizeObject(recommendedGotoOptions);
|
|
5101
|
+
const fallbackGotoOptions = Object.keys(normalizedRecommendedGotoOptions).length > 0 ? normalizedRecommendedGotoOptions : DEFAULT_CLOAK_GOTO_OPTIONS;
|
|
5102
|
+
return async (_crawlingContext, gotoOptions = {}) => {
|
|
5103
|
+
for (const [key, value] of Object.entries(fallbackGotoOptions)) {
|
|
5104
|
+
if (gotoOptions[key] == null) {
|
|
5105
|
+
gotoOptions[key] = value;
|
|
5106
|
+
}
|
|
5107
|
+
}
|
|
5108
|
+
};
|
|
5109
|
+
};
|
|
5110
|
+
var attachCloakBrowserHumanizeHook = ({
|
|
5111
|
+
browserPoolOptions = {},
|
|
5112
|
+
activeBrowsers,
|
|
5113
|
+
patchedBrowsers,
|
|
5114
|
+
humanizeOptions = DEFAULT_CLOAK_HUMANIZE_OPTIONS
|
|
5115
|
+
} = {}) => {
|
|
5116
|
+
const normalizedBrowserPoolOptions = normalizeObject(browserPoolOptions);
|
|
5117
|
+
const shouldHumanize = humanizeOptions !== false;
|
|
5118
|
+
const normalizedHumanizeOptions = shouldHumanize ? {
|
|
5119
|
+
...DEFAULT_CLOAK_HUMANIZE_OPTIONS,
|
|
5120
|
+
...normalizeObject(humanizeOptions)
|
|
5121
|
+
} : null;
|
|
5122
|
+
return {
|
|
5123
|
+
...normalizedBrowserPoolOptions,
|
|
5124
|
+
useFingerprints: false,
|
|
5125
|
+
postLaunchHooks: [
|
|
5126
|
+
...Array.isArray(normalizedBrowserPoolOptions.postLaunchHooks) ? normalizedBrowserPoolOptions.postLaunchHooks : [],
|
|
5127
|
+
async (_pageId, browserController) => {
|
|
5128
|
+
const browser = browserController?.browser;
|
|
5129
|
+
if (!browser || typeof browser.contexts !== "function") {
|
|
5130
|
+
return;
|
|
5131
|
+
}
|
|
5132
|
+
activeBrowsers.add(browser);
|
|
5133
|
+
if (typeof browser.once === "function") {
|
|
5134
|
+
browser.once("disconnected", () => {
|
|
5135
|
+
activeBrowsers.delete(browser);
|
|
5136
|
+
});
|
|
5137
|
+
}
|
|
5138
|
+
if (!shouldHumanize || patchedBrowsers.has(browser)) {
|
|
5139
|
+
return;
|
|
5140
|
+
}
|
|
5141
|
+
const { humanizeBrowser } = await loadCloakBrowserModule();
|
|
5142
|
+
await humanizeBrowser(browser, normalizedHumanizeOptions);
|
|
5143
|
+
patchedBrowsers.add(browser);
|
|
5144
|
+
}
|
|
5145
|
+
]
|
|
5146
|
+
};
|
|
5147
|
+
};
|
|
5148
|
+
var closeTrackedBrowsers = async (activeBrowsers) => {
|
|
5149
|
+
const browsers = Array.from(activeBrowsers || []);
|
|
5150
|
+
activeBrowsers?.clear?.();
|
|
5151
|
+
await Promise.allSettled(
|
|
5152
|
+
browsers.map(async (browser) => {
|
|
5153
|
+
if (!browser || typeof browser.isConnected !== "function" || !browser.isConnected()) {
|
|
5154
|
+
return;
|
|
5155
|
+
}
|
|
5156
|
+
await browser.close().catch(() => {
|
|
5157
|
+
});
|
|
5158
|
+
})
|
|
5159
|
+
);
|
|
5160
|
+
};
|
|
5161
|
+
var forceTerminateBrowsersByFingerprintArg = async (fingerprintArg) => {
|
|
5162
|
+
if (!fingerprintArg) {
|
|
5163
|
+
return;
|
|
5164
|
+
}
|
|
5165
|
+
await execFileAsync("pkill", ["-f", "--", fingerprintArg]).catch((error) => {
|
|
5166
|
+
if (error?.code === 1 || error?.code === "ENOENT") {
|
|
5167
|
+
return;
|
|
5168
|
+
}
|
|
5169
|
+
logger9.info(`\u5F3A\u5236\u5173\u95ED CloakBrowser \u8FDB\u7A0B\u5931\u8D25\uFF08\u5FFD\u7565\uFF09: ${error?.message || String(error)}`);
|
|
5170
|
+
});
|
|
5171
|
+
};
|
|
5172
|
+
var CloakBrowser = {
|
|
5173
|
+
resolveProxyConfiguration(proxyConfiguration = {}) {
|
|
5174
|
+
return resolveCloakBrowserProxy(proxyConfiguration);
|
|
5175
|
+
},
|
|
5176
|
+
extractFingerprintArg(launchOptions = {}) {
|
|
5177
|
+
return extractFingerprintArg(launchOptions);
|
|
5178
|
+
},
|
|
5179
|
+
createStableGotoHook(recommendedGotoOptions = DEFAULT_CLOAK_GOTO_OPTIONS) {
|
|
5180
|
+
return createStableGotoHook(recommendedGotoOptions);
|
|
5181
|
+
},
|
|
5182
|
+
async buildLaunchOptions(options = {}) {
|
|
5183
|
+
return await buildCloakLaunchOptions(options);
|
|
5184
|
+
},
|
|
5185
|
+
async createPlaywrightCrawlerRuntime(options = {}) {
|
|
5186
|
+
const normalizedOptions = normalizeObject(options);
|
|
5187
|
+
const {
|
|
5188
|
+
proxyConfiguration = {},
|
|
5189
|
+
runInHeadfulMode = false,
|
|
5190
|
+
isRunningOnApify = false,
|
|
5191
|
+
launcher = null,
|
|
5192
|
+
cloakOptions = {},
|
|
5193
|
+
humanizeOptions = DEFAULT_CLOAK_HUMANIZE_OPTIONS,
|
|
5194
|
+
crawlerBaseOptions = {},
|
|
5195
|
+
browserPoolOptions = {},
|
|
5196
|
+
launchContext = {},
|
|
5197
|
+
preNavigationHooks = [],
|
|
5198
|
+
postNavigationHooks = [],
|
|
5199
|
+
recommendedGotoOptions = DEFAULT_CLOAK_GOTO_OPTIONS
|
|
5200
|
+
} = normalizedOptions;
|
|
5201
|
+
const normalizedCloakOptions = normalizeObject(cloakOptions);
|
|
5202
|
+
const activeBrowsers = /* @__PURE__ */ new Set();
|
|
5203
|
+
const patchedBrowsers = /* @__PURE__ */ new WeakSet();
|
|
5204
|
+
const defaultArgs = isRunningOnApify ? ["--no-sandbox", "--disable-setuid-sandbox"] : [];
|
|
5205
|
+
const extraArgs = normalizeStringArray(normalizedCloakOptions.args);
|
|
5206
|
+
const proxy = hasOwn(normalizedCloakOptions, "proxy") ? normalizedCloakOptions.proxy : resolveCloakBrowserProxy(proxyConfiguration);
|
|
5207
|
+
const headless = hasOwn(normalizedCloakOptions, "headless") ? normalizedCloakOptions.headless : !runInHeadfulMode || isRunningOnApify;
|
|
5208
|
+
const mergedCloakOptions = {
|
|
5209
|
+
...normalizedCloakOptions,
|
|
5210
|
+
headless,
|
|
5211
|
+
proxy,
|
|
5212
|
+
args: [...defaultArgs, ...extraArgs]
|
|
5213
|
+
};
|
|
5214
|
+
const launchOptions = await buildCloakLaunchOptions(mergedCloakOptions);
|
|
5215
|
+
const fingerprintArg = extractFingerprintArg(launchOptions);
|
|
5216
|
+
const internalPreNavigationHook = createStableGotoHook(recommendedGotoOptions);
|
|
5217
|
+
const normalizedPreNavigationHooks = Array.isArray(preNavigationHooks) ? preNavigationHooks : [];
|
|
5218
|
+
const normalizedPostNavigationHooks = Array.isArray(postNavigationHooks) ? postNavigationHooks : [];
|
|
5219
|
+
const crawlerOptions = {
|
|
5220
|
+
...DEFAULT_CLOAK_CRAWLER_BASE_OPTIONS,
|
|
5221
|
+
...normalizeObject(crawlerBaseOptions),
|
|
5222
|
+
headless,
|
|
5223
|
+
launchContext: {
|
|
5224
|
+
useIncognitoPages: true,
|
|
5225
|
+
...normalizeObject(launchContext),
|
|
5226
|
+
...launcher ? { launcher } : {},
|
|
5227
|
+
launchOptions
|
|
5228
|
+
},
|
|
5229
|
+
browserPoolOptions: attachCloakBrowserHumanizeHook({
|
|
5230
|
+
browserPoolOptions,
|
|
5231
|
+
activeBrowsers,
|
|
5232
|
+
patchedBrowsers,
|
|
5233
|
+
humanizeOptions
|
|
5234
|
+
}),
|
|
5235
|
+
preNavigationHooks: [internalPreNavigationHook, ...normalizedPreNavigationHooks],
|
|
5236
|
+
...normalizedPostNavigationHooks.length > 0 ? { postNavigationHooks: normalizedPostNavigationHooks } : {}
|
|
5237
|
+
};
|
|
5238
|
+
const closeActiveBrowsers = async () => {
|
|
5239
|
+
await closeTrackedBrowsers(activeBrowsers);
|
|
5240
|
+
};
|
|
5241
|
+
const forceTerminateActiveProcesses = async () => {
|
|
5242
|
+
await forceTerminateBrowsersByFingerprintArg(fingerprintArg);
|
|
5243
|
+
};
|
|
5244
|
+
const cleanup = async () => {
|
|
5245
|
+
await closeActiveBrowsers();
|
|
5246
|
+
await forceTerminateActiveProcesses();
|
|
5247
|
+
};
|
|
5248
|
+
return {
|
|
5249
|
+
headless,
|
|
5250
|
+
launchOptions,
|
|
5251
|
+
fingerprintArg,
|
|
5252
|
+
crawlerOptions,
|
|
5253
|
+
closeActiveBrowsers,
|
|
5254
|
+
forceTerminateActiveProcesses,
|
|
5255
|
+
cleanup
|
|
5256
|
+
};
|
|
5257
|
+
}
|
|
5258
|
+
};
|
|
5259
|
+
var createCloakLaunchModule = (baseLaunch = {}) => {
|
|
5260
|
+
const normalizedBaseLaunch = normalizeObject(baseLaunch);
|
|
5261
|
+
return {
|
|
5262
|
+
...normalizedBaseLaunch,
|
|
5263
|
+
resolveProxyConfiguration(proxyConfiguration = {}) {
|
|
5264
|
+
return CloakBrowser.resolveProxyConfiguration(proxyConfiguration);
|
|
5265
|
+
},
|
|
5266
|
+
extractFingerprintArg(launchOptions = {}) {
|
|
5267
|
+
return CloakBrowser.extractFingerprintArg(launchOptions);
|
|
5268
|
+
},
|
|
5269
|
+
createStableGotoHook(recommendedGotoOptions = DEFAULT_CLOAK_GOTO_OPTIONS) {
|
|
5270
|
+
return CloakBrowser.createStableGotoHook(recommendedGotoOptions);
|
|
5271
|
+
},
|
|
5272
|
+
async buildLaunchOptions(options = {}) {
|
|
5273
|
+
return await CloakBrowser.buildLaunchOptions(options);
|
|
5274
|
+
},
|
|
5275
|
+
async createPlaywrightCrawlerRuntime(options = {}) {
|
|
5276
|
+
return await CloakBrowser.createPlaywrightCrawlerRuntime(options);
|
|
5277
|
+
}
|
|
5278
|
+
};
|
|
5279
|
+
};
|
|
5280
|
+
|
|
5030
5281
|
// src/live-view.js
|
|
5031
5282
|
import express from "express";
|
|
5032
5283
|
import { Actor } from "apify";
|
|
5033
|
-
var
|
|
5284
|
+
var logger10 = createInternalLogger("LiveView");
|
|
5034
5285
|
async function startLiveViewServer(liveViewKey) {
|
|
5035
5286
|
const app = express();
|
|
5036
5287
|
app.get("/", async (req, res) => {
|
|
@@ -5055,13 +5306,13 @@ async function startLiveViewServer(liveViewKey) {
|
|
|
5055
5306
|
</html>
|
|
5056
5307
|
`);
|
|
5057
5308
|
} catch (error) {
|
|
5058
|
-
|
|
5309
|
+
logger10.fail("Live View Server", error);
|
|
5059
5310
|
res.status(500).send(`\u65E0\u6CD5\u52A0\u8F7D\u5C4F\u5E55\u622A\u56FE: ${error.message}`);
|
|
5060
5311
|
}
|
|
5061
5312
|
});
|
|
5062
5313
|
const port = process.env.APIFY_CONTAINER_PORT || 4321;
|
|
5063
5314
|
app.listen(port, () => {
|
|
5064
|
-
|
|
5315
|
+
logger10.success("startLiveViewServer", `\u76D1\u542C\u7AEF\u53E3 ${port}`);
|
|
5065
5316
|
});
|
|
5066
5317
|
}
|
|
5067
5318
|
async function takeLiveScreenshot(liveViewKey, page, logMessage) {
|
|
@@ -5069,10 +5320,10 @@ async function takeLiveScreenshot(liveViewKey, page, logMessage) {
|
|
|
5069
5320
|
const buffer = await capturePageScreenshot(page, { type: "png" });
|
|
5070
5321
|
await Actor.setValue(liveViewKey, buffer, { contentType: "image/png" });
|
|
5071
5322
|
if (logMessage) {
|
|
5072
|
-
|
|
5323
|
+
logger10.info(`(\u622A\u56FE): ${logMessage}`);
|
|
5073
5324
|
}
|
|
5074
5325
|
} catch (e) {
|
|
5075
|
-
|
|
5326
|
+
logger10.warn(`\u65E0\u6CD5\u6355\u83B7 Live View \u5C4F\u5E55\u622A\u56FE: ${e.message}`);
|
|
5076
5327
|
}
|
|
5077
5328
|
}
|
|
5078
5329
|
var useLiveView = (liveViewKey = PresetOfLiveViewKey) => {
|
|
@@ -5181,7 +5432,7 @@ var dragCaptchaAction = async (page, sourceLocator, targetLocator, options = {})
|
|
|
5181
5432
|
};
|
|
5182
5433
|
|
|
5183
5434
|
// src/internals/captcha/bytedance.js
|
|
5184
|
-
var
|
|
5435
|
+
var logger11 = createInternalLogger("Captcha");
|
|
5185
5436
|
var DEFAULT_BYTEDANCE_CAPTCHA_OPTIONS = Object.freeze({
|
|
5186
5437
|
apiType: "31234",
|
|
5187
5438
|
maxRetries: 3,
|
|
@@ -5313,7 +5564,7 @@ var collectCaptchaDebugInfo = async (page, frame, iframeLocator, attempt, phase,
|
|
|
5313
5564
|
}
|
|
5314
5565
|
await writeFile(infoPath, JSON.stringify(payload, null, 2), "utf8");
|
|
5315
5566
|
}
|
|
5316
|
-
|
|
5567
|
+
logger11.info(`\u5DF2\u5199\u51FA\u9A8C\u8BC1\u7801\u8C03\u8BD5\u4EA7\u7269\uFF1A${debugDir}`);
|
|
5317
5568
|
};
|
|
5318
5569
|
var maybeCollectCaptchaDebugInfo = async (page, frame, iframeLocator, attempt, phase, options, extra = null) => {
|
|
5319
5570
|
if (!options.debugArtifacts) {
|
|
@@ -5350,14 +5601,14 @@ var getVerifycenterCaptchaContext = async (page, options) => {
|
|
|
5350
5601
|
if (!isContainerVisible) {
|
|
5351
5602
|
return null;
|
|
5352
5603
|
}
|
|
5353
|
-
|
|
5604
|
+
logger11.info("\u68C0\u6D4B\u5230\u9A8C\u8BC1\u7801\u5BB9\u5668\uFF0C\u5F00\u59CB\u7B49\u5F85 iframe \u52A0\u8F7D\u3002");
|
|
5354
5605
|
let iframeLocator = page.locator(options.iframeSelector).first();
|
|
5355
5606
|
let isIframeVisible = await waitForVisible(
|
|
5356
5607
|
iframeLocator,
|
|
5357
5608
|
options.iframeVisibleTimeoutMs
|
|
5358
5609
|
);
|
|
5359
5610
|
if (!isIframeVisible) {
|
|
5360
|
-
|
|
5611
|
+
logger11.warn("\u672A\u5728\u9884\u671F\u9009\u62E9\u5668\u4E2D\u627E\u5230 verifycenter iframe\uFF0C\u5C1D\u8BD5\u5BB9\u5668\u5185\u4EFB\u610F iframe\u3002");
|
|
5361
5612
|
iframeLocator = captchaContainer.locator(options.iframeFallbackSelector).first();
|
|
5362
5613
|
isIframeVisible = await waitForVisible(
|
|
5363
5614
|
iframeLocator,
|
|
@@ -5367,7 +5618,7 @@ var getVerifycenterCaptchaContext = async (page, options) => {
|
|
|
5367
5618
|
if (!isIframeVisible) {
|
|
5368
5619
|
throw new Error("verifycenter iframe not found inside captcha container.");
|
|
5369
5620
|
}
|
|
5370
|
-
|
|
5621
|
+
logger11.info("\u9A8C\u8BC1\u7801 iframe \u5DF2\u53EF\u89C1\uFF0C\u5F00\u59CB\u89E3\u6790\u5185\u5BB9 frame\u3002");
|
|
5371
5622
|
const frame = await resolveContentFrame(page, iframeLocator, options);
|
|
5372
5623
|
if (!frame) {
|
|
5373
5624
|
throw new Error("Failed to resolve verifycenter iframe content frame.");
|
|
@@ -5483,11 +5734,11 @@ var refreshCaptcha = async (page, frame, options) => {
|
|
|
5483
5734
|
const clicked = await clickCaptchaAction(frame, options.refreshTexts, {
|
|
5484
5735
|
...options,
|
|
5485
5736
|
page,
|
|
5486
|
-
logger:
|
|
5737
|
+
logger: logger11,
|
|
5487
5738
|
forceMouse: true
|
|
5488
5739
|
}).catch(() => false);
|
|
5489
5740
|
if (!clicked) {
|
|
5490
|
-
|
|
5741
|
+
logger11.warn("Refresh button not found.");
|
|
5491
5742
|
return false;
|
|
5492
5743
|
}
|
|
5493
5744
|
await page.waitForTimeout(options.refreshWaitMs);
|
|
@@ -5518,24 +5769,24 @@ var waitForCaptchaChallengeReady = async (page, frame, options) => {
|
|
|
5518
5769
|
const hasGuideMaskVisible = options.guideMaskSelector ? await frame.locator(options.guideMaskSelector).first().isVisible({ timeout: options.loadingIndicatorVisibleTimeoutMs }).catch(() => false) : false;
|
|
5519
5770
|
hasSeenGuideMask = hasSeenGuideMask || hasGuideMaskVisible;
|
|
5520
5771
|
if (hasGuideMaskVisible && !hasLoggedGuideMask) {
|
|
5521
|
-
|
|
5772
|
+
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");
|
|
5522
5773
|
hasLoggedGuideMask = true;
|
|
5523
5774
|
}
|
|
5524
5775
|
if (!isLoadingVisible && hasVisibleSourceImage && hasVisibleDropTarget && !hasGuideMaskVisible) {
|
|
5525
|
-
|
|
5776
|
+
logger11.info(
|
|
5526
5777
|
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"
|
|
5527
5778
|
);
|
|
5528
5779
|
return;
|
|
5529
5780
|
}
|
|
5530
5781
|
if (hasErrorTextVisible) {
|
|
5531
|
-
|
|
5782
|
+
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");
|
|
5532
5783
|
await refreshCaptcha(page, frame, options);
|
|
5533
5784
|
refreshDeadline = Date.now() + options.challengeReadyRefreshTimeoutMs;
|
|
5534
5785
|
hasSeenLoading = false;
|
|
5535
5786
|
continue;
|
|
5536
5787
|
}
|
|
5537
5788
|
if ((!hasVisibleSourceImage || !hasVisibleDropTarget) && Date.now() >= refreshDeadline) {
|
|
5538
|
-
|
|
5789
|
+
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`);
|
|
5539
5790
|
await refreshCaptcha(page, frame, options);
|
|
5540
5791
|
refreshDeadline = Date.now() + options.challengeReadyRefreshTimeoutMs;
|
|
5541
5792
|
hasSeenLoading = false;
|
|
@@ -5583,7 +5834,7 @@ var dragPromptCaptchaImage = async (page, frame, iframeLocator, sourceLocator, d
|
|
|
5583
5834
|
accepted
|
|
5584
5835
|
};
|
|
5585
5836
|
dragAttempts.push(attemptInfo);
|
|
5586
|
-
|
|
5837
|
+
logger11.info(
|
|
5587
5838
|
`\u9A8C\u8BC1\u7801\u62D6\u62FD\u7B2C ${visualIndex + 1} \u5F20\uFF0C\u65B9\u6848 ${plan.name}\uFF0Cbadge ${baselineState.badgeCount} -> ${afterState.badgeCount}\uFF0Cselected ${baselineState.selectedCount} -> ${afterState.selectedCount}`
|
|
5588
5839
|
);
|
|
5589
5840
|
if (accepted) {
|
|
@@ -5601,7 +5852,7 @@ var dragPromptCaptchaImage = async (page, frame, iframeLocator, sourceLocator, d
|
|
|
5601
5852
|
dragAttempts,
|
|
5602
5853
|
finalState: await readPromptCaptchaState(frame, options)
|
|
5603
5854
|
}).catch((error) => {
|
|
5604
|
-
|
|
5855
|
+
logger11.warn(`\u9A8C\u8BC1\u7801\u62D6\u62FD\u5931\u8D25\u8C03\u8BD5\u6293\u53D6\u5931\u8D25\uFF1A${error?.message || error}`);
|
|
5605
5856
|
});
|
|
5606
5857
|
return {
|
|
5607
5858
|
accepted: false,
|
|
@@ -5618,16 +5869,16 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
|
|
|
5618
5869
|
...options
|
|
5619
5870
|
};
|
|
5620
5871
|
if (!config.token) {
|
|
5621
|
-
|
|
5872
|
+
logger11.warn("\u7F3A\u5C11\u9A8C\u8BC1\u7801 token\uFF0C\u8DF3\u8FC7\u81EA\u52A8\u8BC6\u522B\u3002");
|
|
5622
5873
|
return false;
|
|
5623
5874
|
}
|
|
5624
|
-
|
|
5875
|
+
logger11.info("\u5F53\u524D\u4F7F\u7528\u672Ctool\u2014\u2014\u6D4B\u8BD5\u7248\u672C");
|
|
5625
5876
|
for (let attempt = 1; attempt <= config.maxRetries; attempt += 1) {
|
|
5626
|
-
|
|
5877
|
+
logger11.info(`\u5F00\u59CB\u7B2C ${attempt}/${config.maxRetries} \u6B21 verifycenter \u9A8C\u8BC1\u7801\u8BC6\u522B\u3002`);
|
|
5627
5878
|
try {
|
|
5628
5879
|
const captchaContext = await getVerifycenterCaptchaContext(page, config);
|
|
5629
5880
|
if (!captchaContext) {
|
|
5630
|
-
|
|
5881
|
+
logger11.info("Captcha container is not visible anymore.");
|
|
5631
5882
|
return true;
|
|
5632
5883
|
}
|
|
5633
5884
|
const { iframeLocator, frame } = captchaContext;
|
|
@@ -5640,7 +5891,7 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
|
|
|
5640
5891
|
"ready",
|
|
5641
5892
|
config
|
|
5642
5893
|
).catch((error) => {
|
|
5643
|
-
|
|
5894
|
+
logger11.warn(`\u9A8C\u8BC1\u7801\u8C03\u8BD5\u6293\u53D6\u5931\u8D25\uFF1A${error?.message || error}`);
|
|
5644
5895
|
});
|
|
5645
5896
|
await page.waitForTimeout(config.recognitionDelayMs);
|
|
5646
5897
|
const screenshotBuffer = await iframeLocator.screenshot();
|
|
@@ -5652,16 +5903,16 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
|
|
|
5652
5903
|
});
|
|
5653
5904
|
const serialNumbers = extractCaptchaSerialNumbers(apiResponse);
|
|
5654
5905
|
if (apiResponse?.code !== config.recognitionSuccessCode || serialNumbers.length === 0) {
|
|
5655
|
-
|
|
5906
|
+
logger11.warn(
|
|
5656
5907
|
`\u9A8C\u8BC1\u7801\u8BC6\u522B\u5931\u8D25\u3002code=${apiResponse?.code}, msg=${apiResponse?.msg || "unknown"}`
|
|
5657
5908
|
);
|
|
5658
5909
|
await refreshCaptcha(page, frame, config);
|
|
5659
5910
|
continue;
|
|
5660
5911
|
}
|
|
5661
|
-
|
|
5912
|
+
logger11.info(`\u9A8C\u8BC1\u7801\u8BC6\u522B\u6210\u529F\uFF0C\u5E8F\u53F7\uFF1A${serialNumbers.join(", ")}`);
|
|
5662
5913
|
const dropTarget = await findCaptchaDropTarget(frame, config);
|
|
5663
5914
|
if (!dropTarget) {
|
|
5664
|
-
|
|
5915
|
+
logger11.warn("\u672A\u627E\u5230\u9A8C\u8BC1\u7801\u62D6\u62FD\u76EE\u6807\u533A\u57DF\u3002");
|
|
5665
5916
|
await refreshCaptcha(page, frame, config);
|
|
5666
5917
|
continue;
|
|
5667
5918
|
}
|
|
@@ -5672,7 +5923,7 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
|
|
|
5672
5923
|
`Captcha image indexes could not be normalized. raw=${serialNumbers.join(", ")}, count=${orderedSourceImages.length}`
|
|
5673
5924
|
);
|
|
5674
5925
|
}
|
|
5675
|
-
|
|
5926
|
+
logger11.info(`\u9A8C\u8BC1\u7801\u89C6\u89C9\u4F4D\u5E8F\u6620\u5C04\uFF1A${normalizedIndexes.map((index) => index + 1).join(", ")}`);
|
|
5676
5927
|
for (const imageIndex of normalizedIndexes) {
|
|
5677
5928
|
if (imageIndex < 0 || imageIndex >= orderedSourceImages.length) {
|
|
5678
5929
|
throw new Error(
|
|
@@ -5704,52 +5955,52 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
|
|
|
5704
5955
|
}
|
|
5705
5956
|
}
|
|
5706
5957
|
const beforeSubmitState = await readPromptCaptchaState(frame, config);
|
|
5707
|
-
|
|
5958
|
+
logger11.info(
|
|
5708
5959
|
`\u63D0\u4EA4\u524D\u9A8C\u8BC1\u7801\u72B6\u6001\uFF1Abadge=${beforeSubmitState.badgeCount}, selected=${beforeSubmitState.selectedCount}, submitDisabled=${beforeSubmitState.submitDisabled}`
|
|
5709
5960
|
);
|
|
5710
5961
|
const submitted = await clickCaptchaAction(frame, config.submitTexts, {
|
|
5711
5962
|
...config,
|
|
5712
5963
|
page,
|
|
5713
|
-
logger:
|
|
5964
|
+
logger: logger11,
|
|
5714
5965
|
forceMouse: true,
|
|
5715
5966
|
actionVisibleTimeoutMs: config.submitReadyTimeoutMs
|
|
5716
5967
|
}).catch(() => false);
|
|
5717
5968
|
if (!submitted) {
|
|
5718
|
-
|
|
5969
|
+
logger11.warn("\u672A\u627E\u5230\u63D0\u4EA4\u6309\u94AE\uFF0C\u53EF\u80FD\u4F1A\u81EA\u52A8\u63D0\u4EA4\u3002");
|
|
5719
5970
|
}
|
|
5720
5971
|
await page.waitForTimeout(config.submitWaitMs);
|
|
5721
5972
|
const afterSubmitState = await readPromptCaptchaState(frame, config);
|
|
5722
|
-
|
|
5973
|
+
logger11.info(
|
|
5723
5974
|
`\u63D0\u4EA4\u540E\u9A8C\u8BC1\u7801\u72B6\u6001\uFF1Abadge=${afterSubmitState.badgeCount}, selected=${afterSubmitState.selectedCount}, submitDisabled=${afterSubmitState.submitDisabled}`
|
|
5724
5975
|
);
|
|
5725
5976
|
const stillVisible = await iframeLocator.isVisible({ timeout: config.containerVisibleTimeoutMs }).catch(() => false);
|
|
5726
5977
|
if (!stillVisible) {
|
|
5727
|
-
|
|
5978
|
+
logger11.info("\u9A8C\u8BC1\u7801\u8BC6\u522B\u5E76\u63D0\u4EA4\u6210\u529F\u3002");
|
|
5728
5979
|
return true;
|
|
5729
5980
|
}
|
|
5730
5981
|
await maybeCollectCaptchaDebugInfo(page, frame, iframeLocator, attempt, "submit-still-visible", config, {
|
|
5731
5982
|
beforeSubmitState,
|
|
5732
5983
|
afterSubmitState
|
|
5733
5984
|
}).catch((error) => {
|
|
5734
|
-
|
|
5985
|
+
logger11.warn(`\u63D0\u4EA4\u540E\u9A8C\u8BC1\u7801\u8C03\u8BD5\u6293\u53D6\u5931\u8D25\uFF1A${error?.message || error}`);
|
|
5735
5986
|
});
|
|
5736
|
-
|
|
5987
|
+
logger11.warn("\u63D0\u4EA4\u540E\u9A8C\u8BC1\u7801 iframe \u4ECD\u7136\u53EF\u89C1\uFF0C\u51C6\u5907\u5237\u65B0\u540E\u91CD\u8BD5\u3002");
|
|
5737
5988
|
await page.waitForTimeout(2e3);
|
|
5738
5989
|
await refreshCaptcha(page, frame, config);
|
|
5739
5990
|
} catch (error) {
|
|
5740
|
-
|
|
5991
|
+
logger11.error(`\u7B2C ${attempt}/${config.maxRetries} \u6B21\u9A8C\u8BC1\u7801\u8BC6\u522B\u5931\u8D25\uFF1A${error?.message || error}`);
|
|
5741
5992
|
}
|
|
5742
5993
|
if (attempt < config.maxRetries) {
|
|
5743
5994
|
await page.waitForTimeout(config.retryDelayBaseMs + attempt * config.retryDelayStepMs);
|
|
5744
5995
|
}
|
|
5745
5996
|
}
|
|
5746
|
-
|
|
5997
|
+
logger11.error(`\u91CD\u8BD5 ${config.maxRetries} \u6B21\u540E\uFF0C\u9A8C\u8BC1\u7801\u4ECD\u672A\u8BC6\u522B\u6210\u529F\u3002`);
|
|
5747
5998
|
return false;
|
|
5748
5999
|
}
|
|
5749
6000
|
var sloveCaptcha = solveCaptcha;
|
|
5750
6001
|
|
|
5751
6002
|
// src/chaptcha.js
|
|
5752
|
-
var
|
|
6003
|
+
var logger12 = createInternalLogger("Captcha");
|
|
5753
6004
|
var DEFAULT_CAPTCHA_RECOGNITION_OPTIONS = Object.freeze({
|
|
5754
6005
|
token: "eKJvBfwfN0YRav0-VD_44E2VBSfm7l0YtddUQ7cFySI",
|
|
5755
6006
|
apiUrl: "https://api.jfbym.com/api/YmServer/customApi"
|
|
@@ -5836,7 +6087,7 @@ function useCaptchaMonitor(page, options) {
|
|
|
5836
6087
|
};
|
|
5837
6088
|
})();
|
|
5838
6089
|
}, { selector: domSelector, callbackName: exposedFunctionName, cleanerName });
|
|
5839
|
-
|
|
6090
|
+
logger12.success("useCaptchaMonitor", `DOM \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${domSelector}`);
|
|
5840
6091
|
cleanupFns.push(async () => {
|
|
5841
6092
|
try {
|
|
5842
6093
|
await page.evaluate((name) => {
|
|
@@ -5860,14 +6111,14 @@ function useCaptchaMonitor(page, options) {
|
|
|
5860
6111
|
}
|
|
5861
6112
|
};
|
|
5862
6113
|
page.on("framenavigated", frameHandler);
|
|
5863
|
-
|
|
6114
|
+
logger12.success("useCaptchaMonitor", `URL \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${urlPattern}`);
|
|
5864
6115
|
cleanupFns.push(async () => {
|
|
5865
6116
|
page.off("framenavigated", frameHandler);
|
|
5866
6117
|
});
|
|
5867
6118
|
}
|
|
5868
6119
|
return {
|
|
5869
6120
|
stop: async () => {
|
|
5870
|
-
|
|
6121
|
+
logger12.info("\u6B63\u5728\u505C\u6B62\u9A8C\u8BC1\u7801\u76D1\u63A7...");
|
|
5871
6122
|
for (const fn of cleanupFns) {
|
|
5872
6123
|
await fn();
|
|
5873
6124
|
}
|
|
@@ -5906,7 +6157,7 @@ async function solveCaptchaWithStrategy(strategyName, page, options = {}) {
|
|
|
5906
6157
|
);
|
|
5907
6158
|
return strategy.sloveCaptcha(page, resolvedOptions, {
|
|
5908
6159
|
callCaptchaRecognitionApi,
|
|
5909
|
-
logger:
|
|
6160
|
+
logger: logger12
|
|
5910
6161
|
});
|
|
5911
6162
|
}
|
|
5912
6163
|
var Captcha = {
|
|
@@ -5917,7 +6168,7 @@ var Captcha = {
|
|
|
5917
6168
|
// src/mutation.js
|
|
5918
6169
|
import { createHash } from "node:crypto";
|
|
5919
6170
|
import { v4 as uuidv42 } from "uuid";
|
|
5920
|
-
var
|
|
6171
|
+
var logger13 = createInternalLogger("Mutation");
|
|
5921
6172
|
var MUTATION_MONITOR_MODE = Object.freeze({
|
|
5922
6173
|
Added: "added",
|
|
5923
6174
|
Changed: "changed",
|
|
@@ -5950,14 +6201,14 @@ var Mutation = {
|
|
|
5950
6201
|
const stableTime = options.stableTime ?? 5 * 1e3;
|
|
5951
6202
|
const timeout = options.timeout ?? 120 * 1e3;
|
|
5952
6203
|
const onMutation = options.onMutation;
|
|
5953
|
-
|
|
6204
|
+
logger13.start("waitForStable", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, \u7A33\u5B9A\u65F6\u95F4=${stableTime}ms`);
|
|
5954
6205
|
if (initialTimeout > 0) {
|
|
5955
6206
|
const selectorQuery = selectorList.join(",");
|
|
5956
6207
|
try {
|
|
5957
6208
|
await page.waitForSelector(selectorQuery, { timeout: initialTimeout });
|
|
5958
|
-
|
|
6209
|
+
logger13.info(`waitForStable \u5DF2\u68C0\u6D4B\u5230\u5143\u7D20: ${selectorQuery}`);
|
|
5959
6210
|
} catch (e) {
|
|
5960
|
-
|
|
6211
|
+
logger13.warning(`waitForStable \u521D\u59CB\u7B49\u5F85\u8D85\u65F6 (${initialTimeout}ms): ${selectorQuery}`);
|
|
5961
6212
|
throw e;
|
|
5962
6213
|
}
|
|
5963
6214
|
}
|
|
@@ -5973,7 +6224,7 @@ var Mutation = {
|
|
|
5973
6224
|
return "__CONTINUE__";
|
|
5974
6225
|
}
|
|
5975
6226
|
});
|
|
5976
|
-
|
|
6227
|
+
logger13.info("waitForStable \u5DF2\u542F\u7528 onMutation \u56DE\u8C03");
|
|
5977
6228
|
} catch (e) {
|
|
5978
6229
|
}
|
|
5979
6230
|
}
|
|
@@ -6088,9 +6339,9 @@ var Mutation = {
|
|
|
6088
6339
|
{ selectorList, stableTime, timeout, callbackName, hasCallback: !!onMutation }
|
|
6089
6340
|
);
|
|
6090
6341
|
if (result.mutationCount === 0 && result.stableTime === 0) {
|
|
6091
|
-
|
|
6342
|
+
logger13.warning("waitForStable \u672A\u627E\u5230\u53EF\u76D1\u63A7\u7684\u5143\u7D20");
|
|
6092
6343
|
}
|
|
6093
|
-
|
|
6344
|
+
logger13.success("waitForStable", `DOM \u7A33\u5B9A, \u603B\u5171 ${result.mutationCount} \u6B21\u53D8\u5316${result.wasPaused ? ", \u66FE\u6682\u505C\u8BA1\u65F6" : ""}`);
|
|
6094
6345
|
return result;
|
|
6095
6346
|
},
|
|
6096
6347
|
/**
|
|
@@ -6262,22 +6513,22 @@ var Mutation = {
|
|
|
6262
6513
|
return "__CONTINUE__";
|
|
6263
6514
|
}
|
|
6264
6515
|
};
|
|
6265
|
-
|
|
6516
|
+
logger13.start(
|
|
6266
6517
|
"waitForStableAcrossRoots",
|
|
6267
6518
|
`\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668(\u8DE8 root), \u7A33\u5B9A\u65F6\u95F4=${waitForStableTime}ms`
|
|
6268
6519
|
);
|
|
6269
6520
|
if (initialTimeout > 0) {
|
|
6270
6521
|
try {
|
|
6271
6522
|
await page.waitForSelector(selectorQuery, { timeout: initialTimeout });
|
|
6272
|
-
|
|
6523
|
+
logger13.info(`waitForStableAcrossRoots \u5DF2\u68C0\u6D4B\u5230\u5143\u7D20: ${selectorQuery}`);
|
|
6273
6524
|
} catch (e) {
|
|
6274
|
-
|
|
6525
|
+
logger13.warning(`waitForStableAcrossRoots \u521D\u59CB\u7B49\u5F85\u8D85\u65F6 (${initialTimeout}ms): ${selectorQuery}`);
|
|
6275
6526
|
throw e;
|
|
6276
6527
|
}
|
|
6277
6528
|
}
|
|
6278
6529
|
let state = await buildState();
|
|
6279
6530
|
if (!state?.hasMatched) {
|
|
6280
|
-
|
|
6531
|
+
logger13.warning("waitForStableAcrossRoots \u672A\u627E\u5230\u53EF\u76D1\u63A7\u7684\u5143\u7D20");
|
|
6281
6532
|
return { mutationCount: 0, stableTime: 0, wasPaused: false };
|
|
6282
6533
|
}
|
|
6283
6534
|
let mutationCount = 0;
|
|
@@ -6314,7 +6565,7 @@ var Mutation = {
|
|
|
6314
6565
|
if (lastState.snapshotKey !== lastSnapshotKey) {
|
|
6315
6566
|
lastSnapshotKey = lastState.snapshotKey;
|
|
6316
6567
|
mutationCount += 1;
|
|
6317
|
-
|
|
6568
|
+
logger13.info(
|
|
6318
6569
|
`waitForStableAcrossRoots \u53D8\u5316#${mutationCount}, len=${lastState.snapshotLength}, path=${lastState.primaryPath || "unknown"}, preview="${truncate(lastState.text, 120)}"`
|
|
6319
6570
|
);
|
|
6320
6571
|
const signal = await invokeMutationCallback({
|
|
@@ -6327,7 +6578,7 @@ var Mutation = {
|
|
|
6327
6578
|
continue;
|
|
6328
6579
|
}
|
|
6329
6580
|
if (!isPaused && stableSince > 0 && Date.now() - stableSince >= waitForStableTime) {
|
|
6330
|
-
|
|
6581
|
+
logger13.success("waitForStableAcrossRoots", `DOM \u7A33\u5B9A, \u603B\u5171 ${mutationCount} \u6B21\u53D8\u5316${wasPaused ? ", \u66FE\u6682\u505C\u8BA1\u65F6" : ""}`);
|
|
6331
6582
|
return {
|
|
6332
6583
|
mutationCount,
|
|
6333
6584
|
stableTime: waitForStableTime,
|
|
@@ -6354,7 +6605,7 @@ var Mutation = {
|
|
|
6354
6605
|
const onMutation = options.onMutation;
|
|
6355
6606
|
const rawMode = String(options.mode || MUTATION_MONITOR_MODE.Added).toLowerCase();
|
|
6356
6607
|
const mode = [MUTATION_MONITOR_MODE.Added, MUTATION_MONITOR_MODE.Changed, MUTATION_MONITOR_MODE.All].includes(rawMode) ? rawMode : MUTATION_MONITOR_MODE.Added;
|
|
6357
|
-
|
|
6608
|
+
logger13.start("useMonitor", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, mode=${mode}`);
|
|
6358
6609
|
const monitorKey = generateKey("pk_mon");
|
|
6359
6610
|
const callbackName = generateKey("pk_mon_cb");
|
|
6360
6611
|
const cleanerName = generateKey("pk_mon_clean");
|
|
@@ -6497,7 +6748,7 @@ var Mutation = {
|
|
|
6497
6748
|
return total;
|
|
6498
6749
|
};
|
|
6499
6750
|
}, { selectorList, monitorKey, callbackName, cleanerName, hasCallback: !!onMutation, mode });
|
|
6500
|
-
|
|
6751
|
+
logger13.success("useMonitor", "\u76D1\u63A7\u5668\u5DF2\u542F\u52A8");
|
|
6501
6752
|
return {
|
|
6502
6753
|
stop: async () => {
|
|
6503
6754
|
let totalMutations = 0;
|
|
@@ -6510,7 +6761,7 @@ var Mutation = {
|
|
|
6510
6761
|
}, cleanerName);
|
|
6511
6762
|
} catch (e) {
|
|
6512
6763
|
}
|
|
6513
|
-
|
|
6764
|
+
logger13.success("useMonitor.stop", `\u76D1\u63A7\u5DF2\u505C\u6B62, \u5171 ${totalMutations} \u6B21\u53D8\u5316`);
|
|
6514
6765
|
return { totalMutations };
|
|
6515
6766
|
}
|
|
6516
6767
|
};
|
|
@@ -7379,7 +7630,7 @@ var createTemplateLogger = (baseLogger = createBaseLogger()) => {
|
|
|
7379
7630
|
};
|
|
7380
7631
|
var getDefaultBaseLogger = () => createBaseLogger("");
|
|
7381
7632
|
var Logger = {
|
|
7382
|
-
setLogger: (
|
|
7633
|
+
setLogger: (logger17) => setDefaultLogger(logger17),
|
|
7383
7634
|
info: (message) => getDefaultBaseLogger().info(message),
|
|
7384
7635
|
success: (message) => getDefaultBaseLogger().success(message),
|
|
7385
7636
|
warning: (message) => getDefaultBaseLogger().warning(message),
|
|
@@ -7387,8 +7638,8 @@ var Logger = {
|
|
|
7387
7638
|
error: (message) => getDefaultBaseLogger().error(message),
|
|
7388
7639
|
debug: (message) => getDefaultBaseLogger().debug(message),
|
|
7389
7640
|
start: (message) => getDefaultBaseLogger().start(message),
|
|
7390
|
-
useTemplate: (
|
|
7391
|
-
if (
|
|
7641
|
+
useTemplate: (logger17) => {
|
|
7642
|
+
if (logger17) return createTemplateLogger(createBaseLogger("", logger17));
|
|
7392
7643
|
return createTemplateLogger();
|
|
7393
7644
|
}
|
|
7394
7645
|
};
|
|
@@ -7462,7 +7713,7 @@ var LOCATION_NETWORK_SUFFIX_PATTERNS = [
|
|
|
7462
7713
|
];
|
|
7463
7714
|
var cachedStripLogoSrcPromise = null;
|
|
7464
7715
|
var cachedEnrichmentByContext = /* @__PURE__ */ new WeakMap();
|
|
7465
|
-
var
|
|
7716
|
+
var logger14 = createInternalLogger("Watermarkify");
|
|
7466
7717
|
var normalizeText = (value) => String(value || "").trim();
|
|
7467
7718
|
var toInline = (value, maxLen = 200) => {
|
|
7468
7719
|
const text = normalizeText(value);
|
|
@@ -7704,9 +7955,9 @@ var resolveWithCustomResolver = async (page, baseMeta, options = {}) => {
|
|
|
7704
7955
|
location: toInline(resolved.location, 80)
|
|
7705
7956
|
};
|
|
7706
7957
|
if (enrichment.ip || enrichment.location) {
|
|
7707
|
-
|
|
7958
|
+
logger14.info(`\u81EA\u5B9A\u4E49 resolver \u547D\u4E2D: ip=${enrichment.ip || "-"}, loc=${enrichment.location || "-"}`);
|
|
7708
7959
|
} else {
|
|
7709
|
-
|
|
7960
|
+
logger14.warning("\u81EA\u5B9A\u4E49 resolver \u5DF2\u6267\u884C\uFF0C\u4F46\u672A\u8FD4\u56DE IP/Loc");
|
|
7710
7961
|
}
|
|
7711
7962
|
return enrichment;
|
|
7712
7963
|
} finally {
|
|
@@ -7890,14 +8141,17 @@ var buildWatermarkifyRenderHtml = ({ imageSrc, overlaySvg, width, height, imageH
|
|
|
7890
8141
|
</html>
|
|
7891
8142
|
`;
|
|
7892
8143
|
};
|
|
7893
|
-
var
|
|
8144
|
+
var normalizeWatermarkifyRenderMode = (value) => {
|
|
8145
|
+
return String(value || "default").trim().toLowerCase() === "cloakbrowser" ? "cloakbrowser" : "default";
|
|
8146
|
+
};
|
|
8147
|
+
var composeScreenshotBufferWithBrowser = async (page, buffer, overlaySvg, imageInfo = {}, options = {}) => {
|
|
7894
8148
|
if (!page || typeof page.context !== "function") {
|
|
7895
|
-
|
|
8149
|
+
logger14.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u8DF3\u8FC7: \u7F3A\u5C11\u53EF\u7528 page");
|
|
7896
8150
|
return buffer;
|
|
7897
8151
|
}
|
|
7898
8152
|
const renderScope = await openProbePage(page);
|
|
7899
8153
|
if (!renderScope?.page) {
|
|
7900
|
-
|
|
8154
|
+
logger14.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u8DF3\u8FC7: \u65E0\u6CD5\u521B\u5EFA render page");
|
|
7901
8155
|
return buffer;
|
|
7902
8156
|
}
|
|
7903
8157
|
try {
|
|
@@ -7914,15 +8168,35 @@ var composeScreenshotBufferWithBrowser = async (page, buffer, overlaySvg, imageI
|
|
|
7914
8168
|
height: viewportHeight
|
|
7915
8169
|
}).catch(() => {
|
|
7916
8170
|
});
|
|
7917
|
-
|
|
7918
|
-
|
|
7919
|
-
|
|
7920
|
-
|
|
7921
|
-
|
|
7922
|
-
|
|
7923
|
-
|
|
7924
|
-
|
|
7925
|
-
|
|
8171
|
+
const renderMode = normalizeWatermarkifyRenderMode(options.mode);
|
|
8172
|
+
if (renderMode === "cloakbrowser") {
|
|
8173
|
+
const renderHtml = buildWatermarkifyRenderHtml({
|
|
8174
|
+
imageSrc: `data:${imageInfo.mimeType || "image/png"};base64,${buffer.toString("base64")}`,
|
|
8175
|
+
overlaySvg,
|
|
8176
|
+
width: safeWidth,
|
|
8177
|
+
height: safeHeight,
|
|
8178
|
+
imageHeight: safeImageHeight
|
|
8179
|
+
});
|
|
8180
|
+
await renderPage.goto("about:blank", {
|
|
8181
|
+
waitUntil: "commit"
|
|
8182
|
+
}).catch(() => {
|
|
8183
|
+
});
|
|
8184
|
+
await renderPage.evaluate((html) => {
|
|
8185
|
+
document.open();
|
|
8186
|
+
document.write(html);
|
|
8187
|
+
document.close();
|
|
8188
|
+
}, renderHtml);
|
|
8189
|
+
} else {
|
|
8190
|
+
await renderPage.setContent(buildWatermarkifyRenderHtml({
|
|
8191
|
+
imageSrc: `data:${imageInfo.mimeType || "image/png"};base64,${buffer.toString("base64")}`,
|
|
8192
|
+
overlaySvg,
|
|
8193
|
+
width: safeWidth,
|
|
8194
|
+
height: safeHeight,
|
|
8195
|
+
imageHeight: safeImageHeight
|
|
8196
|
+
}), {
|
|
8197
|
+
waitUntil: "load"
|
|
8198
|
+
});
|
|
8199
|
+
}
|
|
7926
8200
|
await renderPage.waitForFunction(() => {
|
|
7927
8201
|
const image = document.getElementById("pk-base-image");
|
|
7928
8202
|
return image instanceof HTMLImageElement && image.complete && image.naturalWidth > 0 && image.naturalHeight > 0;
|
|
@@ -7942,13 +8216,13 @@ var composeScreenshotBufferWithBrowser = async (page, buffer, overlaySvg, imageI
|
|
|
7942
8216
|
fullPage: true,
|
|
7943
8217
|
animations: "disabled"
|
|
7944
8218
|
}).catch((error) => {
|
|
7945
|
-
|
|
8219
|
+
logger14.warning(`watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
|
|
7946
8220
|
return null;
|
|
7947
8221
|
});
|
|
7948
8222
|
if (Buffer.isBuffer(composed) && composed.length > 0) {
|
|
7949
8223
|
return composed;
|
|
7950
8224
|
}
|
|
7951
|
-
|
|
8225
|
+
logger14.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u5931\u8D25: \u672A\u5F97\u5230\u6709\u6548\u622A\u56FE\u7ED3\u679C");
|
|
7952
8226
|
return buffer;
|
|
7953
8227
|
} finally {
|
|
7954
8228
|
await renderScope.close().catch(() => {
|
|
@@ -7961,7 +8235,7 @@ var resolveWithIpLookup = async (page, options = {}) => {
|
|
|
7961
8235
|
}
|
|
7962
8236
|
const probeScope = await openProbePage(page);
|
|
7963
8237
|
if (!probeScope?.page) {
|
|
7964
|
-
|
|
8238
|
+
logger14.warning("ipLookup \u8DF3\u8FC7: \u65E0\u6CD5\u521B\u5EFA probe page");
|
|
7965
8239
|
return null;
|
|
7966
8240
|
}
|
|
7967
8241
|
const timeoutMs = Math.max(
|
|
@@ -7970,12 +8244,12 @@ var resolveWithIpLookup = async (page, options = {}) => {
|
|
|
7970
8244
|
);
|
|
7971
8245
|
try {
|
|
7972
8246
|
const probePage = probeScope.page;
|
|
7973
|
-
|
|
8247
|
+
logger14.info(`ipLookup \u5C1D\u8BD5: url=${DEFAULT_IP_LOOKUP_URL}, timeoutMs=${timeoutMs}`);
|
|
7974
8248
|
const response = await probePage.goto(DEFAULT_IP_LOOKUP_URL, {
|
|
7975
8249
|
waitUntil: "commit",
|
|
7976
8250
|
timeout: timeoutMs
|
|
7977
8251
|
}).catch((error) => {
|
|
7978
|
-
|
|
8252
|
+
logger14.warning(`ipLookup \u8BF7\u6C42\u5931\u8D25: url=${DEFAULT_IP_LOOKUP_URL}, error=${error instanceof Error ? error.message : String(error)}`);
|
|
7979
8253
|
return null;
|
|
7980
8254
|
});
|
|
7981
8255
|
const status = response && typeof response.status === "function" ? response.status() : 0;
|
|
@@ -7997,13 +8271,13 @@ var resolveWithIpLookup = async (page, options = {}) => {
|
|
|
7997
8271
|
}
|
|
7998
8272
|
const parsed = parseIpIpJsonResponse(rawText);
|
|
7999
8273
|
if (parsed?.ip || parsed?.location) {
|
|
8000
|
-
|
|
8274
|
+
logger14.info(`ipLookup \u6210\u529F: url=${DEFAULT_IP_LOOKUP_URL}, status=${status || "-"}, contentType=${contentType || "-"}, ip=${parsed.ip || "-"}, loc=${parsed.location || "-"}`);
|
|
8001
8275
|
return parsed;
|
|
8002
8276
|
}
|
|
8003
|
-
|
|
8277
|
+
logger14.warning(`ipLookup \u672A\u89E3\u6790\u51FA IP/Loc: url=${DEFAULT_IP_LOOKUP_URL}, status=${status || "-"}, contentType=${contentType || "-"}, preview=${shortenTail(rawText, 120) || "[empty]"}`);
|
|
8004
8278
|
return null;
|
|
8005
8279
|
} catch (error) {
|
|
8006
|
-
|
|
8280
|
+
logger14.warning(`ipLookup \u6267\u884C\u5F02\u5E38\uFF0C\u672A\u83B7\u5F97 IP/Loc: ${error instanceof Error ? error.message : String(error)}`);
|
|
8007
8281
|
return null;
|
|
8008
8282
|
} finally {
|
|
8009
8283
|
await probeScope.close().catch(() => {
|
|
@@ -8017,10 +8291,10 @@ var resolveEnrichment = async (page, baseMeta, options) => {
|
|
|
8017
8291
|
ip: toInline(options.ip, 80),
|
|
8018
8292
|
location: toInline(options.location, 80)
|
|
8019
8293
|
};
|
|
8020
|
-
|
|
8294
|
+
logger14.info(`enrichment \u5F00\u59CB: host=${baseMeta.hostname || "-"}, hasPresetIp=${Boolean(merged.ip)}, hasPresetLoc=${Boolean(merged.location)}, ipLookup=${options.ipLookup !== false}`);
|
|
8021
8295
|
if (!merged.ip || !merged.location) {
|
|
8022
8296
|
if (cached?.ip || cached?.location) {
|
|
8023
|
-
|
|
8297
|
+
logger14.info(`enrichment \u547D\u4E2D\u4E0A\u4E0B\u6587\u7F13\u5B58: ip=${cached.ip || "-"}, loc=${cached.location || "-"}`);
|
|
8024
8298
|
}
|
|
8025
8299
|
fillEnrichment(merged, cached);
|
|
8026
8300
|
}
|
|
@@ -8044,15 +8318,15 @@ var resolveEnrichment = async (page, baseMeta, options) => {
|
|
|
8044
8318
|
"x-geo-country"
|
|
8045
8319
|
]), 80);
|
|
8046
8320
|
if (!merged.location || isWeakLocationValue(merged.location) && headerLocation) {
|
|
8047
|
-
|
|
8321
|
+
logger14.info(`enrichment \u4F7F\u7528\u54CD\u5E94\u5934\u8865\u5145 Loc: ${headerLocation || "-"}`);
|
|
8048
8322
|
merged.location = headerLocation || merged.location;
|
|
8049
8323
|
}
|
|
8050
8324
|
}
|
|
8051
8325
|
writeCachedEnrichment(page, merged);
|
|
8052
8326
|
if (merged.ip || merged.location) {
|
|
8053
|
-
|
|
8327
|
+
logger14.info(`enrichment \u5B8C\u6210: ip=${merged.ip || "-"}, loc=${merged.location || "-"}`);
|
|
8054
8328
|
} else {
|
|
8055
|
-
|
|
8329
|
+
logger14.warning("enrichment \u5B8C\u6210: \u672A\u83B7\u5F97 IP/Loc");
|
|
8056
8330
|
}
|
|
8057
8331
|
return merged;
|
|
8058
8332
|
};
|
|
@@ -8857,7 +9131,7 @@ var buildWatermarkifySvg = (meta, imageWidth, imageHeight) => {
|
|
|
8857
9131
|
</svg>
|
|
8858
9132
|
`;
|
|
8859
9133
|
};
|
|
8860
|
-
var watermarkifyScreenshotBuffer = async (buffer, meta, page = null) => {
|
|
9134
|
+
var watermarkifyScreenshotBuffer = async (buffer, meta, page = null, options = {}) => {
|
|
8861
9135
|
const hasWatermark = meta?.watermark?.enabled !== false && normalizeText(meta?.watermarkText);
|
|
8862
9136
|
const hasStrip = meta?.strip?.enabled !== false && Array.isArray(meta?.stripSegments) && meta.stripSegments.length > 0;
|
|
8863
9137
|
if (!Buffer.isBuffer(buffer) || !meta || !hasWatermark && !hasStrip) {
|
|
@@ -8865,7 +9139,7 @@ var watermarkifyScreenshotBuffer = async (buffer, meta, page = null) => {
|
|
|
8865
9139
|
}
|
|
8866
9140
|
const imageInfo = readImageInfo(buffer);
|
|
8867
9141
|
if (!imageInfo.width || !imageInfo.height || !imageInfo.mimeType) {
|
|
8868
|
-
|
|
9142
|
+
logger14.warning("watermarkify \u8DF3\u8FC7: \u65E0\u6CD5\u89E3\u6790\u622A\u56FE\u5C3A\u5BF8\u6216\u683C\u5F0F");
|
|
8869
9143
|
return buffer;
|
|
8870
9144
|
}
|
|
8871
9145
|
const isMobileStrip = normalizeDevice(meta.device) === Device.Mobile && hasStrip;
|
|
@@ -8878,12 +9152,12 @@ var watermarkifyScreenshotBuffer = async (buffer, meta, page = null) => {
|
|
|
8878
9152
|
if (!overlaySvg) {
|
|
8879
9153
|
return buffer;
|
|
8880
9154
|
}
|
|
8881
|
-
return await composeScreenshotBufferWithBrowser(page, buffer, overlaySvg, outputImageInfo);
|
|
9155
|
+
return await composeScreenshotBufferWithBrowser(page, buffer, overlaySvg, outputImageInfo, options);
|
|
8882
9156
|
};
|
|
8883
9157
|
|
|
8884
9158
|
// src/internals/compression.js
|
|
8885
9159
|
import { Jimp, JimpMime, ResizeStrategy } from "jimp";
|
|
8886
|
-
var
|
|
9160
|
+
var logger15 = createInternalLogger("Compression");
|
|
8887
9161
|
var DEFAULT_SCREENSHOT_MAX_BYTES = 5 * 1024 * 1024;
|
|
8888
9162
|
var DEFAULT_SCREENSHOT_OUTPUT_TYPE = "jpeg";
|
|
8889
9163
|
var DEFAULT_SCREENSHOT_QUALITY = 0.72;
|
|
@@ -9002,18 +9276,18 @@ var compressImageBufferToBase64 = async (buffer, compression) => {
|
|
|
9002
9276
|
return buffer.toString("base64");
|
|
9003
9277
|
}
|
|
9004
9278
|
const result = await compressImageBuffer(buffer, compression).catch((error) => {
|
|
9005
|
-
|
|
9279
|
+
logger15.warning(`captureScreen \u538B\u7F29\u5931\u8D25\uFF0C\u8FD4\u56DE\u539F\u56FE: ${error instanceof Error ? error.message : String(error)}`);
|
|
9006
9280
|
return null;
|
|
9007
9281
|
});
|
|
9008
9282
|
if (!result?.buffer) {
|
|
9009
9283
|
return buffer.toString("base64");
|
|
9010
9284
|
}
|
|
9011
9285
|
if (result.withinLimit) {
|
|
9012
|
-
|
|
9286
|
+
logger15.info(
|
|
9013
9287
|
`captureScreen \u5DF2\u538B\u7F29: ${originalBytes} -> ${result.bytes} bytes, format=${result.format}, quality=${result.quality}, scale=${result.scale}, size=${result.width}x${result.height}`
|
|
9014
9288
|
);
|
|
9015
9289
|
} else {
|
|
9016
|
-
|
|
9290
|
+
logger15.warning(
|
|
9017
9291
|
`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}`
|
|
9018
9292
|
);
|
|
9019
9293
|
}
|
|
@@ -9021,7 +9295,7 @@ var compressImageBufferToBase64 = async (buffer, compression) => {
|
|
|
9021
9295
|
};
|
|
9022
9296
|
|
|
9023
9297
|
// src/share.js
|
|
9024
|
-
var
|
|
9298
|
+
var logger16 = createInternalLogger("Share");
|
|
9025
9299
|
var DEFAULT_TIMEOUT_MS2 = 50 * 1e3;
|
|
9026
9300
|
var DEFAULT_PAYLOAD_SNAPSHOT_MAX_LEN = 500;
|
|
9027
9301
|
var DEFAULT_POLL_INTERVAL_MS = 120;
|
|
@@ -9158,7 +9432,7 @@ var createDomShareMonitor = async (page, options = {}) => {
|
|
|
9158
9432
|
const onMatch = typeof options.onMatch === "function" ? options.onMatch : null;
|
|
9159
9433
|
const onTelemetry = typeof options.onTelemetry === "function" ? options.onTelemetry : null;
|
|
9160
9434
|
let matched = false;
|
|
9161
|
-
|
|
9435
|
+
logger16.info(`DOM \u76D1\u542C\u51C6\u5907\u6302\u8F7D: selectors=${toJsonInline(selectors, 120)}, mode=${mode}`);
|
|
9162
9436
|
const monitor = await Mutation.useMonitor(page, selectors, {
|
|
9163
9437
|
mode,
|
|
9164
9438
|
onMutation: (context = {}) => {
|
|
@@ -9176,12 +9450,12 @@ ${text}`;
|
|
|
9176
9450
|
});
|
|
9177
9451
|
}
|
|
9178
9452
|
if (mutationCount <= 5 || mutationCount % 50 === 0) {
|
|
9179
|
-
|
|
9453
|
+
logger16.info(`DOM \u53D8\u5316\u5DF2\u6355\u83B7: mutationCount=${mutationCount}, mutationNodes=${mutationNodes.length}`);
|
|
9180
9454
|
}
|
|
9181
9455
|
const [candidate] = Utils.parseLinks(rawDom, { prefix }) || [];
|
|
9182
9456
|
if (!candidate) return;
|
|
9183
9457
|
matched = true;
|
|
9184
|
-
|
|
9458
|
+
logger16.success("captureLink.domHit", `DOM \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: mutationCount=${mutationCount}, link=${candidate}`);
|
|
9185
9459
|
if (onMatch) {
|
|
9186
9460
|
onMatch({
|
|
9187
9461
|
link: candidate,
|
|
@@ -9197,7 +9471,7 @@ ${text}`;
|
|
|
9197
9471
|
return {
|
|
9198
9472
|
stop: async () => {
|
|
9199
9473
|
const result = await monitor.stop();
|
|
9200
|
-
|
|
9474
|
+
logger16.info(`DOM \u76D1\u542C\u5DF2\u505C\u6B62: totalMutations=${result?.totalMutations || 0}`);
|
|
9201
9475
|
return result;
|
|
9202
9476
|
}
|
|
9203
9477
|
};
|
|
@@ -9246,8 +9520,8 @@ var Share = {
|
|
|
9246
9520
|
if (share.mode === "response" && apiMatchers.length === 0) {
|
|
9247
9521
|
throw new Error("Share.captureLink requires share.xurl[0] api matcher when mode=response");
|
|
9248
9522
|
}
|
|
9249
|
-
|
|
9250
|
-
|
|
9523
|
+
logger16.start("captureLink", `mode=${share.mode}, timeoutMs=${timeoutDisabled ? "disabled" : timeoutMs}, prefix=${share.prefix}`);
|
|
9524
|
+
logger16.info(`captureLink \u914D\u7F6E: xurl=${toJsonInline(share.xurl)}, domMode=${domMode}, domSelectors=${toJsonInline(domSelectors, 120)}`);
|
|
9251
9525
|
const stats = {
|
|
9252
9526
|
actionTimedOut: false,
|
|
9253
9527
|
domMutationCount: 0,
|
|
@@ -9259,7 +9533,7 @@ var Share = {
|
|
|
9259
9533
|
responseSampleUrls: []
|
|
9260
9534
|
};
|
|
9261
9535
|
if (isAborted()) {
|
|
9262
|
-
|
|
9536
|
+
logger16.warning(`captureLink \u5DF2\u53D6\u6D88: ${abortReason()}`);
|
|
9263
9537
|
return {
|
|
9264
9538
|
link: null,
|
|
9265
9539
|
payloadText: "",
|
|
@@ -9282,7 +9556,7 @@ var Share = {
|
|
|
9282
9556
|
link: validated,
|
|
9283
9557
|
payloadText: String(payloadText || "")
|
|
9284
9558
|
};
|
|
9285
|
-
|
|
9559
|
+
logger16.info(`\u5019\u9009\u94FE\u63A5\u5DF2\u786E\u8BA4: source=${source}, link=${validated}`);
|
|
9286
9560
|
return true;
|
|
9287
9561
|
};
|
|
9288
9562
|
const resolveResponseCandidate = (responseText) => {
|
|
@@ -9317,7 +9591,7 @@ var Share = {
|
|
|
9317
9591
|
try {
|
|
9318
9592
|
await monitor.stop();
|
|
9319
9593
|
} catch (error) {
|
|
9320
|
-
|
|
9594
|
+
logger16.warning(`\u505C\u6B62 DOM \u76D1\u542C\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
|
|
9321
9595
|
}
|
|
9322
9596
|
};
|
|
9323
9597
|
const onResponse = async (response) => {
|
|
@@ -9331,29 +9605,29 @@ var Share = {
|
|
|
9331
9605
|
stats.responseSampleUrls.push(url);
|
|
9332
9606
|
}
|
|
9333
9607
|
if (stats.responseObserved <= 5) {
|
|
9334
|
-
|
|
9608
|
+
logger16.info(`\u63A5\u53E3\u54CD\u5E94\u91C7\u6837(${stats.responseObserved}): ${url}`);
|
|
9335
9609
|
}
|
|
9336
9610
|
if (!apiMatchers.some((matcher) => url.includes(matcher))) return;
|
|
9337
9611
|
stats.responseMatched += 1;
|
|
9338
9612
|
stats.lastMatchedUrl = url;
|
|
9339
|
-
|
|
9613
|
+
logger16.info(`\u63A5\u53E3\u547D\u4E2D\u5339\u914D(${stats.responseMatched}): ${url}`);
|
|
9340
9614
|
const text = await response.text();
|
|
9341
9615
|
const hit = resolveResponseCandidate(text);
|
|
9342
9616
|
if (!hit?.link) {
|
|
9343
9617
|
if (stats.responseMatched <= 3) {
|
|
9344
|
-
|
|
9618
|
+
logger16.info(`\u63A5\u53E3\u89E3\u6790\u5B8C\u6210\u4F46\u672A\u63D0\u53D6\u5230\u5206\u4EAB\u94FE\u63A5: payloadSize=${text.length}`);
|
|
9345
9619
|
}
|
|
9346
9620
|
return;
|
|
9347
9621
|
}
|
|
9348
9622
|
stats.responseResolved += 1;
|
|
9349
|
-
|
|
9623
|
+
logger16.success("captureLink.responseHit", `\u63A5\u53E3\u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: url=${url}, link=${hit.link}`);
|
|
9350
9624
|
setCandidate("response", hit.link, hit.payloadText);
|
|
9351
9625
|
} catch (error) {
|
|
9352
|
-
|
|
9626
|
+
logger16.warning(`\u63A5\u53E3\u54CD\u5E94\u5904\u7406\u5F02\u5E38: ${error instanceof Error ? error.message : String(error)}`);
|
|
9353
9627
|
}
|
|
9354
9628
|
};
|
|
9355
9629
|
if (share.mode === "dom") {
|
|
9356
|
-
|
|
9630
|
+
logger16.info("\u5F53\u524D\u4E3A DOM \u6A21\u5F0F\uFF0C\u4EC5\u542F\u7528 DOM \u76D1\u542C");
|
|
9357
9631
|
domMonitor = await createDomShareMonitor(page, {
|
|
9358
9632
|
prefix: share.prefix,
|
|
9359
9633
|
selectors: domSelectors,
|
|
@@ -9368,17 +9642,17 @@ var Share = {
|
|
|
9368
9642
|
});
|
|
9369
9643
|
}
|
|
9370
9644
|
if (share.mode === "response") {
|
|
9371
|
-
|
|
9645
|
+
logger16.info(`\u5F53\u524D\u4E3A\u63A5\u53E3\u6A21\u5F0F\uFF0C\u6302\u8F7D response \u76D1\u542C: apiMatchers=${toJsonInline(apiMatchers, 160)}`);
|
|
9372
9646
|
page.on("response", onResponse);
|
|
9373
9647
|
}
|
|
9374
9648
|
if (share.mode === "custom") {
|
|
9375
|
-
|
|
9649
|
+
logger16.info("\u5F53\u524D\u4E3A custom \u6A21\u5F0F\uFF0C\u5C06\u4F7F\u7528 performActions \u8FD4\u56DE\u503C");
|
|
9376
9650
|
}
|
|
9377
9651
|
const deadline = timeoutDisabled ? Infinity : Date.now() + timeoutMs;
|
|
9378
9652
|
const getRemainingMs = () => timeoutDisabled ? Infinity : Math.max(0, deadline - Date.now());
|
|
9379
9653
|
try {
|
|
9380
9654
|
const actionTimeout = getRemainingMs();
|
|
9381
|
-
|
|
9655
|
+
logger16.start("captureLink.performActions", `\u6267\u884C\u52A8\u4F5C\u9884\u7B97=${timeoutDisabled ? "disabled" : `${actionTimeout}ms`}`);
|
|
9382
9656
|
let actionValue;
|
|
9383
9657
|
if (!isAborted() && actionTimeout > 0) {
|
|
9384
9658
|
let timer = null;
|
|
@@ -9391,30 +9665,30 @@ var Share = {
|
|
|
9391
9665
|
]);
|
|
9392
9666
|
if (timer) clearTimeout(timer);
|
|
9393
9667
|
if (actionResult.type === "error") {
|
|
9394
|
-
|
|
9668
|
+
logger16.fail("captureLink.performActions", actionResult.error);
|
|
9395
9669
|
throw actionResult.error;
|
|
9396
9670
|
}
|
|
9397
9671
|
if (actionResult.type === "timeout") {
|
|
9398
9672
|
stats.actionTimedOut = true;
|
|
9399
|
-
|
|
9673
|
+
logger16.warning(`performActions \u5DF2\u8D85\u65F6 (${actionTimeout}ms)\uFF0C\u52A8\u4F5C\u53EF\u80FD\u4ECD\u5728\u5F02\u6B65\u6267\u884C`);
|
|
9400
9674
|
} else {
|
|
9401
9675
|
actionValue = actionResult.result;
|
|
9402
|
-
|
|
9676
|
+
logger16.success("captureLink.performActions", "\u6267\u884C\u52A8\u4F5C\u5B8C\u6210");
|
|
9403
9677
|
}
|
|
9404
9678
|
}
|
|
9405
9679
|
if (share.mode === "custom") {
|
|
9406
9680
|
const customLink = typeof actionValue === "string" ? actionValue : actionValue?.link || actionValue?.payloadText;
|
|
9407
9681
|
const customPayloadText = typeof actionValue === "string" ? actionValue : actionValue?.payloadText;
|
|
9408
9682
|
if (setCandidate("custom", customLink, customPayloadText)) {
|
|
9409
|
-
|
|
9683
|
+
logger16.success("captureLink.customResult", `custom \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: link=${candidates.custom.link}`);
|
|
9410
9684
|
} else {
|
|
9411
|
-
|
|
9685
|
+
logger16.warning("performActions \u6267\u884C\u5B8C\u6210\u4F46\u672A\u8FD4\u56DE\u6709\u6548\u5206\u4EAB\u94FE\u63A5");
|
|
9412
9686
|
}
|
|
9413
9687
|
}
|
|
9414
9688
|
let nextProgressLogTs = Date.now() + 3e3;
|
|
9415
9689
|
while (true) {
|
|
9416
9690
|
if (isAborted()) {
|
|
9417
|
-
|
|
9691
|
+
logger16.warning(`captureLink \u5DF2\u53D6\u6D88: ${abortReason()}`);
|
|
9418
9692
|
return {
|
|
9419
9693
|
link: null,
|
|
9420
9694
|
payloadText: "",
|
|
@@ -9424,7 +9698,7 @@ var Share = {
|
|
|
9424
9698
|
}
|
|
9425
9699
|
const selected = candidates[share.mode];
|
|
9426
9700
|
if (selected?.link) {
|
|
9427
|
-
|
|
9701
|
+
logger16.success("captureLink", `\u6355\u83B7\u6210\u529F: source=${share.mode}, link=${selected.link}`);
|
|
9428
9702
|
return {
|
|
9429
9703
|
link: selected.link,
|
|
9430
9704
|
payloadText: selected.payloadText,
|
|
@@ -9437,7 +9711,7 @@ var Share = {
|
|
|
9437
9711
|
if (remaining <= 0) break;
|
|
9438
9712
|
const now = Date.now();
|
|
9439
9713
|
if (now >= nextProgressLogTs) {
|
|
9440
|
-
|
|
9714
|
+
logger16.info(
|
|
9441
9715
|
`captureLink \u7B49\u5F85\u4E2D: remaining=${timeoutDisabled ? "disabled" : `${remaining}ms`}, domMutationCount=${stats.domMutationCount}, responseMatched=${stats.responseMatched}`
|
|
9442
9716
|
);
|
|
9443
9717
|
nextProgressLogTs = now + 5e3;
|
|
@@ -9445,11 +9719,11 @@ var Share = {
|
|
|
9445
9719
|
await delay4(Math.max(0, Math.min(DEFAULT_POLL_INTERVAL_MS, remaining)));
|
|
9446
9720
|
}
|
|
9447
9721
|
if (!timeoutDisabled && share.mode === "response" && stats.responseMatched === 0) {
|
|
9448
|
-
|
|
9722
|
+
logger16.warning(
|
|
9449
9723
|
`\u63A5\u53E3\u76D1\u542C\u672A\u547D\u4E2D: apiMatchers=${toJsonInline(apiMatchers, 220)}, \u54CD\u5E94\u6837\u672CURLs=${toJsonInline(stats.responseSampleUrls, 420)}`
|
|
9450
9724
|
);
|
|
9451
9725
|
}
|
|
9452
|
-
|
|
9726
|
+
logger16.warning(
|
|
9453
9727
|
`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"}`
|
|
9454
9728
|
);
|
|
9455
9729
|
return {
|
|
@@ -9461,7 +9735,7 @@ var Share = {
|
|
|
9461
9735
|
} finally {
|
|
9462
9736
|
if (share.mode === "response") {
|
|
9463
9737
|
page.off("response", onResponse);
|
|
9464
|
-
|
|
9738
|
+
logger16.info("response \u76D1\u542C\u5DF2\u5378\u8F7D");
|
|
9465
9739
|
}
|
|
9466
9740
|
await stopDomMonitor();
|
|
9467
9741
|
}
|
|
@@ -9476,6 +9750,7 @@ var Share = {
|
|
|
9476
9750
|
* @param {number} [options.maxBytes] 默认 5MiB,返回 base64 超过后会压缩
|
|
9477
9751
|
* @param {'jpeg'|'jpg'} [options.type] 压缩输出格式,默认 jpeg
|
|
9478
9752
|
* @param {boolean|Object} [options.compression] 传 false 可关闭压缩
|
|
9753
|
+
* @param {'default'|'cloakbrowser'} [options.mode] 截图水印合成模式,默认 default
|
|
9479
9754
|
* @returns {Promise<string>} base64 image
|
|
9480
9755
|
*/
|
|
9481
9756
|
async captureScreen(page, options = {}) {
|
|
@@ -9496,7 +9771,9 @@ var Share = {
|
|
|
9496
9771
|
...screenshotWatermarkify,
|
|
9497
9772
|
capturedAt
|
|
9498
9773
|
});
|
|
9499
|
-
outputBuffer = await watermarkifyScreenshotBuffer(rawBuffer, watermarkifyMeta, page
|
|
9774
|
+
outputBuffer = await watermarkifyScreenshotBuffer(rawBuffer, watermarkifyMeta, page, {
|
|
9775
|
+
mode: options.mode === "cloakbrowser" ? "cloakbrowser" : "default"
|
|
9776
|
+
});
|
|
9500
9777
|
}
|
|
9501
9778
|
return await compressImageBufferToBase64(outputBuffer, compression);
|
|
9502
9779
|
}
|
|
@@ -9504,14 +9781,15 @@ var Share = {
|
|
|
9504
9781
|
|
|
9505
9782
|
// entrys/node.js
|
|
9506
9783
|
Logger.setLogger(crawleeLog);
|
|
9507
|
-
var usePlaywrightToolKit = () => {
|
|
9508
|
-
|
|
9784
|
+
var usePlaywrightToolKit = (mode = "default") => {
|
|
9785
|
+
const launchModule = mode === "cloakbrowser" ? createCloakLaunchModule(Launch) : Launch;
|
|
9786
|
+
const toolkit = {
|
|
9509
9787
|
ApifyKit,
|
|
9510
9788
|
AntiCheat,
|
|
9511
9789
|
DeviceInput,
|
|
9512
9790
|
DeviceView,
|
|
9513
9791
|
Humanize: Humanize2,
|
|
9514
|
-
Launch,
|
|
9792
|
+
Launch: launchModule,
|
|
9515
9793
|
LiveView,
|
|
9516
9794
|
Constants: constants_exports,
|
|
9517
9795
|
Utils,
|
|
@@ -9525,6 +9803,7 @@ var usePlaywrightToolKit = () => {
|
|
|
9525
9803
|
ByPass,
|
|
9526
9804
|
$Internals: { LOG_TEMPLATES, stripAnsi }
|
|
9527
9805
|
};
|
|
9806
|
+
return toolkit;
|
|
9528
9807
|
};
|
|
9529
9808
|
export {
|
|
9530
9809
|
usePlaywrightToolKit
|