@crawlee/browser 4.0.0-beta.15 → 4.0.0-beta.150

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.
@@ -1,19 +1,30 @@
1
- import type { Awaitable, BasicCrawlerOptions, BasicCrawlingContext, CrawlingContext, Dictionary, EnqueueLinksOptions, ErrorHandler, LoadedRequest, Request, RequestHandler, RequestProvider, SkippedRequestCallback } from '@crawlee/basic';
2
- import { BasicCrawler, Configuration, ContextPipeline } from '@crawlee/basic';
3
- import type { BrowserController, BrowserPlugin, BrowserPoolHooks, BrowserPoolOptions, CommonPage, InferBrowserPluginArray, LaunchContext } from '@crawlee/browser-pool';
4
- import { BrowserPool } from '@crawlee/browser-pool';
5
- import type { BatchAddRequestsResult } from '@crawlee/types';
6
- import type { RobotsTxtFile } from '@crawlee/utils';
7
- import type { ReadonlyDeep } from 'type-fest';
1
+ import type { AddRequestsBatchedResult, BasicCrawlerOptions, CrawlingContext, EnqueueLinksOptions, ErrorHandler, ExtractLinksOptions, GetUserDataFromRequest, LoadedRequest, Request, RequestHandler, RouterHandler } from '@crawlee/basic';
2
+ import { BasicCrawler, ContextPipeline } from '@crawlee/basic';
3
+ import type { CommonPage, CrawlerRemoteBrowserOptions } from '@crawlee/browser-pool';
4
+ import type { Awaitable, Dictionary, IBrowserPool } from '@crawlee/types';
5
+ import { z } from 'zod';
8
6
  import type { BrowserLaunchContext } from './browser-launcher.js';
9
7
  interface BaseResponse {
10
8
  status(): number;
9
+ /** Optional because only Playwright and Puppeteer responses are guaranteed to carry it. */
10
+ headers?(): Record<string, string>;
11
11
  }
12
- export interface BrowserCrawlingContext<Page extends CommonPage = CommonPage, Response extends BaseResponse = BaseResponse, ProvidedController = BrowserController, UserData extends Dictionary = Dictionary> extends CrawlingContext<UserData> {
13
- /**
14
- * An instance of the {@link BrowserController} that manages the browser instance and provides access to its API.
15
- */
16
- browserController: ProvidedController;
12
+ /**
13
+ * The type of a browser pool the crawler builds (and therefore owns) for itself. It's an {@link IBrowserPool} that
14
+ * additionally exposes `destroy()` — the crawler only ever tears down pools it created, which is why {@link IBrowserPool}
15
+ * itself intentionally omits `destroy`.
16
+ */
17
+ export type OwnedBrowserPool<Page> = IBrowserPool<Page> & {
18
+ destroy: () => Promise<void>;
19
+ };
20
+ /**
21
+ * Rejects options that exist only to configure the browser pool the crawler would have built for itself.
22
+ * Accepting them alongside a pre-built `browserPool` and quietly ignoring them is how `browserPoolOptions` grew
23
+ * into a second, half-working way of configuring the same pool.
24
+ */
25
+ export declare function assertBrowserPoolNotConfigured(crawlerName: string, ignoredOptions: Dictionary): void;
26
+ export interface BrowserCrawlingContext<Page extends CommonPage = CommonPage, Response extends BaseResponse = BaseResponse, UserData extends Dictionary = any, // with default to Dictionary we cant use a typed router in untyped crawler
27
+ GoToOptions extends Dictionary = Dictionary> extends CrawlingContext<UserData> {
17
28
  /**
18
29
  * The browser page object where the web page is loaded and rendered.
19
30
  */
@@ -26,14 +37,50 @@ export interface BrowserCrawlingContext<Page extends CommonPage = CommonPage, Re
26
37
  * The HTTP response object returned by the browser's navigation.
27
38
  */
28
39
  response: Response;
40
+ /**
41
+ * Options object passed to the underlying `page.goto()` call. `preNavigationHooks` can mutate this
42
+ * object (or return `{ gotoOptions: ... }`) to influence the navigation.
43
+ */
44
+ gotoOptions: GoToOptions;
45
+ /**
46
+ * Extracts URLs from the current page, without adding them to the request queue.
47
+ */
48
+ extractLinks: (options?: ExtractLinksOptions) => Promise<string[]>;
29
49
  /**
30
50
  * Helper function for extracting URLs from the current page and adding them to the request queue.
31
51
  */
32
- enqueueLinks: (options?: EnqueueLinksOptions) => Promise<BatchAddRequestsResult>;
52
+ enqueueLinks: (options?: EnqueueLinksOptions) => Promise<AddRequestsBatchedResult>;
33
53
  }
34
- export type BrowserHook<Context = BrowserCrawlingContext, GoToOptions extends Dictionary | undefined = Dictionary> = (crawlingContext: Context, gotoOptions: GoToOptions) => Awaitable<void>;
35
- export interface BrowserCrawlerOptions<Page extends CommonPage = CommonPage, Response extends BaseResponse = BaseResponse, ProvidedController extends BrowserController = BrowserController, Context extends BrowserCrawlingContext<Page, Response, ProvidedController, Dictionary> = BrowserCrawlingContext<Page, Response, ProvidedController, Dictionary>, ContextExtension = {}, ExtendedContext extends Context = Context & ContextExtension, InternalBrowserPoolOptions extends BrowserPoolOptions = BrowserPoolOptions, __BrowserPlugins extends BrowserPlugin[] = InferBrowserPluginArray<InternalBrowserPoolOptions['browserPlugins']>, __BrowserControllerReturn extends BrowserController = ReturnType<__BrowserPlugins[number]['createController']>, __LaunchContextReturn extends LaunchContext = ReturnType<__BrowserPlugins[number]['createLaunchContext']>> extends Omit<BasicCrawlerOptions<Context, ExtendedContext>, 'requestHandler' | 'failedRequestHandler' | 'errorHandler'> {
54
+ export type BrowserHook<Context = BrowserCrawlingContext, ContextExtension = {}> = (crawlingContext: Context & ContextExtension) => Awaitable<void | Partial<Context>>;
55
+ export interface BrowserCrawlerOptions<Page extends CommonPage = CommonPage, Response extends BaseResponse = BaseResponse, Context extends BrowserCrawlingContext<Page, Response> = BrowserCrawlingContext<Page, Response>, ContextExtension = Dictionary<never>, ExtendedContext extends Context = Context & ContextExtension, Routes extends Record<keyof Routes, Dictionary> = Record<string, GetUserDataFromRequest<Context['request']>>, StatisticStateExtension extends object = {}> extends Omit<BasicCrawlerOptions<Context, ContextExtension, ExtendedContext, Routes, StatisticStateExtension>, 'requestHandler' | 'failedRequestHandler' | 'errorHandler'> {
36
56
  launchContext?: BrowserLaunchContext<any, any>;
57
+ /**
58
+ * The browser pool the crawler should serve its pages from. This is the single way to run a pool with
59
+ * non-default options: build one with the factory that matches your crawler
60
+ * ({@link playwrightBrowserPool}, {@link puppeteerBrowserPool}, {@link stagehandBrowserPool}) - it
61
+ * accepts every {@link BrowserPoolOptions|`BrowserPool` option} and supplies the correct browser plugin
62
+ * itself, so the pool can never mismatch the crawler.
63
+ *
64
+ * A pool passed in this way is borrowed, not owned: the crawler will not tear it down, which is what makes it
65
+ * shareable across crawlers. Since the crawler then builds nothing itself, the options that configure its own
66
+ * pool (`launchContext`, `headless`, `remoteBrowser`) are rejected rather than silently ignored.
67
+ *
68
+ * When omitted, the crawler builds - and tears down - a default pool for its own browser.
69
+ */
70
+ browserPool?: IBrowserPool<Page>;
71
+ /**
72
+ * Connect to a remote browser service (Browserbase, Browserless, Steel, …) instead of launching locally.
73
+ *
74
+ * The crawler builds a {@link RemoteBrowserPool} around its own browser plugin, so the connection is
75
+ * always for the right browser — there is no plugin to construct and no way to mismatch the pool with the
76
+ * crawler. Supply the connection details only: a static `endpoint` URL, a function returning one per launch,
77
+ * or a {@link RemoteBrowserProvider}.
78
+ *
79
+ * Cannot be combined with `browserPool`. To tune the pool wrapping the remote connection, or to share it
80
+ * across crawlers, build it with the remote factory for your crawler ({@link remotePlaywrightBrowserPool},
81
+ * {@link remotePuppeteerBrowserPool}, {@link remoteStagehandBrowserPool}) and pass it as `browserPool`.
82
+ */
83
+ remoteBrowser?: CrawlerRemoteBrowserOptions;
37
84
  /**
38
85
  * Function that is called to process each request.
39
86
  *
@@ -44,7 +91,6 @@ export interface BrowserCrawlerOptions<Page extends CommonPage = CommonPage, Res
44
91
  * - {@link BrowserCrawlingContext.page|`page`} is an instance of the
45
92
  * Puppeteer [Page](https://pptr.dev/api/puppeteer.page) or
46
93
  * Playwright [Page](https://playwright.dev/docs/api/class-page);
47
- * - {@link BrowserCrawlingContext.browserController|`browserController`} is an instance of the {@link BrowserController};
48
94
  * - {@link BrowserCrawlingContext.response|`response`} is an instance of the
49
95
  * Puppeteer [Response](https://pptr.dev/api/puppeteer.httpresponse) or
50
96
  * Playwright [Response](https://playwright.dev/docs/api/class-response),
@@ -61,7 +107,7 @@ export interface BrowserCrawlerOptions<Page extends CommonPage = CommonPage, Res
61
107
  * The exceptions are logged to the request using the
62
108
  * {@link Request.pushErrorMessage|`Request.pushErrorMessage()`} function.
63
109
  */
64
- requestHandler?: RequestHandler<ExtendedContext>;
110
+ requestHandler?: RouterHandler<ExtendedContext, Routes> | RequestHandler<ExtendedContext>;
65
111
  /**
66
112
  * User-provided function that allows modifying the request object before it gets retried by the crawler.
67
113
  * It's executed before each retry for the requests that failed less than {@link BrowserCrawlerOptions.maxRequestRetries|`maxRequestRetries`} times.
@@ -83,22 +129,16 @@ export interface BrowserCrawlerOptions<Page extends CommonPage = CommonPage, Res
83
129
  * represents the last error thrown during processing of the request.
84
130
  */
85
131
  failedRequestHandler?: ErrorHandler<CrawlingContext, ExtendedContext>;
86
- /**
87
- * Custom options passed to the underlying {@link BrowserPool} constructor.
88
- * We can tweak those to fine-tune browser management.
89
- */
90
- browserPoolOptions?: Partial<BrowserPoolOptions> & Partial<BrowserPoolHooks<__BrowserControllerReturn, __LaunchContextReturn>>;
91
132
  /**
92
133
  * Async functions that are sequentially evaluated before the navigation. Good for setting additional cookies
93
- * or browser properties before navigation. The function accepts two parameters, `crawlingContext` and `gotoOptions`,
94
- * which are passed to the `page.goto()` function the crawler calls to navigate.
134
+ * or browser properties before navigation. The function receives the `crawlingContext`; the options object
135
+ * forwarded to `page.goto()` is available as `crawlingContext.gotoOptions` and can be mutated in place.
95
136
  *
96
137
  * **Example:**
97
138
  *
98
139
  * ```js
99
140
  * preNavigationHooks: [
100
- * async (crawlingContext, gotoOptions) => {
101
- * const { page } = crawlingContext;
141
+ * async ({ page, gotoOptions }) => {
102
142
  * await page.evaluate((attr) => { window.foo = attr; }, 'bar');
103
143
  * gotoOptions.timeout = 60_000;
104
144
  * gotoOptions.waitUntil = 'domcontentloaded';
@@ -106,14 +146,22 @@ export interface BrowserCrawlerOptions<Page extends CommonPage = CommonPage, Res
106
146
  * ]
107
147
  * ```
108
148
  *
109
- * Modyfing `pageOptions` is supported only in Playwright incognito.
110
- * See {@link PrePageCreateHook}
149
+ * A hook may optionally return a partial object whose properties are merged into the crawling context,
150
+ * allowing the hook to override context members for subsequent hooks and pipeline stages.
151
+ *
152
+ * The context is built up in the following order: base context (`request`, `session`, helpers, ...) ->
153
+ * `extendContext` -> `preNavigationHooks` -> navigation -> `postNavigationHooks` -> `requestHandler`.
154
+ * This means the members added by `extendContext` are already available here, but navigation-dependent
155
+ * members (e.g. `page`, `response`) are not.
111
156
  */
112
- preNavigationHooks?: BrowserHook<Context>[];
157
+ preNavigationHooks?: BrowserHook<Context, ContextExtension>[];
113
158
  /**
114
159
  * Async functions that are sequentially evaluated after the navigation. Good for checking if the navigation was successful.
115
160
  * The function accepts `crawlingContext` as the only parameter.
116
161
  *
162
+ * A hook may optionally return a partial object whose properties are merged into the crawling context.
163
+ * This is useful for overriding context members (e.g. `response`) after solving a challenge.
164
+ *
117
165
  * **Example:**
118
166
  *
119
167
  * ```js
@@ -124,24 +172,27 @@ export interface BrowserCrawlerOptions<Page extends CommonPage = CommonPage, Res
124
172
  * await solveCaptcha(page);
125
173
  * }
126
174
  * },
175
+ * async (crawlingContext) => {
176
+ * if (await needsRevalidation(crawlingContext)) {
177
+ * return { response: await crawlingContext.page.reload() };
178
+ * }
179
+ * },
127
180
  * ]
128
181
  * ```
129
182
  */
130
- postNavigationHooks?: BrowserHook<Context>[];
183
+ postNavigationHooks?: BrowserHook<Context, ContextExtension>[];
131
184
  /**
132
- * Timeout in which page navigation needs to finish, in seconds.
185
+ * Timeout for the whole navigation phase, in seconds. A single window shared by the `preNavigationHooks`,
186
+ * the page navigation, and the `postNavigationHooks` - so a slow hook eats into the same budget the
187
+ * navigation uses. Separate from the
188
+ * {@link BasicCrawlerOptions.requestHandlerTimeoutSecs|`requestHandlerTimeoutSecs`}, which times only the
189
+ * request handler.
133
190
  */
134
191
  navigationTimeoutSecs?: number;
135
192
  /**
136
- * Defines whether the cookies should be persisted for sessions.
137
- * This can only be used when `useSessionPool` is set to `true`.
138
- */
139
- persistCookiesPerSession?: boolean;
140
- /**
141
- * Whether to run browser in headless mode. Defaults to `true`.
142
- * Can be also set via {@link Configuration}.
193
+ * Defines whether the cookies should be persisted for sessions. Enabled by default.
143
194
  */
144
- headless?: boolean | 'new' | 'old';
195
+ saveResponseCookies?: boolean;
145
196
  /**
146
197
  * Whether to ignore custom elements (and their #shadow-roots) when processing the page content via `parseWithCheerio` helper.
147
198
  * By default, they are expanded automatically. Use this option to disable this behavior.
@@ -165,174 +216,212 @@ export interface BrowserCrawlerOptions<Page extends CommonPage = CommonPage, Res
165
216
  * If the target website doesn't need JavaScript, we should consider using the {@link CheerioCrawler},
166
217
  * which downloads the pages using raw HTTP requests and is about 10x faster.
167
218
  *
168
- * The source URLs are represented by the {@link Request} objects that are fed from the {@link RequestList} or {@link RequestQueue} instances
169
- * provided by the {@link BrowserCrawlerOptions.requestList|`requestList`} or {@link BrowserCrawlerOptions.requestQueue|`requestQueue`}
170
- * constructor options, respectively. If neither `requestList` nor `requestQueue` options are provided,
219
+ * The source URLs are represented by the {@link Request} objects that are fed from the
220
+ * {@link IRequestManager|request manager} provided via the {@link BrowserCrawlerOptions.requestManager|`requestManager`}
221
+ * constructor option (a {@link RequestQueue} is itself a request manager). If no `requestManager` is provided,
171
222
  * the crawler will open the default request queue either when the {@link BrowserCrawler.addRequests|`crawler.addRequests()`} function is called,
172
223
  * or if `requests` parameter (representing the initial requests) of the {@link BrowserCrawler.run|`crawler.run()`} function is provided.
173
224
  *
174
- * If both {@link BrowserCrawlerOptions.requestList|`requestList`} and {@link BrowserCrawlerOptions.requestQueue|`requestQueue`} options are used,
175
- * the instance first processes URLs from the {@link RequestList} and automatically enqueues all of them
176
- * to the {@link RequestQueue} before it starts their processing. This ensures that a single URL is not crawled multiple times.
225
+ * To read from a read-only source such as a {@link RequestList} while still being able to enqueue new requests,
226
+ * combine it with a queue into a {@link RequestManagerTandem} via {@link IRequestLoader.toTandem|`requestLoader.toTandem()`}
227
+ * and pass the result as `requestManager`.
228
+ *
229
+ * > The {@link BrowserCrawlerOptions.requestList|`requestList`} and {@link BrowserCrawlerOptions.requestQueue|`requestQueue`}
230
+ * > options are deprecated; they are still accepted and folded into a single `requestManager` for back-compat.
177
231
  *
178
232
  * The crawler finishes when there are no more {@link Request} objects to crawl.
179
233
  *
180
234
  * `BrowserCrawler` opens a new browser page (i.e. tab or window) for each {@link Request} object to crawl
181
235
  * and then calls the function provided by user as the {@link BrowserCrawlerOptions.requestHandler|`requestHandler`} option.
182
236
  *
183
- * New pages are only opened when there is enough free CPU and memory available,
184
- * using the functionality provided by the {@link AutoscaledPool} class.
185
- * All {@link AutoscaledPool} configuration options can be passed to the {@link BrowserCrawlerOptions.autoscaledPoolOptions|`autoscaledPoolOptions`}
186
- * parameter of the `BrowserCrawler` constructor.
187
- * For user convenience, the {@link AutoscaledPoolOptions.minConcurrency|`minConcurrency`} and
188
- * {@link AutoscaledPoolOptions.maxConcurrency|`maxConcurrency`} options of the
189
- * underlying {@link AutoscaledPool} constructor are available directly in the `BrowserCrawler` constructor.
237
+ * New pages are only opened when there is enough free CPU and memory available, as judged by the crawler's
238
+ * {@link ConcurrencySystem}.
239
+ * Concurrency is tuned via the `minConcurrency`, `maxConcurrency` and `maxRequestsPerMinute` options of the
240
+ * `BrowserCrawler` constructor, or, for finer control, by injecting a pre-configured
241
+ * {@link ConcurrencySystem|`concurrencySystem`}.
190
242
  *
191
243
  * > *NOTE:* the pool of browser instances is internally managed by the {@link BrowserPool} class.
192
244
  *
193
245
  * @category Crawlers
194
246
  */
195
- export declare abstract class BrowserCrawler<Page extends CommonPage = CommonPage, Response extends BaseResponse = BaseResponse, ProvidedController extends BrowserController = BrowserController, InternalBrowserPoolOptions extends BrowserPoolOptions = BrowserPoolOptions, LaunchOptions extends Dictionary | undefined = Dictionary, Context extends BrowserCrawlingContext<Page, Response, ProvidedController, Dictionary> = BrowserCrawlingContext<Page, Response, ProvidedController, Dictionary>, ContextExtension = {}, ExtendedContext extends Context = Context & ContextExtension, GoToOptions extends Dictionary = Dictionary> extends BasicCrawler<Context, ContextExtension, ExtendedContext> {
196
- readonly config: Configuration;
247
+ export declare abstract class BrowserCrawler<Page extends CommonPage = CommonPage, Response extends BaseResponse = BaseResponse, LaunchOptions extends Dictionary | undefined = Dictionary, Context extends BrowserCrawlingContext<Page, Response> = BrowserCrawlingContext<Page, Response>, ContextExtension = Dictionary<never>, ExtendedContext extends Context = Context & ContextExtension, Routes extends Record<keyof Routes, Dictionary> = Record<string, GetUserDataFromRequest<Context['request']>>, StatisticStateExtension extends object = {}, GoToOptions extends Dictionary = Dictionary> extends BasicCrawler<Context, ContextExtension, ExtendedContext, Routes, StatisticStateExtension> {
248
+ #private;
197
249
  /**
198
- * A reference to the underlying {@link BrowserPool} class that manages the crawler's browsers.
250
+ * A reference to the underlying browser pool that manages the crawler's browsers. Typed as
251
+ * {@link IBrowserPool} so custom implementations can be plugged in via the `browserPool` constructor option.
199
252
  */
200
- browserPool: BrowserPool<InternalBrowserPoolOptions>;
253
+ get browserPool(): IBrowserPool<Page>;
201
254
  launchContext: BrowserLaunchContext<LaunchOptions, unknown>;
202
255
  protected readonly ignoreShadowRoots: boolean;
203
256
  protected readonly ignoreIframes: boolean;
204
- protected navigationTimeoutMillis: number;
205
- protected preNavigationHooks: BrowserHook<Context>[];
206
- protected postNavigationHooks: BrowserHook<Context>[];
207
- protected persistCookiesPerSession: boolean;
257
+ /**
258
+ * @internal
259
+ */
208
260
  protected static optionsShape: {
209
- // @ts-ignore optional peer dependency or compatibility with es2022
210
- navigationTimeoutSecs: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
211
- // @ts-ignore optional peer dependency or compatibility with es2022
212
- preNavigationHooks: import("ow").ArrayPredicate<unknown> & import("ow").BasePredicate<unknown[] | undefined>;
213
- // @ts-ignore optional peer dependency or compatibility with es2022
214
- postNavigationHooks: import("ow").ArrayPredicate<unknown> & import("ow").BasePredicate<unknown[] | undefined>;
215
- // @ts-ignore optional peer dependency or compatibility with es2022
216
- launchContext: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
217
- // @ts-ignore optional peer dependency or compatibility with es2022
218
- headless: import("ow").AnyPredicate<string | boolean>;
219
- // @ts-ignore optional peer dependency or compatibility with es2022
220
- browserPoolOptions: import("ow").ObjectPredicate<object>;
221
- // @ts-ignore optional peer dependency or compatibility with es2022
222
- sessionPoolOptions: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
223
- // @ts-ignore optional peer dependency or compatibility with es2022
224
- persistCookiesPerSession: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
225
- // @ts-ignore optional peer dependency or compatibility with es2022
226
- useSessionPool: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
227
- // @ts-ignore optional peer dependency or compatibility with es2022
228
- proxyConfiguration: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
229
- // @ts-ignore optional peer dependency or compatibility with es2022
230
- contextPipelineBuilder: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
231
- // @ts-ignore optional peer dependency or compatibility with es2022
232
- extendContext: import("ow").Predicate<Function> & import("ow").BasePredicate<Function | undefined>;
233
- // @ts-ignore optional peer dependency or compatibility with es2022
234
- requestList: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
235
- // @ts-ignore optional peer dependency or compatibility with es2022
236
- requestQueue: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
237
- // @ts-ignore optional peer dependency or compatibility with es2022
238
- requestHandler: import("ow").Predicate<Function> & import("ow").BasePredicate<Function | undefined>;
239
- // @ts-ignore optional peer dependency or compatibility with es2022
240
- requestHandlerTimeoutSecs: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
241
- // @ts-ignore optional peer dependency or compatibility with es2022
242
- errorHandler: import("ow").Predicate<Function> & import("ow").BasePredicate<Function | undefined>;
243
- // @ts-ignore optional peer dependency or compatibility with es2022
244
- failedRequestHandler: import("ow").Predicate<Function> & import("ow").BasePredicate<Function | undefined>;
245
- // @ts-ignore optional peer dependency or compatibility with es2022
246
- maxRequestRetries: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
247
- // @ts-ignore optional peer dependency or compatibility with es2022
248
- sameDomainDelaySecs: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
249
- // @ts-ignore optional peer dependency or compatibility with es2022
250
- maxSessionRotations: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
251
- // @ts-ignore optional peer dependency or compatibility with es2022
252
- maxRequestsPerCrawl: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
253
- // @ts-ignore optional peer dependency or compatibility with es2022
254
- maxCrawlDepth: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
255
- // @ts-ignore optional peer dependency or compatibility with es2022
256
- autoscaledPoolOptions: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
257
- // @ts-ignore optional peer dependency or compatibility with es2022
258
- statusMessageLoggingInterval: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
259
- // @ts-ignore optional peer dependency or compatibility with es2022
260
- statusMessageCallback: import("ow").Predicate<Function> & import("ow").BasePredicate<Function | undefined>;
261
- // @ts-ignore optional peer dependency or compatibility with es2022
262
- retryOnBlocked: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
263
- // @ts-ignore optional peer dependency or compatibility with es2022
264
- respectRobotsTxtFile: import("ow").AnyPredicate<boolean | object>;
265
- // @ts-ignore optional peer dependency or compatibility with es2022
266
- onSkippedRequest: import("ow").Predicate<Function> & import("ow").BasePredicate<Function | undefined>;
267
- // @ts-ignore optional peer dependency or compatibility with es2022
268
- httpClient: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
269
- // @ts-ignore optional peer dependency or compatibility with es2022
270
- minConcurrency: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
271
- // @ts-ignore optional peer dependency or compatibility with es2022
272
- maxConcurrency: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
273
- // @ts-ignore optional peer dependency or compatibility with es2022
274
- maxRequestsPerMinute: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
275
- // @ts-ignore optional peer dependency or compatibility with es2022
276
- keepAlive: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
277
- // @ts-ignore optional peer dependency or compatibility with es2022
278
- log: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
279
- // @ts-ignore optional peer dependency or compatibility with es2022
280
- experiments: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
281
- // @ts-ignore optional peer dependency or compatibility with es2022
282
- statisticsOptions: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
261
+ contextPipelineBuilder: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
262
+ extendContext: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
263
+ requestList: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
264
+ requestQueue: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
265
+ requestManager: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
266
+ requestHandler: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
267
+ requestHandlerTimeoutSecs: z.ZodOptional<z.ZodCustom<number, number>>;
268
+ errorHandler: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
269
+ failedRequestHandler: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
270
+ maxRequestRetries: z.ZodDefault<z.ZodCustom<number, number>>;
271
+ sameDomainDelaySecs: z.ZodDefault<z.ZodCustom<number, number>>;
272
+ maxRequestsPerCrawl: z.ZodOptional<z.ZodCustom<number, number>>;
273
+ maxCrawlDepth: z.ZodOptional<z.ZodCustom<number, number>>;
274
+ taskLoopOptions: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
275
+ concurrencySystem: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
276
+ sessionPool: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
277
+ statusMessageLoggingInterval: z.ZodDefault<z.ZodCustom<number, number>>;
278
+ statusMessageCallback: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
279
+ additionalHttpErrorStatusCodes: z.ZodDefault<z.ZodArray<z.ZodCustom<number, number>>>;
280
+ ignoreHttpErrorStatusCodes: z.ZodDefault<z.ZodArray<z.ZodCustom<number, number>>>;
281
+ blockedStatusCodes: z.ZodOptional<z.ZodArray<z.ZodCustom<number, number>>>;
282
+ retryOnBlocked: z.ZodDefault<z.ZodBoolean>;
283
+ respectRobotsTxtFile: z.ZodDefault<z.ZodUnion<readonly [z.ZodBoolean, z.ZodCustom<Dictionary, Dictionary>]>>;
284
+ transactionalStorage: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
285
+ requestQueue: z.ZodOptional<z.ZodEnum<{
286
+ deferred: "deferred";
287
+ writeThrough: "writeThrough";
288
+ }>>;
289
+ }, z.core.$strict>]>>;
290
+ onSkippedRequest: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
291
+ // @ts-ignore optional peer dependency or compatibility with es2022
292
+ httpClient: z.ZodOptional<z.ZodCustom<import("@crawlee/http-client").BaseHttpClient, import("@crawlee/http-client").BaseHttpClient>>;
293
+ // @ts-ignore optional peer dependency or compatibility with es2022
294
+ configuration: z.ZodOptional<z.ZodCustom<import("@crawlee/basic").Configuration, import("@crawlee/basic").Configuration>>;
295
+ storageBackend: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
296
+ // @ts-ignore optional peer dependency or compatibility with es2022
297
+ eventManager: z.ZodOptional<z.ZodCustom<import("@crawlee/basic").EventManager, import("@crawlee/basic").EventManager>>;
298
+ logger: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
299
+ minConcurrency: z.ZodOptional<z.ZodCustom<number, number>>;
300
+ maxConcurrency: z.ZodOptional<z.ZodCustom<number, number>>;
301
+ initialConcurrency: z.ZodOptional<z.ZodCustom<number, number>>;
302
+ maxRequestsPerMinute: z.ZodOptional<z.ZodCustom<number, number>>;
303
+ keepAlive: z.ZodOptional<z.ZodBoolean>;
304
+ statistics: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
305
+ id: z.ZodOptional<z.ZodString>;
306
+ navigationTimeoutSecs: z.ZodDefault<z.ZodCustom<number, number>>;
307
+ preNavigationHooks: z.ZodDefault<z.ZodCustom<unknown[], unknown[]>>;
308
+ postNavigationHooks: z.ZodDefault<z.ZodCustom<unknown[], unknown[]>>;
309
+ launchContext: z.ZodDefault<z.ZodCustom<Dictionary, Dictionary>>;
310
+ browserPool: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
311
+ browserPoolBuilder: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
312
+ remoteBrowser: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
313
+ saveResponseCookies: z.ZodDefault<z.ZodBoolean>;
314
+ proxyConfiguration: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
315
+ ignoreIframes: z.ZodDefault<z.ZodBoolean>;
316
+ ignoreShadowRoots: z.ZodDefault<z.ZodBoolean>;
283
317
  };
318
+ /** @internal */
319
+ protected static optionsSchema: z.ZodObject<{
320
+ contextPipelineBuilder: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
321
+ extendContext: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
322
+ requestList: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
323
+ requestQueue: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
324
+ requestManager: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
325
+ requestHandler: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
326
+ requestHandlerTimeoutSecs: z.ZodOptional<z.ZodCustom<number, number>>;
327
+ errorHandler: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
328
+ failedRequestHandler: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
329
+ maxRequestRetries: z.ZodDefault<z.ZodCustom<number, number>>;
330
+ sameDomainDelaySecs: z.ZodDefault<z.ZodCustom<number, number>>;
331
+ maxRequestsPerCrawl: z.ZodOptional<z.ZodCustom<number, number>>;
332
+ maxCrawlDepth: z.ZodOptional<z.ZodCustom<number, number>>;
333
+ taskLoopOptions: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
334
+ concurrencySystem: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
335
+ sessionPool: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
336
+ statusMessageLoggingInterval: z.ZodDefault<z.ZodCustom<number, number>>;
337
+ statusMessageCallback: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
338
+ additionalHttpErrorStatusCodes: z.ZodDefault<z.ZodArray<z.ZodCustom<number, number>>>;
339
+ ignoreHttpErrorStatusCodes: z.ZodDefault<z.ZodArray<z.ZodCustom<number, number>>>;
340
+ blockedStatusCodes: z.ZodOptional<z.ZodArray<z.ZodCustom<number, number>>>;
341
+ retryOnBlocked: z.ZodDefault<z.ZodBoolean>;
342
+ respectRobotsTxtFile: z.ZodDefault<z.ZodUnion<readonly [z.ZodBoolean, z.ZodCustom<Dictionary, Dictionary>]>>;
343
+ transactionalStorage: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
344
+ requestQueue: z.ZodOptional<z.ZodEnum<{
345
+ deferred: "deferred";
346
+ writeThrough: "writeThrough";
347
+ }>>;
348
+ }, z.core.$strict>]>>;
349
+ onSkippedRequest: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
350
+ // @ts-ignore optional peer dependency or compatibility with es2022
351
+ httpClient: z.ZodOptional<z.ZodCustom<import("@crawlee/http-client").BaseHttpClient, import("@crawlee/http-client").BaseHttpClient>>;
352
+ // @ts-ignore optional peer dependency or compatibility with es2022
353
+ configuration: z.ZodOptional<z.ZodCustom<import("@crawlee/basic").Configuration, import("@crawlee/basic").Configuration>>;
354
+ storageBackend: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
355
+ // @ts-ignore optional peer dependency or compatibility with es2022
356
+ eventManager: z.ZodOptional<z.ZodCustom<import("@crawlee/basic").EventManager, import("@crawlee/basic").EventManager>>;
357
+ logger: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
358
+ minConcurrency: z.ZodOptional<z.ZodCustom<number, number>>;
359
+ maxConcurrency: z.ZodOptional<z.ZodCustom<number, number>>;
360
+ initialConcurrency: z.ZodOptional<z.ZodCustom<number, number>>;
361
+ maxRequestsPerMinute: z.ZodOptional<z.ZodCustom<number, number>>;
362
+ keepAlive: z.ZodOptional<z.ZodBoolean>;
363
+ statistics: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
364
+ id: z.ZodOptional<z.ZodString>;
365
+ navigationTimeoutSecs: z.ZodDefault<z.ZodCustom<number, number>>;
366
+ preNavigationHooks: z.ZodDefault<z.ZodCustom<unknown[], unknown[]>>;
367
+ postNavigationHooks: z.ZodDefault<z.ZodCustom<unknown[], unknown[]>>;
368
+ launchContext: z.ZodDefault<z.ZodCustom<Dictionary, Dictionary>>;
369
+ browserPool: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
370
+ browserPoolBuilder: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
371
+ remoteBrowser: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
372
+ saveResponseCookies: z.ZodDefault<z.ZodBoolean>;
373
+ proxyConfiguration: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
374
+ ignoreIframes: z.ZodDefault<z.ZodBoolean>;
375
+ ignoreShadowRoots: z.ZodDefault<z.ZodBoolean>;
376
+ }, z.core.$strict>;
284
377
  /**
285
378
  * All `BrowserCrawler` parameters are passed via an options object.
286
379
  */
287
- protected constructor(options: BrowserCrawlerOptions<Page, Response, ProvidedController, Context, ContextExtension, ExtendedContext> & {
380
+ protected constructor(options: BrowserCrawlerOptions<Page, Response, Context, ContextExtension, ExtendedContext, Routes, StatisticStateExtension> & {
288
381
  contextPipelineBuilder: () => ContextPipeline<CrawlingContext, Context>;
289
- }, config?: Configuration);
290
- protected buildContextPipeline(): ContextPipeline<CrawlingContext, BrowserCrawlingContext<Page, Response, ProvidedController, Dictionary>>;
382
+ /**
383
+ * Builds the pool the crawler owns, used only when the user injected no `browserPool`. Supplied by the
384
+ * concrete crawler, which is the only place that knows which browser plugin to run - that is also why
385
+ * `remoteBrowser` is handed to it rather than acted upon here.
386
+ */
387
+ browserPoolBuilder: (remoteBrowser?: CrawlerRemoteBrowserOptions) => OwnedBrowserPool<Page>;
388
+ });
389
+ protected getNavigationTimeoutMillis(): number;
390
+ protected buildContextPipeline(): ContextPipeline<CrawlingContext, BrowserCrawlingContext<Page, Response, Dictionary>>;
291
391
  private containsSelectors;
292
- protected isRequestBlocked(crawlingContext: BrowserCrawlingContext<Page, Response, ProvidedController>): Promise<string | false>;
392
+ private isRequestBlocked;
293
393
  private preparePage;
294
- private performNavigation;
394
+ private prepareNavigation;
395
+ private navigate;
396
+ private finalizeNavigation;
397
+ /**
398
+ * Copies cookies from the live browser page into the session cookie jar.
399
+ */
400
+ private persistCookiesFromPage;
401
+ /**
402
+ * Runs the user request handler, then re-reads browser cookies so login flows /
403
+ * `page.setCookie` / XHR `Set-Cookie` updates are stored for later requests.
404
+ */
405
+ protected runRequestHandler(crawlingContext: ExtendedContext): Promise<void>;
295
406
  private handleBlockedRequestByContent;
296
407
  private restoreRequestState;
297
- protected _applyCookies({ session, request, page, browserController }: BrowserCrawlingContext, preHooksCookies: string, postHooksCookies: string): Promise<void>;
408
+ private applyCookies;
298
409
  /**
299
- * Marks session bad in case of navigation timeout.
410
+ * Marks session bad on navigation timeout, and stops in-flight page loading on any navigation error.
300
411
  */
301
- protected _handleNavigationTimeout(crawlingContext: BrowserCrawlingContext, error: Error): Promise<void>;
412
+ private handleNavigationTimeout;
302
413
  /**
303
414
  * Transforms proxy-related errors to `SessionError`.
304
415
  */
305
- protected _throwIfProxyError(error: Error): void;
306
- protected abstract _navigationHandler(crawlingContext: BrowserCrawlingContext<Page, Response, ProvidedController>, gotoOptions: GoToOptions): Promise<Context['response'] | null | undefined>;
416
+ private throwIfProxyError;
417
+ protected abstract navigationHandler(crawlingContext: BrowserCrawlingContext<Page, Response>, gotoOptions: GoToOptions): Promise<Context['response'] | null | undefined>;
307
418
  private processResponse;
308
- protected _extendLaunchContext(_pageId: string, launchContext: LaunchContext): Promise<void>;
309
- protected _maybeAddSessionRetiredListener(_pageId: string, browserController: Context['browserController']): void;
310
419
  /**
311
420
  * Function for cleaning up after all requests are processed.
312
421
  * @ignore
313
422
  */
314
423
  teardown(): Promise<void>;
315
424
  }
316
- /** @internal */
317
- interface EnqueueLinksInternalOptions {
318
- options?: ReadonlyDeep<Omit<EnqueueLinksOptions, 'requestQueue'>> & Pick<EnqueueLinksOptions, 'requestQueue'>;
319
- page: CommonPage;
320
- requestQueue: RequestProvider;
321
- robotsTxtFile?: RobotsTxtFile;
322
- onSkippedRequest?: SkippedRequestCallback;
323
- originalRequestUrl: string;
324
- finalRequestUrl?: string;
325
- }
326
- /** @internal */
327
- interface BoundEnqueueLinksInternalOptions {
328
- enqueueLinks: BasicCrawlingContext['enqueueLinks'];
329
- options?: ReadonlyDeep<Omit<EnqueueLinksOptions, 'requestQueue'>> & Pick<EnqueueLinksOptions, 'requestQueue'>;
330
- originalRequestUrl: string;
331
- finalRequestUrl?: string;
332
- page: CommonPage;
333
- }
334
- /** @internal */
335
- export declare function browserCrawlerEnqueueLinks(options: EnqueueLinksInternalOptions | BoundEnqueueLinksInternalOptions): Promise<unknown>;
336
425
  /**
337
426
  * Extracts URLs from a given page.
338
427
  * @ignore
@@ -341,4 +430,3 @@ export declare function extractUrlsFromPage(page: {
341
430
  $$eval: Function;
342
431
  }, selector: string, baseUrl: string): Promise<string[]>;
343
432
  export {};
344
- //# sourceMappingURL=browser-crawler.d.ts.map