@crawlee/basic 4.0.0-beta.98 → 4.0.0-rc.0
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/index.d.ts +1 -1
- package/internals/basic-crawler.d.ts +179 -150
- package/internals/basic-crawler.js +495 -313
- package/internals/send-request.d.ts +2 -1
- package/internals/send-request.js +1 -0
- package/package.json +9 -10
package/index.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import type { AddRequestsBatchedOptions, AddRequestsBatchedResult, ConcurrencySystemOptions,
|
|
2
|
-
import { ConcurrencySystem, ContextPipeline, Dataset,
|
|
3
|
-
import
|
|
1
|
+
import type { AddRequestsBatchedOptions, AddRequestsBatchedResult, ConcurrencySystemOptions, CrawleeLogger, CrawlingContext, DatasetExportOptions, EnqueueUrlsOptions, FinalStatistics, GetUserDataFromRequest, IConcurrencySystem, IProxyConfiguration, IRequestLoader, IRequestManager, IStatistics, RequestsLike, RouterHandler, RouterRoutes, SkippedRequestCallback, Source, StatisticState, StorageIdentifier, StorageWritePolicy, TaskLoopPredicates, TypedRequestsLike } from '@crawlee/core';
|
|
2
|
+
import { ConcurrencySystem, Configuration, ContextPipeline, Request, Dataset, EventManager, RequestQueue } from '@crawlee/core';
|
|
3
|
+
import { BaseHttpClient } from '@crawlee/http-client';
|
|
4
|
+
import type { Awaitable, Dictionary, ISession, ISessionPool, ProxyInfo, SetStatusMessageOptions, StorageBackend } from '@crawlee/types';
|
|
4
5
|
import { RobotsTxtFile } from '@crawlee/utils';
|
|
5
|
-
import type { ReadonlyDeep
|
|
6
|
+
import type { ReadonlyDeep } from 'type-fest';
|
|
7
|
+
import { z } from 'zod';
|
|
6
8
|
import { TimeoutError } from '@apify/timeout';
|
|
7
9
|
export interface BasicCrawlingContext<UserData extends Dictionary = Dictionary> extends CrawlingContext<UserData> {
|
|
8
10
|
}
|
|
@@ -27,7 +29,7 @@ export type StatusMessageCallback<Context extends CrawlingContext = BasicCrawlin
|
|
|
27
29
|
export type RequireContextPipeline<DefaultContextType extends CrawlingContext, FinalContextType extends DefaultContextType> = DefaultContextType extends FinalContextType ? {} : {
|
|
28
30
|
contextPipelineBuilder: () => ContextPipeline<CrawlingContext, FinalContextType>;
|
|
29
31
|
};
|
|
30
|
-
export interface BasicCrawlerOptions<Context extends CrawlingContext = CrawlingContext, ContextExtension = Dictionary<never>, ExtendedContext extends Context = Context & ContextExtension, Routes extends Record<keyof Routes, Dictionary> = Record<string, GetUserDataFromRequest<Context['request']
|
|
32
|
+
export interface BasicCrawlerOptions<Context extends CrawlingContext = CrawlingContext, ContextExtension = Dictionary<never>, ExtendedContext extends Context = Context & ContextExtension, Routes extends Record<keyof Routes, Dictionary> = Record<string, GetUserDataFromRequest<Context['request']>>, StatisticStateExtension extends object = {}> {
|
|
31
33
|
/**
|
|
32
34
|
* User-provided function that performs the logic of the crawler. It is called for each URL to crawl.
|
|
33
35
|
*
|
|
@@ -135,7 +137,11 @@ export interface BasicCrawlerOptions<Context extends CrawlingContext = CrawlingC
|
|
|
135
137
|
*/
|
|
136
138
|
maxRequestRetries?: number;
|
|
137
139
|
/**
|
|
138
|
-
* Indicates how much time (in seconds) to wait before crawling another same domain request.
|
|
140
|
+
* Indicates how much time (in seconds) to wait before crawling another same domain request. Subdomains are
|
|
141
|
+
* paced together with the site they belong to.
|
|
142
|
+
*
|
|
143
|
+
* Wraps the crawler's request manager in a {@link ThrottlingRequestManager}; pass one as `requestManager`
|
|
144
|
+
* yourself to configure it further.
|
|
139
145
|
* @default 0
|
|
140
146
|
*/
|
|
141
147
|
sameDomainDelaySecs?: number;
|
|
@@ -236,6 +242,10 @@ export interface BasicCrawlerOptions<Context extends CrawlingContext = CrawlingC
|
|
|
236
242
|
statusMessageCallback?: StatusMessageCallback;
|
|
237
243
|
/**
|
|
238
244
|
* HTTP status codes that indicate the session should be retired.
|
|
245
|
+
*
|
|
246
|
+
* A 429 from a domain covered by a {@link ThrottlingRequestManager} is handled as a rate limit before
|
|
247
|
+
* this is consulted, so removing 429 here only affects domains that manager does not cover.
|
|
248
|
+
*
|
|
239
249
|
* @default [401, 403, 429]
|
|
240
250
|
*/
|
|
241
251
|
blockedStatusCodes?: number[];
|
|
@@ -267,10 +277,29 @@ export interface BasicCrawlerOptions<Context extends CrawlingContext = CrawlingC
|
|
|
267
277
|
*/
|
|
268
278
|
onSkippedRequest?: SkippedRequestCallback;
|
|
269
279
|
/**
|
|
270
|
-
*
|
|
271
|
-
*
|
|
280
|
+
* A preconfigured statistics instance. When provided, the crawler records into it instead of building its own and
|
|
281
|
+
* will not `reset()` it between `run()` calls. Accepts the built-in {@link Statistics} or any object
|
|
282
|
+
* implementing {@link IStatistics}.
|
|
283
|
+
*
|
|
284
|
+
* Custom fields declared via {@link StatisticsOptions.stateExtension|`stateExtension`} are carried over to
|
|
285
|
+
* {@link BasicCrawler.statistics|`crawler.statistics.state`}:
|
|
286
|
+
*
|
|
287
|
+
* ```ts
|
|
288
|
+
* const statistics = new Statistics({ stateExtension: { defaultState: { productsFound: 0 } } });
|
|
289
|
+
*
|
|
290
|
+
* const crawler = new BasicCrawler({
|
|
291
|
+
* statistics,
|
|
292
|
+
* requestHandler: async () => {
|
|
293
|
+
* statistics.state.productsFound++;
|
|
294
|
+
* },
|
|
295
|
+
* });
|
|
296
|
+
*
|
|
297
|
+
* await crawler.run();
|
|
298
|
+
* // the custom fields are typed on `crawler.statistics` too
|
|
299
|
+
* console.log(crawler.statistics.state.productsFound);
|
|
300
|
+
* ```
|
|
272
301
|
*/
|
|
273
|
-
|
|
302
|
+
statistics?: IStatistics<StatisticStateExtension>;
|
|
274
303
|
/**
|
|
275
304
|
* HTTP client implementation for the `sendRequest` context helper and for plain HTTP crawling.
|
|
276
305
|
* Defaults to {@link ImpitHttpClient} when `@crawlee/impit-client` is installed, otherwise {@link FetchHttpClient}.
|
|
@@ -313,6 +342,20 @@ export interface BasicCrawlerOptions<Context extends CrawlingContext = CrawlingC
|
|
|
313
342
|
*
|
|
314
343
|
*/
|
|
315
344
|
id?: string;
|
|
345
|
+
/**
|
|
346
|
+
* Makes the storage writes performed while handling a request atomic with respect to the request
|
|
347
|
+
* succeeding: they are recorded in a {@link StorageTransaction} spanning the whole request
|
|
348
|
+
* lifecycle and only applied when the request handler succeeds, so a thrown handler leaves no partial
|
|
349
|
+
* writes behind and a retry does not double-write. Reads within the handler see its own writes.
|
|
350
|
+
*
|
|
351
|
+
* `false` disables the mechanism entirely; an object overrides the per-storage-type
|
|
352
|
+
* {@link StorageWritePolicy} (e.g. `{ requestQueue: 'deferred' }` for all-or-nothing enqueues).
|
|
353
|
+
* {@link withDirectStorageAccess} is the per-call-site escape hatch; `useState()` is deliberately
|
|
354
|
+
* *not* transactional.
|
|
355
|
+
*
|
|
356
|
+
* @default true
|
|
357
|
+
*/
|
|
358
|
+
transactionalStorage?: boolean | Partial<StorageWritePolicy>;
|
|
316
359
|
/**
|
|
317
360
|
* An array of HTTP response [Status Codes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) to be excluded from error consideration.
|
|
318
361
|
* By default, status codes >= 500 trigger errors.
|
|
@@ -408,7 +451,7 @@ interface CrawlerIdentity {
|
|
|
408
451
|
/** Whether `id` came from the user (as opposed to being derived from `instanceIndex`). */
|
|
409
452
|
readonly hasExplicitId: boolean;
|
|
410
453
|
}
|
|
411
|
-
export declare class BasicCrawler<Context extends CrawlingContext = CrawlingContext, ContextExtension = Dictionary<never>, ExtendedContext extends Context = Context & ContextExtension, Routes extends Record<keyof Routes, Dictionary> = Record<string, GetUserDataFromRequest<Context['request']
|
|
454
|
+
export declare class BasicCrawler<Context extends CrawlingContext = CrawlingContext, ContextExtension = Dictionary<never>, ExtendedContext extends Context = Context & ContextExtension, Routes extends Record<keyof Routes, Dictionary> = Record<string, GetUserDataFromRequest<Context['request']>>, StatisticStateExtension extends object = {}> {
|
|
412
455
|
#private;
|
|
413
456
|
protected static readonly CRAWLEE_STATE_KEY = "CRAWLEE_STATE";
|
|
414
457
|
/**
|
|
@@ -418,47 +461,21 @@ export declare class BasicCrawler<Context extends CrawlingContext = CrawlingCont
|
|
|
418
461
|
*/
|
|
419
462
|
private static instanceCount;
|
|
420
463
|
/**
|
|
421
|
-
*
|
|
422
|
-
*
|
|
464
|
+
* The statistics instance collecting the crawler's run statistics - either the injected `statistics` option or a
|
|
465
|
+
* crawler-built default. Typed as {@link IStatistics} so custom implementations can be plugged in.
|
|
423
466
|
*/
|
|
424
|
-
|
|
425
|
-
/**
|
|
426
|
-
* A reference to the underlying {@link Statistics} class that collects and logs run statistics for requests.
|
|
427
|
-
*/
|
|
428
|
-
readonly stats: Statistics;
|
|
467
|
+
get statistics(): IStatistics<StatisticStateExtension>;
|
|
429
468
|
/**
|
|
430
469
|
* The main request-handling component of the crawler. It manages the requests that the crawler processes,
|
|
431
470
|
* combining any provided request loader and/or queue. It's initialized during the crawler startup or lazily
|
|
432
471
|
* via {@link BasicCrawler.getRequestManager|`getRequestManager()`}.
|
|
433
472
|
*/
|
|
434
473
|
protected requestManager?: IRequestManager;
|
|
435
|
-
/** Backs the {@link BasicCrawler.sessionPool|`sessionPool`} getter. */
|
|
436
|
-
private sessionPoolDep;
|
|
437
474
|
/**
|
|
438
475
|
* A reference to the underlying session pool that manages the crawler's {@link Session|sessions}. Typed as
|
|
439
476
|
* {@link ISessionPool} so custom implementations can be plugged in via the `sessionPool` constructor option.
|
|
440
477
|
*/
|
|
441
478
|
get sessionPool(): ISessionPool;
|
|
442
|
-
/**
|
|
443
|
-
* Tracks **only** the queue the crawler opens for itself — not the {@link RequestManagerTandem} that may wrap it
|
|
444
|
-
* around a user-supplied `requestList` — so the owned-only purge between repeated `run()` calls never reaches
|
|
445
|
-
* through to a borrowed loader. Filled lazily in {@link BasicCrawler.openOwnedRequestQueue|`openOwnedRequestQueue()`}.
|
|
446
|
-
*/
|
|
447
|
-
private ownedRequestQueue;
|
|
448
|
-
/**
|
|
449
|
-
* Whether the request-processing-time hint has already been forwarded to the request manager. The hint
|
|
450
|
-
* derives only from `requestHandlerTimeoutMillis` (constant for the crawler's lifetime) and is raise-only,
|
|
451
|
-
* so it only needs to be applied once, at the first async access of the manager.
|
|
452
|
-
*/
|
|
453
|
-
private requestManagerTimeoutsApplied;
|
|
454
|
-
/**
|
|
455
|
-
* Resolves the governor for one run: either the injected
|
|
456
|
-
* {@link BasicCrawlerOptions.concurrencySystem|`concurrencySystem`} (borrowed) or a freshly built default with
|
|
457
|
-
* the concurrency shortcuts folded in (owned, so the crawler starts and stops it).
|
|
458
|
-
*/
|
|
459
|
-
private readonly resolveConcurrencySystem;
|
|
460
|
-
/** As resolved by `_init()`. Absent until the first run, so a `teardown()` before it is a no-op. */
|
|
461
|
-
private concurrencySystemDep?;
|
|
462
479
|
/**
|
|
463
480
|
* The concurrency governor this run is booking its requests against — either the
|
|
464
481
|
* {@link BasicCrawlerOptions.concurrencySystem|`concurrencySystem`} that was injected, or the default the
|
|
@@ -472,14 +489,6 @@ export declare class BasicCrawler<Context extends CrawlingContext = CrawlingCont
|
|
|
472
489
|
* `minConcurrency`/`maxConcurrency`/`desiredConcurrency` on your own reference.
|
|
473
490
|
*/
|
|
474
491
|
get concurrencySystem(): IConcurrencySystem | undefined;
|
|
475
|
-
/**
|
|
476
|
-
* The task loop that dispatches this run's requests. Private on purpose — it is a bare parallel task runner with
|
|
477
|
-
* no configuration left of its own (see {@link ConcurrencySystem}), and everything a caller legitimately did
|
|
478
|
-
* with it now has a crawler-level counterpart: {@link BasicCrawler.pause|`pause()`},
|
|
479
|
-
* {@link BasicCrawler.resume|`resume()`}, {@link BasicCrawler.teardown|`teardown()`} and
|
|
480
|
-
* {@link BasicCrawler.concurrencySystem|`concurrencySystem`}.
|
|
481
|
-
*/
|
|
482
|
-
private autoscaledPool?;
|
|
483
492
|
/**
|
|
484
493
|
* A reference to the underlying {@link IProxyConfiguration} instance that manages the crawler's proxies.
|
|
485
494
|
* Only available if used by the crawler.
|
|
@@ -490,7 +499,6 @@ export declare class BasicCrawler<Context extends CrawlingContext = CrawlingCont
|
|
|
490
499
|
* See {@link Router.addHandler|`router.addHandler()`} and {@link Router.addDefaultHandler|`router.addDefaultHandler()`}.
|
|
491
500
|
*/
|
|
492
501
|
readonly router: RouterHandler<Context, Routes>;
|
|
493
|
-
private _basicContextPipeline?;
|
|
494
502
|
/**
|
|
495
503
|
* The basic part of the context pipeline. Unlike the subclass pipeline, this
|
|
496
504
|
* part has no major side effects (e.g. launching a browser). It also makes typing more explicit, as subclass
|
|
@@ -502,11 +510,9 @@ export declare class BasicCrawler<Context extends CrawlingContext = CrawlingCont
|
|
|
502
510
|
get basicContextPipeline(): ContextPipeline<{
|
|
503
511
|
request: Request;
|
|
504
512
|
}, CrawlingContext>;
|
|
505
|
-
private _contextPipeline?;
|
|
506
513
|
get contextPipeline(): ContextPipeline<CrawlingContext, ExtendedContext>;
|
|
507
514
|
running: boolean;
|
|
508
515
|
hasFinishedBefore: boolean;
|
|
509
|
-
private unexpectedStop;
|
|
510
516
|
get log(): CrawleeLogger;
|
|
511
517
|
protected readonly requestHandler: RequestHandler<ExtendedContext>;
|
|
512
518
|
protected readonly errorHandler?: ErrorHandler<CrawlingContext, ExtendedContext>;
|
|
@@ -515,15 +521,10 @@ export declare class BasicCrawler<Context extends CrawlingContext = CrawlingCont
|
|
|
515
521
|
protected readonly internalTimeoutMillis: number;
|
|
516
522
|
protected readonly maxRequestRetries: number;
|
|
517
523
|
protected readonly maxCrawlDepth?: number;
|
|
518
|
-
private sameDomainDelayMillis;
|
|
519
|
-
private domainAccessedTime;
|
|
520
524
|
protected readonly maxRequestsPerCrawl?: number;
|
|
521
525
|
private get handledRequestsCount();
|
|
522
|
-
private statusMessageLoggingInterval;
|
|
523
|
-
private statusMessageCallback?;
|
|
524
526
|
protected blockedStatusCodes: Set<number>;
|
|
525
527
|
protected readonly additionalHttpErrorStatusCodes: Set<number>;
|
|
526
|
-
private ignoreHttpErrorStatusCodes;
|
|
527
528
|
/**
|
|
528
529
|
* The resolved options for the crawler's own task loop — the crawler-owned `runTaskFunction`, the (possibly
|
|
529
530
|
* user-overridden) ready/finished predicates and cadence/logging. Concurrency configuration lives on the
|
|
@@ -533,89 +534,100 @@ export declare class BasicCrawler<Context extends CrawlingContext = CrawlingCont
|
|
|
533
534
|
private taskLoopOptions;
|
|
534
535
|
protected readonly httpClient: BaseHttpClient;
|
|
535
536
|
protected readonly retryOnBlocked: boolean;
|
|
536
|
-
private respectRobotsTxtFile;
|
|
537
537
|
protected readonly onSkippedRequest?: SkippedRequestCallback;
|
|
538
|
-
private _closeEvents?;
|
|
539
|
-
private loggedPerRun;
|
|
540
|
-
private readonly robotsTxtFileCache;
|
|
541
538
|
protected readonly identity: CrawlerIdentity;
|
|
542
|
-
private readonly contextPipelineOptions;
|
|
543
539
|
protected static optionsShape: {
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
587
|
-
retryOnBlocked: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
|
|
588
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
589
|
-
respectRobotsTxtFile: import("ow").AnyPredicate<boolean | object>;
|
|
590
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
591
|
-
onSkippedRequest: import("ow").Predicate<Function> & import("ow").BasePredicate<Function | undefined>;
|
|
592
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
593
|
-
httpClient: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
594
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
595
|
-
configuration: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
596
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
597
|
-
storageBackend: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
598
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
599
|
-
eventManager: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
600
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
601
|
-
logger: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
602
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
603
|
-
minConcurrency: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
|
|
604
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
605
|
-
maxConcurrency: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
|
|
606
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
607
|
-
maxRequestsPerMinute: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
|
|
608
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
609
|
-
keepAlive: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
|
|
610
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
611
|
-
statisticsOptions: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
612
|
-
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
613
|
-
id: import("ow").StringPredicate & import("ow").BasePredicate<string | undefined>;
|
|
540
|
+
contextPipelineBuilder: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
|
|
541
|
+
extendContext: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
|
|
542
|
+
requestList: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
543
|
+
requestQueue: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
544
|
+
requestManager: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
545
|
+
requestHandler: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
|
|
546
|
+
requestHandlerTimeoutSecs: z.ZodOptional<z.ZodCustom<number, number>>;
|
|
547
|
+
errorHandler: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
|
|
548
|
+
failedRequestHandler: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
|
|
549
|
+
maxRequestRetries: z.ZodDefault<z.ZodCustom<number, number>>;
|
|
550
|
+
sameDomainDelaySecs: z.ZodDefault<z.ZodCustom<number, number>>;
|
|
551
|
+
maxRequestsPerCrawl: z.ZodOptional<z.ZodCustom<number, number>>;
|
|
552
|
+
maxCrawlDepth: z.ZodOptional<z.ZodCustom<number, number>>;
|
|
553
|
+
taskLoopOptions: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
|
|
554
|
+
concurrencySystem: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
|
|
555
|
+
sessionPool: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
556
|
+
proxyConfiguration: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
557
|
+
statusMessageLoggingInterval: z.ZodDefault<z.ZodCustom<number, number>>;
|
|
558
|
+
statusMessageCallback: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
|
|
559
|
+
additionalHttpErrorStatusCodes: z.ZodDefault<z.ZodArray<z.ZodCustom<number, number>>>;
|
|
560
|
+
ignoreHttpErrorStatusCodes: z.ZodDefault<z.ZodArray<z.ZodCustom<number, number>>>;
|
|
561
|
+
blockedStatusCodes: z.ZodOptional<z.ZodArray<z.ZodCustom<number, number>>>;
|
|
562
|
+
retryOnBlocked: z.ZodDefault<z.ZodBoolean>;
|
|
563
|
+
respectRobotsTxtFile: z.ZodDefault<z.ZodUnion<readonly [z.ZodBoolean, z.ZodCustom<Dictionary, Dictionary>]>>;
|
|
564
|
+
transactionalStorage: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
|
|
565
|
+
requestQueue: z.ZodOptional<z.ZodEnum<{
|
|
566
|
+
deferred: "deferred";
|
|
567
|
+
writeThrough: "writeThrough";
|
|
568
|
+
}>>;
|
|
569
|
+
}, z.core.$strict>]>>;
|
|
570
|
+
onSkippedRequest: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
|
|
571
|
+
httpClient: z.ZodOptional<z.ZodCustom<BaseHttpClient, BaseHttpClient>>;
|
|
572
|
+
configuration: z.ZodOptional<z.ZodCustom<Configuration, Configuration>>;
|
|
573
|
+
storageBackend: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
574
|
+
eventManager: z.ZodOptional<z.ZodCustom<EventManager, EventManager>>;
|
|
575
|
+
logger: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
576
|
+
minConcurrency: z.ZodOptional<z.ZodCustom<number, number>>;
|
|
577
|
+
maxConcurrency: z.ZodOptional<z.ZodCustom<number, number>>;
|
|
578
|
+
maxRequestsPerMinute: z.ZodOptional<z.ZodCustom<number, number>>;
|
|
579
|
+
keepAlive: z.ZodOptional<z.ZodBoolean>;
|
|
580
|
+
statistics: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
|
|
581
|
+
id: z.ZodOptional<z.ZodString>;
|
|
614
582
|
};
|
|
583
|
+
protected static optionsSchema: z.ZodObject<{
|
|
584
|
+
contextPipelineBuilder: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
|
|
585
|
+
extendContext: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
|
|
586
|
+
requestList: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
587
|
+
requestQueue: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
588
|
+
requestManager: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
589
|
+
requestHandler: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
|
|
590
|
+
requestHandlerTimeoutSecs: z.ZodOptional<z.ZodCustom<number, number>>;
|
|
591
|
+
errorHandler: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
|
|
592
|
+
failedRequestHandler: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
|
|
593
|
+
maxRequestRetries: z.ZodDefault<z.ZodCustom<number, number>>;
|
|
594
|
+
sameDomainDelaySecs: z.ZodDefault<z.ZodCustom<number, number>>;
|
|
595
|
+
maxRequestsPerCrawl: z.ZodOptional<z.ZodCustom<number, number>>;
|
|
596
|
+
maxCrawlDepth: z.ZodOptional<z.ZodCustom<number, number>>;
|
|
597
|
+
taskLoopOptions: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
|
|
598
|
+
concurrencySystem: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
|
|
599
|
+
sessionPool: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
600
|
+
proxyConfiguration: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
601
|
+
statusMessageLoggingInterval: z.ZodDefault<z.ZodCustom<number, number>>;
|
|
602
|
+
statusMessageCallback: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
|
|
603
|
+
additionalHttpErrorStatusCodes: z.ZodDefault<z.ZodArray<z.ZodCustom<number, number>>>;
|
|
604
|
+
ignoreHttpErrorStatusCodes: z.ZodDefault<z.ZodArray<z.ZodCustom<number, number>>>;
|
|
605
|
+
blockedStatusCodes: z.ZodOptional<z.ZodArray<z.ZodCustom<number, number>>>;
|
|
606
|
+
retryOnBlocked: z.ZodDefault<z.ZodBoolean>;
|
|
607
|
+
respectRobotsTxtFile: z.ZodDefault<z.ZodUnion<readonly [z.ZodBoolean, z.ZodCustom<Dictionary, Dictionary>]>>;
|
|
608
|
+
transactionalStorage: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
|
|
609
|
+
requestQueue: z.ZodOptional<z.ZodEnum<{
|
|
610
|
+
deferred: "deferred";
|
|
611
|
+
writeThrough: "writeThrough";
|
|
612
|
+
}>>;
|
|
613
|
+
}, z.core.$strict>]>>;
|
|
614
|
+
onSkippedRequest: z.ZodOptional<z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>>;
|
|
615
|
+
httpClient: z.ZodOptional<z.ZodCustom<BaseHttpClient, BaseHttpClient>>;
|
|
616
|
+
configuration: z.ZodOptional<z.ZodCustom<Configuration, Configuration>>;
|
|
617
|
+
storageBackend: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
618
|
+
eventManager: z.ZodOptional<z.ZodCustom<EventManager, EventManager>>;
|
|
619
|
+
logger: z.ZodOptional<z.ZodType<Dictionary<any>, unknown, z.core.$ZodTypeInternals<Dictionary<any>, unknown>>>;
|
|
620
|
+
minConcurrency: z.ZodOptional<z.ZodCustom<number, number>>;
|
|
621
|
+
maxConcurrency: z.ZodOptional<z.ZodCustom<number, number>>;
|
|
622
|
+
maxRequestsPerMinute: z.ZodOptional<z.ZodCustom<number, number>>;
|
|
623
|
+
keepAlive: z.ZodOptional<z.ZodBoolean>;
|
|
624
|
+
statistics: z.ZodOptional<z.ZodCustom<Dictionary, Dictionary>>;
|
|
625
|
+
id: z.ZodOptional<z.ZodString>;
|
|
626
|
+
}, z.core.$strict>;
|
|
615
627
|
/**
|
|
616
628
|
* All `BasicCrawler` parameters are passed via an options object.
|
|
617
629
|
*/
|
|
618
|
-
constructor(options?: BasicCrawlerOptions<Context, ContextExtension, ExtendedContext, Routes> & RequireContextPipeline<CrawlingContext, Context>);
|
|
630
|
+
constructor(options?: BasicCrawlerOptions<Context, ContextExtension, ExtendedContext, Routes, StatisticStateExtension> & RequireContextPipeline<CrawlingContext, Context>);
|
|
619
631
|
/**
|
|
620
632
|
* Builds the crawler-owned default {@link ConcurrencySystem} from the resolved
|
|
621
633
|
* `minConcurrency`/`maxConcurrency`/`maxRequestsPerMinute` shortcuts. Not called when a
|
|
@@ -743,6 +755,11 @@ export declare class BasicCrawler<Context extends CrawlingContext = CrawlingCont
|
|
|
743
755
|
* the batches via `waitBetweenBatchesMillis`. If you want to wait for all batches to be added to the queue, you can use
|
|
744
756
|
* the `waitForAllRequestsToBeAdded` promise you get in the response object.
|
|
745
757
|
*
|
|
758
|
+
* Optionally, the requests can be filtered using `include`/`exclude` glob or regexp patterns and an
|
|
759
|
+
* enqueue `strategy` (both AND-ed together, same as {@link CrawlingContext.enqueueLinks|`enqueueLinks`}),
|
|
760
|
+
* relative to `baseUrl`. Unlike `enqueueLinks`, there is no implicit "current page" to anchor the strategy
|
|
761
|
+
* to, so `strategy` defaults to {@link EnqueueStrategy.All|`all`} here.
|
|
762
|
+
*
|
|
746
763
|
* This is an alias for calling `addRequestsBatched()` on the implicit `RequestQueue` for this crawler instance.
|
|
747
764
|
*
|
|
748
765
|
* @param requests The requests to add
|
|
@@ -769,7 +786,7 @@ export declare class BasicCrawler<Context extends CrawlingContext = CrawlingCont
|
|
|
769
786
|
/**
|
|
770
787
|
* Initializes the crawler.
|
|
771
788
|
*/
|
|
772
|
-
protected
|
|
789
|
+
protected init(): Promise<void>;
|
|
773
790
|
/**
|
|
774
791
|
* The navigation timeout (pre-navigation hooks, navigation, and post-navigation hooks) in milliseconds, used
|
|
775
792
|
* to size the internal request timeout. `BasicCrawler` has no navigation phase, so this is 0; the HTTP and
|
|
@@ -797,33 +814,40 @@ export declare class BasicCrawler<Context extends CrawlingContext = CrawlingCont
|
|
|
797
814
|
*/
|
|
798
815
|
private getRouteTimeoutMillis;
|
|
799
816
|
protected runRequestHandler(crawlingContext: ExtendedContext): Promise<void>;
|
|
817
|
+
/**
|
|
818
|
+
* Runs `callback` inside a {@link StorageTransaction}, unless transactional storage is disabled.
|
|
819
|
+
* Deliberately does **not** commit on return - `handleRequest` swallows request handler failures, so
|
|
820
|
+
* a normal return says nothing about success. `handleRequest` owns the outcome.
|
|
821
|
+
*/
|
|
822
|
+
private runInStorageTransaction;
|
|
800
823
|
/**
|
|
801
824
|
* Handles blocked request
|
|
802
825
|
*/
|
|
803
|
-
protected
|
|
826
|
+
protected throwOnBlockedRequest(statusCode: number): void;
|
|
804
827
|
private isAllowedBasedOnRobotsTxtFile;
|
|
828
|
+
/**
|
|
829
|
+
* Records an HTTP 429 against the URL's domain so the request manager can pace the retry.
|
|
830
|
+
*
|
|
831
|
+
* @param retryAfterHeader The raw `Retry-After` response header, if the server sent one.
|
|
832
|
+
* @returns `true` if a manager took responsibility for the delay, in which case the caller should throw
|
|
833
|
+
* {@link RequestThrottledError} rather than treating the response as a blocked session.
|
|
834
|
+
*/
|
|
835
|
+
protected recordDomainRateLimit(url: string, retryAfterHeader?: string | null): boolean;
|
|
836
|
+
/**
|
|
837
|
+
* Hands a robots.txt `Crawl-delay` to the request manager, warning if nothing is able to honour it.
|
|
838
|
+
*
|
|
839
|
+
* The warning is driven by whether the delay was actually accepted rather than by the type of the manager,
|
|
840
|
+
* because a manager that does throttle still drops the delay for a domain missing from its `domains` list.
|
|
841
|
+
*/
|
|
842
|
+
private applyCrawlDelay;
|
|
805
843
|
protected getRobotsTxtFileForUrl(url: string): Promise<RobotsTxtFile | undefined>;
|
|
806
844
|
private pauseOnMigration;
|
|
807
845
|
/**
|
|
808
846
|
* Fetches the next request to process from the underlying request provider.
|
|
809
847
|
*/
|
|
810
848
|
private fetchNextRequest;
|
|
811
|
-
/**
|
|
812
|
-
* Delays processing of the request based on the `sameDomainDelaySecs` option,
|
|
813
|
-
* adding it back to the queue after the timeout passes. Returns `true` if the request
|
|
814
|
-
* should be ignored and will be reclaimed to the queue once ready.
|
|
815
|
-
*/
|
|
816
|
-
private delayRequest;
|
|
817
849
|
/** Handles a single request - runs the request handler with retries, error handling, and lifecycle management. */
|
|
818
850
|
private handleRequest;
|
|
819
|
-
/**
|
|
820
|
-
* Wrapper around the crawling context's `enqueueLinks` method:
|
|
821
|
-
* - Injects `crawlDepth` to each request being added based on the crawling context request.
|
|
822
|
-
* - Provides defaults for the `enqueueLinks` options based on the crawler configuration.
|
|
823
|
-
* - These options can be overridden by the user.
|
|
824
|
-
* @internal
|
|
825
|
-
*/
|
|
826
|
-
protected enqueueLinksWithCrawlDepth(options: SetRequired<EnqueueLinksOptions, 'urls'>, request: Request<Dictionary>, requestManager: IRequestManager): Promise<BatchAddRequestsResult>;
|
|
827
851
|
/**
|
|
828
852
|
* Generator function that yields requests injected with the given crawl depth.
|
|
829
853
|
* @internal
|
|
@@ -859,7 +883,12 @@ export declare class BasicCrawler<Context extends CrawlingContext = CrawlingCont
|
|
|
859
883
|
* @param error The error received
|
|
860
884
|
* @returns The message to be logged
|
|
861
885
|
*/
|
|
862
|
-
protected
|
|
886
|
+
protected getMessageFromError(error: Error, forceStack?: boolean): string | TimeoutError | undefined;
|
|
887
|
+
/**
|
|
888
|
+
* Whether the session should be spared for this error - either because it was already retired, or because the
|
|
889
|
+
* failure says nothing about the session (a rate limit is a property of the domain).
|
|
890
|
+
*/
|
|
891
|
+
private errorAbsolvesSession;
|
|
863
892
|
private canRequestBeRetried;
|
|
864
893
|
/**
|
|
865
894
|
* Stops the crawler immediately.
|
|
@@ -869,7 +898,7 @@ export declare class BasicCrawler<Context extends CrawlingContext = CrawlingCont
|
|
|
869
898
|
* To stop the crawler gracefully (waiting for all running requests to finish), use {@link BasicCrawler.stop|`crawler.stop()`} instead.
|
|
870
899
|
*/
|
|
871
900
|
teardown(): Promise<void>;
|
|
872
|
-
protected
|
|
901
|
+
protected getCookieHeaderFromRequest(request: Request): string;
|
|
873
902
|
private requestMatchesEnqueueStrategy;
|
|
874
903
|
}
|
|
875
904
|
export interface CreateContextOptions {
|
|
@@ -877,7 +906,7 @@ export interface CreateContextOptions {
|
|
|
877
906
|
session: ISession;
|
|
878
907
|
proxyInfo?: ProxyInfo;
|
|
879
908
|
}
|
|
880
|
-
export interface CrawlerAddRequestsOptions extends AddRequestsBatchedOptions {
|
|
909
|
+
export interface CrawlerAddRequestsOptions extends AddRequestsBatchedOptions, EnqueueUrlsOptions {
|
|
881
910
|
}
|
|
882
911
|
export interface CrawlerAddRequestsResult extends AddRequestsBatchedResult {
|
|
883
912
|
}
|