@crawlee/basic 4.0.0-beta.142 → 4.0.0-beta.144
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/internals/basic-crawler.d.ts +2 -10
- package/internals/basic-crawler.js +14 -15
- package/package.json +7 -7
|
@@ -1,4 +1,4 @@
|
|
|
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,
|
|
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, TaskLoopOptions, TypedRequestsLike } from '@crawlee/core';
|
|
2
2
|
import { ConcurrencySystem, Configuration, ContextPipeline, Request, Dataset, EventManager, RequestQueue } from '@crawlee/core';
|
|
3
3
|
import { BaseHttpClient } from '@crawlee/http-client';
|
|
4
4
|
import type { Awaitable, Dictionary, ISession, ISessionPool, ProxyInfo, SetStatusMessageOptions, StorageBackend } from '@crawlee/types';
|
|
@@ -165,7 +165,7 @@ export interface BasicCrawlerOptions<Context extends CrawlingContext = CrawlingC
|
|
|
165
165
|
* Concurrency is configured elsewhere — through the `minConcurrency`/`maxConcurrency`/`maxRequestsPerMinute`
|
|
166
166
|
* shortcuts, or a {@link BasicCrawlerOptions.concurrencySystem|`concurrencySystem`} for finer control.
|
|
167
167
|
*/
|
|
168
|
-
taskLoopOptions?:
|
|
168
|
+
taskLoopOptions?: TaskLoopOptions;
|
|
169
169
|
/**
|
|
170
170
|
* A pre-configured concurrency governor — the component that decides whether there is free compute for one more
|
|
171
171
|
* task. Typically a {@link ConcurrencySystem}, though any {@link IConcurrencySystem} is accepted. All
|
|
@@ -430,18 +430,10 @@ export declare class BasicCrawler<Context extends CrawlingContext = CrawlingCont
|
|
|
430
430
|
hasFinishedBefore: boolean;
|
|
431
431
|
get log(): CrawleeLogger;
|
|
432
432
|
protected readonly requestHandler: RequestHandler<ExtendedContext>;
|
|
433
|
-
private requestHandlerTimeoutMillis;
|
|
434
433
|
protected readonly internalTimeoutMillis: number;
|
|
435
434
|
private get handledRequestsCount();
|
|
436
435
|
protected blockedStatusCodes: Set<number>;
|
|
437
436
|
protected readonly additionalHttpErrorStatusCodes: Set<number>;
|
|
438
|
-
/**
|
|
439
|
-
* The resolved options for the crawler's own task loop — the crawler-owned `runTaskFunction`, the (possibly
|
|
440
|
-
* user-overridden) ready/finished predicates and cadence/logging. Concurrency configuration lives on the
|
|
441
|
-
* {@link ConcurrencySystem} instead, and the loop's `consumer` identity is the crawler's own, so neither is
|
|
442
|
-
* settable here.
|
|
443
|
-
*/
|
|
444
|
-
private taskLoopOptions;
|
|
445
437
|
protected readonly httpClient: BaseHttpClient;
|
|
446
438
|
protected readonly retryOnBlocked: boolean;
|
|
447
439
|
/**
|
|
@@ -7,7 +7,7 @@ import { RobotsTxtFile } from '@crawlee/utils';
|
|
|
7
7
|
import { getDomain } from 'tldts';
|
|
8
8
|
import { z } from 'zod';
|
|
9
9
|
import { LruCache } from '@apify/datastructures';
|
|
10
|
-
import { addTimeoutToPromise, extendTimeout, TimeoutError } from '@apify/timeout';
|
|
10
|
+
import { addTimeoutToPromise, extendTimeout, TimeoutError, tryCancel } from '@apify/timeout';
|
|
11
11
|
import { cryptoRandomObjectId } from '@apify/utilities';
|
|
12
12
|
import { extendTimeoutKey, navigationDeadlineKey, raceWithTimeout, timeoutExpiredKey, } from './request-timeout.js';
|
|
13
13
|
import { createSendRequest } from './send-request.js';
|
|
@@ -193,8 +193,7 @@ export class BasicCrawler {
|
|
|
193
193
|
requestHandler;
|
|
194
194
|
#errorHandler;
|
|
195
195
|
#failedRequestHandler;
|
|
196
|
-
|
|
197
|
-
requestHandlerTimeoutMillis;
|
|
196
|
+
#requestHandlerTimeoutMillis;
|
|
198
197
|
internalTimeoutMillis;
|
|
199
198
|
#maxRequestRetries;
|
|
200
199
|
#maxCrawlDepth;
|
|
@@ -214,8 +213,7 @@ export class BasicCrawler {
|
|
|
214
213
|
* {@link ConcurrencySystem} instead, and the loop's `consumer` identity is the crawler's own, so neither is
|
|
215
214
|
* settable here.
|
|
216
215
|
*/
|
|
217
|
-
|
|
218
|
-
taskLoopOptions;
|
|
216
|
+
#taskLoopOptions;
|
|
219
217
|
httpClient;
|
|
220
218
|
retryOnBlocked;
|
|
221
219
|
#respectRobotsTxtFile;
|
|
@@ -370,10 +368,10 @@ export class BasicCrawler {
|
|
|
370
368
|
this.#failedRequestHandler = failedRequestHandler;
|
|
371
369
|
this.#errorHandler = errorHandler;
|
|
372
370
|
if (requestHandlerTimeoutSecs) {
|
|
373
|
-
this
|
|
371
|
+
this.#requestHandlerTimeoutMillis = requestHandlerTimeoutSecs * 1000;
|
|
374
372
|
}
|
|
375
373
|
else {
|
|
376
|
-
this
|
|
374
|
+
this.#requestHandlerTimeoutMillis = 60_000;
|
|
377
375
|
}
|
|
378
376
|
this.retryOnBlocked = retryOnBlocked;
|
|
379
377
|
this.#respectRobotsTxtFile = respectRobotsTxtFile;
|
|
@@ -385,7 +383,7 @@ export class BasicCrawler {
|
|
|
385
383
|
// allow at least 5min for internal timeouts
|
|
386
384
|
this.internalTimeoutMillis =
|
|
387
385
|
serviceLocator.getConfiguration().internalTimeoutMillis ??
|
|
388
|
-
Math.max(this
|
|
386
|
+
Math.max(this.#requestHandlerTimeoutMillis * 2, 300e3);
|
|
389
387
|
this.#maxRequestRetries = maxRequestRetries;
|
|
390
388
|
this.#maxCrawlDepth = maxCrawlDepth;
|
|
391
389
|
this.#sameDomainDelaySecs = sameDomainDelaySecs;
|
|
@@ -412,10 +410,10 @@ export class BasicCrawler {
|
|
|
412
410
|
}));
|
|
413
411
|
this.blockedStatusCodes = new Set(blockedStatusCodesInput ?? BLOCKED_STATUS_CODES);
|
|
414
412
|
const maxSignedInteger = 2 ** 31 - 1;
|
|
415
|
-
if (this
|
|
416
|
-
this.log.warning(`requestHandlerTimeoutMillis ${this
|
|
413
|
+
if (this.#requestHandlerTimeoutMillis > maxSignedInteger) {
|
|
414
|
+
this.log.warning(`requestHandlerTimeoutMillis ${this.#requestHandlerTimeoutMillis}` +
|
|
417
415
|
` does not fit a signed 32-bit integer. Limiting the value to ${maxSignedInteger}`);
|
|
418
|
-
this
|
|
416
|
+
this.#requestHandlerTimeoutMillis = maxSignedInteger;
|
|
419
417
|
}
|
|
420
418
|
this.internalTimeoutMillis = Math.min(this.internalTimeoutMillis, maxSignedInteger);
|
|
421
419
|
this.#maxRequestsPerCrawl = maxRequestsPerCrawl;
|
|
@@ -525,7 +523,7 @@ export class BasicCrawler {
|
|
|
525
523
|
},
|
|
526
524
|
log: this.log,
|
|
527
525
|
};
|
|
528
|
-
this
|
|
526
|
+
this.#taskLoopOptions = { ...taskLoopOptions, ...crawlerOwnedTaskLoopConfiguration };
|
|
529
527
|
this.#resolveConcurrencySystem = () => OwnedOrInjected.resolve(concurrencySystem, () => this.createDefaultConcurrencySystem({
|
|
530
528
|
minConcurrency,
|
|
531
529
|
maxConcurrency,
|
|
@@ -975,7 +973,7 @@ export class BasicCrawler {
|
|
|
975
973
|
// which routes a run will hit, so reserve for the longest one any route asked for. The hint is
|
|
976
974
|
// raise-only, so erring high here is safe.
|
|
977
975
|
const maxRouteTimeoutSecs = this.requestHandler.getMaxTimeoutSecs?.() ?? 0;
|
|
978
|
-
const handlerTimeoutSecs = Math.max(this
|
|
976
|
+
const handlerTimeoutSecs = Math.max(this.#requestHandlerTimeoutMillis / 1000, maxRouteTimeoutSecs);
|
|
979
977
|
await requestManager.setExpectedRequestProcessingTimeSecs?.(Math.max(handlerTimeoutSecs + 5, 60));
|
|
980
978
|
}
|
|
981
979
|
/**
|
|
@@ -1167,6 +1165,7 @@ export class BasicCrawler {
|
|
|
1167
1165
|
* Pushes data to the specified {@link Dataset}, or the default crawler {@link Dataset} by calling {@link Dataset.pushData}.
|
|
1168
1166
|
*/
|
|
1169
1167
|
async pushData(data, datasetIdentifier) {
|
|
1168
|
+
tryCancel();
|
|
1170
1169
|
const dataset = await this.getDataset(datasetIdentifier);
|
|
1171
1170
|
return dataset.pushData(data);
|
|
1172
1171
|
}
|
|
@@ -1256,7 +1255,7 @@ export class BasicCrawler {
|
|
|
1256
1255
|
this.#concurrencySystemDep = this.#resolveConcurrencySystem();
|
|
1257
1256
|
await this.#concurrencySystemDep.ifOwned((system) => system.start());
|
|
1258
1257
|
this.#autoscaledPool = new AutoscaledPool({
|
|
1259
|
-
...this
|
|
1258
|
+
...this.#taskLoopOptions,
|
|
1260
1259
|
concurrencySystem: this.#concurrencySystemDep.value,
|
|
1261
1260
|
consumer: this.#identity,
|
|
1262
1261
|
});
|
|
@@ -1289,7 +1288,7 @@ export class BasicCrawler {
|
|
|
1289
1288
|
* @param label The request's route label, or `undefined` for the default route / no specific request.
|
|
1290
1289
|
* @param fallbackMillis Timeout to use when no route overrides it.
|
|
1291
1290
|
*/
|
|
1292
|
-
resolveRequestHandlerTimeoutMillis(label, fallbackMillis = this
|
|
1291
|
+
resolveRequestHandlerTimeoutMillis(label, fallbackMillis = this.#requestHandlerTimeoutMillis) {
|
|
1293
1292
|
return this.getRouteTimeoutMillis(label) ?? fallbackMillis;
|
|
1294
1293
|
}
|
|
1295
1294
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crawlee/basic",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.144",
|
|
4
4
|
"description": "The scalable web crawling and scraping library for JavaScript/Node.js. Enables development of data extraction and web automation jobs (not only) with headless Chrome and Puppeteer.",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=22.0.0"
|
|
@@ -42,10 +42,10 @@
|
|
|
42
42
|
"@apify/datastructures": "^2.0.0",
|
|
43
43
|
"@apify/timeout": "^0.4.4",
|
|
44
44
|
"@apify/utilities": "^2.15.5",
|
|
45
|
-
"@crawlee/core": "4.0.0-beta.
|
|
46
|
-
"@crawlee/http-client": "4.0.0-beta.
|
|
47
|
-
"@crawlee/types": "4.0.0-beta.
|
|
48
|
-
"@crawlee/utils": "4.0.0-beta.
|
|
45
|
+
"@crawlee/core": "4.0.0-beta.144",
|
|
46
|
+
"@crawlee/http-client": "4.0.0-beta.144",
|
|
47
|
+
"@crawlee/types": "4.0.0-beta.144",
|
|
48
|
+
"@crawlee/utils": "4.0.0-beta.144",
|
|
49
49
|
"csv-stringify": "^6.5.2",
|
|
50
50
|
"tldts": "^7.0.6",
|
|
51
51
|
"tslib": "^2.8.1",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"zod": "^4.4.3"
|
|
54
54
|
},
|
|
55
55
|
"optionalDependencies": {
|
|
56
|
-
"@crawlee/impit-client": "^4.0.0-beta.
|
|
56
|
+
"@crawlee/impit-client": "^4.0.0-beta.144"
|
|
57
57
|
},
|
|
58
58
|
"lerna": {
|
|
59
59
|
"command": {
|
|
@@ -62,5 +62,5 @@
|
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
},
|
|
65
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "4acf68a225909523047f872cbdeb87428bfc560d"
|
|
66
66
|
}
|