@skrillex1224/playwright-toolkit 2.0.92 → 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 +69 -107
- package/dist/index.cjs.map +3 -3
- package/dist/index.js +69 -107
- package/dist/index.js.map +3 -3
- 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,82 +1260,92 @@ var Blocking = {
|
|
|
1308
1260
|
};
|
|
1309
1261
|
},
|
|
1310
1262
|
/**
|
|
1311
|
-
*
|
|
1312
|
-
*
|
|
1263
|
+
* 设置网络拦截规则(资源屏蔽 + CDN 直连)
|
|
1264
|
+
*
|
|
1265
|
+
* 工作流程:
|
|
1266
|
+
* 1. 检查请求是否在屏蔽列表中 → 如果是,直接 abort
|
|
1267
|
+
* 2. 检查是否匹配直连域名 → 如果是,使用 Node.js fetch 直连
|
|
1268
|
+
* 3. 其他请求正常走代理
|
|
1313
1269
|
*
|
|
1314
1270
|
* 适用场景:
|
|
1315
|
-
* - 代理 IP 无法访问某些 CDN
|
|
1271
|
+
* - 代理 IP 无法访问某些 CDN 域名
|
|
1316
1272
|
* - 需要加速静态资源加载
|
|
1317
|
-
*
|
|
1318
|
-
* 注意事项:
|
|
1319
|
-
* - 仅当代码运行在国内环境(本地/国内服务器)时,直连才能访问国内 CDN
|
|
1320
|
-
* - 如果在海外服务器(如 Apify 云端)运行,直连仍使用海外 IP,可能依然无法访问
|
|
1273
|
+
* - 屏蔽不必要的资源请求
|
|
1321
1274
|
*
|
|
1322
1275
|
* @param {import('playwright').Page} page - Playwright Page 对象
|
|
1323
1276
|
* @param {Object} [options] - 配置选项
|
|
1324
|
-
* @param {string[]} [options.
|
|
1325
|
-
* @param {
|
|
1277
|
+
* @param {string[]} [options.directDomains] - 需要直连的域名列表
|
|
1278
|
+
* @param {Object} [options.blockingConfig] - 资源屏蔽配置
|
|
1326
1279
|
* @param {boolean} [options.fallbackToProxy] - 直连失败时是否回退到代理(默认 true)
|
|
1327
1280
|
* @returns {Promise<void>}
|
|
1328
1281
|
*/
|
|
1329
|
-
async
|
|
1282
|
+
async setup(page, options = {}) {
|
|
1330
1283
|
const {
|
|
1331
|
-
|
|
1332
|
-
|
|
1284
|
+
directDomains = [],
|
|
1285
|
+
blockingConfig = {},
|
|
1333
1286
|
fallbackToProxy = true
|
|
1334
1287
|
} = options;
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1288
|
+
const mergedBlockingConfig = { ...DEFAULT_BLOCKING_CONFIG, ...blockingConfig };
|
|
1289
|
+
const blockedExtensions = this.getBlockedExtensions(mergedBlockingConfig);
|
|
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");
|
|
1342
1301
|
await page.route("**/*", async (route) => {
|
|
1343
1302
|
const request = route.request();
|
|
1344
1303
|
const url = request.url();
|
|
1345
1304
|
const urlLower = url.toLowerCase();
|
|
1346
1305
|
const urlPath = urlLower.split("?")[0];
|
|
1347
|
-
const
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1306
|
+
const shouldBlock = blockedExtensions.some((ext) => urlPath.endsWith(ext));
|
|
1307
|
+
if (shouldBlock) {
|
|
1308
|
+
logger9.debug(`blocked: ${url.substring(0, 100)}`);
|
|
1309
|
+
return route.abort();
|
|
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
|
+
}
|
|
1381
1343
|
}
|
|
1382
1344
|
}
|
|
1383
1345
|
}
|
|
1384
1346
|
return route.continue();
|
|
1385
1347
|
});
|
|
1386
|
-
logger9.success("
|
|
1348
|
+
logger9.success("setup", `\u5C4F\u853D\u5206\u7C7B: [${enabledCategories.join(", ")}]`);
|
|
1387
1349
|
}
|
|
1388
1350
|
};
|
|
1389
1351
|
|
|
@@ -1400,7 +1362,7 @@ var usePlaywrightToolKit = () => {
|
|
|
1400
1362
|
Captcha,
|
|
1401
1363
|
Sse,
|
|
1402
1364
|
Errors: errors_exports,
|
|
1403
|
-
|
|
1365
|
+
Interception
|
|
1404
1366
|
};
|
|
1405
1367
|
};
|
|
1406
1368
|
export {
|