@skrillex1224/playwright-toolkit 2.0.23 → 2.0.25
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 +179 -81
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +179 -81
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -34,7 +34,7 @@ __export(index_exports, {
|
|
|
34
34
|
module.exports = __toCommonJS(index_exports);
|
|
35
35
|
|
|
36
36
|
// src/apify-kit.js
|
|
37
|
-
var
|
|
37
|
+
var import_crawlee2 = require("crawlee");
|
|
38
38
|
|
|
39
39
|
// src/constants.js
|
|
40
40
|
var constants_exports = {};
|
|
@@ -60,7 +60,65 @@ var StatusCode = {
|
|
|
60
60
|
var FAILED_KEY_SEPARATOR = "::<@>::";
|
|
61
61
|
var PresetOfLiveViewKey = "LIVE_VIEW_SCREENSHOT";
|
|
62
62
|
|
|
63
|
+
// src/internal/logger.js
|
|
64
|
+
var import_crawlee = require("crawlee");
|
|
65
|
+
var GLOBAL_PREFIX = "\u26A1";
|
|
66
|
+
function createLogger(moduleName) {
|
|
67
|
+
const prefix = `${GLOBAL_PREFIX}[${moduleName}]`;
|
|
68
|
+
return {
|
|
69
|
+
/**
|
|
70
|
+
* 方法开始日志
|
|
71
|
+
* @param {string} methodName - 方法名称
|
|
72
|
+
* @param {string} [params] - 参数摘要 (可选)
|
|
73
|
+
*/
|
|
74
|
+
start(methodName, params = "") {
|
|
75
|
+
const paramStr = params ? ` (${params})` : "";
|
|
76
|
+
import_crawlee.log.info(`${prefix} \u{1F537} ${methodName} \u5F00\u59CB${paramStr}`);
|
|
77
|
+
},
|
|
78
|
+
/**
|
|
79
|
+
* 方法成功日志
|
|
80
|
+
* @param {string} methodName - 方法名称
|
|
81
|
+
* @param {string} [result] - 结果摘要 (可选)
|
|
82
|
+
*/
|
|
83
|
+
success(methodName, result = "") {
|
|
84
|
+
const resultStr = result ? ` (${result})` : "";
|
|
85
|
+
import_crawlee.log.info(`${prefix} \u2705 ${methodName} \u5B8C\u6210${resultStr}`);
|
|
86
|
+
},
|
|
87
|
+
/**
|
|
88
|
+
* 方法失败日志
|
|
89
|
+
* @param {string} methodName - 方法名称
|
|
90
|
+
* @param {Error|string} error - 错误对象或信息
|
|
91
|
+
*/
|
|
92
|
+
fail(methodName, error) {
|
|
93
|
+
const message = error instanceof Error ? error.message : error;
|
|
94
|
+
import_crawlee.log.error(`${prefix} \u274C ${methodName} \u5931\u8D25: ${message}`);
|
|
95
|
+
},
|
|
96
|
+
/**
|
|
97
|
+
* 调试日志
|
|
98
|
+
* @param {string} message - 详情
|
|
99
|
+
*/
|
|
100
|
+
debug(message) {
|
|
101
|
+
import_crawlee.log.debug(`${prefix} \u{1F539} ${message}`);
|
|
102
|
+
},
|
|
103
|
+
/**
|
|
104
|
+
* 警告日志
|
|
105
|
+
* @param {string} message - 警告信息
|
|
106
|
+
*/
|
|
107
|
+
warn(message) {
|
|
108
|
+
import_crawlee.log.warning(`${prefix} \u26A0\uFE0F ${message}`);
|
|
109
|
+
},
|
|
110
|
+
/**
|
|
111
|
+
* 普通信息日志
|
|
112
|
+
* @param {string} message - 信息
|
|
113
|
+
*/
|
|
114
|
+
info(message) {
|
|
115
|
+
import_crawlee.log.info(`${prefix} ${message}`);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
63
120
|
// src/apify-kit.js
|
|
121
|
+
var logger = createLogger("ApifyKit");
|
|
64
122
|
async function createApifyKit() {
|
|
65
123
|
let apify = null;
|
|
66
124
|
try {
|
|
@@ -94,13 +152,13 @@ async function createApifyKit() {
|
|
|
94
152
|
async runStep(pendingStepName, page, actionFn, options = {}) {
|
|
95
153
|
const { failActor = true } = options;
|
|
96
154
|
const [failedKey, stepName] = this.unwrapStepName(pendingStepName);
|
|
97
|
-
|
|
155
|
+
logger.start(`[Step] ${stepName}`);
|
|
98
156
|
try {
|
|
99
157
|
const result = await actionFn();
|
|
100
|
-
|
|
158
|
+
logger.success(`[Step] ${stepName}`);
|
|
101
159
|
return result;
|
|
102
160
|
} catch (error) {
|
|
103
|
-
|
|
161
|
+
logger.fail(`[Step] ${stepName}`, error);
|
|
104
162
|
let screenshotBase64 = "\u622A\u56FE\u5931\u8D25";
|
|
105
163
|
try {
|
|
106
164
|
if (page) {
|
|
@@ -108,7 +166,7 @@ async function createApifyKit() {
|
|
|
108
166
|
screenshotBase64 = `data:image/jpeg;base64,${buffer.toString("base64")}`;
|
|
109
167
|
}
|
|
110
168
|
} catch (snapErr) {
|
|
111
|
-
|
|
169
|
+
logger.warn(`\u622A\u56FE\u751F\u6210\u5931\u8D25: ${snapErr.message}`);
|
|
112
170
|
}
|
|
113
171
|
await this.pushFailed(error, {
|
|
114
172
|
failedStep: stepName,
|
|
@@ -141,6 +199,7 @@ async function createApifyKit() {
|
|
|
141
199
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
142
200
|
...data
|
|
143
201
|
});
|
|
202
|
+
logger.success("pushSuccess", "Data pushed");
|
|
144
203
|
},
|
|
145
204
|
/**
|
|
146
205
|
* 推送失败数据的通用方法(私有方法,仅供runStep内部使用)
|
|
@@ -157,6 +216,7 @@ async function createApifyKit() {
|
|
|
157
216
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
158
217
|
...meta
|
|
159
218
|
});
|
|
219
|
+
logger.success("pushFailed", "Error data pushed");
|
|
160
220
|
}
|
|
161
221
|
};
|
|
162
222
|
}
|
|
@@ -172,6 +232,7 @@ var ApifyKit = {
|
|
|
172
232
|
};
|
|
173
233
|
|
|
174
234
|
// src/utils.js
|
|
235
|
+
var logger2 = createLogger("Utils");
|
|
175
236
|
var Utils = {
|
|
176
237
|
/**
|
|
177
238
|
* 解析 SSE 流文本
|
|
@@ -190,12 +251,13 @@ var Utils = {
|
|
|
190
251
|
}
|
|
191
252
|
}
|
|
192
253
|
}
|
|
254
|
+
logger2.success("parseSseStream", `parsed events: ${events.length}`);
|
|
193
255
|
return events;
|
|
194
256
|
}
|
|
195
257
|
};
|
|
196
258
|
|
|
197
259
|
// src/stealth.js
|
|
198
|
-
var
|
|
260
|
+
var logger3 = createLogger("Stealth");
|
|
199
261
|
var Stealth = {
|
|
200
262
|
/**
|
|
201
263
|
* 关键修复:将 Page 视口调整为与浏览器指纹 (window.screen) 一致。
|
|
@@ -214,9 +276,9 @@ var Stealth = {
|
|
|
214
276
|
width: screen.width,
|
|
215
277
|
height: screen.height
|
|
216
278
|
});
|
|
217
|
-
|
|
279
|
+
logger3.success("syncViewportWithScreen", `size=${screen.width}x${screen.height}`);
|
|
218
280
|
} catch (e) {
|
|
219
|
-
|
|
281
|
+
logger3.warn(`syncViewportWithScreen Failed: ${e.message}. Fallback to 1920x1080.`);
|
|
220
282
|
await page.setViewportSize({ width: 1920, height: 1080 });
|
|
221
283
|
}
|
|
222
284
|
},
|
|
@@ -229,6 +291,7 @@ var Stealth = {
|
|
|
229
291
|
get: () => false
|
|
230
292
|
});
|
|
231
293
|
});
|
|
294
|
+
logger3.success("hideWebdriver");
|
|
232
295
|
},
|
|
233
296
|
/**
|
|
234
297
|
* 通用的 Playwright 资源拦截器,用于屏蔽不必要的资源以加速加载
|
|
@@ -244,6 +307,7 @@ var Stealth = {
|
|
|
244
307
|
}
|
|
245
308
|
return route.continue();
|
|
246
309
|
});
|
|
310
|
+
logger3.success("setupBlockingResources", `types=[${resourceTypes.join(",")}]`);
|
|
247
311
|
},
|
|
248
312
|
/**
|
|
249
313
|
* 获取推荐的 Stealth 启动参数
|
|
@@ -305,13 +369,13 @@ var Stealth = {
|
|
|
305
369
|
return -480;
|
|
306
370
|
};
|
|
307
371
|
});
|
|
308
|
-
|
|
372
|
+
logger3.success("setChinaTimezone", "Asia/Shanghai (UTC+8)");
|
|
309
373
|
}
|
|
310
374
|
};
|
|
311
375
|
|
|
312
376
|
// src/humanize.js
|
|
313
377
|
var import_delay = __toESM(require("delay"), 1);
|
|
314
|
-
var
|
|
378
|
+
var logger4 = createLogger("Humanize");
|
|
315
379
|
var Humanize = {
|
|
316
380
|
/**
|
|
317
381
|
* 随机延迟一段毫秒数 (API Wrapper for 'delay' package)
|
|
@@ -319,8 +383,10 @@ var Humanize = {
|
|
|
319
383
|
* @param {number} max - 最大毫秒
|
|
320
384
|
*/
|
|
321
385
|
async randomSleep(min, max) {
|
|
386
|
+
logger4.start("randomSleep", `min=${min}, max=${max}`);
|
|
322
387
|
const ms = typeof max === "number" ? (0, import_delay.rangeDelay)(min, max) : (0, import_delay.default)(min);
|
|
323
388
|
await ms;
|
|
389
|
+
logger4.success("randomSleep", `waited=${await ms}ms`);
|
|
324
390
|
},
|
|
325
391
|
/**
|
|
326
392
|
* 模拟人类“注视”或“阅读”行为:鼠标在页面上随机微动。
|
|
@@ -328,6 +394,7 @@ var Humanize = {
|
|
|
328
394
|
* @param {number} durationMs - 持续时间
|
|
329
395
|
*/
|
|
330
396
|
async simulateGaze(cursor, durationMs = 2e3) {
|
|
397
|
+
logger4.start("simulateGaze", `duration=${durationMs}ms`);
|
|
331
398
|
const startTime = Date.now();
|
|
332
399
|
while (Date.now() - startTime < durationMs) {
|
|
333
400
|
const x = Math.random() * 800;
|
|
@@ -335,6 +402,7 @@ var Humanize = {
|
|
|
335
402
|
await cursor.actions.move({ x, y });
|
|
336
403
|
await (0, import_delay.rangeDelay)(200, 800);
|
|
337
404
|
}
|
|
405
|
+
logger4.success("simulateGaze");
|
|
338
406
|
},
|
|
339
407
|
/**
|
|
340
408
|
* 人类化输入 - 带节奏变化(快-慢-停顿-偶尔加速)
|
|
@@ -349,6 +417,7 @@ var Humanize = {
|
|
|
349
417
|
* @param {number} [options.pauseMax=800] - 停顿最大时长 (ms)
|
|
350
418
|
*/
|
|
351
419
|
async humanType(page, selector, text, options = {}) {
|
|
420
|
+
logger4.start("humanType", `selector=${selector}, textLen=${text.length}`);
|
|
352
421
|
const {
|
|
353
422
|
minDelay = 50,
|
|
354
423
|
maxDelay = 200,
|
|
@@ -356,26 +425,32 @@ var Humanize = {
|
|
|
356
425
|
pauseMin = 300,
|
|
357
426
|
pauseMax = 800
|
|
358
427
|
} = options;
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
428
|
+
try {
|
|
429
|
+
const locator = page.locator(selector);
|
|
430
|
+
await locator.click();
|
|
431
|
+
await (0, import_delay.rangeDelay)(100, 300);
|
|
432
|
+
for (let i = 0; i < text.length; i++) {
|
|
433
|
+
const char = text[i];
|
|
434
|
+
let charDelay;
|
|
435
|
+
if (char === " ") {
|
|
436
|
+
charDelay = minDelay + Math.random() * 50;
|
|
437
|
+
} else if (/[,.!?;:,。!?;:]/.test(char)) {
|
|
438
|
+
charDelay = maxDelay + Math.random() * 100;
|
|
439
|
+
} else {
|
|
440
|
+
charDelay = minDelay + Math.random() * (maxDelay - minDelay);
|
|
441
|
+
}
|
|
442
|
+
await page.keyboard.type(char);
|
|
443
|
+
await (0, import_delay.default)(charDelay);
|
|
444
|
+
if (Math.random() < pauseProbability && i < text.length - 1) {
|
|
445
|
+
const pauseTime = pauseMin + Math.random() * (pauseMax - pauseMin);
|
|
446
|
+
logger4.debug(`\u505C\u987F ${Math.round(pauseTime)}ms...`);
|
|
447
|
+
await (0, import_delay.default)(pauseTime);
|
|
448
|
+
}
|
|
378
449
|
}
|
|
450
|
+
logger4.success("humanType");
|
|
451
|
+
} catch (error) {
|
|
452
|
+
logger4.fail("humanType", error);
|
|
453
|
+
throw error;
|
|
379
454
|
}
|
|
380
455
|
},
|
|
381
456
|
/**
|
|
@@ -392,25 +467,30 @@ var Humanize = {
|
|
|
392
467
|
durationMs = duration;
|
|
393
468
|
}
|
|
394
469
|
durationMs = Math.round(durationMs);
|
|
395
|
-
|
|
470
|
+
logger4.start("warmUpBrowsing", `duration=${durationMs}ms`);
|
|
396
471
|
const startTime = Date.now();
|
|
397
472
|
const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
473
|
+
try {
|
|
474
|
+
while (Date.now() - startTime < durationMs) {
|
|
475
|
+
const action = Math.random();
|
|
476
|
+
if (action < 0.4) {
|
|
477
|
+
const x = 100 + Math.random() * (viewportSize.width - 200);
|
|
478
|
+
const y = 100 + Math.random() * (viewportSize.height - 200);
|
|
479
|
+
await cursor.actions.move({ x, y });
|
|
480
|
+
await (0, import_delay.rangeDelay)(200, 500);
|
|
481
|
+
} else if (action < 0.7) {
|
|
482
|
+
const scrollY = (Math.random() - 0.5) * 200;
|
|
483
|
+
await page.mouse.wheel(0, scrollY);
|
|
484
|
+
await (0, import_delay.rangeDelay)(300, 700);
|
|
485
|
+
} else {
|
|
486
|
+
await (0, import_delay.rangeDelay)(500, 1e3);
|
|
487
|
+
}
|
|
411
488
|
}
|
|
489
|
+
logger4.success("warmUpBrowsing");
|
|
490
|
+
} catch (error) {
|
|
491
|
+
logger4.fail("warmUpBrowsing", error);
|
|
492
|
+
throw error;
|
|
412
493
|
}
|
|
413
|
-
import_crawlee3.log.info("[Humanize] \u9875\u9762\u9884\u70ED\u5B8C\u6210");
|
|
414
494
|
},
|
|
415
495
|
/**
|
|
416
496
|
* 自然滚动 - 带惯性和减速效果
|
|
@@ -420,14 +500,21 @@ var Humanize = {
|
|
|
420
500
|
* @param {number} [steps=5] - 分几步完成
|
|
421
501
|
*/
|
|
422
502
|
async naturalScroll(page, direction = "down", distance = 300, steps = 5) {
|
|
503
|
+
logger4.start("naturalScroll", `dir=${direction}, dist=${distance}, steps=${steps}`);
|
|
423
504
|
const sign = direction === "down" ? 1 : -1;
|
|
424
505
|
const stepDistance = distance / steps;
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
506
|
+
try {
|
|
507
|
+
for (let i = 0; i < steps; i++) {
|
|
508
|
+
const factor = 1 - i / steps * 0.5;
|
|
509
|
+
const scrollAmount = stepDistance * factor * sign;
|
|
510
|
+
await page.mouse.wheel(0, scrollAmount);
|
|
511
|
+
const delayTime = 50 + i * 30;
|
|
512
|
+
await (0, import_delay.default)(delayTime);
|
|
513
|
+
}
|
|
514
|
+
logger4.success("naturalScroll");
|
|
515
|
+
} catch (error) {
|
|
516
|
+
logger4.fail("naturalScroll", error);
|
|
517
|
+
throw error;
|
|
431
518
|
}
|
|
432
519
|
},
|
|
433
520
|
/**
|
|
@@ -444,39 +531,47 @@ var Humanize = {
|
|
|
444
531
|
* @param {boolean} [options.throwOnMissing=true] - 元素不存在时是否抛出错误
|
|
445
532
|
*/
|
|
446
533
|
async humanClick(page, cursor, selector, options = {}) {
|
|
534
|
+
logger4.start("humanClick", `selector=${selector}`);
|
|
447
535
|
const {
|
|
448
536
|
delayBefore = 300,
|
|
449
537
|
delayAfter = 800,
|
|
450
538
|
throwOnMissing = true
|
|
451
539
|
} = options;
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
if (
|
|
455
|
-
|
|
540
|
+
try {
|
|
541
|
+
const element = await page.$(selector);
|
|
542
|
+
if (!element) {
|
|
543
|
+
if (throwOnMissing) {
|
|
544
|
+
throw new Error(`\u627E\u4E0D\u5230\u5143\u7D20 ${selector}`);
|
|
545
|
+
}
|
|
546
|
+
logger4.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${selector}`);
|
|
547
|
+
return false;
|
|
456
548
|
}
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
549
|
+
const box = await element.boundingBox();
|
|
550
|
+
if (!box) {
|
|
551
|
+
if (throwOnMissing) {
|
|
552
|
+
throw new Error(`\u65E0\u6CD5\u83B7\u53D6\u5143\u7D20\u4F4D\u7F6E ${selector}`);
|
|
553
|
+
}
|
|
554
|
+
logger4.warn(`humanClick: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${selector}`);
|
|
555
|
+
return false;
|
|
464
556
|
}
|
|
465
|
-
|
|
466
|
-
|
|
557
|
+
const offsetX = (Math.random() - 0.5) * box.width * 0.3;
|
|
558
|
+
const offsetY = (Math.random() - 0.5) * box.height * 0.3;
|
|
559
|
+
const x = box.x + box.width / 2 + offsetX;
|
|
560
|
+
const y = box.y + box.height / 2 + offsetY;
|
|
561
|
+
await cursor.actions.move({ x, y });
|
|
562
|
+
await (0, import_delay.rangeDelay)(delayBefore, delayAfter);
|
|
563
|
+
await cursor.actions.click();
|
|
564
|
+
logger4.success("humanClick");
|
|
565
|
+
return true;
|
|
566
|
+
} catch (error) {
|
|
567
|
+
logger4.fail("humanClick", error);
|
|
568
|
+
throw error;
|
|
467
569
|
}
|
|
468
|
-
const offsetX = (Math.random() - 0.5) * box.width * 0.3;
|
|
469
|
-
const offsetY = (Math.random() - 0.5) * box.height * 0.3;
|
|
470
|
-
const x = box.x + box.width / 2 + offsetX;
|
|
471
|
-
const y = box.y + box.height / 2 + offsetY;
|
|
472
|
-
await cursor.actions.move({ x, y });
|
|
473
|
-
await (0, import_delay.rangeDelay)(delayBefore, delayAfter);
|
|
474
|
-
await cursor.actions.click();
|
|
475
|
-
return true;
|
|
476
570
|
}
|
|
477
571
|
};
|
|
478
572
|
|
|
479
573
|
// src/launch.js
|
|
574
|
+
var logger5 = createLogger("Launch");
|
|
480
575
|
var Launch = {
|
|
481
576
|
getLaunchOptions(customArgs = []) {
|
|
482
577
|
return {
|
|
@@ -531,6 +626,7 @@ var Launch = {
|
|
|
531
626
|
*/
|
|
532
627
|
createStealthChromium(chromium, stealthPlugin) {
|
|
533
628
|
chromium.use(stealthPlugin());
|
|
629
|
+
logger5.success("createStealthChromium", "Stealth plugin registered");
|
|
534
630
|
return chromium;
|
|
535
631
|
},
|
|
536
632
|
/**
|
|
@@ -543,14 +639,16 @@ var Launch = {
|
|
|
543
639
|
* @returns {Promise<import('ghost-cursor-playwright').Cursor>}
|
|
544
640
|
*/
|
|
545
641
|
async createGhostCursor(page, createCursor) {
|
|
546
|
-
|
|
642
|
+
const cursor = await createCursor(page);
|
|
643
|
+
logger5.success("createGhostCursor", "initialized");
|
|
644
|
+
return cursor;
|
|
547
645
|
}
|
|
548
646
|
};
|
|
549
647
|
|
|
550
648
|
// src/live-view.js
|
|
551
649
|
var import_express = __toESM(require("express"), 1);
|
|
552
|
-
var import_crawlee4 = require("crawlee");
|
|
553
650
|
var import_apify = require("apify");
|
|
651
|
+
var logger6 = createLogger("LiveView");
|
|
554
652
|
async function startLiveViewServer(liveViewKey) {
|
|
555
653
|
const app = (0, import_express.default)();
|
|
556
654
|
app.get("/", async (req, res) => {
|
|
@@ -575,13 +673,13 @@ async function startLiveViewServer(liveViewKey) {
|
|
|
575
673
|
</html>
|
|
576
674
|
`);
|
|
577
675
|
} catch (error) {
|
|
578
|
-
|
|
676
|
+
logger6.fail("Live View Server", error);
|
|
579
677
|
res.status(500).send(`\u65E0\u6CD5\u52A0\u8F7D\u5C4F\u5E55\u622A\u56FE: ${error.message}`);
|
|
580
678
|
}
|
|
581
679
|
});
|
|
582
680
|
const port = process.env.APIFY_CONTAINER_PORT || 4321;
|
|
583
681
|
app.listen(port, () => {
|
|
584
|
-
|
|
682
|
+
logger6.success("startLiveViewServer", `\u76D1\u542C\u7AEF\u53E3 ${port}`);
|
|
585
683
|
});
|
|
586
684
|
}
|
|
587
685
|
async function takeLiveScreenshot(liveViewKey, page, logMessage) {
|
|
@@ -589,10 +687,10 @@ async function takeLiveScreenshot(liveViewKey, page, logMessage) {
|
|
|
589
687
|
const buffer = await page.screenshot({ type: "png" });
|
|
590
688
|
await import_apify.Actor.setValue(liveViewKey, buffer, { contentType: "image/png" });
|
|
591
689
|
if (logMessage) {
|
|
592
|
-
|
|
690
|
+
logger6.info(`(\u622A\u56FE): ${logMessage}`);
|
|
593
691
|
}
|
|
594
692
|
} catch (e) {
|
|
595
|
-
|
|
693
|
+
logger6.warn(`\u65E0\u6CD5\u6355\u83B7 Live View \u5C4F\u5E55\u622A\u56FE: ${e.message}`);
|
|
596
694
|
}
|
|
597
695
|
}
|
|
598
696
|
var useLiveView = (liveViewKey = PresetOfLiveViewKey) => {
|
|
@@ -610,7 +708,7 @@ var LiveView = {
|
|
|
610
708
|
};
|
|
611
709
|
|
|
612
710
|
// src/captcha-monitor.js
|
|
613
|
-
var
|
|
711
|
+
var logger7 = createLogger("Captcha");
|
|
614
712
|
function useCaptchaMonitor(page, options) {
|
|
615
713
|
const { domSelector, urlPattern, onDetected } = options;
|
|
616
714
|
if (!domSelector && !urlPattern) {
|
|
@@ -625,7 +723,7 @@ function useCaptchaMonitor(page, options) {
|
|
|
625
723
|
const triggerDetected = async () => {
|
|
626
724
|
if (isHandled) return;
|
|
627
725
|
isHandled = true;
|
|
628
|
-
|
|
726
|
+
logger7.fail("Captcha Detected", "\u{1F6D1} \u68C0\u6D4B\u5230\u9A8C\u8BC1\u7801\uFF01");
|
|
629
727
|
await onDetected();
|
|
630
728
|
};
|
|
631
729
|
if (domSelector) {
|
|
@@ -675,7 +773,7 @@ function useCaptchaMonitor(page, options) {
|
|
|
675
773
|
}
|
|
676
774
|
})();
|
|
677
775
|
}, { selector: domSelector, callbackName: exposedFunctionName });
|
|
678
|
-
|
|
776
|
+
logger7.success("useCaptchaMonitor", `DOM \u76D1\u63A7\u5DF2\u542F\u7528: ${domSelector}`);
|
|
679
777
|
}
|
|
680
778
|
if (urlPattern) {
|
|
681
779
|
frameHandler = async (frame) => {
|
|
@@ -687,7 +785,7 @@ function useCaptchaMonitor(page, options) {
|
|
|
687
785
|
}
|
|
688
786
|
};
|
|
689
787
|
page.on("framenavigated", frameHandler);
|
|
690
|
-
|
|
788
|
+
logger7.success("useCaptchaMonitor", `URL \u76D1\u63A7\u5DF2\u542F\u7528: ${urlPattern}`);
|
|
691
789
|
}
|
|
692
790
|
}
|
|
693
791
|
var Captcha = {
|