@skrillex1224/playwright-toolkit 2.1.220 → 2.1.221
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 +375 -326
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +375 -326
- package/dist/index.js.map +4 -4
- package/index.d.ts +5 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -334,18 +334,18 @@ var fallbackLog = {
|
|
|
334
334
|
error: (...args) => console.error(...args),
|
|
335
335
|
debug: (...args) => console.debug ? console.debug(...args) : console.log(...args)
|
|
336
336
|
};
|
|
337
|
-
var resolveLogMethod = (
|
|
338
|
-
if (
|
|
339
|
-
return
|
|
337
|
+
var resolveLogMethod = (logger14, name) => {
|
|
338
|
+
if (logger14 && typeof logger14[name] === "function") {
|
|
339
|
+
return logger14[name].bind(logger14);
|
|
340
340
|
}
|
|
341
|
-
if (name === "warning" &&
|
|
342
|
-
return
|
|
341
|
+
if (name === "warning" && logger14 && typeof logger14.warn === "function") {
|
|
342
|
+
return logger14.warn.bind(logger14);
|
|
343
343
|
}
|
|
344
344
|
return fallbackLog[name];
|
|
345
345
|
};
|
|
346
346
|
var defaultLogger = null;
|
|
347
|
-
var setDefaultLogger = (
|
|
348
|
-
defaultLogger =
|
|
347
|
+
var setDefaultLogger = (logger14) => {
|
|
348
|
+
defaultLogger = logger14;
|
|
349
349
|
};
|
|
350
350
|
var resolveLogger = (explicitLogger) => {
|
|
351
351
|
if (explicitLogger && typeof explicitLogger.info === "function") {
|
|
@@ -372,8 +372,8 @@ var colorize = (text, color) => {
|
|
|
372
372
|
var createBaseLogger = (prefix = "", explicitLogger) => {
|
|
373
373
|
const name = prefix ? String(prefix) : "";
|
|
374
374
|
const dispatch = (methodName, icon, message, color) => {
|
|
375
|
-
const
|
|
376
|
-
const logFn = resolveLogMethod(
|
|
375
|
+
const logger14 = resolveLogger(explicitLogger);
|
|
376
|
+
const logFn = resolveLogMethod(logger14, methodName);
|
|
377
377
|
const timestamp = colorize(`[${formatTimestamp()}]`, ANSI.gray);
|
|
378
378
|
const line = formatLine(name, icon, message);
|
|
379
379
|
const coloredLine = colorize(line, color);
|
|
@@ -2948,13 +2948,91 @@ var LiveView = {
|
|
|
2948
2948
|
useLiveView
|
|
2949
2949
|
};
|
|
2950
2950
|
|
|
2951
|
-
// src/
|
|
2951
|
+
// src/chaptcha.js
|
|
2952
2952
|
import { v4 as uuidv4 } from "uuid";
|
|
2953
|
+
|
|
2954
|
+
// src/internals/captcha/shared.js
|
|
2955
|
+
var waitForVisible = async (locator, timeout) => {
|
|
2956
|
+
try {
|
|
2957
|
+
await locator.waitFor({
|
|
2958
|
+
state: "visible",
|
|
2959
|
+
timeout
|
|
2960
|
+
});
|
|
2961
|
+
return true;
|
|
2962
|
+
} catch {
|
|
2963
|
+
return false;
|
|
2964
|
+
}
|
|
2965
|
+
};
|
|
2966
|
+
var isAnyCaptchaTextVisible = async (frame, texts, timeout) => {
|
|
2967
|
+
for (const text of texts || []) {
|
|
2968
|
+
if (!text) {
|
|
2969
|
+
continue;
|
|
2970
|
+
}
|
|
2971
|
+
const candidates = [
|
|
2972
|
+
frame.getByText(text, { exact: false }).first(),
|
|
2973
|
+
frame.locator(`text=${text}`).first()
|
|
2974
|
+
];
|
|
2975
|
+
for (const candidate of candidates) {
|
|
2976
|
+
const isVisible = await candidate.isVisible({ timeout }).catch(() => false);
|
|
2977
|
+
if (isVisible) {
|
|
2978
|
+
return true;
|
|
2979
|
+
}
|
|
2980
|
+
}
|
|
2981
|
+
}
|
|
2982
|
+
return false;
|
|
2983
|
+
};
|
|
2984
|
+
var clickCaptchaAction = async (frame, texts, options) => {
|
|
2985
|
+
for (const text of texts || []) {
|
|
2986
|
+
const candidates = [
|
|
2987
|
+
frame.getByText(text, { exact: false }).first(),
|
|
2988
|
+
frame.locator(`text=${text}`).first()
|
|
2989
|
+
];
|
|
2990
|
+
for (const candidate of candidates) {
|
|
2991
|
+
const isVisible = await waitForVisible(candidate, options.actionVisibleTimeoutMs);
|
|
2992
|
+
if (!isVisible) {
|
|
2993
|
+
continue;
|
|
2994
|
+
}
|
|
2995
|
+
await candidate.click();
|
|
2996
|
+
return true;
|
|
2997
|
+
}
|
|
2998
|
+
}
|
|
2999
|
+
return false;
|
|
3000
|
+
};
|
|
3001
|
+
var dragCaptchaWithMouse = async (page, sourceLocator, targetLocator) => {
|
|
3002
|
+
const sourceBox = await sourceLocator.boundingBox();
|
|
3003
|
+
const targetBox = await targetLocator.boundingBox();
|
|
3004
|
+
if (!sourceBox || !targetBox) {
|
|
3005
|
+
throw new Error("Unable to resolve captcha drag coordinates.");
|
|
3006
|
+
}
|
|
3007
|
+
const startX = sourceBox.x + sourceBox.width / 2;
|
|
3008
|
+
const startY = sourceBox.y + sourceBox.height / 2;
|
|
3009
|
+
const endX = targetBox.x + targetBox.width / 2;
|
|
3010
|
+
const endY = targetBox.y + targetBox.height / 2;
|
|
3011
|
+
const steps = 10;
|
|
3012
|
+
const liftOffsetX = Math.min(18, Math.max(8, sourceBox.width * 0.12));
|
|
3013
|
+
const liftOffsetY = Math.min(12, Math.max(4, sourceBox.height * 0.08));
|
|
3014
|
+
await page.mouse.move(startX, startY, { steps: 8 });
|
|
3015
|
+
await page.waitForTimeout(250);
|
|
3016
|
+
await page.mouse.down();
|
|
3017
|
+
await page.waitForTimeout(350);
|
|
3018
|
+
await page.mouse.move(startX + liftOffsetX, startY + liftOffsetY, { steps: 6 });
|
|
3019
|
+
await page.waitForTimeout(250);
|
|
3020
|
+
for (let step = 1; step <= steps; step++) {
|
|
3021
|
+
const progress = step / steps;
|
|
3022
|
+
const easedProgress = 1 - (1 - progress) * (1 - progress);
|
|
3023
|
+
const currentX = startX + liftOffsetX + (endX - startX - liftOffsetX) * easedProgress;
|
|
3024
|
+
const currentY = startY + liftOffsetY + (endY - startY - liftOffsetY) * easedProgress;
|
|
3025
|
+
await page.mouse.move(currentX, currentY, { steps: 2 });
|
|
3026
|
+
await page.waitForTimeout(90);
|
|
3027
|
+
}
|
|
3028
|
+
await page.waitForTimeout(100);
|
|
3029
|
+
await page.mouse.up();
|
|
3030
|
+
await page.waitForTimeout(100);
|
|
3031
|
+
};
|
|
3032
|
+
|
|
3033
|
+
// src/internals/captcha/bytedance.js
|
|
2953
3034
|
var logger9 = createInternalLogger("Captcha");
|
|
2954
|
-
var DEFAULT_BYTEDANCE_CAPTCHA_TOKEN = "eKJvBfwfN0YRav0-VD_44E2VBSfm7l0YtddUQ7cFySI";
|
|
2955
3035
|
var DEFAULT_BYTEDANCE_CAPTCHA_OPTIONS = Object.freeze({
|
|
2956
|
-
token: DEFAULT_BYTEDANCE_CAPTCHA_TOKEN,
|
|
2957
|
-
apiUrl: "https://api.jfbym.com/api/YmServer/customApi",
|
|
2958
3036
|
apiType: "31234",
|
|
2959
3037
|
maxRetries: 3,
|
|
2960
3038
|
containerSelector: "#captcha_container",
|
|
@@ -2991,128 +3069,6 @@ var DEFAULT_BYTEDANCE_CAPTCHA_OPTIONS = Object.freeze({
|
|
|
2991
3069
|
retryDelayBaseMs: 2e3,
|
|
2992
3070
|
retryDelayStepMs: 1e3
|
|
2993
3071
|
});
|
|
2994
|
-
function useCaptchaMonitor(page, options) {
|
|
2995
|
-
const { domSelector, urlPattern, onDetected } = options;
|
|
2996
|
-
if (!domSelector && !urlPattern) {
|
|
2997
|
-
throw new Error("[CaptchaMonitor] \u5FC5\u987B\u63D0\u4F9B domSelector \u6216 urlPattern\u3002");
|
|
2998
|
-
}
|
|
2999
|
-
if (!onDetected || typeof onDetected !== "function") {
|
|
3000
|
-
throw new Error("[CaptchaMonitor] onDetected \u5FC5\u987B\u662F\u51FD\u6570\u3002");
|
|
3001
|
-
}
|
|
3002
|
-
let isStopped = false;
|
|
3003
|
-
let isHandling = false;
|
|
3004
|
-
let frameHandler = null;
|
|
3005
|
-
let exposedFunctionName = null;
|
|
3006
|
-
const triggerDetected = async () => {
|
|
3007
|
-
if (isStopped || isHandling) return;
|
|
3008
|
-
isHandling = true;
|
|
3009
|
-
try {
|
|
3010
|
-
await onDetected();
|
|
3011
|
-
} finally {
|
|
3012
|
-
isHandling = false;
|
|
3013
|
-
}
|
|
3014
|
-
};
|
|
3015
|
-
const cleanupFns = [];
|
|
3016
|
-
if (domSelector) {
|
|
3017
|
-
exposedFunctionName = `__c_d_${uuidv4().replace(/-/g, "_")}`;
|
|
3018
|
-
const cleanerName = `__c_cleaner_${uuidv4().replace(/-/g, "_")}`;
|
|
3019
|
-
page.exposeFunction(exposedFunctionName, triggerDetected).catch(() => {
|
|
3020
|
-
});
|
|
3021
|
-
page.addInitScript(({ selector, callbackName, cleanerName: cleanupName }) => {
|
|
3022
|
-
(() => {
|
|
3023
|
-
let observer = null;
|
|
3024
|
-
const checkAndReport = () => {
|
|
3025
|
-
const element = document.querySelector(selector);
|
|
3026
|
-
if (!element) {
|
|
3027
|
-
return false;
|
|
3028
|
-
}
|
|
3029
|
-
if (window[callbackName]) {
|
|
3030
|
-
window[callbackName]();
|
|
3031
|
-
}
|
|
3032
|
-
return true;
|
|
3033
|
-
};
|
|
3034
|
-
checkAndReport();
|
|
3035
|
-
observer = new MutationObserver((mutations) => {
|
|
3036
|
-
const shouldCheck = mutations.some((mutation) => mutation.addedNodes.length > 0);
|
|
3037
|
-
if (shouldCheck && observer) {
|
|
3038
|
-
checkAndReport();
|
|
3039
|
-
}
|
|
3040
|
-
});
|
|
3041
|
-
const mountObserver = () => {
|
|
3042
|
-
const target = document.documentElement;
|
|
3043
|
-
if (target && observer) {
|
|
3044
|
-
observer.observe(target, { childList: true, subtree: true });
|
|
3045
|
-
}
|
|
3046
|
-
};
|
|
3047
|
-
if (document.readyState === "loading") {
|
|
3048
|
-
window.addEventListener("DOMContentLoaded", mountObserver);
|
|
3049
|
-
} else {
|
|
3050
|
-
mountObserver();
|
|
3051
|
-
}
|
|
3052
|
-
window[cleanupName] = () => {
|
|
3053
|
-
if (observer) {
|
|
3054
|
-
observer.disconnect();
|
|
3055
|
-
observer = null;
|
|
3056
|
-
}
|
|
3057
|
-
};
|
|
3058
|
-
})();
|
|
3059
|
-
}, { selector: domSelector, callbackName: exposedFunctionName, cleanerName });
|
|
3060
|
-
logger9.success("useCaptchaMonitor", `DOM \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${domSelector}`);
|
|
3061
|
-
cleanupFns.push(async () => {
|
|
3062
|
-
try {
|
|
3063
|
-
await page.evaluate((name) => {
|
|
3064
|
-
if (window[name]) {
|
|
3065
|
-
window[name]();
|
|
3066
|
-
delete window[name];
|
|
3067
|
-
}
|
|
3068
|
-
}, cleanerName);
|
|
3069
|
-
} catch {
|
|
3070
|
-
}
|
|
3071
|
-
});
|
|
3072
|
-
}
|
|
3073
|
-
if (urlPattern) {
|
|
3074
|
-
frameHandler = async (frame) => {
|
|
3075
|
-
if (frame !== page.mainFrame()) {
|
|
3076
|
-
return;
|
|
3077
|
-
}
|
|
3078
|
-
const currentUrl = page.url();
|
|
3079
|
-
if (currentUrl.includes(urlPattern)) {
|
|
3080
|
-
await triggerDetected();
|
|
3081
|
-
}
|
|
3082
|
-
};
|
|
3083
|
-
page.on("framenavigated", frameHandler);
|
|
3084
|
-
logger9.success("useCaptchaMonitor", `URL \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${urlPattern}`);
|
|
3085
|
-
cleanupFns.push(async () => {
|
|
3086
|
-
page.off("framenavigated", frameHandler);
|
|
3087
|
-
});
|
|
3088
|
-
}
|
|
3089
|
-
return {
|
|
3090
|
-
stop: async () => {
|
|
3091
|
-
logger9.info("\u6B63\u5728\u505C\u6B62\u9A8C\u8BC1\u7801\u76D1\u63A7...");
|
|
3092
|
-
for (const fn of cleanupFns) {
|
|
3093
|
-
await fn();
|
|
3094
|
-
}
|
|
3095
|
-
isStopped = true;
|
|
3096
|
-
}
|
|
3097
|
-
};
|
|
3098
|
-
}
|
|
3099
|
-
var callCaptchaRecognitionApi = async (imageBase64, { apiUrl, apiType, token }) => {
|
|
3100
|
-
const response = await fetch(apiUrl, {
|
|
3101
|
-
method: "POST",
|
|
3102
|
-
headers: {
|
|
3103
|
-
"Content-Type": "application/json"
|
|
3104
|
-
},
|
|
3105
|
-
body: JSON.stringify({
|
|
3106
|
-
type: apiType,
|
|
3107
|
-
image: imageBase64,
|
|
3108
|
-
token
|
|
3109
|
-
})
|
|
3110
|
-
});
|
|
3111
|
-
if (!response.ok) {
|
|
3112
|
-
throw new Error(`Captcha API request failed with status ${response.status}`);
|
|
3113
|
-
}
|
|
3114
|
-
return await response.json();
|
|
3115
|
-
};
|
|
3116
3072
|
var extractCaptchaSerialNumbers = (apiResponse) => {
|
|
3117
3073
|
const serialNumbers = apiResponse?.data?.data?.serial_number;
|
|
3118
3074
|
if (!Array.isArray(serialNumbers)) {
|
|
@@ -3120,76 +3076,6 @@ var extractCaptchaSerialNumbers = (apiResponse) => {
|
|
|
3120
3076
|
}
|
|
3121
3077
|
return serialNumbers.map((value) => Number(value)).filter((value) => Number.isInteger(value) && value >= 0);
|
|
3122
3078
|
};
|
|
3123
|
-
var waitForVisible = async (locator, timeout) => {
|
|
3124
|
-
try {
|
|
3125
|
-
await locator.waitFor({
|
|
3126
|
-
state: "visible",
|
|
3127
|
-
timeout
|
|
3128
|
-
});
|
|
3129
|
-
return true;
|
|
3130
|
-
} catch {
|
|
3131
|
-
return false;
|
|
3132
|
-
}
|
|
3133
|
-
};
|
|
3134
|
-
var isAnyCaptchaTextVisible = async (frame, texts, timeout) => {
|
|
3135
|
-
for (const text of texts || []) {
|
|
3136
|
-
if (!text) {
|
|
3137
|
-
continue;
|
|
3138
|
-
}
|
|
3139
|
-
const candidates = [
|
|
3140
|
-
frame.getByText(text, { exact: false }).first(),
|
|
3141
|
-
frame.locator(`text=${text}`).first()
|
|
3142
|
-
];
|
|
3143
|
-
for (const candidate of candidates) {
|
|
3144
|
-
const isVisible = await candidate.isVisible({ timeout }).catch(() => false);
|
|
3145
|
-
if (isVisible) {
|
|
3146
|
-
return true;
|
|
3147
|
-
}
|
|
3148
|
-
}
|
|
3149
|
-
}
|
|
3150
|
-
return false;
|
|
3151
|
-
};
|
|
3152
|
-
var waitForCaptchaChallengeReady = async (page, frame, options) => {
|
|
3153
|
-
const deadline = Date.now() + options.challengeReadyTimeoutMs;
|
|
3154
|
-
let refreshDeadline = Date.now() + options.challengeReadyRefreshTimeoutMs;
|
|
3155
|
-
let hasSeenLoading = false;
|
|
3156
|
-
while (Date.now() < deadline) {
|
|
3157
|
-
const isLoadingVisible = await isAnyCaptchaTextVisible(
|
|
3158
|
-
frame,
|
|
3159
|
-
options.loadingTexts,
|
|
3160
|
-
options.loadingIndicatorVisibleTimeoutMs
|
|
3161
|
-
);
|
|
3162
|
-
const hasErrorTextVisible = await isAnyCaptchaTextVisible(
|
|
3163
|
-
frame,
|
|
3164
|
-
options.errorTexts,
|
|
3165
|
-
options.loadingIndicatorVisibleTimeoutMs
|
|
3166
|
-
);
|
|
3167
|
-
hasSeenLoading = hasSeenLoading || isLoadingVisible;
|
|
3168
|
-
const sourceImages = frame.locator(options.sourceImageSelector);
|
|
3169
|
-
const imageCount = await sourceImages.count().catch(() => 0);
|
|
3170
|
-
const hasVisibleSourceImage = imageCount > 0 ? await sourceImages.first().isVisible({ timeout: options.loadingIndicatorVisibleTimeoutMs }).catch(() => false) : false;
|
|
3171
|
-
if (!isLoadingVisible && hasVisibleSourceImage) {
|
|
3172
|
-
logger9.info(hasSeenLoading ? "\u9A8C\u8BC1\u7801\u56FE\u7247\u5DF2\u52A0\u8F7D\u5B8C\u6210\u3002" : "\u9A8C\u8BC1\u7801\u56FE\u7247\u5DF2\u5C31\u7EEA\u3002");
|
|
3173
|
-
return;
|
|
3174
|
-
}
|
|
3175
|
-
if (hasErrorTextVisible) {
|
|
3176
|
-
logger9.warn("\u9A8C\u8BC1\u7801\u9762\u677F\u51FA\u73B0\u7F51\u7EDC\u5F02\u5E38\u6587\u6848\uFF0C\u5C1D\u8BD5\u7ACB\u5373\u5237\u65B0\u9898\u76EE\u3002");
|
|
3177
|
-
await refreshCaptcha(page, frame, options);
|
|
3178
|
-
refreshDeadline = Date.now() + options.challengeReadyRefreshTimeoutMs;
|
|
3179
|
-
hasSeenLoading = false;
|
|
3180
|
-
continue;
|
|
3181
|
-
}
|
|
3182
|
-
if (!hasVisibleSourceImage && Date.now() >= refreshDeadline) {
|
|
3183
|
-
logger9.warn(`\u9A8C\u8BC1\u7801\u56FE\u7247\u8D85\u8FC7 ${options.challengeReadyRefreshTimeoutMs}ms \u4ECD\u672A\u51FA\u73B0\uFF0C\u5C1D\u8BD5\u5237\u65B0\u9898\u76EE\u3002`);
|
|
3184
|
-
await refreshCaptcha(page, frame, options);
|
|
3185
|
-
refreshDeadline = Date.now() + options.challengeReadyRefreshTimeoutMs;
|
|
3186
|
-
hasSeenLoading = false;
|
|
3187
|
-
continue;
|
|
3188
|
-
}
|
|
3189
|
-
await page.waitForTimeout(options.challengeReadyPollMs);
|
|
3190
|
-
}
|
|
3191
|
-
throw new Error("Captcha challenge is still loading and did not become ready in time.");
|
|
3192
|
-
};
|
|
3193
3079
|
var resolveContentFrame = async (page, iframeLocator, options) => {
|
|
3194
3080
|
for (let attempt = 1; attempt <= options.contentFrameResolveRetries; attempt++) {
|
|
3195
3081
|
const iframeHandle = await iframeLocator.elementHandle();
|
|
@@ -3236,22 +3122,14 @@ var getVerifycenterCaptchaContext = async (page, options) => {
|
|
|
3236
3122
|
}
|
|
3237
3123
|
return { iframeLocator, frame };
|
|
3238
3124
|
};
|
|
3239
|
-
var
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
];
|
|
3245
|
-
for (const candidate of candidates) {
|
|
3246
|
-
const isVisible = await waitForVisible(candidate, options.actionVisibleTimeoutMs);
|
|
3247
|
-
if (!isVisible) {
|
|
3248
|
-
continue;
|
|
3249
|
-
}
|
|
3250
|
-
await candidate.click();
|
|
3251
|
-
return true;
|
|
3252
|
-
}
|
|
3125
|
+
var refreshCaptcha = async (page, frame, options) => {
|
|
3126
|
+
const clicked = await clickCaptchaAction(frame, options.refreshTexts, options).catch(() => false);
|
|
3127
|
+
if (!clicked) {
|
|
3128
|
+
logger9.warn("Refresh button not found.");
|
|
3129
|
+
return false;
|
|
3253
3130
|
}
|
|
3254
|
-
|
|
3131
|
+
await page.waitForTimeout(options.refreshWaitMs);
|
|
3132
|
+
return true;
|
|
3255
3133
|
};
|
|
3256
3134
|
var findCaptchaDropTarget = async (frame, options) => {
|
|
3257
3135
|
for (const text of options.dropTargetTexts) {
|
|
@@ -3268,47 +3146,52 @@ var findCaptchaDropTarget = async (frame, options) => {
|
|
|
3268
3146
|
}
|
|
3269
3147
|
return null;
|
|
3270
3148
|
};
|
|
3271
|
-
var
|
|
3272
|
-
const
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3149
|
+
var waitForCaptchaChallengeReady = async (page, frame, options) => {
|
|
3150
|
+
const deadline = Date.now() + options.challengeReadyTimeoutMs;
|
|
3151
|
+
let refreshDeadline = Date.now() + options.challengeReadyRefreshTimeoutMs;
|
|
3152
|
+
let hasSeenLoading = false;
|
|
3153
|
+
while (Date.now() < deadline) {
|
|
3154
|
+
const isLoadingVisible = await isAnyCaptchaTextVisible(
|
|
3155
|
+
frame,
|
|
3156
|
+
options.loadingTexts,
|
|
3157
|
+
options.loadingIndicatorVisibleTimeoutMs
|
|
3158
|
+
);
|
|
3159
|
+
const hasErrorTextVisible = await isAnyCaptchaTextVisible(
|
|
3160
|
+
frame,
|
|
3161
|
+
options.errorTexts,
|
|
3162
|
+
options.loadingIndicatorVisibleTimeoutMs
|
|
3163
|
+
);
|
|
3164
|
+
hasSeenLoading = hasSeenLoading || isLoadingVisible;
|
|
3165
|
+
const sourceImages = frame.locator(options.sourceImageSelector);
|
|
3166
|
+
const imageCount = await sourceImages.count().catch(() => 0);
|
|
3167
|
+
const hasVisibleSourceImage = imageCount > 0 ? await sourceImages.first().isVisible({ timeout: options.loadingIndicatorVisibleTimeoutMs }).catch(() => false) : false;
|
|
3168
|
+
if (!isLoadingVisible && hasVisibleSourceImage) {
|
|
3169
|
+
logger9.info(hasSeenLoading ? "\u9A8C\u8BC1\u7801\u56FE\u7247\u5DF2\u52A0\u8F7D\u5B8C\u6210\u3002" : "\u9A8C\u8BC1\u7801\u56FE\u7247\u5DF2\u5C31\u7EEA\u3002");
|
|
3170
|
+
return;
|
|
3171
|
+
}
|
|
3172
|
+
if (hasErrorTextVisible) {
|
|
3173
|
+
logger9.warn("\u9A8C\u8BC1\u7801\u9762\u677F\u51FA\u73B0\u7F51\u7EDC\u5F02\u5E38\u6587\u6848\uFF0C\u5C1D\u8BD5\u7ACB\u5373\u5237\u65B0\u9898\u76EE\u3002");
|
|
3174
|
+
await refreshCaptcha(page, frame, options);
|
|
3175
|
+
refreshDeadline = Date.now() + options.challengeReadyRefreshTimeoutMs;
|
|
3176
|
+
hasSeenLoading = false;
|
|
3177
|
+
continue;
|
|
3178
|
+
}
|
|
3179
|
+
if (!hasVisibleSourceImage && Date.now() >= refreshDeadline) {
|
|
3180
|
+
logger9.warn(`\u9A8C\u8BC1\u7801\u56FE\u7247\u8D85\u8FC7 ${options.challengeReadyRefreshTimeoutMs}ms \u4ECD\u672A\u51FA\u73B0\uFF0C\u5C1D\u8BD5\u5237\u65B0\u9898\u76EE\u3002`);
|
|
3181
|
+
await refreshCaptcha(page, frame, options);
|
|
3182
|
+
refreshDeadline = Date.now() + options.challengeReadyRefreshTimeoutMs;
|
|
3183
|
+
hasSeenLoading = false;
|
|
3184
|
+
continue;
|
|
3185
|
+
}
|
|
3186
|
+
await page.waitForTimeout(options.challengeReadyPollMs);
|
|
3297
3187
|
}
|
|
3298
|
-
|
|
3299
|
-
await page.mouse.up();
|
|
3300
|
-
await page.waitForTimeout(100);
|
|
3188
|
+
throw new Error("Captcha challenge is still loading and did not become ready in time.");
|
|
3301
3189
|
};
|
|
3302
|
-
|
|
3303
|
-
const
|
|
3304
|
-
if (
|
|
3305
|
-
|
|
3306
|
-
return false;
|
|
3190
|
+
async function solveCaptcha(page, options = {}, dependencies = {}) {
|
|
3191
|
+
const { callCaptchaRecognitionApi: callCaptchaRecognitionApi2 } = dependencies;
|
|
3192
|
+
if (typeof callCaptchaRecognitionApi2 !== "function") {
|
|
3193
|
+
throw new Error("[Captcha] \u7F3A\u5C11\u901A\u7528\u8BC6\u522B\u8BF7\u6C42\u51FD\u6570 callCaptchaRecognitionApi\u3002");
|
|
3307
3194
|
}
|
|
3308
|
-
await page.waitForTimeout(options.refreshWaitMs);
|
|
3309
|
-
return true;
|
|
3310
|
-
};
|
|
3311
|
-
async function solveBytedanceCaptcha(page, options = {}) {
|
|
3312
3195
|
const config = {
|
|
3313
3196
|
...DEFAULT_BYTEDANCE_CAPTCHA_OPTIONS,
|
|
3314
3197
|
...options
|
|
@@ -3317,6 +3200,7 @@ async function solveBytedanceCaptcha(page, options = {}) {
|
|
|
3317
3200
|
logger9.warn("\u7F3A\u5C11\u9A8C\u8BC1\u7801 token\uFF0C\u8DF3\u8FC7\u81EA\u52A8\u8BC6\u522B\u3002");
|
|
3318
3201
|
return false;
|
|
3319
3202
|
}
|
|
3203
|
+
logger9.info("\u5F53\u524D\u4F7F\u7528\u672Ctool\u2014\u2014\u6D4B\u8BD5\u7248\u672C");
|
|
3320
3204
|
for (let attempt = 1; attempt <= config.maxRetries; attempt++) {
|
|
3321
3205
|
logger9.info(`\u5F00\u59CB\u7B2C ${attempt}/${config.maxRetries} \u6B21 verifycenter \u9A8C\u8BC1\u7801\u8BC6\u522B\u3002`);
|
|
3322
3206
|
try {
|
|
@@ -3329,10 +3213,12 @@ async function solveBytedanceCaptcha(page, options = {}) {
|
|
|
3329
3213
|
await waitForCaptchaChallengeReady(page, frame, config);
|
|
3330
3214
|
await page.waitForTimeout(config.recognitionDelayMs);
|
|
3331
3215
|
const screenshotBuffer = await iframeLocator.screenshot();
|
|
3332
|
-
const apiResponse = await
|
|
3333
|
-
|
|
3334
|
-
config
|
|
3335
|
-
|
|
3216
|
+
const apiResponse = await callCaptchaRecognitionApi2({
|
|
3217
|
+
apiUrl: config.apiUrl,
|
|
3218
|
+
type: config.apiType,
|
|
3219
|
+
image: screenshotBuffer.toString("base64"),
|
|
3220
|
+
token: config.token
|
|
3221
|
+
});
|
|
3336
3222
|
const serialNumbers = extractCaptchaSerialNumbers(apiResponse);
|
|
3337
3223
|
if (apiResponse?.code !== config.recognitionSuccessCode || serialNumbers.length === 0) {
|
|
3338
3224
|
logger9.warn(
|
|
@@ -3388,15 +3274,178 @@ async function solveBytedanceCaptcha(page, options = {}) {
|
|
|
3388
3274
|
logger9.error(`\u91CD\u8BD5 ${config.maxRetries} \u6B21\u540E\uFF0C\u9A8C\u8BC1\u7801\u4ECD\u672A\u8BC6\u522B\u6210\u529F\u3002`);
|
|
3389
3275
|
return false;
|
|
3390
3276
|
}
|
|
3277
|
+
var sloveCaptcha = solveCaptcha;
|
|
3278
|
+
|
|
3279
|
+
// src/chaptcha.js
|
|
3280
|
+
var logger10 = createInternalLogger("Captcha");
|
|
3281
|
+
var DEFAULT_CAPTCHA_RECOGNITION_OPTIONS = Object.freeze({
|
|
3282
|
+
token: "eKJvBfwfN0YRav0-VD_44E2VBSfm7l0YtddUQ7cFySI",
|
|
3283
|
+
apiUrl: "https://api.jfbym.com/api/YmServer/customApi"
|
|
3284
|
+
});
|
|
3285
|
+
var CAPTCHA_STRATEGIES = Object.freeze({
|
|
3286
|
+
bytedance: {
|
|
3287
|
+
sloveCaptcha
|
|
3288
|
+
}
|
|
3289
|
+
});
|
|
3290
|
+
var mergeDefinedOptions = (...sources) => {
|
|
3291
|
+
const merged = {};
|
|
3292
|
+
for (const source of sources) {
|
|
3293
|
+
for (const [key, value] of Object.entries(source || {})) {
|
|
3294
|
+
if (value !== void 0) {
|
|
3295
|
+
merged[key] = value;
|
|
3296
|
+
}
|
|
3297
|
+
}
|
|
3298
|
+
}
|
|
3299
|
+
return merged;
|
|
3300
|
+
};
|
|
3301
|
+
function useCaptchaMonitor(page, options) {
|
|
3302
|
+
const { domSelector, urlPattern, onDetected } = options;
|
|
3303
|
+
if (!domSelector && !urlPattern) {
|
|
3304
|
+
throw new Error("[CaptchaMonitor] \u5FC5\u987B\u63D0\u4F9B domSelector \u6216 urlPattern\u3002");
|
|
3305
|
+
}
|
|
3306
|
+
if (!onDetected || typeof onDetected !== "function") {
|
|
3307
|
+
throw new Error("[CaptchaMonitor] onDetected \u5FC5\u987B\u662F\u51FD\u6570\u3002");
|
|
3308
|
+
}
|
|
3309
|
+
let isStopped = false;
|
|
3310
|
+
let isHandling = false;
|
|
3311
|
+
let frameHandler = null;
|
|
3312
|
+
let exposedFunctionName = null;
|
|
3313
|
+
const triggerDetected = async () => {
|
|
3314
|
+
if (isStopped || isHandling) return;
|
|
3315
|
+
isHandling = true;
|
|
3316
|
+
try {
|
|
3317
|
+
await onDetected();
|
|
3318
|
+
} finally {
|
|
3319
|
+
isHandling = false;
|
|
3320
|
+
}
|
|
3321
|
+
};
|
|
3322
|
+
const cleanupFns = [];
|
|
3323
|
+
if (domSelector) {
|
|
3324
|
+
exposedFunctionName = `__c_d_${uuidv4().replace(/-/g, "_")}`;
|
|
3325
|
+
const cleanerName = `__c_cleaner_${uuidv4().replace(/-/g, "_")}`;
|
|
3326
|
+
page.exposeFunction(exposedFunctionName, triggerDetected).catch(() => {
|
|
3327
|
+
});
|
|
3328
|
+
page.addInitScript(({ selector, callbackName, cleanerName: cleanupName }) => {
|
|
3329
|
+
(() => {
|
|
3330
|
+
let observer = null;
|
|
3331
|
+
const checkAndReport = () => {
|
|
3332
|
+
const element = document.querySelector(selector);
|
|
3333
|
+
if (!element) {
|
|
3334
|
+
return false;
|
|
3335
|
+
}
|
|
3336
|
+
if (window[callbackName]) {
|
|
3337
|
+
window[callbackName]();
|
|
3338
|
+
}
|
|
3339
|
+
return true;
|
|
3340
|
+
};
|
|
3341
|
+
checkAndReport();
|
|
3342
|
+
observer = new MutationObserver((mutations) => {
|
|
3343
|
+
const shouldCheck = mutations.some((mutation) => mutation.addedNodes.length > 0);
|
|
3344
|
+
if (shouldCheck && observer) {
|
|
3345
|
+
checkAndReport();
|
|
3346
|
+
}
|
|
3347
|
+
});
|
|
3348
|
+
const mountObserver = () => {
|
|
3349
|
+
const target = document.documentElement;
|
|
3350
|
+
if (target && observer) {
|
|
3351
|
+
observer.observe(target, { childList: true, subtree: true });
|
|
3352
|
+
}
|
|
3353
|
+
};
|
|
3354
|
+
if (document.readyState === "loading") {
|
|
3355
|
+
window.addEventListener("DOMContentLoaded", mountObserver);
|
|
3356
|
+
} else {
|
|
3357
|
+
mountObserver();
|
|
3358
|
+
}
|
|
3359
|
+
window[cleanupName] = () => {
|
|
3360
|
+
if (observer) {
|
|
3361
|
+
observer.disconnect();
|
|
3362
|
+
observer = null;
|
|
3363
|
+
}
|
|
3364
|
+
};
|
|
3365
|
+
})();
|
|
3366
|
+
}, { selector: domSelector, callbackName: exposedFunctionName, cleanerName });
|
|
3367
|
+
logger10.success("useCaptchaMonitor", `DOM \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${domSelector}`);
|
|
3368
|
+
cleanupFns.push(async () => {
|
|
3369
|
+
try {
|
|
3370
|
+
await page.evaluate((name) => {
|
|
3371
|
+
if (window[name]) {
|
|
3372
|
+
window[name]();
|
|
3373
|
+
delete window[name];
|
|
3374
|
+
}
|
|
3375
|
+
}, cleanerName);
|
|
3376
|
+
} catch {
|
|
3377
|
+
}
|
|
3378
|
+
});
|
|
3379
|
+
}
|
|
3380
|
+
if (urlPattern) {
|
|
3381
|
+
frameHandler = async (frame) => {
|
|
3382
|
+
if (frame !== page.mainFrame()) {
|
|
3383
|
+
return;
|
|
3384
|
+
}
|
|
3385
|
+
const currentUrl = page.url();
|
|
3386
|
+
if (currentUrl.includes(urlPattern)) {
|
|
3387
|
+
await triggerDetected();
|
|
3388
|
+
}
|
|
3389
|
+
};
|
|
3390
|
+
page.on("framenavigated", frameHandler);
|
|
3391
|
+
logger10.success("useCaptchaMonitor", `URL \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${urlPattern}`);
|
|
3392
|
+
cleanupFns.push(async () => {
|
|
3393
|
+
page.off("framenavigated", frameHandler);
|
|
3394
|
+
});
|
|
3395
|
+
}
|
|
3396
|
+
return {
|
|
3397
|
+
stop: async () => {
|
|
3398
|
+
logger10.info("\u6B63\u5728\u505C\u6B62\u9A8C\u8BC1\u7801\u76D1\u63A7...");
|
|
3399
|
+
for (const fn of cleanupFns) {
|
|
3400
|
+
await fn();
|
|
3401
|
+
}
|
|
3402
|
+
isStopped = true;
|
|
3403
|
+
}
|
|
3404
|
+
};
|
|
3405
|
+
}
|
|
3406
|
+
var callCaptchaRecognitionApi = async (requestParams = {}) => {
|
|
3407
|
+
const { apiUrl, ...payload } = mergeDefinedOptions(
|
|
3408
|
+
DEFAULT_CAPTCHA_RECOGNITION_OPTIONS,
|
|
3409
|
+
requestParams
|
|
3410
|
+
);
|
|
3411
|
+
if (!apiUrl) {
|
|
3412
|
+
throw new Error("[Captcha] \u7F3A\u5C11\u9A8C\u8BC1\u7801\u8BC6\u522B\u63A5\u53E3\u5730\u5740 apiUrl\u3002");
|
|
3413
|
+
}
|
|
3414
|
+
const response = await fetch(apiUrl, {
|
|
3415
|
+
method: "POST",
|
|
3416
|
+
headers: {
|
|
3417
|
+
"Content-Type": "application/json"
|
|
3418
|
+
},
|
|
3419
|
+
body: JSON.stringify(payload)
|
|
3420
|
+
});
|
|
3421
|
+
if (!response.ok) {
|
|
3422
|
+
throw new Error(`Captcha API request failed with status ${response.status}`);
|
|
3423
|
+
}
|
|
3424
|
+
return await response.json();
|
|
3425
|
+
};
|
|
3426
|
+
async function solveCaptchaWithStrategy(strategyName, page, options = {}) {
|
|
3427
|
+
const strategy = CAPTCHA_STRATEGIES[strategyName];
|
|
3428
|
+
if (!strategy?.sloveCaptcha) {
|
|
3429
|
+
throw new Error(`[Captcha] \u672A\u627E\u5230\u9A8C\u8BC1\u7801\u7B56\u7565\uFF1A${strategyName}`);
|
|
3430
|
+
}
|
|
3431
|
+
const resolvedOptions = mergeDefinedOptions(
|
|
3432
|
+
DEFAULT_CAPTCHA_RECOGNITION_OPTIONS,
|
|
3433
|
+
options
|
|
3434
|
+
);
|
|
3435
|
+
return strategy.sloveCaptcha(page, resolvedOptions, {
|
|
3436
|
+
callCaptchaRecognitionApi,
|
|
3437
|
+
logger: logger10
|
|
3438
|
+
});
|
|
3439
|
+
}
|
|
3391
3440
|
var Captcha = {
|
|
3392
3441
|
useCaptchaMonitor,
|
|
3393
|
-
|
|
3442
|
+
solveCaptchaWithStrategy
|
|
3394
3443
|
};
|
|
3395
3444
|
|
|
3396
3445
|
// src/mutation.js
|
|
3397
3446
|
import { createHash } from "node:crypto";
|
|
3398
3447
|
import { v4 as uuidv42 } from "uuid";
|
|
3399
|
-
var
|
|
3448
|
+
var logger11 = createInternalLogger("Mutation");
|
|
3400
3449
|
var MUTATION_MONITOR_MODE = Object.freeze({
|
|
3401
3450
|
Added: "added",
|
|
3402
3451
|
Changed: "changed",
|
|
@@ -3429,14 +3478,14 @@ var Mutation = {
|
|
|
3429
3478
|
const stableTime = options.stableTime ?? 5 * 1e3;
|
|
3430
3479
|
const timeout = options.timeout ?? 120 * 1e3;
|
|
3431
3480
|
const onMutation = options.onMutation;
|
|
3432
|
-
|
|
3481
|
+
logger11.start("waitForStable", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, \u7A33\u5B9A\u65F6\u95F4=${stableTime}ms`);
|
|
3433
3482
|
if (initialTimeout > 0) {
|
|
3434
3483
|
const selectorQuery = selectorList.join(",");
|
|
3435
3484
|
try {
|
|
3436
3485
|
await page.waitForSelector(selectorQuery, { timeout: initialTimeout });
|
|
3437
|
-
|
|
3486
|
+
logger11.info(`waitForStable \u5DF2\u68C0\u6D4B\u5230\u5143\u7D20: ${selectorQuery}`);
|
|
3438
3487
|
} catch (e) {
|
|
3439
|
-
|
|
3488
|
+
logger11.warning(`waitForStable \u521D\u59CB\u7B49\u5F85\u8D85\u65F6 (${initialTimeout}ms): ${selectorQuery}`);
|
|
3440
3489
|
throw e;
|
|
3441
3490
|
}
|
|
3442
3491
|
}
|
|
@@ -3452,7 +3501,7 @@ var Mutation = {
|
|
|
3452
3501
|
return "__CONTINUE__";
|
|
3453
3502
|
}
|
|
3454
3503
|
});
|
|
3455
|
-
|
|
3504
|
+
logger11.info("waitForStable \u5DF2\u542F\u7528 onMutation \u56DE\u8C03");
|
|
3456
3505
|
} catch (e) {
|
|
3457
3506
|
}
|
|
3458
3507
|
}
|
|
@@ -3567,9 +3616,9 @@ var Mutation = {
|
|
|
3567
3616
|
{ selectorList, stableTime, timeout, callbackName, hasCallback: !!onMutation }
|
|
3568
3617
|
);
|
|
3569
3618
|
if (result.mutationCount === 0 && result.stableTime === 0) {
|
|
3570
|
-
|
|
3619
|
+
logger11.warning("waitForStable \u672A\u627E\u5230\u53EF\u76D1\u63A7\u7684\u5143\u7D20");
|
|
3571
3620
|
}
|
|
3572
|
-
|
|
3621
|
+
logger11.success("waitForStable", `DOM \u7A33\u5B9A, \u603B\u5171 ${result.mutationCount} \u6B21\u53D8\u5316${result.wasPaused ? ", \u66FE\u6682\u505C\u8BA1\u65F6" : ""}`);
|
|
3573
3622
|
return result;
|
|
3574
3623
|
},
|
|
3575
3624
|
/**
|
|
@@ -3741,22 +3790,22 @@ var Mutation = {
|
|
|
3741
3790
|
return "__CONTINUE__";
|
|
3742
3791
|
}
|
|
3743
3792
|
};
|
|
3744
|
-
|
|
3793
|
+
logger11.start(
|
|
3745
3794
|
"waitForStableAcrossRoots",
|
|
3746
3795
|
`\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668(\u8DE8 root), \u7A33\u5B9A\u65F6\u95F4=${waitForStableTime}ms`
|
|
3747
3796
|
);
|
|
3748
3797
|
if (initialTimeout > 0) {
|
|
3749
3798
|
try {
|
|
3750
3799
|
await page.waitForSelector(selectorQuery, { timeout: initialTimeout });
|
|
3751
|
-
|
|
3800
|
+
logger11.info(`waitForStableAcrossRoots \u5DF2\u68C0\u6D4B\u5230\u5143\u7D20: ${selectorQuery}`);
|
|
3752
3801
|
} catch (e) {
|
|
3753
|
-
|
|
3802
|
+
logger11.warning(`waitForStableAcrossRoots \u521D\u59CB\u7B49\u5F85\u8D85\u65F6 (${initialTimeout}ms): ${selectorQuery}`);
|
|
3754
3803
|
throw e;
|
|
3755
3804
|
}
|
|
3756
3805
|
}
|
|
3757
3806
|
let state = await buildState();
|
|
3758
3807
|
if (!state?.hasMatched) {
|
|
3759
|
-
|
|
3808
|
+
logger11.warning("waitForStableAcrossRoots \u672A\u627E\u5230\u53EF\u76D1\u63A7\u7684\u5143\u7D20");
|
|
3760
3809
|
return { mutationCount: 0, stableTime: 0, wasPaused: false };
|
|
3761
3810
|
}
|
|
3762
3811
|
let mutationCount = 0;
|
|
@@ -3793,7 +3842,7 @@ var Mutation = {
|
|
|
3793
3842
|
if (lastState.snapshotKey !== lastSnapshotKey) {
|
|
3794
3843
|
lastSnapshotKey = lastState.snapshotKey;
|
|
3795
3844
|
mutationCount += 1;
|
|
3796
|
-
|
|
3845
|
+
logger11.info(
|
|
3797
3846
|
`waitForStableAcrossRoots \u53D8\u5316#${mutationCount}, len=${lastState.snapshotLength}, path=${lastState.primaryPath || "unknown"}, preview="${truncate(lastState.text, 120)}"`
|
|
3798
3847
|
);
|
|
3799
3848
|
const signal = await invokeMutationCallback({
|
|
@@ -3806,7 +3855,7 @@ var Mutation = {
|
|
|
3806
3855
|
continue;
|
|
3807
3856
|
}
|
|
3808
3857
|
if (!isPaused && stableSince > 0 && Date.now() - stableSince >= waitForStableTime) {
|
|
3809
|
-
|
|
3858
|
+
logger11.success("waitForStableAcrossRoots", `DOM \u7A33\u5B9A, \u603B\u5171 ${mutationCount} \u6B21\u53D8\u5316${wasPaused ? ", \u66FE\u6682\u505C\u8BA1\u65F6" : ""}`);
|
|
3810
3859
|
return {
|
|
3811
3860
|
mutationCount,
|
|
3812
3861
|
stableTime: waitForStableTime,
|
|
@@ -3833,7 +3882,7 @@ var Mutation = {
|
|
|
3833
3882
|
const onMutation = options.onMutation;
|
|
3834
3883
|
const rawMode = String(options.mode || MUTATION_MONITOR_MODE.Added).toLowerCase();
|
|
3835
3884
|
const mode = [MUTATION_MONITOR_MODE.Added, MUTATION_MONITOR_MODE.Changed, MUTATION_MONITOR_MODE.All].includes(rawMode) ? rawMode : MUTATION_MONITOR_MODE.Added;
|
|
3836
|
-
|
|
3885
|
+
logger11.start("useMonitor", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, mode=${mode}`);
|
|
3837
3886
|
const monitorKey = generateKey("pk_mon");
|
|
3838
3887
|
const callbackName = generateKey("pk_mon_cb");
|
|
3839
3888
|
const cleanerName = generateKey("pk_mon_clean");
|
|
@@ -3976,7 +4025,7 @@ var Mutation = {
|
|
|
3976
4025
|
return total;
|
|
3977
4026
|
};
|
|
3978
4027
|
}, { selectorList, monitorKey, callbackName, cleanerName, hasCallback: !!onMutation, mode });
|
|
3979
|
-
|
|
4028
|
+
logger11.success("useMonitor", "\u76D1\u63A7\u5668\u5DF2\u542F\u52A8");
|
|
3980
4029
|
return {
|
|
3981
4030
|
stop: async () => {
|
|
3982
4031
|
let totalMutations = 0;
|
|
@@ -3989,7 +4038,7 @@ var Mutation = {
|
|
|
3989
4038
|
}, cleanerName);
|
|
3990
4039
|
} catch (e) {
|
|
3991
4040
|
}
|
|
3992
|
-
|
|
4041
|
+
logger11.success("useMonitor.stop", `\u76D1\u63A7\u5DF2\u505C\u6B62, \u5171 ${totalMutations} \u6B21\u53D8\u5316`);
|
|
3993
4042
|
return { totalMutations };
|
|
3994
4043
|
}
|
|
3995
4044
|
};
|
|
@@ -4858,7 +4907,7 @@ var createTemplateLogger = (baseLogger = createBaseLogger()) => {
|
|
|
4858
4907
|
};
|
|
4859
4908
|
var getDefaultBaseLogger = () => createBaseLogger("");
|
|
4860
4909
|
var Logger = {
|
|
4861
|
-
setLogger: (
|
|
4910
|
+
setLogger: (logger14) => setDefaultLogger(logger14),
|
|
4862
4911
|
info: (message) => getDefaultBaseLogger().info(message),
|
|
4863
4912
|
success: (message) => getDefaultBaseLogger().success(message),
|
|
4864
4913
|
warning: (message) => getDefaultBaseLogger().warning(message),
|
|
@@ -4866,8 +4915,8 @@ var Logger = {
|
|
|
4866
4915
|
error: (message) => getDefaultBaseLogger().error(message),
|
|
4867
4916
|
debug: (message) => getDefaultBaseLogger().debug(message),
|
|
4868
4917
|
start: (message) => getDefaultBaseLogger().start(message),
|
|
4869
|
-
useTemplate: (
|
|
4870
|
-
if (
|
|
4918
|
+
useTemplate: (logger14) => {
|
|
4919
|
+
if (logger14) return createTemplateLogger(createBaseLogger("", logger14));
|
|
4871
4920
|
return createTemplateLogger();
|
|
4872
4921
|
}
|
|
4873
4922
|
};
|
|
@@ -4932,7 +4981,7 @@ var LOCATION_NETWORK_SUFFIX_PATTERNS = [
|
|
|
4932
4981
|
];
|
|
4933
4982
|
var cachedStripLogoSrcPromise = null;
|
|
4934
4983
|
var cachedEnrichmentByContext = /* @__PURE__ */ new WeakMap();
|
|
4935
|
-
var
|
|
4984
|
+
var logger12 = createInternalLogger("Watermarkify");
|
|
4936
4985
|
var normalizeText = (value) => String(value || "").trim();
|
|
4937
4986
|
var toInline = (value, maxLen = 200) => {
|
|
4938
4987
|
const text = normalizeText(value);
|
|
@@ -5174,9 +5223,9 @@ var resolveWithCustomResolver = async (page, baseMeta, options = {}) => {
|
|
|
5174
5223
|
location: toInline(resolved.location, 80)
|
|
5175
5224
|
};
|
|
5176
5225
|
if (enrichment.ip || enrichment.location) {
|
|
5177
|
-
|
|
5226
|
+
logger12.info(`\u81EA\u5B9A\u4E49 resolver \u547D\u4E2D: ip=${enrichment.ip || "-"}, loc=${enrichment.location || "-"}`);
|
|
5178
5227
|
} else {
|
|
5179
|
-
|
|
5228
|
+
logger12.warning("\u81EA\u5B9A\u4E49 resolver \u5DF2\u6267\u884C\uFF0C\u4F46\u672A\u8FD4\u56DE IP/Loc");
|
|
5180
5229
|
}
|
|
5181
5230
|
return enrichment;
|
|
5182
5231
|
} finally {
|
|
@@ -5360,12 +5409,12 @@ var buildWatermarkifyRenderHtml = ({ imageSrc, overlaySvg, width, height }) => {
|
|
|
5360
5409
|
};
|
|
5361
5410
|
var composeScreenshotBufferWithBrowser = async (page, buffer, overlaySvg, imageInfo = {}) => {
|
|
5362
5411
|
if (!page || typeof page.context !== "function") {
|
|
5363
|
-
|
|
5412
|
+
logger12.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u8DF3\u8FC7: \u7F3A\u5C11\u53EF\u7528 page");
|
|
5364
5413
|
return buffer;
|
|
5365
5414
|
}
|
|
5366
5415
|
const renderScope = await openProbePage(page);
|
|
5367
5416
|
if (!renderScope?.page) {
|
|
5368
|
-
|
|
5417
|
+
logger12.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u8DF3\u8FC7: \u65E0\u6CD5\u521B\u5EFA render page");
|
|
5369
5418
|
return buffer;
|
|
5370
5419
|
}
|
|
5371
5420
|
try {
|
|
@@ -5408,13 +5457,13 @@ var composeScreenshotBufferWithBrowser = async (page, buffer, overlaySvg, imageI
|
|
|
5408
5457
|
fullPage: true,
|
|
5409
5458
|
animations: "disabled"
|
|
5410
5459
|
}).catch((error) => {
|
|
5411
|
-
|
|
5460
|
+
logger12.warning(`watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
|
|
5412
5461
|
return null;
|
|
5413
5462
|
});
|
|
5414
5463
|
if (Buffer.isBuffer(composed) && composed.length > 0) {
|
|
5415
5464
|
return composed;
|
|
5416
5465
|
}
|
|
5417
|
-
|
|
5466
|
+
logger12.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u5931\u8D25: \u672A\u5F97\u5230\u6709\u6548\u622A\u56FE\u7ED3\u679C");
|
|
5418
5467
|
return buffer;
|
|
5419
5468
|
} finally {
|
|
5420
5469
|
await renderScope.close().catch(() => {
|
|
@@ -5427,7 +5476,7 @@ var resolveWithIpLookup = async (page, options = {}) => {
|
|
|
5427
5476
|
}
|
|
5428
5477
|
const probeScope = await openProbePage(page);
|
|
5429
5478
|
if (!probeScope?.page) {
|
|
5430
|
-
|
|
5479
|
+
logger12.warning("ipLookup \u8DF3\u8FC7: \u65E0\u6CD5\u521B\u5EFA probe page");
|
|
5431
5480
|
return null;
|
|
5432
5481
|
}
|
|
5433
5482
|
const timeoutMs = Math.max(
|
|
@@ -5436,12 +5485,12 @@ var resolveWithIpLookup = async (page, options = {}) => {
|
|
|
5436
5485
|
);
|
|
5437
5486
|
try {
|
|
5438
5487
|
const probePage = probeScope.page;
|
|
5439
|
-
|
|
5488
|
+
logger12.info(`ipLookup \u5C1D\u8BD5: url=${DEFAULT_IP_LOOKUP_URL}, timeoutMs=${timeoutMs}`);
|
|
5440
5489
|
const response = await probePage.goto(DEFAULT_IP_LOOKUP_URL, {
|
|
5441
5490
|
waitUntil: "commit",
|
|
5442
5491
|
timeout: timeoutMs
|
|
5443
5492
|
}).catch((error) => {
|
|
5444
|
-
|
|
5493
|
+
logger12.warning(`ipLookup \u8BF7\u6C42\u5931\u8D25: url=${DEFAULT_IP_LOOKUP_URL}, error=${error instanceof Error ? error.message : String(error)}`);
|
|
5445
5494
|
return null;
|
|
5446
5495
|
});
|
|
5447
5496
|
const status = response && typeof response.status === "function" ? response.status() : 0;
|
|
@@ -5463,13 +5512,13 @@ var resolveWithIpLookup = async (page, options = {}) => {
|
|
|
5463
5512
|
}
|
|
5464
5513
|
const parsed = parseIpIpJsonResponse(rawText);
|
|
5465
5514
|
if (parsed?.ip || parsed?.location) {
|
|
5466
|
-
|
|
5515
|
+
logger12.info(`ipLookup \u6210\u529F: url=${DEFAULT_IP_LOOKUP_URL}, status=${status || "-"}, contentType=${contentType || "-"}, ip=${parsed.ip || "-"}, loc=${parsed.location || "-"}`);
|
|
5467
5516
|
return parsed;
|
|
5468
5517
|
}
|
|
5469
|
-
|
|
5518
|
+
logger12.warning(`ipLookup \u672A\u89E3\u6790\u51FA IP/Loc: url=${DEFAULT_IP_LOOKUP_URL}, status=${status || "-"}, contentType=${contentType || "-"}, preview=${shortenTail(rawText, 120) || "[empty]"}`);
|
|
5470
5519
|
return null;
|
|
5471
5520
|
} catch (error) {
|
|
5472
|
-
|
|
5521
|
+
logger12.warning(`ipLookup \u6267\u884C\u5F02\u5E38\uFF0C\u672A\u83B7\u5F97 IP/Loc: ${error instanceof Error ? error.message : String(error)}`);
|
|
5473
5522
|
return null;
|
|
5474
5523
|
} finally {
|
|
5475
5524
|
await probeScope.close().catch(() => {
|
|
@@ -5483,10 +5532,10 @@ var resolveEnrichment = async (page, baseMeta, options) => {
|
|
|
5483
5532
|
ip: toInline(options.ip, 80),
|
|
5484
5533
|
location: toInline(options.location, 80)
|
|
5485
5534
|
};
|
|
5486
|
-
|
|
5535
|
+
logger12.info(`enrichment \u5F00\u59CB: host=${baseMeta.hostname || "-"}, hasPresetIp=${Boolean(merged.ip)}, hasPresetLoc=${Boolean(merged.location)}, ipLookup=${options.ipLookup !== false}`);
|
|
5487
5536
|
if (!merged.ip || !merged.location) {
|
|
5488
5537
|
if (cached?.ip || cached?.location) {
|
|
5489
|
-
|
|
5538
|
+
logger12.info(`enrichment \u547D\u4E2D\u4E0A\u4E0B\u6587\u7F13\u5B58: ip=${cached.ip || "-"}, loc=${cached.location || "-"}`);
|
|
5490
5539
|
}
|
|
5491
5540
|
fillEnrichment(merged, cached);
|
|
5492
5541
|
}
|
|
@@ -5510,15 +5559,15 @@ var resolveEnrichment = async (page, baseMeta, options) => {
|
|
|
5510
5559
|
"x-geo-country"
|
|
5511
5560
|
]), 80);
|
|
5512
5561
|
if (!merged.location || isWeakLocationValue(merged.location) && headerLocation) {
|
|
5513
|
-
|
|
5562
|
+
logger12.info(`enrichment \u4F7F\u7528\u54CD\u5E94\u5934\u8865\u5145 Loc: ${headerLocation || "-"}`);
|
|
5514
5563
|
merged.location = headerLocation || merged.location;
|
|
5515
5564
|
}
|
|
5516
5565
|
}
|
|
5517
5566
|
writeCachedEnrichment(page, merged);
|
|
5518
5567
|
if (merged.ip || merged.location) {
|
|
5519
|
-
|
|
5568
|
+
logger12.info(`enrichment \u5B8C\u6210: ip=${merged.ip || "-"}, loc=${merged.location || "-"}`);
|
|
5520
5569
|
} else {
|
|
5521
|
-
|
|
5570
|
+
logger12.warning("enrichment \u5B8C\u6210: \u672A\u83B7\u5F97 IP/Loc");
|
|
5522
5571
|
}
|
|
5523
5572
|
return merged;
|
|
5524
5573
|
};
|
|
@@ -6186,7 +6235,7 @@ var watermarkifyScreenshotBuffer = async (buffer, meta, page = null) => {
|
|
|
6186
6235
|
}
|
|
6187
6236
|
const imageInfo = readImageInfo(buffer);
|
|
6188
6237
|
if (!imageInfo.width || !imageInfo.height || !imageInfo.mimeType) {
|
|
6189
|
-
|
|
6238
|
+
logger12.warning("watermarkify \u8DF3\u8FC7: \u65E0\u6CD5\u89E3\u6790\u622A\u56FE\u5C3A\u5BF8\u6216\u683C\u5F0F");
|
|
6190
6239
|
return buffer;
|
|
6191
6240
|
}
|
|
6192
6241
|
const overlaySvg = buildWatermarkifySvg(meta, imageInfo.width, imageInfo.height);
|
|
@@ -6197,7 +6246,7 @@ var watermarkifyScreenshotBuffer = async (buffer, meta, page = null) => {
|
|
|
6197
6246
|
};
|
|
6198
6247
|
|
|
6199
6248
|
// src/share.js
|
|
6200
|
-
var
|
|
6249
|
+
var logger13 = createInternalLogger("Share");
|
|
6201
6250
|
var DEFAULT_TIMEOUT_MS2 = 50 * 1e3;
|
|
6202
6251
|
var DEFAULT_PAYLOAD_SNAPSHOT_MAX_LEN = 500;
|
|
6203
6252
|
var DEFAULT_POLL_INTERVAL_MS = 120;
|
|
@@ -6334,7 +6383,7 @@ var createDomShareMonitor = async (page, options = {}) => {
|
|
|
6334
6383
|
const onMatch = typeof options.onMatch === "function" ? options.onMatch : null;
|
|
6335
6384
|
const onTelemetry = typeof options.onTelemetry === "function" ? options.onTelemetry : null;
|
|
6336
6385
|
let matched = false;
|
|
6337
|
-
|
|
6386
|
+
logger13.info(`DOM \u76D1\u542C\u51C6\u5907\u6302\u8F7D: selectors=${toJsonInline(selectors, 120)}, mode=${mode}`);
|
|
6338
6387
|
const monitor = await Mutation.useMonitor(page, selectors, {
|
|
6339
6388
|
mode,
|
|
6340
6389
|
onMutation: (context = {}) => {
|
|
@@ -6352,12 +6401,12 @@ ${text}`;
|
|
|
6352
6401
|
});
|
|
6353
6402
|
}
|
|
6354
6403
|
if (mutationCount <= 5 || mutationCount % 50 === 0) {
|
|
6355
|
-
|
|
6404
|
+
logger13.info(`DOM \u53D8\u5316\u5DF2\u6355\u83B7: mutationCount=${mutationCount}, mutationNodes=${mutationNodes.length}`);
|
|
6356
6405
|
}
|
|
6357
6406
|
const [candidate] = Utils.parseLinks(rawDom, { prefix }) || [];
|
|
6358
6407
|
if (!candidate) return;
|
|
6359
6408
|
matched = true;
|
|
6360
|
-
|
|
6409
|
+
logger13.success("captureLink.domHit", `DOM \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: mutationCount=${mutationCount}, link=${candidate}`);
|
|
6361
6410
|
if (onMatch) {
|
|
6362
6411
|
onMatch({
|
|
6363
6412
|
link: candidate,
|
|
@@ -6373,7 +6422,7 @@ ${text}`;
|
|
|
6373
6422
|
return {
|
|
6374
6423
|
stop: async () => {
|
|
6375
6424
|
const result = await monitor.stop();
|
|
6376
|
-
|
|
6425
|
+
logger13.info(`DOM \u76D1\u542C\u5DF2\u505C\u6B62: totalMutations=${result?.totalMutations || 0}`);
|
|
6377
6426
|
return result;
|
|
6378
6427
|
}
|
|
6379
6428
|
};
|
|
@@ -6413,8 +6462,8 @@ var Share = {
|
|
|
6413
6462
|
if (share.mode === "response" && apiMatchers.length === 0) {
|
|
6414
6463
|
throw new Error("Share.captureLink requires share.xurl[0] api matcher when mode=response");
|
|
6415
6464
|
}
|
|
6416
|
-
|
|
6417
|
-
|
|
6465
|
+
logger13.start("captureLink", `mode=${share.mode}, timeoutMs=${timeoutMs}, prefix=${share.prefix}`);
|
|
6466
|
+
logger13.info(`captureLink \u914D\u7F6E: xurl=${toJsonInline(share.xurl)}, domMode=${domMode}, domSelectors=${toJsonInline(domSelectors, 120)}`);
|
|
6418
6467
|
const stats = {
|
|
6419
6468
|
actionTimedOut: false,
|
|
6420
6469
|
domMutationCount: 0,
|
|
@@ -6439,7 +6488,7 @@ var Share = {
|
|
|
6439
6488
|
link: validated,
|
|
6440
6489
|
payloadText: String(payloadText || "")
|
|
6441
6490
|
};
|
|
6442
|
-
|
|
6491
|
+
logger13.info(`\u5019\u9009\u94FE\u63A5\u5DF2\u786E\u8BA4: source=${source}, link=${validated}`);
|
|
6443
6492
|
return true;
|
|
6444
6493
|
};
|
|
6445
6494
|
const resolveResponseCandidate = (responseText) => {
|
|
@@ -6474,7 +6523,7 @@ var Share = {
|
|
|
6474
6523
|
try {
|
|
6475
6524
|
await monitor.stop();
|
|
6476
6525
|
} catch (error) {
|
|
6477
|
-
|
|
6526
|
+
logger13.warning(`\u505C\u6B62 DOM \u76D1\u542C\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
|
|
6478
6527
|
}
|
|
6479
6528
|
};
|
|
6480
6529
|
const onResponse = async (response) => {
|
|
@@ -6487,29 +6536,29 @@ var Share = {
|
|
|
6487
6536
|
stats.responseSampleUrls.push(url);
|
|
6488
6537
|
}
|
|
6489
6538
|
if (stats.responseObserved <= 5) {
|
|
6490
|
-
|
|
6539
|
+
logger13.info(`\u63A5\u53E3\u54CD\u5E94\u91C7\u6837(${stats.responseObserved}): ${url}`);
|
|
6491
6540
|
}
|
|
6492
6541
|
if (!apiMatchers.some((matcher) => url.includes(matcher))) return;
|
|
6493
6542
|
stats.responseMatched += 1;
|
|
6494
6543
|
stats.lastMatchedUrl = url;
|
|
6495
|
-
|
|
6544
|
+
logger13.info(`\u63A5\u53E3\u547D\u4E2D\u5339\u914D(${stats.responseMatched}): ${url}`);
|
|
6496
6545
|
const text = await response.text();
|
|
6497
6546
|
const hit = resolveResponseCandidate(text);
|
|
6498
6547
|
if (!hit?.link) {
|
|
6499
6548
|
if (stats.responseMatched <= 3) {
|
|
6500
|
-
|
|
6549
|
+
logger13.info(`\u63A5\u53E3\u89E3\u6790\u5B8C\u6210\u4F46\u672A\u63D0\u53D6\u5230\u5206\u4EAB\u94FE\u63A5: payloadSize=${text.length}`);
|
|
6501
6550
|
}
|
|
6502
6551
|
return;
|
|
6503
6552
|
}
|
|
6504
6553
|
stats.responseResolved += 1;
|
|
6505
|
-
|
|
6554
|
+
logger13.success("captureLink.responseHit", `\u63A5\u53E3\u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: url=${url}, link=${hit.link}`);
|
|
6506
6555
|
setCandidate("response", hit.link, hit.payloadText);
|
|
6507
6556
|
} catch (error) {
|
|
6508
|
-
|
|
6557
|
+
logger13.warning(`\u63A5\u53E3\u54CD\u5E94\u5904\u7406\u5F02\u5E38: ${error instanceof Error ? error.message : String(error)}`);
|
|
6509
6558
|
}
|
|
6510
6559
|
};
|
|
6511
6560
|
if (share.mode === "dom") {
|
|
6512
|
-
|
|
6561
|
+
logger13.info("\u5F53\u524D\u4E3A DOM \u6A21\u5F0F\uFF0C\u4EC5\u542F\u7528 DOM \u76D1\u542C");
|
|
6513
6562
|
domMonitor = await createDomShareMonitor(page, {
|
|
6514
6563
|
prefix: share.prefix,
|
|
6515
6564
|
selectors: domSelectors,
|
|
@@ -6524,14 +6573,14 @@ var Share = {
|
|
|
6524
6573
|
});
|
|
6525
6574
|
}
|
|
6526
6575
|
if (share.mode === "response") {
|
|
6527
|
-
|
|
6576
|
+
logger13.info(`\u5F53\u524D\u4E3A\u63A5\u53E3\u6A21\u5F0F\uFF0C\u6302\u8F7D response \u76D1\u542C: apiMatchers=${toJsonInline(apiMatchers, 160)}`);
|
|
6528
6577
|
page.on("response", onResponse);
|
|
6529
6578
|
}
|
|
6530
6579
|
const deadline = Date.now() + timeoutMs;
|
|
6531
6580
|
const getRemainingMs = () => Math.max(0, deadline - Date.now());
|
|
6532
6581
|
try {
|
|
6533
6582
|
const actionTimeout = getRemainingMs();
|
|
6534
|
-
|
|
6583
|
+
logger13.start("captureLink.performActions", `\u6267\u884C\u52A8\u4F5C\u9884\u7B97=${actionTimeout}ms`);
|
|
6535
6584
|
if (actionTimeout > 0) {
|
|
6536
6585
|
let timer = null;
|
|
6537
6586
|
let actionError = null;
|
|
@@ -6545,21 +6594,21 @@ var Share = {
|
|
|
6545
6594
|
const actionResult = await Promise.race([actionPromise, timeoutPromise]);
|
|
6546
6595
|
if (timer) clearTimeout(timer);
|
|
6547
6596
|
if (actionResult === "__ACTION_ERROR__") {
|
|
6548
|
-
|
|
6597
|
+
logger13.fail("captureLink.performActions", actionError);
|
|
6549
6598
|
throw actionError;
|
|
6550
6599
|
}
|
|
6551
6600
|
if (actionResult === "__ACTION_TIMEOUT__") {
|
|
6552
6601
|
stats.actionTimedOut = true;
|
|
6553
|
-
|
|
6602
|
+
logger13.warning(`performActions \u5DF2\u8D85\u65F6 (${actionTimeout}ms)\uFF0C\u52A8\u4F5C\u53EF\u80FD\u4ECD\u5728\u5F02\u6B65\u6267\u884C`);
|
|
6554
6603
|
} else {
|
|
6555
|
-
|
|
6604
|
+
logger13.success("captureLink.performActions", "\u6267\u884C\u52A8\u4F5C\u5B8C\u6210");
|
|
6556
6605
|
}
|
|
6557
6606
|
}
|
|
6558
6607
|
let nextProgressLogTs = Date.now() + 3e3;
|
|
6559
6608
|
while (true) {
|
|
6560
6609
|
const selected = share.mode === "dom" ? candidates.dom : candidates.response;
|
|
6561
6610
|
if (selected?.link) {
|
|
6562
|
-
|
|
6611
|
+
logger13.success("captureLink", `\u6355\u83B7\u6210\u529F: source=${share.mode}, link=${selected.link}`);
|
|
6563
6612
|
return {
|
|
6564
6613
|
link: selected.link,
|
|
6565
6614
|
payloadText: selected.payloadText,
|
|
@@ -6571,7 +6620,7 @@ var Share = {
|
|
|
6571
6620
|
if (remaining <= 0) break;
|
|
6572
6621
|
const now = Date.now();
|
|
6573
6622
|
if (now >= nextProgressLogTs) {
|
|
6574
|
-
|
|
6623
|
+
logger13.info(
|
|
6575
6624
|
`captureLink \u7B49\u5F85\u4E2D: remaining=${remaining}ms, domMutationCount=${stats.domMutationCount}, responseMatched=${stats.responseMatched}`
|
|
6576
6625
|
);
|
|
6577
6626
|
nextProgressLogTs = now + 5e3;
|
|
@@ -6579,11 +6628,11 @@ var Share = {
|
|
|
6579
6628
|
await delay2(Math.max(0, Math.min(DEFAULT_POLL_INTERVAL_MS, remaining)));
|
|
6580
6629
|
}
|
|
6581
6630
|
if (share.mode === "response" && stats.responseMatched === 0) {
|
|
6582
|
-
|
|
6631
|
+
logger13.warning(
|
|
6583
6632
|
`\u63A5\u53E3\u76D1\u542C\u672A\u547D\u4E2D: apiMatchers=${toJsonInline(apiMatchers, 220)}, \u54CD\u5E94\u6837\u672CURLs=${toJsonInline(stats.responseSampleUrls, 420)}`
|
|
6584
6633
|
);
|
|
6585
6634
|
}
|
|
6586
|
-
|
|
6635
|
+
logger13.warning(
|
|
6587
6636
|
`captureLink \u8D85\u65F6\u672A\u62FF\u5230\u94FE\u63A5: mode=${share.mode}, actionTimedOut=${stats.actionTimedOut}, domMutationCount=${stats.domMutationCount}, responseObserved=${stats.responseObserved}, responseMatched=${stats.responseMatched}, lastMatchedUrl=${stats.lastMatchedUrl || "none"}`
|
|
6588
6637
|
);
|
|
6589
6638
|
return {
|
|
@@ -6595,7 +6644,7 @@ var Share = {
|
|
|
6595
6644
|
} finally {
|
|
6596
6645
|
if (share.mode === "response") {
|
|
6597
6646
|
page.off("response", onResponse);
|
|
6598
|
-
|
|
6647
|
+
logger13.info("response \u76D1\u542C\u5DF2\u5378\u8F7D");
|
|
6599
6648
|
}
|
|
6600
6649
|
await stopDomMonitor();
|
|
6601
6650
|
}
|