@crawlee/playwright 4.0.0-beta.11 → 4.0.0-beta.110

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.
Files changed (31) hide show
  1. package/README.md +17 -13
  2. package/index.d.ts +1 -2
  3. package/index.js +0 -1
  4. package/internals/adaptive-playwright-crawler.d.ts +106 -46
  5. package/internals/adaptive-playwright-crawler.js +301 -218
  6. package/internals/enqueue-links/click-elements.d.ts +37 -55
  7. package/internals/enqueue-links/click-elements.js +51 -43
  8. package/internals/playwright-crawler.d.ts +103 -55
  9. package/internals/playwright-crawler.js +48 -42
  10. package/internals/playwright-launcher.d.ts +6 -5
  11. package/internals/playwright-launcher.js +10 -11
  12. package/internals/utils/playwright-utils.d.ts +61 -24
  13. package/internals/utils/playwright-utils.js +100 -53
  14. package/internals/utils/rendering-type-prediction.d.ts +28 -13
  15. package/internals/utils/rendering-type-prediction.js +71 -29
  16. package/package.json +17 -13
  17. package/index.d.ts.map +0 -1
  18. package/index.js.map +0 -1
  19. package/internals/adaptive-playwright-crawler.d.ts.map +0 -1
  20. package/internals/adaptive-playwright-crawler.js.map +0 -1
  21. package/internals/enqueue-links/click-elements.d.ts.map +0 -1
  22. package/internals/enqueue-links/click-elements.js.map +0 -1
  23. package/internals/playwright-crawler.d.ts.map +0 -1
  24. package/internals/playwright-crawler.js.map +0 -1
  25. package/internals/playwright-launcher.d.ts.map +0 -1
  26. package/internals/playwright-launcher.js.map +0 -1
  27. package/internals/utils/playwright-utils.d.ts.map +0 -1
  28. package/internals/utils/playwright-utils.js.map +0 -1
  29. package/internals/utils/rendering-type-prediction.d.ts.map +0 -1
  30. package/internals/utils/rendering-type-prediction.js.map +0 -1
  31. package/tsconfig.build.tsbuildinfo +0 -1
@@ -1,20 +1,19 @@
1
- import type { BrowserCrawlerOptions, BrowserCrawlingContext, BrowserHook, GetUserDataFromRequest, RequestHandler, RouterRoutes } from '@crawlee/browser';
2
- import { BrowserCrawler, Configuration } from '@crawlee/browser';
3
- import type { PlaywrightController, PlaywrightPlugin } from '@crawlee/browser-pool';
1
+ import type { BrowserCrawlerOptions, BrowserCrawlingContext, BrowserHook, GetUserDataFromRequest, RequestHandler, RouterHandler, RouterRoutes, RouteSchemas, RoutesFromSchemas } from '@crawlee/browser';
2
+ import { BrowserCrawler } from '@crawlee/browser';
3
+ import type { PlaywrightPlugin } from '@crawlee/browser-pool';
4
4
  import type { Dictionary } from '@crawlee/types';
5
5
  // @ts-ignore optional peer dependency or compatibility with es2022
6
- import type { LaunchOptions, Page, Response } from 'playwright';
6
+ import type { Download, LaunchOptions, Page, Response } from 'playwright';
7
+ import type { EnqueueLinksByClickingElementsOptions } from './enqueue-links/click-elements.js';
7
8
  import type { PlaywrightLaunchContext } from './playwright-launcher.js';
8
- import type { DirectNavigationOptions, PlaywrightContextUtils } from './utils/playwright-utils.js';
9
- export interface PlaywrightCrawlingContext<UserData extends Dictionary = Dictionary> extends BrowserCrawlingContext<Page, Response, PlaywrightController, UserData>, PlaywrightContextUtils {
9
+ import type { BlockRequestsOptions, DirectNavigationOptions, HandleCloudflareChallengeOptions, InfiniteScrollOptions, InjectFileOptions, PlaywrightContextUtils, SaveSnapshotOptions } from './utils/playwright-utils.js';
10
+ export type PlaywrightGotoOptions = NonNullable<Parameters<Page['goto']>[1]>;
11
+ export interface PlaywrightCrawlingContext<UserData extends Dictionary = any> extends BrowserCrawlingContext<Page, Response, UserData, PlaywrightGotoOptions>, PlaywrightContextUtils {
10
12
  }
11
- // @ts-ignore optional peer dependency or compatibility with es2022
12
- export interface PlaywrightHook extends BrowserHook<PlaywrightCrawlingContext, PlaywrightGotoOptions> {
13
- }
14
- export type PlaywrightGotoOptions = Parameters<Page['goto']>[1];
15
- export interface PlaywrightCrawlerOptions<ContextExtension = {}, ExtendedContext extends PlaywrightCrawlingContext = PlaywrightCrawlingContext & ContextExtension> extends BrowserCrawlerOptions<Page, Response, PlaywrightController, PlaywrightCrawlingContext, ContextExtension, ExtendedContext, {
13
+ export type PlaywrightHook<UserData extends Dictionary = any> = BrowserHook<PlaywrightCrawlingContext<UserData>>;
14
+ export interface PlaywrightCrawlerOptions<ContextExtension = Dictionary<never>, ExtendedContext extends PlaywrightCrawlingContext = PlaywrightCrawlingContext & ContextExtension, Routes extends Record<keyof Routes, Dictionary> = Record<string, GetUserDataFromRequest<PlaywrightCrawlingContext['request']>>> extends BrowserCrawlerOptions<Page, Response, PlaywrightCrawlingContext, ContextExtension, ExtendedContext, {
16
15
  browserPlugins: [PlaywrightPlugin];
17
- }> {
16
+ }, Routes> {
18
17
  /**
19
18
  * The same options as used by {@link launchPlaywright}.
20
19
  */
@@ -26,8 +25,6 @@ export interface PlaywrightCrawlerOptions<ContextExtension = {}, ExtendedContext
26
25
  * - `request` is an instance of the {@link Request} object with details about the URL to open, HTTP method etc.
27
26
  * - `page` is an instance of the `Playwright`
28
27
  * [`Page`](https://playwright.dev/docs/api/class-page)
29
- * - `browserController` is an instance of the
30
- * [`BrowserController`](https://github.com/apify/browser-pool#browsercontroller),
31
28
  * - `response` is an instance of the `Playwright`
32
29
  * [`Response`](https://playwright.dev/docs/api/class-response),
33
30
  * which is the main resource response as returned by `page.goto(request.url)`.
@@ -43,28 +40,28 @@ export interface PlaywrightCrawlerOptions<ContextExtension = {}, ExtendedContext
43
40
  * The exceptions are logged to the request using the
44
41
  * {@link Request.pushErrorMessage} function.
45
42
  */
46
- requestHandler?: RequestHandler<ExtendedContext>;
43
+ requestHandler?: RouterHandler<ExtendedContext, Routes> | RequestHandler<ExtendedContext>;
47
44
  /**
48
45
  * Async functions that are sequentially evaluated before the navigation. Good for setting additional cookies
49
- * or browser properties before navigation. The function accepts two parameters, `crawlingContext` and `gotoOptions`,
50
- * which are passed to the `page.goto()` function the crawler calls to navigate.
46
+ * or browser properties before navigation. The function receives the `crawlingContext`; the options object
47
+ * forwarded to `page.goto()` is available as `crawlingContext.gotoOptions` and can be mutated in place.
48
+ * A hook may optionally return a partial object whose properties are merged into the crawling context
49
+ * (e.g. to override context members for subsequent hooks and pipeline stages).
51
50
  * Example:
52
51
  * ```
53
52
  * preNavigationHooks: [
54
- * async (crawlingContext, gotoOptions) => {
55
- * const { page } = crawlingContext;
53
+ * async ({ page, gotoOptions }) => {
56
54
  * await page.evaluate((attr) => { window.foo = attr; }, 'bar');
55
+ * gotoOptions.timeout = 60_000;
57
56
  * },
58
57
  * ]
59
58
  * ```
60
- *
61
- * Modyfing `pageOptions` is supported only in Playwright incognito.
62
- * See {@link PrePageCreateHook}
63
59
  */
64
- preNavigationHooks?: PlaywrightHook[];
60
+ preNavigationHooks?: BrowserHook<PlaywrightCrawlingContext<GetUserDataFromRequest<ExtendedContext['request']>>, ContextExtension>[];
65
61
  /**
66
62
  * Async functions that are sequentially evaluated after the navigation. Good for checking if the navigation was successful.
67
- * The function accepts `crawlingContext` as the only parameter.
63
+ * The function accepts `crawlingContext` as the only parameter. A hook may optionally return a partial object
64
+ * whose properties are merged into the crawling context (e.g. to override `response` after solving a challenge).
68
65
  * Example:
69
66
  * ```
70
67
  * postNavigationHooks: [
@@ -77,7 +74,7 @@ export interface PlaywrightCrawlerOptions<ContextExtension = {}, ExtendedContext
77
74
  * ]
78
75
  * ```
79
76
  */
80
- postNavigationHooks?: PlaywrightHook[];
77
+ postNavigationHooks?: BrowserHook<PlaywrightCrawlingContext<GetUserDataFromRequest<ExtendedContext['request']>>, ContextExtension>[];
81
78
  }
82
79
  /**
83
80
  * Provides a simple framework for parallel crawling of web pages
@@ -90,24 +87,26 @@ export interface PlaywrightCrawlerOptions<ContextExtension = {}, ExtendedContext
90
87
  * If the target website doesn't need JavaScript, consider using {@link CheerioCrawler},
91
88
  * which downloads the pages using raw HTTP requests and is about 10x faster.
92
89
  *
93
- * The source URLs are represented using {@link Request} objects that are fed from
94
- * {@link RequestList} or {@link RequestQueue} instances provided by the {@link PlaywrightCrawlerOptions.requestList}
95
- * or {@link PlaywrightCrawlerOptions.requestQueue} constructor options, respectively.
90
+ * The source URLs are represented using {@link Request} objects that are fed from the
91
+ * {@link IRequestManager|request manager} provided via the {@link PlaywrightCrawlerOptions.requestManager|`requestManager`}
92
+ * constructor option (a {@link RequestQueue} is itself a request manager). To read from a read-only source such
93
+ * as a {@link RequestList} while still being able to enqueue new requests, combine it with a queue into a
94
+ * {@link RequestManagerTandem} via {@link IRequestLoader.toTandem|`requestLoader.toTandem()`} and pass the
95
+ * result as `requestManager`.
96
96
  *
97
- * If both {@link PlaywrightCrawlerOptions.requestList} and {@link PlaywrightCrawlerOptions.requestQueue} are used,
98
- * the instance first processes URLs from the {@link RequestList} and automatically enqueues all of them
99
- * to {@link RequestQueue} before it starts their processing. This ensures that a single URL is not crawled multiple times.
97
+ * > The {@link PlaywrightCrawlerOptions.requestList|`requestList`} and {@link PlaywrightCrawlerOptions.requestQueue|`requestQueue`}
98
+ * > options are deprecated; they are still accepted and folded into a single `requestManager` for back-compat.
100
99
  *
101
100
  * The crawler finishes when there are no more {@link Request} objects to crawl.
102
101
  *
103
102
  * `PlaywrightCrawler` opens a new Chrome page (i.e. tab) for each {@link Request} object to crawl
104
103
  * and then calls the function provided by user as the {@link PlaywrightCrawlerOptions.requestHandler} option.
105
104
  *
106
- * New pages are only opened when there is enough free CPU and memory available,
107
- * using the functionality provided by the {@link AutoscaledPool} class.
108
- * All {@link AutoscaledPool} configuration options can be passed to the {@link PlaywrightCrawlerOptions.autoscaledPoolOptions}
109
- * parameter of the `PlaywrightCrawler` constructor. For user convenience, the `minConcurrency` and `maxConcurrency`
110
- * {@link AutoscaledPoolOptions} are available directly in the `PlaywrightCrawler` constructor.
105
+ * New pages are only opened when there is enough free CPU and memory available, as judged by the crawler's
106
+ * {@link ConcurrencySystem}.
107
+ * Concurrency is tuned via the `minConcurrency`, `maxConcurrency` and `maxRequestsPerMinute` options of the
108
+ * `PlaywrightCrawler` constructor, or, for finer control, by injecting a pre-configured
109
+ * {@link ConcurrencySystem|`concurrencySystem`}.
111
110
  *
112
111
  * Note that the pool of Playwright instances is internally managed by the [BrowserPool](https://github.com/apify/browser-pool) class.
113
112
  *
@@ -142,10 +141,9 @@ export interface PlaywrightCrawlerOptions<ContextExtension = {}, ExtendedContext
142
141
  * ```
143
142
  * @category Crawlers
144
143
  */
145
- export declare class PlaywrightCrawler<ContextExtension = {}, ExtendedContext extends PlaywrightCrawlingContext = PlaywrightCrawlingContext & ContextExtension> extends BrowserCrawler<Page, Response, PlaywrightController, {
144
+ export declare class PlaywrightCrawler<ContextExtension = Dictionary<never>, ExtendedContext extends PlaywrightCrawlingContext = PlaywrightCrawlingContext & ContextExtension, Routes extends Record<keyof Routes, Dictionary> = Record<string, GetUserDataFromRequest<PlaywrightCrawlingContext['request']>>> extends BrowserCrawler<Page, Response, {
146
145
  browserPlugins: [PlaywrightPlugin];
147
- }, LaunchOptions, PlaywrightCrawlingContext, ContextExtension, ExtendedContext> {
148
- readonly config: Configuration;
146
+ }, LaunchOptions, PlaywrightCrawlingContext, ContextExtension, ExtendedContext, Routes> {
149
147
  protected static optionsShape: {
150
148
  // @ts-ignore optional peer dependency or compatibility with es2022
151
149
  browserPoolOptions: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
@@ -166,11 +164,11 @@ export declare class PlaywrightCrawler<ContextExtension = {}, ExtendedContext ex
166
164
  // @ts-ignore optional peer dependency or compatibility with es2022
167
165
  headless: import("ow").AnyPredicate<string | boolean>;
168
166
  // @ts-ignore optional peer dependency or compatibility with es2022
169
- sessionPoolOptions: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
167
+ browserPool: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
170
168
  // @ts-ignore optional peer dependency or compatibility with es2022
171
- persistCookiesPerSession: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
169
+ remoteBrowser: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
172
170
  // @ts-ignore optional peer dependency or compatibility with es2022
173
- useSessionPool: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
171
+ saveResponseCookies: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
174
172
  // @ts-ignore optional peer dependency or compatibility with es2022
175
173
  proxyConfiguration: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
176
174
  // @ts-ignore optional peer dependency or compatibility with es2022
@@ -193,24 +191,44 @@ export declare class PlaywrightCrawler<ContextExtension = {}, ExtendedContext ex
193
191
  maxRequestRetries: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
194
192
  // @ts-ignore optional peer dependency or compatibility with es2022
195
193
  sameDomainDelaySecs: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
196
- // @ts-ignore optional peer dependency or compatibility with es2022
197
- maxSessionRotations: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
198
194
  // @ts-ignore optional peer dependency or compatibility with es2022
199
195
  maxRequestsPerCrawl: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
200
196
  // @ts-ignore optional peer dependency or compatibility with es2022
201
- autoscaledPoolOptions: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
197
+ maxCrawlDepth: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
198
+ // @ts-ignore optional peer dependency or compatibility with es2022
199
+ taskLoopOptions: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
200
+ // @ts-ignore optional peer dependency or compatibility with es2022
201
+ concurrencySystem: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
202
+ // @ts-ignore optional peer dependency or compatibility with es2022
203
+ sessionPool: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
202
204
  // @ts-ignore optional peer dependency or compatibility with es2022
203
205
  statusMessageLoggingInterval: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
204
206
  // @ts-ignore optional peer dependency or compatibility with es2022
205
207
  statusMessageCallback: import("ow").Predicate<Function> & import("ow").BasePredicate<Function | undefined>;
208
+ // @ts-ignore optional peer dependency or compatibility with es2022
209
+ additionalHttpErrorStatusCodes: import("ow").ArrayPredicate<number>;
210
+ // @ts-ignore optional peer dependency or compatibility with es2022
211
+ ignoreHttpErrorStatusCodes: import("ow").ArrayPredicate<number>;
212
+ // @ts-ignore optional peer dependency or compatibility with es2022
213
+ blockedStatusCodes: import("ow").ArrayPredicate<number>;
206
214
  // @ts-ignore optional peer dependency or compatibility with es2022
207
215
  retryOnBlocked: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
208
216
  // @ts-ignore optional peer dependency or compatibility with es2022
209
- respectRobotsTxtFile: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
217
+ respectRobotsTxtFile: import("ow").AnyPredicate<boolean | object>;
218
+ // @ts-ignore optional peer dependency or compatibility with es2022
219
+ transactionalStorage: import("ow").BasePredicate<boolean | Partial<import("@crawlee/browser").StorageWritePolicy> | undefined>;
210
220
  // @ts-ignore optional peer dependency or compatibility with es2022
211
221
  onSkippedRequest: import("ow").Predicate<Function> & import("ow").BasePredicate<Function | undefined>;
212
222
  // @ts-ignore optional peer dependency or compatibility with es2022
213
223
  httpClient: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
224
+ // @ts-ignore optional peer dependency or compatibility with es2022
225
+ configuration: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
226
+ // @ts-ignore optional peer dependency or compatibility with es2022
227
+ storageBackend: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
228
+ // @ts-ignore optional peer dependency or compatibility with es2022
229
+ eventManager: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
230
+ // @ts-ignore optional peer dependency or compatibility with es2022
231
+ logger: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
214
232
  // @ts-ignore optional peer dependency or compatibility with es2022
215
233
  minConcurrency: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
216
234
  // @ts-ignore optional peer dependency or compatibility with es2022
@@ -220,19 +238,49 @@ export declare class PlaywrightCrawler<ContextExtension = {}, ExtendedContext ex
220
238
  // @ts-ignore optional peer dependency or compatibility with es2022
221
239
  keepAlive: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
222
240
  // @ts-ignore optional peer dependency or compatibility with es2022
223
- log: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
224
- // @ts-ignore optional peer dependency or compatibility with es2022
225
- experiments: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
241
+ statistics: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
226
242
  // @ts-ignore optional peer dependency or compatibility with es2022
227
- statisticsOptions: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
243
+ id: import("ow").StringPredicate & import("ow").BasePredicate<string | undefined>;
228
244
  };
229
245
  /**
230
246
  * All `PlaywrightCrawler` parameters are passed via an options object.
231
247
  */
232
- constructor(options?: PlaywrightCrawlerOptions<ExtendedContext>, config?: Configuration);
233
- protected _navigationHandler(crawlingContext: PlaywrightCrawlingContext, gotoOptions: DirectNavigationOptions): Promise<Response | null>;
248
+ constructor(options?: PlaywrightCrawlerOptions<ContextExtension, ExtendedContext, Routes>);
249
+ // @ts-ignore optional peer dependency or compatibility with es2022
250
+ protected buildContextPipeline(): import("@crawlee/browser").ContextPipeline<import("@crawlee/browser").CrawlingContext<Dictionary>, BrowserCrawlingContext<Page, Response, Dictionary, Dictionary> & {
251
+ injectFile: (filePath: string, options?: InjectFileOptions) => Promise<unknown>;
252
+ injectJQuery: () => Promise<void>;
253
+ blockRequests: (options?: BlockRequestsOptions) => Promise<void>;
254
+ waitForSelector: (selector: string, timeoutMs?: number) => Promise<void>;
255
+ // @ts-ignore optional peer dependency or compatibility with es2022
256
+ parseWithCheerio: (selector?: string, timeoutMs?: number) => Promise<import("@crawlee/browser").CheerioAPI>;
257
+ infiniteScroll: (options?: InfiniteScrollOptions) => Promise<void>;
258
+ listDownloads: () => Promise<Download[]>;
259
+ saveSnapshot: (options?: SaveSnapshotOptions) => Promise<void>;
260
+ // @ts-ignore optional peer dependency or compatibility with es2022
261
+ enqueueLinksByClickingElements: (options: Omit<EnqueueLinksByClickingElementsOptions, "page" | "requestManager">) => Promise<import("@crawlee/types").BatchAddRequestsResult>;
262
+ // @ts-ignore optional peer dependency or compatibility with es2022
263
+ compileScript: (scriptString: string, ctx?: Dictionary) => import("./utils/playwright-utils.js").CompiledScriptFunction;
264
+ closeCookieModals: () => Promise<void>;
265
+ handleCloudflareChallenge: (options?: HandleCloudflareChallengeOptions) => Promise<Response | undefined>;
266
+ }>;
267
+ protected navigationHandler(crawlingContext: PlaywrightCrawlingContext, gotoOptions: DirectNavigationOptions): Promise<Response | null>;
234
268
  private enhanceContext;
235
269
  }
270
+ /**
271
+ * Returns a `postNavigationHooks`-ready hook that runs {@link PlaywrightContextUtils.handleCloudflareChallenge}
272
+ * and propagates the post-challenge {@link Response} back into the crawling context via its return value.
273
+ *
274
+ * **Example usage**
275
+ * ```ts
276
+ * import { PlaywrightCrawler, handleCloudflareChallengeHook } from 'crawlee';
277
+ *
278
+ * const crawler = new PlaywrightCrawler({
279
+ * postNavigationHooks: [handleCloudflareChallengeHook()],
280
+ * });
281
+ * ```
282
+ */
283
+ export declare function handleCloudflareChallengeHook(options?: HandleCloudflareChallengeOptions): PlaywrightHook;
236
284
  /**
237
285
  * Creates new {@link Router} instance that works based on request labels.
238
286
  * This instance can then serve as a `requestHandler` of your {@link PlaywrightCrawler}.
@@ -257,6 +305,6 @@ export declare class PlaywrightCrawler<ContextExtension = {}, ExtendedContext ex
257
305
  * await crawler.run();
258
306
  * ```
259
307
  */
260
- // @ts-ignore optional peer dependency or compatibility with es2022
261
- export declare function createPlaywrightRouter<Context extends PlaywrightCrawlingContext = PlaywrightCrawlingContext, UserData extends Dictionary = GetUserDataFromRequest<Context['request']>>(routes?: RouterRoutes<Context, UserData>): import("@crawlee/browser").RouterHandler<Context>;
262
- //# sourceMappingURL=playwright-crawler.d.ts.map
308
+ export declare function createPlaywrightRouter<Context extends PlaywrightCrawlingContext = PlaywrightCrawlingContext, Routes extends Record<keyof Routes, Dictionary> = Record<string, GetUserDataFromRequest<Context['request']>>>(routes?: RouterRoutes<Context, Routes>): RouterHandler<Context, Routes>;
309
+ export declare function createPlaywrightRouter<Context extends PlaywrightCrawlingContext = PlaywrightCrawlingContext, UserData extends Dictionary = GetUserDataFromRequest<Context['request']>>(routes?: RouterRoutes<Context, Record<string, UserData>>): RouterHandler<Context, Record<string, UserData>>;
310
+ export declare function createPlaywrightRouter<Context extends PlaywrightCrawlingContext = PlaywrightCrawlingContext, const Schemas extends RouteSchemas = RouteSchemas>(schemas: Schemas): RouterHandler<Context, RoutesFromSchemas<Schemas>>;
@@ -1,4 +1,4 @@
1
- import { BrowserCrawler, Configuration, RequestState, Router } from '@crawlee/browser';
1
+ import { BrowserCrawler, RequestState, Router, serviceLocator } from '@crawlee/browser';
2
2
  import ow from 'ow';
3
3
  import { PlaywrightLauncher } from './playwright-launcher.js';
4
4
  import { gotoExtended, playwrightUtils } from './utils/playwright-utils.js';
@@ -13,24 +13,26 @@ import { gotoExtended, playwrightUtils } from './utils/playwright-utils.js';
13
13
  * If the target website doesn't need JavaScript, consider using {@link CheerioCrawler},
14
14
  * which downloads the pages using raw HTTP requests and is about 10x faster.
15
15
  *
16
- * The source URLs are represented using {@link Request} objects that are fed from
17
- * {@link RequestList} or {@link RequestQueue} instances provided by the {@link PlaywrightCrawlerOptions.requestList}
18
- * or {@link PlaywrightCrawlerOptions.requestQueue} constructor options, respectively.
16
+ * The source URLs are represented using {@link Request} objects that are fed from the
17
+ * {@link IRequestManager|request manager} provided via the {@link PlaywrightCrawlerOptions.requestManager|`requestManager`}
18
+ * constructor option (a {@link RequestQueue} is itself a request manager). To read from a read-only source such
19
+ * as a {@link RequestList} while still being able to enqueue new requests, combine it with a queue into a
20
+ * {@link RequestManagerTandem} via {@link IRequestLoader.toTandem|`requestLoader.toTandem()`} and pass the
21
+ * result as `requestManager`.
19
22
  *
20
- * If both {@link PlaywrightCrawlerOptions.requestList} and {@link PlaywrightCrawlerOptions.requestQueue} are used,
21
- * the instance first processes URLs from the {@link RequestList} and automatically enqueues all of them
22
- * to {@link RequestQueue} before it starts their processing. This ensures that a single URL is not crawled multiple times.
23
+ * > The {@link PlaywrightCrawlerOptions.requestList|`requestList`} and {@link PlaywrightCrawlerOptions.requestQueue|`requestQueue`}
24
+ * > options are deprecated; they are still accepted and folded into a single `requestManager` for back-compat.
23
25
  *
24
26
  * The crawler finishes when there are no more {@link Request} objects to crawl.
25
27
  *
26
28
  * `PlaywrightCrawler` opens a new Chrome page (i.e. tab) for each {@link Request} object to crawl
27
29
  * and then calls the function provided by user as the {@link PlaywrightCrawlerOptions.requestHandler} option.
28
30
  *
29
- * New pages are only opened when there is enough free CPU and memory available,
30
- * using the functionality provided by the {@link AutoscaledPool} class.
31
- * All {@link AutoscaledPool} configuration options can be passed to the {@link PlaywrightCrawlerOptions.autoscaledPoolOptions}
32
- * parameter of the `PlaywrightCrawler` constructor. For user convenience, the `minConcurrency` and `maxConcurrency`
33
- * {@link AutoscaledPoolOptions} are available directly in the `PlaywrightCrawler` constructor.
31
+ * New pages are only opened when there is enough free CPU and memory available, as judged by the crawler's
32
+ * {@link ConcurrencySystem}.
33
+ * Concurrency is tuned via the `minConcurrency`, `maxConcurrency` and `maxRequestsPerMinute` options of the
34
+ * `PlaywrightCrawler` constructor, or, for finer control, by injecting a pre-configured
35
+ * {@link ConcurrencySystem|`concurrencySystem`}.
34
36
  *
35
37
  * Note that the pool of Playwright instances is internally managed by the [BrowserPool](https://github.com/apify/browser-pool) class.
36
38
  *
@@ -66,7 +68,6 @@ import { gotoExtended, playwrightUtils } from './utils/playwright-utils.js';
66
68
  * @category Crawlers
67
69
  */
68
70
  export class PlaywrightCrawler extends BrowserCrawler {
69
- config;
70
71
  static optionsShape = {
71
72
  ...BrowserCrawler.optionsShape,
72
73
  browserPoolOptions: ow.optional.object,
@@ -77,9 +78,9 @@ export class PlaywrightCrawler extends BrowserCrawler {
77
78
  /**
78
79
  * All `PlaywrightCrawler` parameters are passed via an options object.
79
80
  */
80
- constructor(options = {}, config = Configuration.getGlobalConfig()) {
81
+ constructor(options = {}) {
81
82
  ow(options, 'PlaywrightCrawlerOptions', ow.object.exactShape(PlaywrightCrawler.optionsShape));
82
- const { launchContext = {}, headless, ...browserCrawlerOptions } = options;
83
+ const { launchContext = {}, headless, contextPipelineBuilder, ...browserCrawlerOptions } = options;
83
84
  const browserPoolOptions = {
84
85
  ...options.browserPoolOptions,
85
86
  };
@@ -96,17 +97,19 @@ export class PlaywrightCrawler extends BrowserCrawler {
96
97
  launchContext.launchOptions ??= {};
97
98
  launchContext.launchOptions.headless = headless;
98
99
  }
99
- const playwrightLauncher = new PlaywrightLauncher(launchContext, config);
100
+ const playwrightLauncher = new PlaywrightLauncher(launchContext, options.configuration);
100
101
  browserPoolOptions.browserPlugins = [playwrightLauncher.createBrowserPlugin()];
101
102
  super({
102
103
  ...browserCrawlerOptions,
103
104
  launchContext,
104
105
  browserPoolOptions,
105
- contextPipelineBuilder: () => this.buildContextPipeline().compose({ action: this.enhanceContext.bind(this) }),
106
- }, config);
107
- this.config = config;
106
+ contextPipelineBuilder: contextPipelineBuilder ?? (() => this.buildContextPipeline()),
107
+ });
108
108
  }
109
- async _navigationHandler(crawlingContext, gotoOptions) {
109
+ buildContextPipeline() {
110
+ return super.buildContextPipeline().compose({ action: this.enhanceContext.bind(this) });
111
+ }
112
+ async navigationHandler(crawlingContext, gotoOptions) {
110
113
  return gotoExtended(crawlingContext.page, crawlingContext.request, gotoOptions);
111
114
  }
112
115
  async enhanceContext(context) {
@@ -114,6 +117,8 @@ export class PlaywrightCrawler extends BrowserCrawler {
114
117
  const locator = context.page.locator(selector).first();
115
118
  await locator.waitFor({ timeout: timeoutMs, state: 'attached' });
116
119
  };
120
+ const downloads = [];
121
+ context.page.on('download', (download) => downloads.push(download));
117
122
  return {
118
123
  injectFile: async (filePath, options) => playwrightUtils.injectFile(context.page, filePath, options),
119
124
  injectJQuery: async () => {
@@ -133,45 +138,46 @@ export class PlaywrightCrawler extends BrowserCrawler {
133
138
  return playwrightUtils.parseWithCheerio(context.page, this.ignoreShadowRoots, this.ignoreIframes);
134
139
  },
135
140
  infiniteScroll: async (options) => playwrightUtils.infiniteScroll(context.page, options),
136
- saveSnapshot: async (options) => playwrightUtils.saveSnapshot(context.page, { ...options, config: this.config }),
141
+ listDownloads: async () => downloads,
142
+ saveSnapshot: async (options) => playwrightUtils.saveSnapshot(context.page, {
143
+ ...options,
144
+ configuration: serviceLocator.getConfiguration(),
145
+ }),
137
146
  enqueueLinksByClickingElements: async (options) => playwrightUtils.enqueueLinksByClickingElements({
138
147
  ...options,
139
148
  page: context.page,
140
- requestQueue: this.requestQueue,
149
+ requestManager: this.requestManager,
141
150
  }),
142
151
  compileScript: (scriptString, ctx) => playwrightUtils.compileScript(scriptString, ctx),
143
152
  closeCookieModals: async () => playwrightUtils.closeCookieModals(context.page),
144
153
  handleCloudflareChallenge: async (options) => {
145
- return playwrightUtils.handleCloudflareChallenge(context.page, context.request.url, context.session, options);
154
+ return playwrightUtils.handleCloudflareChallenge(context.page, context.request.url, options);
146
155
  },
147
156
  };
148
157
  }
149
158
  }
150
159
  /**
151
- * Creates new {@link Router} instance that works based on request labels.
152
- * This instance can then serve as a `requestHandler` of your {@link PlaywrightCrawler}.
153
- * Defaults to the {@link PlaywrightCrawlingContext}.
154
- *
155
- * > Serves as a shortcut for using `Router.create<PlaywrightCrawlingContext>()`.
160
+ * Returns a `postNavigationHooks`-ready hook that runs {@link PlaywrightContextUtils.handleCloudflareChallenge}
161
+ * and propagates the post-challenge {@link Response} back into the crawling context via its return value.
156
162
  *
163
+ * **Example usage**
157
164
  * ```ts
158
- * import { PlaywrightCrawler, createPlaywrightRouter } from 'crawlee';
159
- *
160
- * const router = createPlaywrightRouter();
161
- * router.addHandler('label-a', async (ctx) => {
162
- * ctx.log.info('...');
163
- * });
164
- * router.addDefaultHandler(async (ctx) => {
165
- * ctx.log.info('...');
166
- * });
165
+ * import { PlaywrightCrawler, handleCloudflareChallengeHook } from 'crawlee';
167
166
  *
168
167
  * const crawler = new PlaywrightCrawler({
169
- * requestHandler: router,
168
+ * postNavigationHooks: [handleCloudflareChallengeHook()],
170
169
  * });
171
- * await crawler.run();
172
170
  * ```
173
171
  */
174
- export function createPlaywrightRouter(routes) {
175
- return Router.create(routes);
172
+ export function handleCloudflareChallengeHook(options) {
173
+ return async (context) => {
174
+ const response = await context.handleCloudflareChallenge(options);
175
+ if (response !== undefined) {
176
+ return { response };
177
+ }
178
+ return undefined;
179
+ };
180
+ }
181
+ export function createPlaywrightRouter(routesOrSchemas) {
182
+ return Router.create(routesOrSchemas);
176
183
  }
177
- //# sourceMappingURL=playwright-crawler.js.map
@@ -70,7 +70,7 @@ export interface PlaywrightLaunchContext extends BrowserLaunchContext<LaunchOpti
70
70
  * @ignore
71
71
  */
72
72
  export declare class PlaywrightLauncher extends BrowserLauncher<PlaywrightPlugin> {
73
- readonly config: Configuration;
73
+ readonly configuration: Configuration;
74
74
  protected static optionsShape: {
75
75
  // @ts-ignore optional peer dependency or compatibility with es2022
76
76
  launcher: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
@@ -84,6 +84,8 @@ export declare class PlaywrightLauncher extends BrowserLauncher<PlaywrightPlugin
84
84
  useIncognitoPages: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
85
85
  // @ts-ignore optional peer dependency or compatibility with es2022
86
86
  browserPerProxy: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
87
+ // @ts-ignore optional peer dependency or compatibility with es2022
88
+ ignoreProxyCertificate: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
87
89
  // @ts-ignore optional peer dependency or compatibility with es2022
88
90
  userDataDir: import("ow").StringPredicate & import("ow").BasePredicate<string | undefined>;
89
91
  // @ts-ignore optional peer dependency or compatibility with es2022
@@ -94,7 +96,7 @@ export declare class PlaywrightLauncher extends BrowserLauncher<PlaywrightPlugin
94
96
  /**
95
97
  * All `PlaywrightLauncher` parameters are passed via this launchContext object.
96
98
  */
97
- constructor(launchContext?: PlaywrightLaunchContext, config?: Configuration);
99
+ constructor(launchContext?: PlaywrightLaunchContext, configuration?: Configuration);
98
100
  }
99
101
  /**
100
102
  * Launches headless browsers using Playwright pre-configured to work within the Apify platform.
@@ -125,9 +127,8 @@ export declare class PlaywrightLauncher extends BrowserLauncher<PlaywrightPlugin
125
127
  * Optional settings passed to `browserType.launch()`. In addition to
126
128
  * [Playwright's options](https://playwright.dev/docs/api/class-browsertype?_highlight=launch#browsertypelaunchoptions)
127
129
  * the object may contain our own {@link PlaywrightLaunchContext} that enable additional features.
128
- * @param [config]
130
+ * @param [configuration]
129
131
  * @returns
130
132
  * Promise that resolves to Playwright's `Browser` instance.
131
133
  */
132
- export declare function launchPlaywright(launchContext?: PlaywrightLaunchContext, config?: Configuration): Promise<Browser>;
133
- //# sourceMappingURL=playwright-launcher.d.ts.map
134
+ export declare function launchPlaywright(launchContext?: PlaywrightLaunchContext, configuration?: Configuration): Promise<Browser>;
@@ -6,7 +6,7 @@ import ow from 'ow';
6
6
  * @ignore
7
7
  */
8
8
  export class PlaywrightLauncher extends BrowserLauncher {
9
- config;
9
+ configuration;
10
10
  static optionsShape = {
11
11
  ...BrowserLauncher.optionsShape,
12
12
  launcher: ow.optional.object,
@@ -15,7 +15,7 @@ export class PlaywrightLauncher extends BrowserLauncher {
15
15
  /**
16
16
  * All `PlaywrightLauncher` parameters are passed via this launchContext object.
17
17
  */
18
- constructor(launchContext = {}, config = Configuration.getGlobalConfig()) {
18
+ constructor(launchContext = {}, configuration = Configuration.getGlobalConfiguration()) {
19
19
  ow(launchContext, 'PlaywrightLauncherOptions', ow.object.exactShape(PlaywrightLauncher.optionsShape));
20
20
  const { launcher = BrowserLauncher.requireLauncherOrThrow('playwright', 'apify/actor-node-playwright-*').chromium, } = launchContext;
21
21
  const { launchOptions = {}, ...rest } = launchContext;
@@ -23,11 +23,11 @@ export class PlaywrightLauncher extends BrowserLauncher {
23
23
  ...rest,
24
24
  launchOptions: {
25
25
  ...launchOptions,
26
- executablePath: getDefaultExecutablePath(launchContext, config),
26
+ executablePath: getDefaultExecutablePath(launchContext, configuration),
27
27
  },
28
28
  launcher,
29
- }, config);
30
- this.config = config;
29
+ }, configuration);
30
+ this.configuration = configuration;
31
31
  this.Plugin = PlaywrightPlugin;
32
32
  }
33
33
  }
@@ -36,8 +36,8 @@ export class PlaywrightLauncher extends BrowserLauncher {
36
36
  * @returns default path to browser.
37
37
  * @ignore
38
38
  */
39
- function getDefaultExecutablePath(launchContext, config) {
40
- const pathFromPlaywrightImage = config.get('defaultBrowserPath');
39
+ function getDefaultExecutablePath(launchContext, configuration) {
40
+ const pathFromPlaywrightImage = configuration.defaultBrowserPath;
41
41
  const { launchOptions = {} } = launchContext;
42
42
  if (launchOptions.executablePath) {
43
43
  return launchOptions.executablePath;
@@ -79,12 +79,11 @@ function getDefaultExecutablePath(launchContext, config) {
79
79
  * Optional settings passed to `browserType.launch()`. In addition to
80
80
  * [Playwright's options](https://playwright.dev/docs/api/class-browsertype?_highlight=launch#browsertypelaunchoptions)
81
81
  * the object may contain our own {@link PlaywrightLaunchContext} that enable additional features.
82
- * @param [config]
82
+ * @param [configuration]
83
83
  * @returns
84
84
  * Promise that resolves to Playwright's `Browser` instance.
85
85
  */
86
- export async function launchPlaywright(launchContext, config = Configuration.getGlobalConfig()) {
87
- const playwrightLauncher = new PlaywrightLauncher(launchContext, config);
86
+ export async function launchPlaywright(launchContext, configuration = Configuration.getGlobalConfiguration()) {
87
+ const playwrightLauncher = new PlaywrightLauncher(launchContext, configuration);
88
88
  return playwrightLauncher.launch();
89
89
  }
90
- //# sourceMappingURL=playwright-launcher.js.map