@crawlee/playwright 4.0.0-beta.12 → 4.0.0-beta.120
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/README.md +17 -13
- package/index.d.ts +1 -2
- package/index.js +0 -1
- package/internals/adaptive-playwright-crawler.d.ts +114 -50
- package/internals/adaptive-playwright-crawler.js +316 -235
- package/internals/enqueue-links/click-elements.d.ts +37 -55
- package/internals/enqueue-links/click-elements.js +51 -43
- package/internals/playwright-crawler.d.ts +105 -55
- package/internals/playwright-crawler.js +48 -42
- package/internals/playwright-launcher.d.ts +6 -5
- package/internals/playwright-launcher.js +10 -11
- package/internals/utils/playwright-utils.d.ts +61 -24
- package/internals/utils/playwright-utils.js +100 -53
- package/internals/utils/rendering-type-prediction.d.ts +28 -13
- package/internals/utils/rendering-type-prediction.js +87 -29
- package/package.json +18 -13
- package/index.d.ts.map +0 -1
- package/index.js.map +0 -1
- package/internals/adaptive-playwright-crawler.d.ts.map +0 -1
- package/internals/adaptive-playwright-crawler.js.map +0 -1
- package/internals/enqueue-links/click-elements.d.ts.map +0 -1
- package/internals/enqueue-links/click-elements.js.map +0 -1
- package/internals/playwright-crawler.d.ts.map +0 -1
- package/internals/playwright-crawler.js.map +0 -1
- package/internals/playwright-launcher.d.ts.map +0 -1
- package/internals/playwright-launcher.js.map +0 -1
- package/internals/utils/playwright-utils.d.ts.map +0 -1
- package/internals/utils/playwright-utils.js.map +0 -1
- package/internals/utils/rendering-type-prediction.d.ts.map +0 -1
- package/internals/utils/rendering-type-prediction.js.map +0 -1
- 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
|
|
3
|
-
import type {
|
|
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
|
|
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
|
-
|
|
12
|
-
export interface
|
|
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
|
|
50
|
-
*
|
|
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 (
|
|
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?:
|
|
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?:
|
|
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
|
|
95
|
-
*
|
|
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
|
-
*
|
|
98
|
-
*
|
|
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
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
* {@link
|
|
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 =
|
|
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
|
-
|
|
167
|
+
browserPool: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
170
168
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
171
|
-
|
|
169
|
+
remoteBrowser: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
172
170
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
173
|
-
|
|
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
|
|
@@ -181,6 +179,8 @@ export declare class PlaywrightCrawler<ContextExtension = {}, ExtendedContext ex
|
|
|
181
179
|
requestList: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
182
180
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
183
181
|
requestQueue: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
182
|
+
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
183
|
+
requestManager: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
184
184
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
185
185
|
requestHandler: import("ow").Predicate<Function> & import("ow").BasePredicate<Function | undefined>;
|
|
186
186
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
@@ -193,24 +193,44 @@ export declare class PlaywrightCrawler<ContextExtension = {}, ExtendedContext ex
|
|
|
193
193
|
maxRequestRetries: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
|
|
194
194
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
195
195
|
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
196
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
199
197
|
maxRequestsPerCrawl: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
|
|
200
198
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
201
|
-
|
|
199
|
+
maxCrawlDepth: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
|
|
200
|
+
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
201
|
+
taskLoopOptions: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
202
|
+
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
203
|
+
concurrencySystem: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
204
|
+
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
205
|
+
sessionPool: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
202
206
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
203
207
|
statusMessageLoggingInterval: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
|
|
204
208
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
205
209
|
statusMessageCallback: import("ow").Predicate<Function> & import("ow").BasePredicate<Function | undefined>;
|
|
210
|
+
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
211
|
+
additionalHttpErrorStatusCodes: import("ow").ArrayPredicate<number>;
|
|
212
|
+
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
213
|
+
ignoreHttpErrorStatusCodes: import("ow").ArrayPredicate<number>;
|
|
214
|
+
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
215
|
+
blockedStatusCodes: import("ow").ArrayPredicate<number>;
|
|
206
216
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
207
217
|
retryOnBlocked: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
|
|
208
218
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
209
|
-
respectRobotsTxtFile: import("ow").
|
|
219
|
+
respectRobotsTxtFile: import("ow").AnyPredicate<boolean | object>;
|
|
220
|
+
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
221
|
+
transactionalStorage: import("ow").BasePredicate<boolean | Partial<import("@crawlee/browser").StorageWritePolicy> | undefined>;
|
|
210
222
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
211
223
|
onSkippedRequest: import("ow").Predicate<Function> & import("ow").BasePredicate<Function | undefined>;
|
|
212
224
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
213
225
|
httpClient: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
226
|
+
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
227
|
+
configuration: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
228
|
+
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
229
|
+
storageBackend: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
230
|
+
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
231
|
+
eventManager: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
232
|
+
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
233
|
+
logger: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
214
234
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
215
235
|
minConcurrency: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
|
|
216
236
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
@@ -220,19 +240,49 @@ export declare class PlaywrightCrawler<ContextExtension = {}, ExtendedContext ex
|
|
|
220
240
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
221
241
|
keepAlive: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
|
|
222
242
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
223
|
-
|
|
224
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
225
|
-
experiments: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
243
|
+
statistics: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
226
244
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
227
|
-
|
|
245
|
+
id: import("ow").StringPredicate & import("ow").BasePredicate<string | undefined>;
|
|
228
246
|
};
|
|
229
247
|
/**
|
|
230
248
|
* All `PlaywrightCrawler` parameters are passed via an options object.
|
|
231
249
|
*/
|
|
232
|
-
constructor(options?: PlaywrightCrawlerOptions<ExtendedContext
|
|
233
|
-
|
|
250
|
+
constructor(options?: PlaywrightCrawlerOptions<ContextExtension, ExtendedContext, Routes>);
|
|
251
|
+
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
252
|
+
protected buildContextPipeline(): import("@crawlee/browser").ContextPipeline<import("@crawlee/browser").CrawlingContext<Dictionary>, BrowserCrawlingContext<Page, Response, Dictionary, Dictionary> & {
|
|
253
|
+
injectFile: (filePath: string, options?: InjectFileOptions) => Promise<unknown>;
|
|
254
|
+
injectJQuery: () => Promise<void>;
|
|
255
|
+
blockRequests: (options?: BlockRequestsOptions) => Promise<void>;
|
|
256
|
+
waitForSelector: (selector: string, timeoutMs?: number) => Promise<void>;
|
|
257
|
+
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
258
|
+
parseWithCheerio: (selector?: string, timeoutMs?: number) => Promise<import("@crawlee/browser").CheerioAPI>;
|
|
259
|
+
infiniteScroll: (options?: InfiniteScrollOptions) => Promise<void>;
|
|
260
|
+
listDownloads: () => Promise<Download[]>;
|
|
261
|
+
saveSnapshot: (options?: SaveSnapshotOptions) => Promise<void>;
|
|
262
|
+
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
263
|
+
enqueueLinksByClickingElements: (options: Omit<EnqueueLinksByClickingElementsOptions, "page" | "requestManager">) => Promise<import("@crawlee/types").BatchAddRequestsResult>;
|
|
264
|
+
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
265
|
+
compileScript: (scriptString: string, ctx?: Dictionary) => import("./utils/playwright-utils.js").CompiledScriptFunction;
|
|
266
|
+
closeCookieModals: () => Promise<void>;
|
|
267
|
+
handleCloudflareChallenge: (options?: HandleCloudflareChallengeOptions) => Promise<Response | undefined>;
|
|
268
|
+
}>;
|
|
269
|
+
protected navigationHandler(crawlingContext: PlaywrightCrawlingContext, gotoOptions: DirectNavigationOptions): Promise<Response | null>;
|
|
234
270
|
private enhanceContext;
|
|
235
271
|
}
|
|
272
|
+
/**
|
|
273
|
+
* Returns a `postNavigationHooks`-ready hook that runs {@link PlaywrightContextUtils.handleCloudflareChallenge}
|
|
274
|
+
* and propagates the post-challenge {@link Response} back into the crawling context via its return value.
|
|
275
|
+
*
|
|
276
|
+
* **Example usage**
|
|
277
|
+
* ```ts
|
|
278
|
+
* import { PlaywrightCrawler, handleCloudflareChallengeHook } from 'crawlee';
|
|
279
|
+
*
|
|
280
|
+
* const crawler = new PlaywrightCrawler({
|
|
281
|
+
* postNavigationHooks: [handleCloudflareChallengeHook()],
|
|
282
|
+
* });
|
|
283
|
+
* ```
|
|
284
|
+
*/
|
|
285
|
+
export declare function handleCloudflareChallengeHook(options?: HandleCloudflareChallengeOptions): PlaywrightHook;
|
|
236
286
|
/**
|
|
237
287
|
* Creates new {@link Router} instance that works based on request labels.
|
|
238
288
|
* This instance can then serve as a `requestHandler` of your {@link PlaywrightCrawler}.
|
|
@@ -257,6 +307,6 @@ export declare class PlaywrightCrawler<ContextExtension = {}, ExtendedContext ex
|
|
|
257
307
|
* await crawler.run();
|
|
258
308
|
* ```
|
|
259
309
|
*/
|
|
260
|
-
|
|
261
|
-
export declare function createPlaywrightRouter<Context extends PlaywrightCrawlingContext = PlaywrightCrawlingContext, UserData extends Dictionary = GetUserDataFromRequest<Context['request']>>(routes?: RouterRoutes<Context, UserData
|
|
262
|
-
|
|
310
|
+
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>;
|
|
311
|
+
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>>;
|
|
312
|
+
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,
|
|
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
|
|
18
|
-
*
|
|
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
|
-
*
|
|
21
|
-
*
|
|
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
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* {@link
|
|
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 = {}
|
|
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,
|
|
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()
|
|
106
|
-
}
|
|
107
|
-
this.config = config;
|
|
106
|
+
contextPipelineBuilder: contextPipelineBuilder ?? (() => this.buildContextPipeline()),
|
|
107
|
+
});
|
|
108
108
|
}
|
|
109
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
154
|
+
return playwrightUtils.handleCloudflareChallenge(context.page, context.request.url, options);
|
|
146
155
|
},
|
|
147
156
|
};
|
|
148
157
|
}
|
|
149
158
|
}
|
|
150
159
|
/**
|
|
151
|
-
*
|
|
152
|
-
*
|
|
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,
|
|
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
|
-
*
|
|
168
|
+
* postNavigationHooks: [handleCloudflareChallengeHook()],
|
|
170
169
|
* });
|
|
171
|
-
* await crawler.run();
|
|
172
170
|
* ```
|
|
173
171
|
*/
|
|
174
|
-
export function
|
|
175
|
-
return
|
|
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
|
|
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,
|
|
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 [
|
|
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,
|
|
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
|
-
|
|
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 = {},
|
|
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,
|
|
26
|
+
executablePath: getDefaultExecutablePath(launchContext, configuration),
|
|
27
27
|
},
|
|
28
28
|
launcher,
|
|
29
|
-
},
|
|
30
|
-
this.
|
|
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,
|
|
40
|
-
const pathFromPlaywrightImage =
|
|
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 [
|
|
82
|
+
* @param [configuration]
|
|
83
83
|
* @returns
|
|
84
84
|
* Promise that resolves to Playwright's `Browser` instance.
|
|
85
85
|
*/
|
|
86
|
-
export async function launchPlaywright(launchContext,
|
|
87
|
-
const playwrightLauncher = new PlaywrightLauncher(launchContext,
|
|
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
|