@letsscrapedata/controller 0.0.1 → 0.0.3
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.mjs → index.cjs} +293 -184
- package/dist/{index.d.mts → index.d.cts} +67 -19
- package/dist/index.d.ts +67 -19
- package/dist/index.js +273 -204
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -28,13 +27,12 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
27
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
29
28
|
mod
|
|
30
29
|
));
|
|
31
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
32
30
|
|
|
33
31
|
// ../../node_modules/boolbase/index.js
|
|
34
32
|
var require_boolbase = __commonJS({
|
|
35
|
-
"../../node_modules/boolbase/index.js"(
|
|
33
|
+
"../../node_modules/boolbase/index.js"(exports, module) {
|
|
36
34
|
"use strict";
|
|
37
|
-
|
|
35
|
+
module.exports = {
|
|
38
36
|
trueFunc: function trueFunc2() {
|
|
39
37
|
return true;
|
|
40
38
|
},
|
|
@@ -45,23 +43,6 @@ var require_boolbase = __commonJS({
|
|
|
45
43
|
}
|
|
46
44
|
});
|
|
47
45
|
|
|
48
|
-
// src/index.ts
|
|
49
|
-
var src_exports = {};
|
|
50
|
-
__export(src_exports, {
|
|
51
|
-
CheerioElement: () => CheerioElement,
|
|
52
|
-
CheerioPage: () => CheerioPage,
|
|
53
|
-
PlaywrightBrowser: () => PlaywrightBrowser,
|
|
54
|
-
PlaywrightBrowserContext: () => PlaywrightBrowserContext,
|
|
55
|
-
PlaywrightElement: () => PlaywrightElement,
|
|
56
|
-
PlaywrightPage: () => PlaywrightPage,
|
|
57
|
-
PuppeteerBrowser: () => PuppeteerBrowser,
|
|
58
|
-
PuppeteerBrowserContext: () => PuppeteerBrowserContext,
|
|
59
|
-
PuppeteerElement: () => PuppeteerElement,
|
|
60
|
-
PuppeteerPage: () => PuppeteerPage,
|
|
61
|
-
defaultProxy: () => defaultProxy
|
|
62
|
-
});
|
|
63
|
-
module.exports = __toCommonJS(src_exports);
|
|
64
|
-
|
|
65
46
|
// src/types/types.ts
|
|
66
47
|
var defaultProxy = {
|
|
67
48
|
server: "default",
|
|
@@ -73,18 +54,18 @@ var defaultProxy = {
|
|
|
73
54
|
};
|
|
74
55
|
|
|
75
56
|
// src/playwright/browser.ts
|
|
76
|
-
|
|
57
|
+
import EventEmitter3 from "events";
|
|
77
58
|
|
|
78
59
|
// src/playwright/context.ts
|
|
79
|
-
|
|
80
|
-
|
|
60
|
+
import EventEmitter2 from "events";
|
|
61
|
+
import { getCurrentUnixTime as getCurrentUnixTime2, logerr as logerr2, loginfo as loginfo2, logwarn as logwarn2, sleep } from "@letsscrapedata/utils";
|
|
81
62
|
|
|
82
63
|
// src/playwright/page.ts
|
|
83
|
-
|
|
84
|
-
|
|
64
|
+
import EventEmitter from "events";
|
|
65
|
+
import { getCurrentUnixTime, logerr, loginfo, logwarn, unreachable as unreachable2 } from "@letsscrapedata/utils";
|
|
85
66
|
|
|
86
67
|
// src/playwright/element.ts
|
|
87
|
-
|
|
68
|
+
import { unreachable } from "@letsscrapedata/utils";
|
|
88
69
|
var PlaywrightElement = class _PlaywrightElement {
|
|
89
70
|
#frame;
|
|
90
71
|
#locator;
|
|
@@ -300,39 +281,21 @@ var PlaywrightElement = class _PlaywrightElement {
|
|
|
300
281
|
}
|
|
301
282
|
break;
|
|
302
283
|
default:
|
|
303
|
-
|
|
284
|
+
unreachable(type);
|
|
304
285
|
}
|
|
305
286
|
return true;
|
|
306
287
|
}
|
|
307
288
|
async screenshot(options) {
|
|
308
289
|
return await this.#locator.screenshot(options);
|
|
309
290
|
}
|
|
310
|
-
async scrollBy(x, y) {
|
|
311
|
-
await this.#locator.page().evaluate(
|
|
312
|
-
([x2, y2]) => {
|
|
313
|
-
window.scrollBy(x2, y2);
|
|
314
|
-
},
|
|
315
|
-
[x, y]
|
|
316
|
-
);
|
|
317
|
-
return true;
|
|
318
|
-
}
|
|
319
291
|
async scrollIntoView() {
|
|
320
292
|
await this.#locator.scrollIntoViewIfNeeded();
|
|
321
293
|
return true;
|
|
322
294
|
}
|
|
323
|
-
async scrollTo(x, y) {
|
|
324
|
-
await this.#locator.page().evaluate(
|
|
325
|
-
([x2, y2]) => {
|
|
326
|
-
window.scrollTo(x2, y2);
|
|
327
|
-
},
|
|
328
|
-
[x, y]
|
|
329
|
-
);
|
|
330
|
-
return true;
|
|
331
|
-
}
|
|
332
295
|
};
|
|
333
296
|
|
|
334
297
|
// src/playwright/page.ts
|
|
335
|
-
var PlaywrightPage = class extends
|
|
298
|
+
var PlaywrightPage = class extends EventEmitter {
|
|
336
299
|
#lsdBrowserContext;
|
|
337
300
|
#page;
|
|
338
301
|
#status;
|
|
@@ -354,7 +317,7 @@ var PlaywrightPage = class extends import_node_events.default {
|
|
|
354
317
|
const cookieItems = await this.#getCookies(page);
|
|
355
318
|
const domainSet = new Set(cookieItems.map((c) => c.domain));
|
|
356
319
|
if (domainSet.size !== 1) {
|
|
357
|
-
|
|
320
|
+
logwarn(`Domains in clearCookies: ${Array.from(domainSet.values())}`);
|
|
358
321
|
}
|
|
359
322
|
for (const domain of domainSet.values()) {
|
|
360
323
|
await browserContext.clearCookies({ domain });
|
|
@@ -506,9 +469,9 @@ var PlaywrightPage = class extends import_node_events.default {
|
|
|
506
469
|
const page = this.#page;
|
|
507
470
|
const pageId = this.#pageId;
|
|
508
471
|
page.on("close", async () => {
|
|
509
|
-
|
|
472
|
+
loginfo(`##browser ${pageId} closed`);
|
|
510
473
|
if (!page.pageInfo) {
|
|
511
|
-
|
|
474
|
+
logerr(`Logic error in page.on("close")`);
|
|
512
475
|
}
|
|
513
476
|
this.emit("pageClose");
|
|
514
477
|
this.#lsdBrowserContext.emit("pageClose", this);
|
|
@@ -522,12 +485,12 @@ var PlaywrightPage = class extends import_node_events.default {
|
|
|
522
485
|
popupPageId = `page-${browserIdx}-${browserContextIdx}-${pageIdx}`;
|
|
523
486
|
pageInfo.openType = "popup";
|
|
524
487
|
} else {
|
|
525
|
-
|
|
488
|
+
logerr(`##browser ${pageId} has popup without page.pageInfo`);
|
|
526
489
|
}
|
|
527
|
-
|
|
490
|
+
loginfo(`##browser ${pageId} has popup ${popupPageId}`);
|
|
528
491
|
this.emit("pagePopup", pageInfo);
|
|
529
492
|
} else {
|
|
530
|
-
|
|
493
|
+
logerr(`##browser ${pageId} has popup page with null page`);
|
|
531
494
|
}
|
|
532
495
|
});
|
|
533
496
|
}
|
|
@@ -539,7 +502,7 @@ var PlaywrightPage = class extends import_node_events.default {
|
|
|
539
502
|
this.#lsdBrowserContext = browserContext;
|
|
540
503
|
this.#page = page;
|
|
541
504
|
this.#status = "free";
|
|
542
|
-
const currentTime =
|
|
505
|
+
const currentTime = getCurrentUnixTime();
|
|
543
506
|
const { browserIdx = 0, browserContextIdx = 0, pageIdx = 0, openType = "other", openTime = currentTime, lastStatusUpdateTime = currentTime, taskId = 0 } = pageInfo ? pageInfo : {};
|
|
544
507
|
this.#page.pageInfo = { browserIdx, browserContextIdx, pageIdx, openType, openTime, lastStatusUpdateTime, taskId };
|
|
545
508
|
this.#pageId = `page${browserIdx}-${browserContextIdx}-${pageIdx}`;
|
|
@@ -587,7 +550,7 @@ var PlaywrightPage = class extends import_node_events.default {
|
|
|
587
550
|
}
|
|
588
551
|
return true;
|
|
589
552
|
} catch (err) {
|
|
590
|
-
|
|
553
|
+
logerr(err);
|
|
591
554
|
return false;
|
|
592
555
|
}
|
|
593
556
|
}
|
|
@@ -685,12 +648,19 @@ var PlaywrightPage = class extends import_node_events.default {
|
|
|
685
648
|
await this.clearResponseInterceptions();
|
|
686
649
|
return true;
|
|
687
650
|
}
|
|
651
|
+
#getWaitUntil(origWaitUntil) {
|
|
652
|
+
if (origWaitUntil === "networkidle0" || origWaitUntil === "networkidle2") {
|
|
653
|
+
return "networkidle";
|
|
654
|
+
} else {
|
|
655
|
+
return origWaitUntil;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
688
658
|
async goto(url, options) {
|
|
689
659
|
if (!this.#page) {
|
|
690
660
|
throw new Error("No valid page");
|
|
691
661
|
}
|
|
692
662
|
if (options) {
|
|
693
|
-
const { referer, timeout, waitUntil } = options;
|
|
663
|
+
const { referer, timeout, waitUntil = "load" } = options;
|
|
694
664
|
const newOptions = {};
|
|
695
665
|
if (referer) {
|
|
696
666
|
newOptions.referer = referer;
|
|
@@ -698,9 +668,7 @@ var PlaywrightPage = class extends import_node_events.default {
|
|
|
698
668
|
if (timeout) {
|
|
699
669
|
newOptions.timeout = timeout;
|
|
700
670
|
}
|
|
701
|
-
|
|
702
|
-
newOptions.waitUntil = waitUntil === "networkidle" ? "networkidle0" : waitUntil;
|
|
703
|
-
}
|
|
671
|
+
newOptions.waitUntil = this.#getWaitUntil(waitUntil);
|
|
704
672
|
await this.#page.goto(url, newOptions);
|
|
705
673
|
} else {
|
|
706
674
|
await this.#page.goto(url);
|
|
@@ -771,6 +739,30 @@ var PlaywrightPage = class extends import_node_events.default {
|
|
|
771
739
|
}
|
|
772
740
|
return await this.#page.screenshot(options);
|
|
773
741
|
}
|
|
742
|
+
async scrollBy(x, y) {
|
|
743
|
+
if (!this.#page) {
|
|
744
|
+
throw new Error("No valid page");
|
|
745
|
+
}
|
|
746
|
+
await this.#page.evaluate(
|
|
747
|
+
([x2, y2]) => {
|
|
748
|
+
window.scrollBy(x2, y2);
|
|
749
|
+
},
|
|
750
|
+
[x, y]
|
|
751
|
+
);
|
|
752
|
+
return true;
|
|
753
|
+
}
|
|
754
|
+
async scrollTo(x, y) {
|
|
755
|
+
if (!this.#page) {
|
|
756
|
+
throw new Error("No valid page");
|
|
757
|
+
}
|
|
758
|
+
await this.#page.evaluate(
|
|
759
|
+
([x2, y2]) => {
|
|
760
|
+
window.scrollTo(x2, y2);
|
|
761
|
+
},
|
|
762
|
+
[x, y]
|
|
763
|
+
);
|
|
764
|
+
return true;
|
|
765
|
+
}
|
|
774
766
|
async setCookies(cookies) {
|
|
775
767
|
if (!this.#page) {
|
|
776
768
|
throw new Error("No valid page");
|
|
@@ -831,7 +823,7 @@ var PlaywrightPage = class extends import_node_events.default {
|
|
|
831
823
|
}
|
|
832
824
|
return true;
|
|
833
825
|
} catch (err) {
|
|
834
|
-
|
|
826
|
+
logerr(err);
|
|
835
827
|
return false;
|
|
836
828
|
}
|
|
837
829
|
}
|
|
@@ -841,7 +833,7 @@ var PlaywrightPage = class extends import_node_events.default {
|
|
|
841
833
|
}
|
|
842
834
|
const actOptions = Array.isArray(options) ? options : [options];
|
|
843
835
|
if (actOptions.length <= 0) {
|
|
844
|
-
|
|
836
|
+
logwarn("Invalid paras in setRequestInterception");
|
|
845
837
|
return false;
|
|
846
838
|
}
|
|
847
839
|
const firstRequestInterception = this.#resquestInterceptionOptions.length <= 0;
|
|
@@ -852,7 +844,7 @@ var PlaywrightPage = class extends import_node_events.default {
|
|
|
852
844
|
this.#resquestInterceptionOptions.push(option);
|
|
853
845
|
break;
|
|
854
846
|
default:
|
|
855
|
-
(
|
|
847
|
+
unreachable2(option.action);
|
|
856
848
|
}
|
|
857
849
|
}
|
|
858
850
|
if (firstRequestInterception && this.#resquestInterceptionOptions.length > 0) {
|
|
@@ -876,7 +868,7 @@ var PlaywrightPage = class extends import_node_events.default {
|
|
|
876
868
|
});
|
|
877
869
|
break;
|
|
878
870
|
default:
|
|
879
|
-
(
|
|
871
|
+
unreachable2(action);
|
|
880
872
|
}
|
|
881
873
|
return true;
|
|
882
874
|
} else {
|
|
@@ -885,7 +877,7 @@ var PlaywrightPage = class extends import_node_events.default {
|
|
|
885
877
|
await route.continue();
|
|
886
878
|
return true;
|
|
887
879
|
} catch (err) {
|
|
888
|
-
|
|
880
|
+
logerr(err);
|
|
889
881
|
return false;
|
|
890
882
|
}
|
|
891
883
|
});
|
|
@@ -903,7 +895,7 @@ var PlaywrightPage = class extends import_node_events.default {
|
|
|
903
895
|
return;
|
|
904
896
|
}
|
|
905
897
|
for (const option of this.#responseInterceptionOptions) {
|
|
906
|
-
const { requestMatch, responseMatch,
|
|
898
|
+
const { requestMatch, responseMatch, responseItems, handler, handlerOptions } = option;
|
|
907
899
|
let matchedFlag = !requestMatch || this.#checkRequestMatch(request, requestMatch);
|
|
908
900
|
if (matchedFlag && responseMatch) {
|
|
909
901
|
const { minLength, maxLength } = responseMatch;
|
|
@@ -916,20 +908,20 @@ var PlaywrightPage = class extends import_node_events.default {
|
|
|
916
908
|
if (!matchedFlag) {
|
|
917
909
|
continue;
|
|
918
910
|
}
|
|
919
|
-
if (Array.isArray(
|
|
911
|
+
if (Array.isArray(responseItems)) {
|
|
920
912
|
const requestMethod = request.method();
|
|
921
913
|
const requestUrl = request.url();
|
|
922
914
|
const reqData2 = request.postData();
|
|
923
915
|
const requestData = reqData2 ? reqData2 : "";
|
|
924
916
|
const responseData = await response.text();
|
|
925
|
-
|
|
917
|
+
responseItems.push({
|
|
926
918
|
pageUrl,
|
|
927
919
|
requestMethod,
|
|
928
920
|
requestUrl,
|
|
929
921
|
requestData,
|
|
930
922
|
responseData
|
|
931
923
|
});
|
|
932
|
-
|
|
924
|
+
loginfo(`##browser cache matched response: ${requestUrl}`);
|
|
933
925
|
}
|
|
934
926
|
if (typeof handler === "function") {
|
|
935
927
|
await handler(response, handlerOptions);
|
|
@@ -937,7 +929,7 @@ var PlaywrightPage = class extends import_node_events.default {
|
|
|
937
929
|
}
|
|
938
930
|
return;
|
|
939
931
|
} catch (err) {
|
|
940
|
-
|
|
932
|
+
logerr(err);
|
|
941
933
|
return;
|
|
942
934
|
}
|
|
943
935
|
}
|
|
@@ -952,7 +944,7 @@ var PlaywrightPage = class extends import_node_events.default {
|
|
|
952
944
|
}
|
|
953
945
|
const firstResponseInterception = this.#responseInterceptionOptions.length <= 0;
|
|
954
946
|
for (const option of actOptions) {
|
|
955
|
-
if (option?.
|
|
947
|
+
if (option?.responseItems || option?.handler) {
|
|
956
948
|
this.#responseInterceptionOptions.push(option);
|
|
957
949
|
} else {
|
|
958
950
|
throw new Error(`Invalid ResponseInterceptionOption`);
|
|
@@ -1009,6 +1001,30 @@ var PlaywrightPage = class extends import_node_events.default {
|
|
|
1009
1001
|
this.#status = "busy";
|
|
1010
1002
|
return true;
|
|
1011
1003
|
}
|
|
1004
|
+
async waitForElement(selector, options = {}) {
|
|
1005
|
+
if (!this.#page) {
|
|
1006
|
+
throw new Error("No valid page");
|
|
1007
|
+
}
|
|
1008
|
+
const locator = this.#page.locator(selector);
|
|
1009
|
+
const { timeout = 3e4, state = "visible" } = options;
|
|
1010
|
+
await locator.waitFor({ state, timeout });
|
|
1011
|
+
return true;
|
|
1012
|
+
}
|
|
1013
|
+
async waitForNavigation(options) {
|
|
1014
|
+
if (!this.#page) {
|
|
1015
|
+
throw new Error("No valid page");
|
|
1016
|
+
}
|
|
1017
|
+
const { url = "", timeout = 3e4, waitUntil = "load" } = options;
|
|
1018
|
+
const newWaitUntil = this.#getWaitUntil(waitUntil);
|
|
1019
|
+
if (url) {
|
|
1020
|
+
await this.#page.waitForURL(url, { timeout, waitUntil: newWaitUntil });
|
|
1021
|
+
} else if (newWaitUntil === "commit") {
|
|
1022
|
+
throw new Error("commit is not supported in PlaywrightPage.waitForNavigation");
|
|
1023
|
+
} else {
|
|
1024
|
+
await this.#page.waitForLoadState(newWaitUntil, { timeout });
|
|
1025
|
+
}
|
|
1026
|
+
return true;
|
|
1027
|
+
}
|
|
1012
1028
|
async windowMember(keys) {
|
|
1013
1029
|
if (!this.#page) {
|
|
1014
1030
|
throw new Error("No valid page");
|
|
@@ -1037,7 +1053,7 @@ var PlaywrightPage = class extends import_node_events.default {
|
|
|
1037
1053
|
};
|
|
1038
1054
|
|
|
1039
1055
|
// src/playwright/context.ts
|
|
1040
|
-
var PlaywrightBrowserContext = class extends
|
|
1056
|
+
var PlaywrightBrowserContext = class extends EventEmitter2 {
|
|
1041
1057
|
#lsdBrowser;
|
|
1042
1058
|
#browserIdx;
|
|
1043
1059
|
#browserContextIdx;
|
|
@@ -1056,12 +1072,12 @@ var PlaywrightBrowserContext = class extends import_node_events2.default {
|
|
|
1056
1072
|
}
|
|
1057
1073
|
const pages = this.#browserContext.pages();
|
|
1058
1074
|
const openType = this.#lsdBrowser.browserCreationMethod();
|
|
1059
|
-
const lastStatusUpdateTime = (
|
|
1075
|
+
const lastStatusUpdateTime = getCurrentUnixTime2();
|
|
1060
1076
|
for (const page of pages) {
|
|
1061
1077
|
const pageInfo = { browserIdx: this.#browserIdx, browserContextIdx: this.#browserContextIdx, pageIdx: this.#nextPageIdx++, openType, openTime: this.#createTime, lastStatusUpdateTime, taskId: 0 };
|
|
1062
1078
|
const lsdPage = new PlaywrightPage(this, page, pageInfo);
|
|
1063
1079
|
this.#lsdPages.push(lsdPage);
|
|
1064
|
-
(
|
|
1080
|
+
loginfo2(`##browser ${lsdPage.id()} ${openType}ed`);
|
|
1065
1081
|
}
|
|
1066
1082
|
}
|
|
1067
1083
|
constructor(lsdBrowser, browserContext, incognito = false, proxy = null, browserIdx = 0, browserContextIdx = 0, maxPagesPerBrowserContext = 20, maxPageFreeSeconds = 0) {
|
|
@@ -1076,7 +1092,7 @@ var PlaywrightBrowserContext = class extends import_node_events2.default {
|
|
|
1076
1092
|
this.#browserIdx = browserIdx;
|
|
1077
1093
|
this.#browserContextIdx = browserContextIdx;
|
|
1078
1094
|
this.#browserContext = browserContext;
|
|
1079
|
-
this.#createTime = (
|
|
1095
|
+
this.#createTime = getCurrentUnixTime2();
|
|
1080
1096
|
this.#incognito = incognito === false ? false : true;
|
|
1081
1097
|
this.#proxy = proxy?.server ? proxy : null;
|
|
1082
1098
|
this.#maxPagesPerBrowserContext = maxPagesPerBrowserContext;
|
|
@@ -1089,29 +1105,29 @@ var PlaywrightBrowserContext = class extends import_node_events2.default {
|
|
|
1089
1105
|
const pageInfo = page.pageInfo;
|
|
1090
1106
|
if (pageInfo) {
|
|
1091
1107
|
const { browserIdx: browserIdx2, browserContextIdx: browserContextIdx2, pageIdx } = pageInfo;
|
|
1092
|
-
(
|
|
1108
|
+
logwarn2(`##browser page-${browserIdx2}-${browserContextIdx2}-${pageIdx} has been already created`);
|
|
1093
1109
|
} else {
|
|
1094
|
-
const currentTime = (
|
|
1110
|
+
const currentTime = getCurrentUnixTime2();
|
|
1095
1111
|
const pageInfo2 = { browserIdx: this.#browserIdx, browserContextIdx: this.#browserContextIdx, pageIdx: this.#nextPageIdx++, openType: "other", openTime: currentTime, lastStatusUpdateTime: currentTime, taskId: 0 };
|
|
1096
1112
|
const lsdPage = new PlaywrightPage(this, page, pageInfo2);
|
|
1097
1113
|
this.#lsdPages.push(lsdPage);
|
|
1098
|
-
(
|
|
1114
|
+
loginfo2(`##browser ${lsdPage.id()} created`);
|
|
1099
1115
|
}
|
|
1100
1116
|
});
|
|
1101
1117
|
browserContext.on("close", (bc) => {
|
|
1102
1118
|
if (browserContext !== bc) {
|
|
1103
|
-
(
|
|
1119
|
+
logerr2(`##browser different browserContext in browserContext.on("close")`);
|
|
1104
1120
|
}
|
|
1105
1121
|
this.#lsdBrowser.emit("browserContextClose", this);
|
|
1106
1122
|
});
|
|
1107
1123
|
this.on("pageClose", (lsdPage) => {
|
|
1108
1124
|
if (!(lsdPage instanceof PlaywrightPage)) {
|
|
1109
|
-
(
|
|
1125
|
+
logerr2(`Invalid data in LsdBrowserContext.on("pageClose)`);
|
|
1110
1126
|
return;
|
|
1111
1127
|
}
|
|
1112
1128
|
const idx = this.#lsdPages.findIndex((p) => p === lsdPage);
|
|
1113
1129
|
if (idx < 0) {
|
|
1114
|
-
(
|
|
1130
|
+
logerr2(`Invalid lsdPage in LsdBrowserContext.on("pageClose)`);
|
|
1115
1131
|
return;
|
|
1116
1132
|
}
|
|
1117
1133
|
this.#lsdPages.splice(idx, 1);
|
|
@@ -1134,15 +1150,15 @@ var PlaywrightBrowserContext = class extends import_node_events2.default {
|
|
|
1134
1150
|
this.#gettingPage = true;
|
|
1135
1151
|
return true;
|
|
1136
1152
|
} else {
|
|
1137
|
-
await
|
|
1153
|
+
await sleep(200);
|
|
1138
1154
|
}
|
|
1139
1155
|
}
|
|
1140
|
-
(
|
|
1156
|
+
logwarn2(`Cannot get the gettingLock.`);
|
|
1141
1157
|
return false;
|
|
1142
1158
|
}
|
|
1143
1159
|
#freeGettingLock() {
|
|
1144
1160
|
if (!this.#gettingPage) {
|
|
1145
|
-
(
|
|
1161
|
+
logwarn2(`Getting lock is already free now.`);
|
|
1146
1162
|
}
|
|
1147
1163
|
this.#gettingPage = false;
|
|
1148
1164
|
}
|
|
@@ -1151,7 +1167,7 @@ var PlaywrightBrowserContext = class extends import_node_events2.default {
|
|
|
1151
1167
|
maxPageFreeSeconds = this.#maxPageFreeSeconds;
|
|
1152
1168
|
}
|
|
1153
1169
|
if (maxPageFreeSeconds <= 0) {
|
|
1154
|
-
(
|
|
1170
|
+
logwarn2(`Please set valid maxPageFreeSeconds to close free pages`);
|
|
1155
1171
|
return false;
|
|
1156
1172
|
}
|
|
1157
1173
|
const gotLock = await this.#tryToGetGettingLock();
|
|
@@ -1159,7 +1175,7 @@ var PlaywrightBrowserContext = class extends import_node_events2.default {
|
|
|
1159
1175
|
return false;
|
|
1160
1176
|
}
|
|
1161
1177
|
try {
|
|
1162
|
-
const maxUpdateTime = (
|
|
1178
|
+
const maxUpdateTime = getCurrentUnixTime2() - this.#maxPageFreeSeconds;
|
|
1163
1179
|
let freePages = this.#lsdPages.filter((p) => p.isFree() && p.pageInfo().lastStatusUpdateTime < maxUpdateTime);
|
|
1164
1180
|
if (freePages.length === this.#lsdPages.length) {
|
|
1165
1181
|
freePages = freePages.slice(1);
|
|
@@ -1170,7 +1186,7 @@ var PlaywrightBrowserContext = class extends import_node_events2.default {
|
|
|
1170
1186
|
this.#freeGettingLock();
|
|
1171
1187
|
return true;
|
|
1172
1188
|
} catch (err) {
|
|
1173
|
-
(
|
|
1189
|
+
logerr2(err);
|
|
1174
1190
|
this.#freeGettingLock();
|
|
1175
1191
|
return false;
|
|
1176
1192
|
}
|
|
@@ -1211,7 +1227,7 @@ var PlaywrightBrowserContext = class extends import_node_events2.default {
|
|
|
1211
1227
|
return null;
|
|
1212
1228
|
}
|
|
1213
1229
|
} catch (err) {
|
|
1214
|
-
(
|
|
1230
|
+
logerr2(err);
|
|
1215
1231
|
this.#freeGettingLock();
|
|
1216
1232
|
return null;
|
|
1217
1233
|
}
|
|
@@ -1274,8 +1290,8 @@ var PlaywrightBrowserContext = class extends import_node_events2.default {
|
|
|
1274
1290
|
};
|
|
1275
1291
|
|
|
1276
1292
|
// src/playwright/browser.ts
|
|
1277
|
-
|
|
1278
|
-
var PlaywrightBrowser = class extends
|
|
1293
|
+
import { logerr as logerr3, loginfo as loginfo3, logwarn as logwarn3 } from "@letsscrapedata/utils";
|
|
1294
|
+
var PlaywrightBrowser = class extends EventEmitter3 {
|
|
1279
1295
|
#browser;
|
|
1280
1296
|
#browserIdx;
|
|
1281
1297
|
#lsdBrowserContexts;
|
|
@@ -1320,38 +1336,38 @@ var PlaywrightBrowser = class extends import_node_events3.default {
|
|
|
1320
1336
|
this.#executablePath = executablePath;
|
|
1321
1337
|
this.#nextBrowserContextIdx = 1;
|
|
1322
1338
|
this.#closeFreePagesIntervalId = null;
|
|
1323
|
-
(
|
|
1339
|
+
loginfo3(`##browser ${this.#browserType} ${this.id()} ${this.#browserCreationMethod}ed by ${this.#browserControllerType}`);
|
|
1324
1340
|
const browserContexts = browser.contexts();
|
|
1325
1341
|
if (browserContexts.length > 0) {
|
|
1326
|
-
(
|
|
1342
|
+
logwarn3(`There are ${browserContexts.length} new browserContexts when playwright launches new browser`);
|
|
1327
1343
|
}
|
|
1328
1344
|
const incognito = typeof options?.incognito === "boolean" ? options.incognito : true;
|
|
1329
1345
|
for (const browserContext of browserContexts) {
|
|
1330
1346
|
const lsdBrowserContext = new PlaywrightBrowserContext(this, browserContext, incognito, this.#proxy, this.#browserIdx++, this.#nextBrowserContextIdx++, this.#maxPagesPerBrowserContext(), this.#maxPageFreeSeconds());
|
|
1331
1347
|
this.#lsdBrowserContexts.push(lsdBrowserContext);
|
|
1332
|
-
(
|
|
1348
|
+
loginfo3(`##browser ${lsdBrowserContext.id()} ${this.#browserCreationMethod}ed`);
|
|
1333
1349
|
}
|
|
1334
1350
|
browser.on("disconnected", () => {
|
|
1335
|
-
(
|
|
1351
|
+
loginfo3(`##browser ${this.id()} disconnected`);
|
|
1336
1352
|
if (this.#lsdBrowserContexts.length > 0) {
|
|
1337
|
-
(
|
|
1353
|
+
logerr3(`${this.id()} has browserContexts when disconnected`);
|
|
1338
1354
|
}
|
|
1339
1355
|
});
|
|
1340
1356
|
this.on("browserContextClose", (lsdBrowserContext) => {
|
|
1341
1357
|
if (!(lsdBrowserContext instanceof PlaywrightBrowserContext)) {
|
|
1342
|
-
(
|
|
1358
|
+
logerr3(`Invalid data in LsdBrowser.on("browserContextClose)`);
|
|
1343
1359
|
return;
|
|
1344
1360
|
}
|
|
1345
1361
|
const idx = this.#lsdBrowserContexts.findIndex((bc) => bc === lsdBrowserContext);
|
|
1346
1362
|
if (idx < 0) {
|
|
1347
|
-
(
|
|
1363
|
+
logerr3(`Invalid lsdBrowserContext in LsdBrowser.on("browserContextClose)`);
|
|
1348
1364
|
return;
|
|
1349
1365
|
}
|
|
1350
|
-
(
|
|
1366
|
+
loginfo3(`##browser ${lsdBrowserContext.id()} closed
|
|
1351
1367
|
`);
|
|
1352
1368
|
this.#lsdBrowserContexts.splice(idx, 1);
|
|
1353
1369
|
if (this.#lsdBrowserContexts.length === 0) {
|
|
1354
|
-
(
|
|
1370
|
+
loginfo3(`##browser ${this.id()} has no browserContexts now`);
|
|
1355
1371
|
}
|
|
1356
1372
|
return;
|
|
1357
1373
|
});
|
|
@@ -1369,7 +1385,7 @@ var PlaywrightBrowser = class extends import_node_events3.default {
|
|
|
1369
1385
|
// 常用方法(按常见调用顺序排序)
|
|
1370
1386
|
async newBrowserContext(options) {
|
|
1371
1387
|
if (this.#lsdBrowserContexts.length >= this.#maxBrowserContextsPerBrowser()) {
|
|
1372
|
-
(
|
|
1388
|
+
logwarn3(`##browser ${this.id()} can not create more new browserContext`);
|
|
1373
1389
|
return null;
|
|
1374
1390
|
}
|
|
1375
1391
|
const browserContextOptions = {};
|
|
@@ -1384,7 +1400,7 @@ var PlaywrightBrowser = class extends import_node_events3.default {
|
|
|
1384
1400
|
const browserContext = await this.#browser.newContext(browserContextOptions);
|
|
1385
1401
|
const lsdBrowserContext = new PlaywrightBrowserContext(this, browserContext, true, proxy, this.#browserIdx++, this.#nextBrowserContextIdx++, this.#maxPagesPerBrowserContext(), this.#maxPageFreeSeconds());
|
|
1386
1402
|
this.#lsdBrowserContexts.push(lsdBrowserContext);
|
|
1387
|
-
(
|
|
1403
|
+
loginfo3(`##browser ${lsdBrowserContext.id()} created`);
|
|
1388
1404
|
return lsdBrowserContext;
|
|
1389
1405
|
}
|
|
1390
1406
|
async close() {
|
|
@@ -1435,16 +1451,16 @@ var PlaywrightBrowser = class extends import_node_events3.default {
|
|
|
1435
1451
|
};
|
|
1436
1452
|
|
|
1437
1453
|
// src/puppeteer/browser.ts
|
|
1438
|
-
|
|
1454
|
+
import EventEmitter6 from "events";
|
|
1439
1455
|
|
|
1440
1456
|
// src/puppeteer/context.ts
|
|
1441
|
-
|
|
1457
|
+
import EventEmitter5 from "events";
|
|
1442
1458
|
|
|
1443
1459
|
// src/puppeteer/page.ts
|
|
1444
|
-
|
|
1460
|
+
import EventEmitter4 from "events";
|
|
1445
1461
|
|
|
1446
1462
|
// src/puppeteer/element.ts
|
|
1447
|
-
|
|
1463
|
+
import { logerr as logerr4, unreachable as unreachable3 } from "@letsscrapedata/utils";
|
|
1448
1464
|
var PuppeteerElement = class _PuppeteerElement {
|
|
1449
1465
|
#frame;
|
|
1450
1466
|
#$ele;
|
|
@@ -1532,7 +1548,7 @@ var PuppeteerElement = class _PuppeteerElement {
|
|
|
1532
1548
|
}
|
|
1533
1549
|
return retObj;
|
|
1534
1550
|
} catch (err) {
|
|
1535
|
-
(
|
|
1551
|
+
logerr4(err);
|
|
1536
1552
|
return retObj;
|
|
1537
1553
|
}
|
|
1538
1554
|
}
|
|
@@ -1682,44 +1698,24 @@ var PuppeteerElement = class _PuppeteerElement {
|
|
|
1682
1698
|
}
|
|
1683
1699
|
break;
|
|
1684
1700
|
default:
|
|
1685
|
-
(
|
|
1701
|
+
unreachable3(type);
|
|
1686
1702
|
}
|
|
1687
1703
|
return true;
|
|
1688
1704
|
}
|
|
1689
1705
|
async screenshot(options) {
|
|
1690
1706
|
return await this.#$ele.screenshot(options);
|
|
1691
1707
|
}
|
|
1692
|
-
async scrollBy(x, y) {
|
|
1693
|
-
await this.#frame.evaluate(
|
|
1694
|
-
(x2, y2) => {
|
|
1695
|
-
window.scrollBy(x2, y2);
|
|
1696
|
-
},
|
|
1697
|
-
x,
|
|
1698
|
-
y
|
|
1699
|
-
);
|
|
1700
|
-
return true;
|
|
1701
|
-
}
|
|
1702
1708
|
async scrollIntoView() {
|
|
1703
1709
|
await this.#frame.evaluate((ele) => {
|
|
1704
1710
|
ele.scrollIntoView();
|
|
1705
1711
|
}, this.#$ele);
|
|
1706
1712
|
return true;
|
|
1707
1713
|
}
|
|
1708
|
-
async scrollTo(x, y) {
|
|
1709
|
-
await this.#frame.evaluate(
|
|
1710
|
-
(x2, y2) => {
|
|
1711
|
-
window.scrollTo(x2, y2);
|
|
1712
|
-
},
|
|
1713
|
-
x,
|
|
1714
|
-
y
|
|
1715
|
-
);
|
|
1716
|
-
return true;
|
|
1717
|
-
}
|
|
1718
1714
|
};
|
|
1719
1715
|
|
|
1720
1716
|
// src/puppeteer/page.ts
|
|
1721
|
-
|
|
1722
|
-
var PuppeteerPage = class extends
|
|
1717
|
+
import { getCurrentUnixTime as getCurrentUnixTime3, logerr as logerr5, loginfo as loginfo4, unreachable as unreachable4 } from "@letsscrapedata/utils";
|
|
1718
|
+
var PuppeteerPage = class extends EventEmitter4 {
|
|
1723
1719
|
#lsdBrowserContext;
|
|
1724
1720
|
#page;
|
|
1725
1721
|
#status;
|
|
@@ -1878,9 +1874,9 @@ var PuppeteerPage = class extends import_node_events4.default {
|
|
|
1878
1874
|
const page = this.#page;
|
|
1879
1875
|
const pageId = this.#pageId;
|
|
1880
1876
|
page.on("close", async () => {
|
|
1881
|
-
(
|
|
1877
|
+
loginfo4(`##browser ${pageId} closed`);
|
|
1882
1878
|
if (!page.pageInfo) {
|
|
1883
|
-
(
|
|
1879
|
+
logerr5(`Logic error in page.on("close")`);
|
|
1884
1880
|
}
|
|
1885
1881
|
this.emit("pageClose");
|
|
1886
1882
|
this.#lsdBrowserContext.emit("pageClose", this);
|
|
@@ -1894,12 +1890,12 @@ var PuppeteerPage = class extends import_node_events4.default {
|
|
|
1894
1890
|
popupPageId = `page-${browserIdx}-${browserContextIdx}-${pageIdx}`;
|
|
1895
1891
|
pageInfo.openType = "popup";
|
|
1896
1892
|
} else {
|
|
1897
|
-
(
|
|
1893
|
+
logerr5(`##browser ${pageId} has popup without page.pageInfo`);
|
|
1898
1894
|
}
|
|
1899
|
-
(
|
|
1895
|
+
loginfo4(`##browser ${pageId} has popup ${popupPageId}`);
|
|
1900
1896
|
this.emit("pagePopup", pageInfo);
|
|
1901
1897
|
} else {
|
|
1902
|
-
(
|
|
1898
|
+
logerr5(`##browser ${pageId} has popup page with null page`);
|
|
1903
1899
|
}
|
|
1904
1900
|
});
|
|
1905
1901
|
}
|
|
@@ -1911,7 +1907,7 @@ var PuppeteerPage = class extends import_node_events4.default {
|
|
|
1911
1907
|
this.#lsdBrowserContext = browserContext;
|
|
1912
1908
|
this.#page = page;
|
|
1913
1909
|
this.#status = "free";
|
|
1914
|
-
const currentTime = (
|
|
1910
|
+
const currentTime = getCurrentUnixTime3();
|
|
1915
1911
|
const { browserIdx = 0, browserContextIdx = 0, pageIdx = 0, openType = "other", openTime = currentTime, lastStatusUpdateTime = currentTime, taskId = 0 } = pageInfo ? pageInfo : {};
|
|
1916
1912
|
this.#page.pageInfo = { browserIdx, browserContextIdx, pageIdx, openType, openTime, lastStatusUpdateTime, taskId };
|
|
1917
1913
|
this.#pageId = `page${browserIdx}-${browserContextIdx}-${pageIdx}`;
|
|
@@ -2056,12 +2052,21 @@ var PuppeteerPage = class extends import_node_events4.default {
|
|
|
2056
2052
|
await this.clearResponseInterceptions();
|
|
2057
2053
|
return true;
|
|
2058
2054
|
}
|
|
2055
|
+
#getWaitUntil(origWaitUntil) {
|
|
2056
|
+
if (origWaitUntil === "networkidle") {
|
|
2057
|
+
return "networkidle0";
|
|
2058
|
+
} else if (origWaitUntil === "commit") {
|
|
2059
|
+
throw new Error("commit is not supported in PuppeteerPage");
|
|
2060
|
+
} else {
|
|
2061
|
+
return origWaitUntil;
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2059
2064
|
async goto(url, options) {
|
|
2060
2065
|
if (!this.#page) {
|
|
2061
2066
|
throw new Error("No valid page");
|
|
2062
2067
|
}
|
|
2063
2068
|
if (options) {
|
|
2064
|
-
const { referer, timeout, waitUntil } = options;
|
|
2069
|
+
const { referer, timeout, waitUntil = "load" } = options;
|
|
2065
2070
|
const newOptions = {};
|
|
2066
2071
|
if (referer) {
|
|
2067
2072
|
newOptions.referer = referer;
|
|
@@ -2070,7 +2075,7 @@ var PuppeteerPage = class extends import_node_events4.default {
|
|
|
2070
2075
|
newOptions.timeout = timeout;
|
|
2071
2076
|
}
|
|
2072
2077
|
if (waitUntil && waitUntil !== "commit") {
|
|
2073
|
-
newOptions.waitUntil = waitUntil
|
|
2078
|
+
newOptions.waitUntil = this.#getWaitUntil(waitUntil);
|
|
2074
2079
|
}
|
|
2075
2080
|
await this.#page.goto(url, newOptions);
|
|
2076
2081
|
} else {
|
|
@@ -2142,6 +2147,30 @@ var PuppeteerPage = class extends import_node_events4.default {
|
|
|
2142
2147
|
}
|
|
2143
2148
|
return await this.#page.screenshot(options);
|
|
2144
2149
|
}
|
|
2150
|
+
async scrollBy(x, y) {
|
|
2151
|
+
if (!this.#page) {
|
|
2152
|
+
throw new Error("No valid page");
|
|
2153
|
+
}
|
|
2154
|
+
await this.#page.evaluate(
|
|
2155
|
+
([x2, y2]) => {
|
|
2156
|
+
window.scrollBy(x2, y2);
|
|
2157
|
+
},
|
|
2158
|
+
[x, y]
|
|
2159
|
+
);
|
|
2160
|
+
return true;
|
|
2161
|
+
}
|
|
2162
|
+
async scrollTo(x, y) {
|
|
2163
|
+
if (!this.#page) {
|
|
2164
|
+
throw new Error("No valid page");
|
|
2165
|
+
}
|
|
2166
|
+
await this.#page.evaluate(
|
|
2167
|
+
([x2, y2]) => {
|
|
2168
|
+
window.scrollTo(x2, y2);
|
|
2169
|
+
},
|
|
2170
|
+
[x, y]
|
|
2171
|
+
);
|
|
2172
|
+
return true;
|
|
2173
|
+
}
|
|
2145
2174
|
async setCookies(cookies) {
|
|
2146
2175
|
if (!this.#page) {
|
|
2147
2176
|
throw new Error("No valid page");
|
|
@@ -2239,7 +2268,7 @@ var PuppeteerPage = class extends import_node_events4.default {
|
|
|
2239
2268
|
});
|
|
2240
2269
|
break;
|
|
2241
2270
|
default:
|
|
2242
|
-
(
|
|
2271
|
+
unreachable4(action);
|
|
2243
2272
|
}
|
|
2244
2273
|
return true;
|
|
2245
2274
|
}
|
|
@@ -2274,7 +2303,7 @@ var PuppeteerPage = class extends import_node_events4.default {
|
|
|
2274
2303
|
return false;
|
|
2275
2304
|
}
|
|
2276
2305
|
for (const option of actOptions) {
|
|
2277
|
-
const { requestMatch, responseMatch,
|
|
2306
|
+
const { requestMatch, responseMatch, responseItems, handler, handlerOptions } = option;
|
|
2278
2307
|
let matchedFlag = !requestMatch || this.#checkRequestMatch(request, requestMatch);
|
|
2279
2308
|
if (matchedFlag && responseMatch) {
|
|
2280
2309
|
const { minLength, maxLength } = responseMatch;
|
|
@@ -2287,13 +2316,13 @@ var PuppeteerPage = class extends import_node_events4.default {
|
|
|
2287
2316
|
if (!matchedFlag) {
|
|
2288
2317
|
continue;
|
|
2289
2318
|
}
|
|
2290
|
-
if (Array.isArray(
|
|
2319
|
+
if (Array.isArray(responseItems)) {
|
|
2291
2320
|
const requestMethod = request.method();
|
|
2292
2321
|
const requestUrl = request.url();
|
|
2293
2322
|
const reqData2 = request.postData();
|
|
2294
2323
|
const requestData = reqData2 ? reqData2 : "";
|
|
2295
2324
|
const responseData = await response.text();
|
|
2296
|
-
|
|
2325
|
+
responseItems.push({
|
|
2297
2326
|
pageUrl,
|
|
2298
2327
|
requestMethod,
|
|
2299
2328
|
requestUrl,
|
|
@@ -2360,6 +2389,33 @@ var PuppeteerPage = class extends import_node_events4.default {
|
|
|
2360
2389
|
this.#status = "busy";
|
|
2361
2390
|
return true;
|
|
2362
2391
|
}
|
|
2392
|
+
async waitForElement(selector, options = {}) {
|
|
2393
|
+
if (!this.#page) {
|
|
2394
|
+
throw new Error("No valid page");
|
|
2395
|
+
}
|
|
2396
|
+
const { timeout = 3e4, state = "visible" } = options;
|
|
2397
|
+
if (state === "visible") {
|
|
2398
|
+
await this.#page.waitForSelector(selector, { timeout, visible: true });
|
|
2399
|
+
} else if (state === "hidden") {
|
|
2400
|
+
await this.#page.waitForSelector(selector, { timeout, hidden: true });
|
|
2401
|
+
} else {
|
|
2402
|
+
throw new Error(`${state} is not supported in PuppeteerPage.waitForElement`);
|
|
2403
|
+
}
|
|
2404
|
+
return true;
|
|
2405
|
+
}
|
|
2406
|
+
async waitForNavigation(options) {
|
|
2407
|
+
if (!this.#page) {
|
|
2408
|
+
throw new Error("No valid page");
|
|
2409
|
+
}
|
|
2410
|
+
const { url = "", timeout = 3e4, waitUntil = "load" } = options;
|
|
2411
|
+
const newWaitUntil = this.#getWaitUntil(waitUntil);
|
|
2412
|
+
if (url) {
|
|
2413
|
+
throw new Error("url is not supported in PuppeteerPage.waitForNavigation");
|
|
2414
|
+
} else {
|
|
2415
|
+
await this.#page.waitForNavigation({ timeout, waitUntil: newWaitUntil });
|
|
2416
|
+
}
|
|
2417
|
+
return true;
|
|
2418
|
+
}
|
|
2363
2419
|
async windowMember(keys) {
|
|
2364
2420
|
if (!this.#page) {
|
|
2365
2421
|
throw new Error("No valid page");
|
|
@@ -2388,8 +2444,8 @@ var PuppeteerPage = class extends import_node_events4.default {
|
|
|
2388
2444
|
};
|
|
2389
2445
|
|
|
2390
2446
|
// src/puppeteer/context.ts
|
|
2391
|
-
|
|
2392
|
-
var PuppeteerBrowserContext = class extends
|
|
2447
|
+
import { getCurrentUnixTime as getCurrentUnixTime4, logerr as logerr6, loginfo as loginfo5, logwarn as logwarn4, sleep as sleep2 } from "@letsscrapedata/utils";
|
|
2448
|
+
var PuppeteerBrowserContext = class extends EventEmitter5 {
|
|
2393
2449
|
#lsdBrowser;
|
|
2394
2450
|
#browserIdx;
|
|
2395
2451
|
#browserContextIdx;
|
|
@@ -2413,7 +2469,7 @@ var PuppeteerBrowserContext = class extends import_node_events5.default {
|
|
|
2413
2469
|
}
|
|
2414
2470
|
const pages = await this.#browserContext.pages();
|
|
2415
2471
|
const openType = this.#lsdBrowser.browserCreationMethod();
|
|
2416
|
-
const lastStatusUpdateTime = (
|
|
2472
|
+
const lastStatusUpdateTime = getCurrentUnixTime4();
|
|
2417
2473
|
for (const page of pages) {
|
|
2418
2474
|
const pageInfo = { browserIdx: this.#browserIdx, browserContextIdx: this.#browserContextIdx, pageIdx: this.#nextPageIdx++, openType, openTime: this.#createTime, lastStatusUpdateTime, taskId: 0 };
|
|
2419
2475
|
const lsdPage = new PuppeteerPage(this, page, pageInfo);
|
|
@@ -2421,7 +2477,7 @@ var PuppeteerBrowserContext = class extends import_node_events5.default {
|
|
|
2421
2477
|
await lsdPage.setUserAgent(this.#userAgent);
|
|
2422
2478
|
}
|
|
2423
2479
|
this.#lsdPages.push(lsdPage);
|
|
2424
|
-
(
|
|
2480
|
+
loginfo5(`##browser ${lsdPage.id()} ${openType}ed`);
|
|
2425
2481
|
}
|
|
2426
2482
|
}
|
|
2427
2483
|
constructor(lsdBrowser, browserContext, incognito = false, proxy = null, browserIdx = 0, browserContextIdx = 0, maxPagesPerBrowserContext = 20, maxPageFreeSeconds = 0, userAgent = "") {
|
|
@@ -2437,7 +2493,7 @@ var PuppeteerBrowserContext = class extends import_node_events5.default {
|
|
|
2437
2493
|
this.#browserContextIdx = browserContextIdx;
|
|
2438
2494
|
this.#browserContext = browserContext;
|
|
2439
2495
|
this.#userAgent = userAgent;
|
|
2440
|
-
this.#createTime = (
|
|
2496
|
+
this.#createTime = getCurrentUnixTime4();
|
|
2441
2497
|
this.#incognito = incognito === false ? false : true;
|
|
2442
2498
|
this.#proxy = proxy?.server ? proxy : null;
|
|
2443
2499
|
this.#maxPagesPerBrowserContext = maxPagesPerBrowserContext;
|
|
@@ -2455,27 +2511,27 @@ var PuppeteerBrowserContext = class extends import_node_events5.default {
|
|
|
2455
2511
|
const pageInfo = page.pageInfo;
|
|
2456
2512
|
if (pageInfo) {
|
|
2457
2513
|
const { browserIdx: browserIdx2, browserContextIdx: browserContextIdx2, pageIdx } = pageInfo;
|
|
2458
|
-
(
|
|
2514
|
+
logwarn4(`##browser page-${browserIdx2}-${browserContextIdx2}-${pageIdx} has been already created`);
|
|
2459
2515
|
} else {
|
|
2460
|
-
const currentTime = (
|
|
2516
|
+
const currentTime = getCurrentUnixTime4();
|
|
2461
2517
|
const pageInfo2 = { browserIdx: this.#browserIdx, browserContextIdx: this.#browserContextIdx, pageIdx: this.#nextPageIdx++, openType: "other", openTime: currentTime, lastStatusUpdateTime: currentTime, taskId: 0 };
|
|
2462
2518
|
const lsdPage = new PuppeteerPage(this, page, pageInfo2);
|
|
2463
2519
|
if (this.#userAgent) {
|
|
2464
2520
|
await lsdPage.setUserAgent(this.#userAgent);
|
|
2465
2521
|
}
|
|
2466
2522
|
this.#lsdPages.push(lsdPage);
|
|
2467
|
-
(
|
|
2523
|
+
loginfo5(`##browser ${lsdPage.id()} created`);
|
|
2468
2524
|
}
|
|
2469
2525
|
}
|
|
2470
2526
|
});
|
|
2471
2527
|
this.on("pageClose", (lsdPage) => {
|
|
2472
2528
|
if (!(lsdPage instanceof PuppeteerPage)) {
|
|
2473
|
-
(
|
|
2529
|
+
logerr6(`Invalid data in LsdBrowserContext.on("pageClose)`);
|
|
2474
2530
|
return;
|
|
2475
2531
|
}
|
|
2476
2532
|
const idx = this.#lsdPages.findIndex((p) => p === lsdPage);
|
|
2477
2533
|
if (idx < 0) {
|
|
2478
|
-
(
|
|
2534
|
+
logerr6(`Invalid lsdPage in LsdBrowserContext.on("pageClose)`);
|
|
2479
2535
|
return;
|
|
2480
2536
|
}
|
|
2481
2537
|
this.#lsdPages.splice(idx, 1);
|
|
@@ -2501,15 +2557,15 @@ var PuppeteerBrowserContext = class extends import_node_events5.default {
|
|
|
2501
2557
|
this.#gettingPage = true;
|
|
2502
2558
|
return true;
|
|
2503
2559
|
} else {
|
|
2504
|
-
await (
|
|
2560
|
+
await sleep2(200);
|
|
2505
2561
|
}
|
|
2506
2562
|
}
|
|
2507
|
-
(
|
|
2563
|
+
logwarn4(`Cannot get the gettingLock.`);
|
|
2508
2564
|
return false;
|
|
2509
2565
|
}
|
|
2510
2566
|
#freeGettingLock() {
|
|
2511
2567
|
if (!this.#gettingPage) {
|
|
2512
|
-
(
|
|
2568
|
+
logwarn4(`Getting lock is already free now.`);
|
|
2513
2569
|
}
|
|
2514
2570
|
this.#gettingPage = false;
|
|
2515
2571
|
}
|
|
@@ -2518,7 +2574,7 @@ var PuppeteerBrowserContext = class extends import_node_events5.default {
|
|
|
2518
2574
|
maxPageFreeSeconds = this.#maxPageFreeSeconds;
|
|
2519
2575
|
}
|
|
2520
2576
|
if (maxPageFreeSeconds <= 0) {
|
|
2521
|
-
(
|
|
2577
|
+
logwarn4(`Please set valid maxPageFreeSeconds to close free pages`);
|
|
2522
2578
|
return false;
|
|
2523
2579
|
}
|
|
2524
2580
|
const gotLock = await this.#tryToGetGettingLock();
|
|
@@ -2526,7 +2582,7 @@ var PuppeteerBrowserContext = class extends import_node_events5.default {
|
|
|
2526
2582
|
return false;
|
|
2527
2583
|
}
|
|
2528
2584
|
try {
|
|
2529
|
-
const maxUpdateTime = (
|
|
2585
|
+
const maxUpdateTime = getCurrentUnixTime4() - this.#maxPageFreeSeconds;
|
|
2530
2586
|
let freePages = this.#lsdPages.filter((p) => p.isFree() && p.pageInfo().lastStatusUpdateTime < maxUpdateTime);
|
|
2531
2587
|
if (freePages.length === this.#lsdPages.length) {
|
|
2532
2588
|
freePages = freePages.slice(1);
|
|
@@ -2537,7 +2593,7 @@ var PuppeteerBrowserContext = class extends import_node_events5.default {
|
|
|
2537
2593
|
this.#freeGettingLock();
|
|
2538
2594
|
return true;
|
|
2539
2595
|
} catch (err) {
|
|
2540
|
-
(
|
|
2596
|
+
logerr6(err);
|
|
2541
2597
|
this.#freeGettingLock();
|
|
2542
2598
|
return false;
|
|
2543
2599
|
}
|
|
@@ -2552,7 +2608,7 @@ var PuppeteerBrowserContext = class extends import_node_events5.default {
|
|
|
2552
2608
|
}
|
|
2553
2609
|
try {
|
|
2554
2610
|
if (this.#lsdPages.length === 0) {
|
|
2555
|
-
await (
|
|
2611
|
+
await sleep2(1e3);
|
|
2556
2612
|
}
|
|
2557
2613
|
let lsdPage = this.#lsdPages.find((p) => p.isFree());
|
|
2558
2614
|
if (lsdPage) {
|
|
@@ -2580,7 +2636,7 @@ var PuppeteerBrowserContext = class extends import_node_events5.default {
|
|
|
2580
2636
|
return null;
|
|
2581
2637
|
}
|
|
2582
2638
|
} catch (err) {
|
|
2583
|
-
(
|
|
2639
|
+
logerr6(err);
|
|
2584
2640
|
this.#freeGettingLock();
|
|
2585
2641
|
return null;
|
|
2586
2642
|
}
|
|
@@ -2643,8 +2699,8 @@ var PuppeteerBrowserContext = class extends import_node_events5.default {
|
|
|
2643
2699
|
};
|
|
2644
2700
|
|
|
2645
2701
|
// src/puppeteer/browser.ts
|
|
2646
|
-
|
|
2647
|
-
var PuppeteerBrowser = class extends
|
|
2702
|
+
import { logerr as logerr7, loginfo as loginfo6, logwarn as logwarn5 } from "@letsscrapedata/utils";
|
|
2703
|
+
var PuppeteerBrowser = class extends EventEmitter6 {
|
|
2648
2704
|
#browser;
|
|
2649
2705
|
#browserIdx;
|
|
2650
2706
|
#lsdBrowserContexts;
|
|
@@ -2692,35 +2748,35 @@ var PuppeteerBrowser = class extends import_node_events6.default {
|
|
|
2692
2748
|
this.#executablePath = executablePath;
|
|
2693
2749
|
this.#nextBrowserContextIdx = 1;
|
|
2694
2750
|
this.#closeFreePagesIntervalId = null;
|
|
2695
|
-
(
|
|
2751
|
+
loginfo6(`##browser ${this.#browserType} ${this.id()} ${this.#browserCreationMethod}ed by ${this.#browserControllerType}`);
|
|
2696
2752
|
const browserContexts = browser.browserContexts();
|
|
2697
2753
|
const incognito = typeof options?.incognito === "boolean" ? options.incognito : false;
|
|
2698
2754
|
for (const browserContext of browserContexts) {
|
|
2699
2755
|
const lsdBrowserContext = new PuppeteerBrowserContext(this, browserContext, incognito, this.#proxy, this.#browserIdx, this.#nextBrowserContextIdx++, this.#maxPagesPerBrowserContext(), this.#maxPageFreeSeconds(), this.#userAgent());
|
|
2700
2756
|
this.#lsdBrowserContexts.push(lsdBrowserContext);
|
|
2701
|
-
(
|
|
2757
|
+
loginfo6(`##browser ${lsdBrowserContext.id()} ${this.#browserCreationMethod}ed`);
|
|
2702
2758
|
}
|
|
2703
2759
|
browser.on("disconnected", () => {
|
|
2704
|
-
(
|
|
2760
|
+
loginfo6(`##browser ${this.id()} disconnected`);
|
|
2705
2761
|
if (this.#lsdBrowserContexts.length > 0) {
|
|
2706
|
-
(
|
|
2762
|
+
logerr7(`${this.id()} has browserContexts when disconnected`);
|
|
2707
2763
|
}
|
|
2708
2764
|
});
|
|
2709
2765
|
this.on("browserContextClose", (lsdBrowserContext) => {
|
|
2710
2766
|
if (!(lsdBrowserContext instanceof PuppeteerBrowserContext)) {
|
|
2711
|
-
(
|
|
2767
|
+
logerr7(`Invalid data in LsdBrowser.on("browserContextClose)`);
|
|
2712
2768
|
return;
|
|
2713
2769
|
}
|
|
2714
2770
|
const idx = this.#lsdBrowserContexts.findIndex((bc) => bc === lsdBrowserContext);
|
|
2715
2771
|
if (idx < 0) {
|
|
2716
|
-
(
|
|
2772
|
+
logerr7(`Invalid lsdBrowserContext in LsdBrowser.on("browserContextClose)`);
|
|
2717
2773
|
return;
|
|
2718
2774
|
}
|
|
2719
|
-
(
|
|
2775
|
+
loginfo6(`##browser ${lsdBrowserContext.id()} closed
|
|
2720
2776
|
`);
|
|
2721
2777
|
this.#lsdBrowserContexts.splice(idx, 1);
|
|
2722
2778
|
if (this.#lsdBrowserContexts.length === 0) {
|
|
2723
|
-
(
|
|
2779
|
+
loginfo6(`##browser ${this.id()} has no browserContexts now`);
|
|
2724
2780
|
}
|
|
2725
2781
|
return;
|
|
2726
2782
|
});
|
|
@@ -2738,7 +2794,7 @@ var PuppeteerBrowser = class extends import_node_events6.default {
|
|
|
2738
2794
|
// 常用方法(按常见调用顺序排序)
|
|
2739
2795
|
async newBrowserContext(options) {
|
|
2740
2796
|
if (this.#lsdBrowserContexts.length >= this.#maxBrowserContextsPerBrowser()) {
|
|
2741
|
-
(
|
|
2797
|
+
logwarn5(`##browser ${this.id()} can not create more new browserContext`);
|
|
2742
2798
|
return null;
|
|
2743
2799
|
}
|
|
2744
2800
|
const browserContextOptions = {};
|
|
@@ -2750,7 +2806,7 @@ var PuppeteerBrowser = class extends import_node_events6.default {
|
|
|
2750
2806
|
const userAgent = options?.userAgent ? options.userAgent : "";
|
|
2751
2807
|
const lsdBrowserContext = new PuppeteerBrowserContext(this, browserContext, true, proxy, this.#browserIdx, this.#nextBrowserContextIdx++, this.#maxPagesPerBrowserContext(), this.#maxPageFreeSeconds(), userAgent);
|
|
2752
2808
|
this.#lsdBrowserContexts.push(lsdBrowserContext);
|
|
2753
|
-
(
|
|
2809
|
+
loginfo6(`##browser ${lsdBrowserContext.id()} created`);
|
|
2754
2810
|
return lsdBrowserContext;
|
|
2755
2811
|
}
|
|
2756
2812
|
async close() {
|
|
@@ -2803,7 +2859,7 @@ var PuppeteerBrowser = class extends import_node_events6.default {
|
|
|
2803
2859
|
};
|
|
2804
2860
|
|
|
2805
2861
|
// src/cheerio/page.ts
|
|
2806
|
-
|
|
2862
|
+
import EventEmitter7 from "events";
|
|
2807
2863
|
|
|
2808
2864
|
// ../../node_modules/cheerio/lib/esm/options.js
|
|
2809
2865
|
var defaultOpts = {
|
|
@@ -16675,29 +16731,34 @@ var CheerioElement = class _CheerioElement {
|
|
|
16675
16731
|
return Array.from(Object.keys(element.attribs));
|
|
16676
16732
|
}
|
|
16677
16733
|
}
|
|
16678
|
-
#findNodes(selector) {
|
|
16734
|
+
#findNodes(selector, absolute) {
|
|
16679
16735
|
if (selector.startsWith("./") || selector.startsWith("/")) {
|
|
16680
16736
|
throw new Error("Do not support XPath in cheerio.");
|
|
16681
16737
|
}
|
|
16682
16738
|
if (selector === ".") {
|
|
16683
16739
|
return [this.#node];
|
|
16684
16740
|
}
|
|
16685
|
-
const
|
|
16686
|
-
|
|
16687
|
-
|
|
16741
|
+
const nodes = [];
|
|
16742
|
+
const cheerioNode = !absolute ? this.#node.find(selector) : this.#node._root?.find(selector);
|
|
16743
|
+
if (!cheerioNode) {
|
|
16744
|
+
return nodes;
|
|
16745
|
+
} else if (cheerioNode.length > 0) {
|
|
16688
16746
|
const len = cheerioNode.length;
|
|
16689
16747
|
for (let i = 0; i < len; i++) {
|
|
16690
16748
|
nodes.push(cheerioNode.eq(i));
|
|
16691
16749
|
}
|
|
16692
16750
|
return nodes;
|
|
16693
16751
|
} else {
|
|
16694
|
-
return
|
|
16752
|
+
return nodes;
|
|
16695
16753
|
}
|
|
16696
16754
|
}
|
|
16697
|
-
async findElement(selectorOrXpath) {
|
|
16755
|
+
async findElement(selectorOrXpath, iframeOptions = [], absolute = false) {
|
|
16756
|
+
if (!iframeOptions) {
|
|
16757
|
+
return null;
|
|
16758
|
+
}
|
|
16698
16759
|
const selectors = typeof selectorOrXpath === "string" ? [selectorOrXpath] : selectorOrXpath;
|
|
16699
16760
|
for (const selector of selectors) {
|
|
16700
|
-
const nodes = this.#findNodes(selector);
|
|
16761
|
+
const nodes = this.#findNodes(selector, absolute);
|
|
16701
16762
|
if (nodes.length > 0) {
|
|
16702
16763
|
const cheerioElement = new _CheerioElement(nodes[0]);
|
|
16703
16764
|
return cheerioElement;
|
|
@@ -16705,10 +16766,13 @@ var CheerioElement = class _CheerioElement {
|
|
|
16705
16766
|
}
|
|
16706
16767
|
return null;
|
|
16707
16768
|
}
|
|
16708
|
-
async findElements(selectorOrXpath) {
|
|
16769
|
+
async findElements(selectorOrXpath, iframeOptions = [], absolute = false) {
|
|
16770
|
+
if (!iframeOptions) {
|
|
16771
|
+
return [];
|
|
16772
|
+
}
|
|
16709
16773
|
const selectors = typeof selectorOrXpath === "string" ? [selectorOrXpath] : selectorOrXpath;
|
|
16710
16774
|
for (const selector of selectors) {
|
|
16711
|
-
const nodes = this.#findNodes(selector);
|
|
16775
|
+
const nodes = this.#findNodes(selector, absolute);
|
|
16712
16776
|
if (nodes.length > 0) {
|
|
16713
16777
|
const cheerioElements = nodes.map((node) => new _CheerioElement(node));
|
|
16714
16778
|
return cheerioElements;
|
|
@@ -16757,19 +16821,13 @@ var CheerioElement = class _CheerioElement {
|
|
|
16757
16821
|
async screenshot() {
|
|
16758
16822
|
throw new Error("Not supported in CheerioElement.");
|
|
16759
16823
|
}
|
|
16760
|
-
async scrollBy() {
|
|
16761
|
-
throw new Error("Not supported in CheerioElement.");
|
|
16762
|
-
}
|
|
16763
16824
|
async scrollIntoView() {
|
|
16764
16825
|
throw new Error("Not supported in CheerioElement.");
|
|
16765
16826
|
}
|
|
16766
|
-
async scrollTo() {
|
|
16767
|
-
throw new Error("Not supported in CheerioElement.");
|
|
16768
|
-
}
|
|
16769
16827
|
};
|
|
16770
16828
|
|
|
16771
16829
|
// src/cheerio/page.ts
|
|
16772
|
-
var CheerioPage = class extends
|
|
16830
|
+
var CheerioPage = class extends EventEmitter7 {
|
|
16773
16831
|
#document;
|
|
16774
16832
|
constructor(html3 = "") {
|
|
16775
16833
|
super();
|
|
@@ -16886,6 +16944,12 @@ var CheerioPage = class extends import_node_events7.default {
|
|
|
16886
16944
|
async screenshot() {
|
|
16887
16945
|
throw new Error("Not supported in CheerioPage.");
|
|
16888
16946
|
}
|
|
16947
|
+
async scrollBy() {
|
|
16948
|
+
throw new Error("Not supported in CheerioElement.");
|
|
16949
|
+
}
|
|
16950
|
+
async scrollTo() {
|
|
16951
|
+
throw new Error("Not supported in CheerioElement.");
|
|
16952
|
+
}
|
|
16889
16953
|
async setCookies() {
|
|
16890
16954
|
throw new Error("Not supported in CheerioPage.");
|
|
16891
16955
|
}
|
|
@@ -16928,16 +16992,22 @@ var CheerioPage = class extends import_node_events7.default {
|
|
|
16928
16992
|
use() {
|
|
16929
16993
|
throw new Error("Not supported in CheerioPage.");
|
|
16930
16994
|
}
|
|
16995
|
+
waitForElement() {
|
|
16996
|
+
throw new Error("Not supported in CheerioPage.");
|
|
16997
|
+
}
|
|
16998
|
+
waitForNavigation() {
|
|
16999
|
+
throw new Error("Not supported in CheerioPage.");
|
|
17000
|
+
}
|
|
16931
17001
|
async windowMember() {
|
|
16932
17002
|
throw new Error("Not supported in CheerioPage.");
|
|
16933
17003
|
}
|
|
16934
17004
|
};
|
|
16935
17005
|
|
|
16936
17006
|
// src/controller/controller.ts
|
|
16937
|
-
|
|
16938
|
-
|
|
16939
|
-
|
|
16940
|
-
|
|
17007
|
+
import os from "os";
|
|
17008
|
+
import puppeteer from "puppeteer";
|
|
17009
|
+
import playwright from "playwright";
|
|
17010
|
+
import { logwarn as logwarn6 } from "@letsscrapedata/utils";
|
|
16941
17011
|
var LsdBrowserController = class _LsdBrowserController {
|
|
16942
17012
|
static #forbidConstructor = false;
|
|
16943
17013
|
#nextBrowserIdx;
|
|
@@ -16949,19 +17019,19 @@ var LsdBrowserController = class _LsdBrowserController {
|
|
|
16949
17019
|
if (_LsdBrowserController.#forbidConstructor) {
|
|
16950
17020
|
throw new Error("Only one LsdBrowserController instance can be created!");
|
|
16951
17021
|
}
|
|
16952
|
-
this.#osPlatform =
|
|
17022
|
+
this.#osPlatform = os.platform();
|
|
16953
17023
|
this.#nextBrowserIdx = 1;
|
|
16954
17024
|
_LsdBrowserController.#forbidConstructor = true;
|
|
16955
17025
|
}
|
|
16956
17026
|
#playwrightBrowserType(browserType, connectFlag = false) {
|
|
16957
17027
|
if (browserType === "chromium") {
|
|
16958
|
-
return
|
|
17028
|
+
return playwright.chromium;
|
|
16959
17029
|
} else if (connectFlag) {
|
|
16960
17030
|
throw new Error(`playwright only can connect to chromium browser, not support ${browserType} browser`);
|
|
16961
17031
|
} else if (browserType === "firefox") {
|
|
16962
|
-
return
|
|
17032
|
+
return playwright.firefox;
|
|
16963
17033
|
} else if (browserType === "webkit") {
|
|
16964
|
-
return
|
|
17034
|
+
return playwright.webkit;
|
|
16965
17035
|
} else {
|
|
16966
17036
|
throw new Error(`Invalid playwright browserType ${browserType}`);
|
|
16967
17037
|
}
|
|
@@ -16993,17 +17063,17 @@ var LsdBrowserController = class _LsdBrowserController {
|
|
|
16993
17063
|
const actOptions = { closeFreePagesIntervalSeconds, maxBrowserContextsPerBrowser, maxPagesPerBrowserContext, maxPageFreeSeconds, timeout, args, executablePath, headless, incognito, proxy, proxyPerBrowserContext, userDataDir, userAgent };
|
|
16994
17064
|
let idx = args.findIndex((arg) => arg.toLowerCase().startsWith("--incoginto"));
|
|
16995
17065
|
if (idx >= 0) {
|
|
16996
|
-
(
|
|
17066
|
+
logwarn6(`Please use options.incognito instead when launching new browser.`);
|
|
16997
17067
|
args.splice(idx, 1);
|
|
16998
17068
|
}
|
|
16999
17069
|
idx = args.findIndex((arg) => arg.toLowerCase().startsWith("--proxy-server"));
|
|
17000
17070
|
if (idx >= 0) {
|
|
17001
|
-
(
|
|
17071
|
+
logwarn6(`Please use options.proxy instead when launching new browser.`);
|
|
17002
17072
|
args.splice(idx, 1);
|
|
17003
17073
|
}
|
|
17004
17074
|
idx = args.findIndex((arg) => arg.toLowerCase().startsWith("--user-data-dir"));
|
|
17005
17075
|
if (idx >= 0) {
|
|
17006
|
-
(
|
|
17076
|
+
logwarn6(`Please use options.userDataDir instead when launching new browser.`);
|
|
17007
17077
|
args.splice(idx, 1);
|
|
17008
17078
|
}
|
|
17009
17079
|
if (browserControllerType === "playwright") {
|
|
@@ -17055,9 +17125,9 @@ var LsdBrowserController = class _LsdBrowserController {
|
|
|
17055
17125
|
launchOptions.args = args;
|
|
17056
17126
|
}
|
|
17057
17127
|
if (!actOptions.executablePath) {
|
|
17058
|
-
actOptions.executablePath =
|
|
17128
|
+
actOptions.executablePath = puppeteer.executablePath();
|
|
17059
17129
|
}
|
|
17060
|
-
const browser = await
|
|
17130
|
+
const browser = await puppeteer.launch(launchOptions);
|
|
17061
17131
|
const lsdBrowser = new PuppeteerBrowser(browser, browserType, "launch", actOptions, this.#nextBrowserIdx++);
|
|
17062
17132
|
return lsdBrowser;
|
|
17063
17133
|
} else {
|
|
@@ -17076,7 +17146,7 @@ var LsdBrowserController = class _LsdBrowserController {
|
|
|
17076
17146
|
return lsdBrowser;
|
|
17077
17147
|
} else if (browserControllerType === "puppeteer") {
|
|
17078
17148
|
this.#puppeteerProduct(browserType);
|
|
17079
|
-
const browser = await
|
|
17149
|
+
const browser = await puppeteer.connect({ browserURL: browserUrl });
|
|
17080
17150
|
const lsdBrowser = new PuppeteerBrowser(browser, browserType, "connect", options, this.#nextBrowserIdx++);
|
|
17081
17151
|
;
|
|
17082
17152
|
return lsdBrowser;
|
|
@@ -17086,8 +17156,7 @@ var LsdBrowserController = class _LsdBrowserController {
|
|
|
17086
17156
|
}
|
|
17087
17157
|
};
|
|
17088
17158
|
var controller = new LsdBrowserController();
|
|
17089
|
-
|
|
17090
|
-
0 && (module.exports = {
|
|
17159
|
+
export {
|
|
17091
17160
|
CheerioElement,
|
|
17092
17161
|
CheerioPage,
|
|
17093
17162
|
PlaywrightBrowser,
|
|
@@ -17099,4 +17168,4 @@ var controller = new LsdBrowserController();
|
|
|
17099
17168
|
PuppeteerElement,
|
|
17100
17169
|
PuppeteerPage,
|
|
17101
17170
|
defaultProxy
|
|
17102
|
-
}
|
|
17171
|
+
};
|