@skrillex1224/playwright-toolkit 2.0.93 → 2.0.94
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 +64 -121
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +64 -121
- package/dist/index.js.map +4 -4
- package/index.d.ts +14 -4
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1200,8 +1200,8 @@ var Sse = {
|
|
|
1200
1200
|
}
|
|
1201
1201
|
};
|
|
1202
1202
|
|
|
1203
|
-
// src/
|
|
1204
|
-
var logger9 = createLogger("
|
|
1203
|
+
// src/interception.js
|
|
1204
|
+
var logger9 = createLogger("Interception");
|
|
1205
1205
|
var ARCHIVE_EXTENSIONS = [".7z", ".zip", ".rar", ".gz", ".bz2", ".tar", ".zst"];
|
|
1206
1206
|
var EXECUTABLE_EXTENSIONS = [".exe", ".apk", ".bin", ".dmg", ".jar", ".class"];
|
|
1207
1207
|
var DOCUMENT_EXTENSIONS = [".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".csv"];
|
|
@@ -1248,20 +1248,11 @@ var DEFAULT_BLOCKING_CONFIG = {
|
|
|
1248
1248
|
/** 额外自定义扩展名列表 */
|
|
1249
1249
|
customExtensions: []
|
|
1250
1250
|
};
|
|
1251
|
-
var
|
|
1251
|
+
var Interception = {
|
|
1252
1252
|
/**
|
|
1253
1253
|
* 根据配置生成需要屏蔽的扩展名列表
|
|
1254
1254
|
*
|
|
1255
|
-
* @param {Object} [config] -
|
|
1256
|
-
* @param {boolean} [config.blockArchive] - 是否屏蔽压缩包
|
|
1257
|
-
* @param {boolean} [config.blockExecutable] - 是否屏蔽可执行文件
|
|
1258
|
-
* @param {boolean} [config.blockDocument] - 是否屏蔽办公文档
|
|
1259
|
-
* @param {boolean} [config.blockImage] - 是否屏蔽图片
|
|
1260
|
-
* @param {boolean} [config.blockMedia] - 是否屏蔽音视频
|
|
1261
|
-
* @param {boolean} [config.blockFont] - 是否屏蔽字体
|
|
1262
|
-
* @param {boolean} [config.blockCss] - 是否屏蔽 CSS
|
|
1263
|
-
* @param {boolean} [config.blockOther] - 是否屏蔽其他资源
|
|
1264
|
-
* @param {string[]} [config.customExtensions] - 额外自定义扩展名
|
|
1255
|
+
* @param {Object} [config] - 屏蔽配置
|
|
1265
1256
|
* @returns {string[]} 需要屏蔽的扩展名列表
|
|
1266
1257
|
*/
|
|
1267
1258
|
getBlockedExtensions(config = {}) {
|
|
@@ -1280,45 +1271,6 @@ var Blocking = {
|
|
|
1280
1271
|
}
|
|
1281
1272
|
return [...new Set(extensions)];
|
|
1282
1273
|
},
|
|
1283
|
-
/**
|
|
1284
|
-
* 设置资源屏蔽规则
|
|
1285
|
-
* 拦截指定扩展名的请求,优化加载速度并绕过代理问题
|
|
1286
|
-
*
|
|
1287
|
-
* @param {import('playwright').Page} page - Playwright Page 对象
|
|
1288
|
-
* @param {Object} [config] - 屏蔽配置
|
|
1289
|
-
* @returns {Promise<void>}
|
|
1290
|
-
*/
|
|
1291
|
-
async setupBlockingResources(page, config = {}) {
|
|
1292
|
-
const mergedConfig = { ...DEFAULT_BLOCKING_CONFIG, ...config };
|
|
1293
|
-
const blockedExtensions = this.getBlockedExtensions(mergedConfig);
|
|
1294
|
-
const enabledCategories = [];
|
|
1295
|
-
if (mergedConfig.blockArchive) enabledCategories.push("\u538B\u7F29\u5305");
|
|
1296
|
-
if (mergedConfig.blockExecutable) enabledCategories.push("\u53EF\u6267\u884C\u6587\u4EF6");
|
|
1297
|
-
if (mergedConfig.blockDocument) enabledCategories.push("\u529E\u516C\u6587\u6863");
|
|
1298
|
-
if (mergedConfig.blockImage) enabledCategories.push("\u56FE\u7247");
|
|
1299
|
-
if (mergedConfig.blockMedia) enabledCategories.push("\u97F3\u89C6\u9891");
|
|
1300
|
-
if (mergedConfig.blockFont) enabledCategories.push("\u5B57\u4F53");
|
|
1301
|
-
if (mergedConfig.blockCss) enabledCategories.push("CSS");
|
|
1302
|
-
if (mergedConfig.blockOther) enabledCategories.push("\u5176\u4ED6");
|
|
1303
|
-
if (mergedConfig.customExtensions?.length > 0) {
|
|
1304
|
-
enabledCategories.push(`\u81EA\u5B9A\u4E49(${mergedConfig.customExtensions.join(",")})`);
|
|
1305
|
-
}
|
|
1306
|
-
logger9.start("setupBlockingResources", `\u5C4F\u853D\u5206\u7C7B: [${enabledCategories.join(", ")}]`);
|
|
1307
|
-
await page.route("**/*", async (route) => {
|
|
1308
|
-
const url = route.request().url();
|
|
1309
|
-
const urlLower = url.toLowerCase();
|
|
1310
|
-
const shouldBlock = blockedExtensions.some((ext) => {
|
|
1311
|
-
const urlPath = urlLower.split("?")[0];
|
|
1312
|
-
return urlPath.endsWith(ext);
|
|
1313
|
-
});
|
|
1314
|
-
if (shouldBlock) {
|
|
1315
|
-
logger9.debug(`blocked: ${url.substring(0, 120)}`);
|
|
1316
|
-
return route.abort();
|
|
1317
|
-
}
|
|
1318
|
-
return route.continue();
|
|
1319
|
-
});
|
|
1320
|
-
logger9.success("setupBlockingResources", `\u5171 ${blockedExtensions.length} \u79CD\u6269\u5C55\u540D`);
|
|
1321
|
-
},
|
|
1322
1274
|
/**
|
|
1323
1275
|
* 获取所有可用的扩展名分类信息
|
|
1324
1276
|
*
|
|
@@ -1337,101 +1289,92 @@ var Blocking = {
|
|
|
1337
1289
|
};
|
|
1338
1290
|
},
|
|
1339
1291
|
/**
|
|
1340
|
-
*
|
|
1292
|
+
* 设置网络拦截规则(资源屏蔽 + CDN 直连)
|
|
1341
1293
|
*
|
|
1342
|
-
*
|
|
1343
|
-
* 1.
|
|
1344
|
-
* 2.
|
|
1294
|
+
* 工作流程:
|
|
1295
|
+
* 1. 检查请求是否在屏蔽列表中 → 如果是,直接 abort
|
|
1296
|
+
* 2. 检查是否匹配直连域名 → 如果是,使用 Node.js fetch 直连
|
|
1297
|
+
* 3. 其他请求正常走代理
|
|
1345
1298
|
*
|
|
1346
1299
|
* 适用场景:
|
|
1347
|
-
* - 代理 IP 无法访问某些 CDN
|
|
1300
|
+
* - 代理 IP 无法访问某些 CDN 域名
|
|
1348
1301
|
* - 需要加速静态资源加载
|
|
1349
|
-
*
|
|
1350
|
-
* 注意事项:
|
|
1351
|
-
* - 仅当代码运行在国内环境(本地/国内服务器)时,直连才能访问国内 CDN
|
|
1352
|
-
* - 如果在海外服务器(如 Apify 云端)运行,直连仍使用海外 IP,可能依然无法访问
|
|
1302
|
+
* - 屏蔽不必要的资源请求
|
|
1353
1303
|
*
|
|
1354
1304
|
* @param {import('playwright').Page} page - Playwright Page 对象
|
|
1355
|
-
* @param {Object} options - 配置选项
|
|
1356
|
-
* @param {string[]} options.
|
|
1357
|
-
* @param {Object} [options.blockingConfig] -
|
|
1305
|
+
* @param {Object} [options] - 配置选项
|
|
1306
|
+
* @param {string[]} [options.directDomains] - 需要直连的域名列表
|
|
1307
|
+
* @param {Object} [options.blockingConfig] - 资源屏蔽配置
|
|
1358
1308
|
* @param {boolean} [options.fallbackToProxy] - 直连失败时是否回退到代理(默认 true)
|
|
1359
1309
|
* @returns {Promise<void>}
|
|
1360
1310
|
*/
|
|
1361
|
-
async
|
|
1311
|
+
async setup(page, options = {}) {
|
|
1362
1312
|
const {
|
|
1363
|
-
|
|
1313
|
+
directDomains = [],
|
|
1364
1314
|
blockingConfig = {},
|
|
1365
1315
|
fallbackToProxy = true
|
|
1366
1316
|
} = options;
|
|
1367
|
-
if (domains.length === 0) {
|
|
1368
|
-
logger9.warn("setupDirectConnect", "\u672A\u6307\u5B9A\u57DF\u540D\u5217\u8868\uFF0C\u8DF3\u8FC7\u76F4\u8FDE\u914D\u7F6E");
|
|
1369
|
-
return;
|
|
1370
|
-
}
|
|
1371
1317
|
const mergedBlockingConfig = { ...DEFAULT_BLOCKING_CONFIG, ...blockingConfig };
|
|
1372
1318
|
const blockedExtensions = this.getBlockedExtensions(mergedBlockingConfig);
|
|
1373
|
-
|
|
1319
|
+
const enabledCategories = [];
|
|
1320
|
+
if (mergedBlockingConfig.blockArchive) enabledCategories.push("\u538B\u7F29\u5305");
|
|
1321
|
+
if (mergedBlockingConfig.blockExecutable) enabledCategories.push("\u53EF\u6267\u884C\u6587\u4EF6");
|
|
1322
|
+
if (mergedBlockingConfig.blockDocument) enabledCategories.push("\u529E\u516C\u6587\u6863");
|
|
1323
|
+
if (mergedBlockingConfig.blockImage) enabledCategories.push("\u56FE\u7247");
|
|
1324
|
+
if (mergedBlockingConfig.blockMedia) enabledCategories.push("\u97F3\u89C6\u9891");
|
|
1325
|
+
if (mergedBlockingConfig.blockFont) enabledCategories.push("\u5B57\u4F53");
|
|
1326
|
+
if (mergedBlockingConfig.blockCss) enabledCategories.push("CSS");
|
|
1327
|
+
if (mergedBlockingConfig.blockOther) enabledCategories.push("\u5176\u4ED6");
|
|
1328
|
+
const hasDirectDomains = directDomains.length > 0;
|
|
1329
|
+
logger9.start("setup", hasDirectDomains ? `\u76F4\u8FDE\u57DF\u540D: [${directDomains.join(", ")}]` : "\u4EC5\u8D44\u6E90\u5C4F\u853D\u6A21\u5F0F");
|
|
1374
1330
|
await page.route("**/*", async (route) => {
|
|
1375
1331
|
const request = route.request();
|
|
1376
1332
|
const url = request.url();
|
|
1377
1333
|
const urlLower = url.toLowerCase();
|
|
1378
1334
|
const urlPath = urlLower.split("?")[0];
|
|
1379
|
-
const matchesDomain = domains.some((domain) => url.includes(domain));
|
|
1380
|
-
if (matchesDomain) {
|
|
1381
|
-
const shouldBlock2 = blockedExtensions.some((ext) => urlPath.endsWith(ext));
|
|
1382
|
-
if (shouldBlock2) {
|
|
1383
|
-
logger9.debug(`blocked: ${url.substring(0, 100)}`);
|
|
1384
|
-
return route.abort();
|
|
1385
|
-
}
|
|
1386
|
-
try {
|
|
1387
|
-
const response = await fetch(url, {
|
|
1388
|
-
method: request.method(),
|
|
1389
|
-
headers: request.headers()
|
|
1390
|
-
// 不传 agent 参数 = 直连(使用服务器本地网络)
|
|
1391
|
-
});
|
|
1392
|
-
if (!response.ok) {
|
|
1393
|
-
throw new Error(`HTTP ${response.status}`);
|
|
1394
|
-
}
|
|
1395
|
-
const buffer = await response.arrayBuffer();
|
|
1396
|
-
const body = Buffer.from(buffer);
|
|
1397
|
-
const headers = {};
|
|
1398
|
-
response.headers.forEach((value, key) => {
|
|
1399
|
-
headers[key] = value;
|
|
1400
|
-
});
|
|
1401
|
-
logger9.debug(`direct: ${url.substring(0, 100)}`);
|
|
1402
|
-
await route.fulfill({
|
|
1403
|
-
status: response.status,
|
|
1404
|
-
headers,
|
|
1405
|
-
body
|
|
1406
|
-
});
|
|
1407
|
-
return;
|
|
1408
|
-
} catch (e) {
|
|
1409
|
-
if (fallbackToProxy) {
|
|
1410
|
-
logger9.debug(`fallback: ${url.substring(0, 80)} (${e.message})`);
|
|
1411
|
-
return route.continue();
|
|
1412
|
-
} else {
|
|
1413
|
-
logger9.warn("setupDirectConnect", `\u76F4\u8FDE\u5931\u8D25: ${url.substring(0, 80)}`);
|
|
1414
|
-
return route.abort();
|
|
1415
|
-
}
|
|
1416
|
-
}
|
|
1417
|
-
}
|
|
1418
1335
|
const shouldBlock = blockedExtensions.some((ext) => urlPath.endsWith(ext));
|
|
1419
1336
|
if (shouldBlock) {
|
|
1420
1337
|
logger9.debug(`blocked: ${url.substring(0, 100)}`);
|
|
1421
1338
|
return route.abort();
|
|
1422
1339
|
}
|
|
1340
|
+
if (hasDirectDomains) {
|
|
1341
|
+
const matchesDomain = directDomains.some((domain) => url.includes(domain));
|
|
1342
|
+
if (matchesDomain) {
|
|
1343
|
+
try {
|
|
1344
|
+
const response = await fetch(url, {
|
|
1345
|
+
method: request.method(),
|
|
1346
|
+
headers: request.headers()
|
|
1347
|
+
});
|
|
1348
|
+
if (!response.ok) {
|
|
1349
|
+
throw new Error(`HTTP ${response.status}`);
|
|
1350
|
+
}
|
|
1351
|
+
const buffer = await response.arrayBuffer();
|
|
1352
|
+
const body = Buffer.from(buffer);
|
|
1353
|
+
const headers = {};
|
|
1354
|
+
response.headers.forEach((value, key) => {
|
|
1355
|
+
headers[key] = value;
|
|
1356
|
+
});
|
|
1357
|
+
logger9.debug(`direct: ${url.substring(0, 100)}`);
|
|
1358
|
+
await route.fulfill({
|
|
1359
|
+
status: response.status,
|
|
1360
|
+
headers,
|
|
1361
|
+
body
|
|
1362
|
+
});
|
|
1363
|
+
return;
|
|
1364
|
+
} catch (e) {
|
|
1365
|
+
if (fallbackToProxy) {
|
|
1366
|
+
logger9.debug(`fallback: ${url.substring(0, 80)} (${e.message})`);
|
|
1367
|
+
return route.continue();
|
|
1368
|
+
} else {
|
|
1369
|
+
logger9.warn("setup", `\u76F4\u8FDE\u5931\u8D25: ${url.substring(0, 80)}`);
|
|
1370
|
+
return route.abort();
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1423
1375
|
return route.continue();
|
|
1424
1376
|
});
|
|
1425
|
-
|
|
1426
|
-
if (mergedBlockingConfig.blockArchive) enabledCategories.push("\u538B\u7F29\u5305");
|
|
1427
|
-
if (mergedBlockingConfig.blockExecutable) enabledCategories.push("\u53EF\u6267\u884C\u6587\u4EF6");
|
|
1428
|
-
if (mergedBlockingConfig.blockDocument) enabledCategories.push("\u529E\u516C\u6587\u6863");
|
|
1429
|
-
if (mergedBlockingConfig.blockImage) enabledCategories.push("\u56FE\u7247");
|
|
1430
|
-
if (mergedBlockingConfig.blockMedia) enabledCategories.push("\u97F3\u89C6\u9891");
|
|
1431
|
-
if (mergedBlockingConfig.blockFont) enabledCategories.push("\u5B57\u4F53");
|
|
1432
|
-
if (mergedBlockingConfig.blockCss) enabledCategories.push("CSS");
|
|
1433
|
-
if (mergedBlockingConfig.blockOther) enabledCategories.push("\u5176\u4ED6");
|
|
1434
|
-
logger9.success("setupDirectConnect", `\u5C4F\u853D\u5206\u7C7B: [${enabledCategories.join(", ")}]`);
|
|
1377
|
+
logger9.success("setup", `\u5C4F\u853D\u5206\u7C7B: [${enabledCategories.join(", ")}]`);
|
|
1435
1378
|
}
|
|
1436
1379
|
};
|
|
1437
1380
|
|
|
@@ -1448,7 +1391,7 @@ var usePlaywrightToolKit = () => {
|
|
|
1448
1391
|
Captcha,
|
|
1449
1392
|
Sse,
|
|
1450
1393
|
Errors: errors_exports,
|
|
1451
|
-
|
|
1394
|
+
Interception
|
|
1452
1395
|
};
|
|
1453
1396
|
};
|
|
1454
1397
|
// Annotate the CommonJS export names for ESM import in node:
|