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