@crawlee/basic 4.0.0-beta.211 → 4.0.0-beta.212
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/autoscaling/autoscaled_pool.d.ts +0 -20
- package/internals/autoscaling/autoscaled_pool.js +11 -12
- package/internals/autoscaling/concurrency_system.d.ts +0 -38
- package/internals/autoscaling/concurrency_system.js +51 -53
- package/internals/autoscaling/memory_load_signal.d.ts +0 -2
- package/internals/autoscaling/memory_load_signal.js +4 -4
- package/internals/autoscaling/system_status.d.ts +0 -10
- package/internals/autoscaling/system_status.js +5 -5
- package/internals/basic-crawler.d.ts +0 -88
- package/internals/basic-crawler.js +70 -67
- package/internals/crawlers/context_pipeline.js +3 -3
- package/internals/crawlers/error_tracker.d.ts +0 -1
- package/internals/crawlers/error_tracker.js +3 -3
- package/internals/crawlers/statistics.d.ts +0 -2
- package/internals/crawlers/statistics.js +11 -11
- package/internals/crawling_request.d.ts +1 -1
- package/internals/crawling_request.js +12 -12
- package/internals/router.d.ts +0 -9
- package/internals/router.js +5 -5
- package/internals/session_pool/session.d.ts +0 -5
- package/internals/session_pool/session.js +3 -3
- package/internals/session_pool/session_pool.d.ts +0 -51
- package/internals/session_pool/session_pool.js +36 -36
- package/internals/sitemap_request_loader.d.ts +0 -39
- package/internals/sitemap_request_loader.js +18 -18
- package/internals/throttling_request_manager.d.ts +0 -1
- package/internals/throttling_request_manager.js +5 -5
- package/package.json +7 -7
|
@@ -95,49 +95,12 @@ export declare class SitemapRequestLoader implements IRequestLoader {
|
|
|
95
95
|
inProgress: Set<string>;
|
|
96
96
|
/** @internal */
|
|
97
97
|
private constructor();
|
|
98
|
-
/**
|
|
99
|
-
* Creates a new object stream with the specified highWaterMark.
|
|
100
|
-
* @param highWaterMark High water mark for the stream (the maximum number of objects the stream will buffer).
|
|
101
|
-
* @returns A new object stream.
|
|
102
|
-
*/
|
|
103
|
-
private createNewStream;
|
|
104
|
-
/**
|
|
105
|
-
* Returns a function that checks whether the provided pattern matches the closure URL.
|
|
106
|
-
* @param url URL to be checked.
|
|
107
|
-
* @returns A matcher function that checks whether the pattern matches the closure URL.
|
|
108
|
-
*/
|
|
109
|
-
private matchesUrl;
|
|
110
|
-
/**
|
|
111
|
-
* Checks whether the URL matches the `include` / `exclude` patterns provided in the `options`.
|
|
112
|
-
* @param url URL to be checked.
|
|
113
|
-
* @returns `true` if the URL matches the patterns, `false` otherwise.
|
|
114
|
-
*/
|
|
115
|
-
private isUrlMatchingPatterns;
|
|
116
|
-
/**
|
|
117
|
-
* Adds a URL to the queue of parsed URLs.
|
|
118
|
-
*
|
|
119
|
-
* Blocks if the stream is full until it is drained.
|
|
120
|
-
*/
|
|
121
|
-
private pushNextUrl;
|
|
122
|
-
/**
|
|
123
|
-
* Reads the next URL from the queue of parsed URLs.
|
|
124
|
-
*
|
|
125
|
-
* If the stream is empty, blocks until a new URL is pushed.
|
|
126
|
-
* @returns The next URL from the queue or `null` if we have read all URLs.
|
|
127
|
-
*/
|
|
128
|
-
private readNextUrl;
|
|
129
98
|
/**
|
|
130
99
|
* Indicates whether the background processing of sitemap contents has successfully finished.
|
|
131
100
|
*
|
|
132
101
|
* If this is `false`, the background processing is either still in progress or was aborted.
|
|
133
102
|
*/
|
|
134
103
|
isSitemapFullyLoaded(): boolean;
|
|
135
|
-
/**
|
|
136
|
-
* Start processing the sitemaps and loading the URLs.
|
|
137
|
-
*
|
|
138
|
-
* Resolves once all the sitemaps URLs have been fully loaded (sets `isSitemapFullyLoaded` to `true`).
|
|
139
|
-
*/
|
|
140
|
-
private load;
|
|
141
104
|
/**
|
|
142
105
|
* Open a sitemap and start processing it.
|
|
143
106
|
*
|
|
@@ -172,7 +135,6 @@ export declare class SitemapRequestLoader implements IRequestLoader {
|
|
|
172
135
|
* @inheritDoc
|
|
173
136
|
*/
|
|
174
137
|
persistState(): Promise<void>;
|
|
175
|
-
private restoreState;
|
|
176
138
|
/**
|
|
177
139
|
* @inheritDoc
|
|
178
140
|
*/
|
|
@@ -192,6 +154,5 @@ export declare class SitemapRequestLoader implements IRequestLoader {
|
|
|
192
154
|
* @inheritDoc
|
|
193
155
|
*/
|
|
194
156
|
markRequestAsHandled(request: Request): Promise<void>;
|
|
195
|
-
private ensureInProgress;
|
|
196
157
|
}
|
|
197
158
|
export {};
|
|
@@ -107,7 +107,7 @@ export class SitemapRequestLoader {
|
|
|
107
107
|
this.#persistenceOptions = { enable: true, ...persistenceOptions };
|
|
108
108
|
this.#proxyUrl = proxyUrl;
|
|
109
109
|
this.#enqueueStrategy = enqueueStrategy;
|
|
110
|
-
this.#urlQueueStream = this
|
|
110
|
+
this.#urlQueueStream = this.#createNewStream(maxBufferSize);
|
|
111
111
|
this.#sitemapParsingProgress.pendingSitemapUrls = new Set(sitemapUrls);
|
|
112
112
|
this.#events = serviceLocator.getEventManager();
|
|
113
113
|
this.persistState = this.persistState.bind(this);
|
|
@@ -117,7 +117,7 @@ export class SitemapRequestLoader {
|
|
|
117
117
|
* @param highWaterMark High water mark for the stream (the maximum number of objects the stream will buffer).
|
|
118
118
|
* @returns A new object stream.
|
|
119
119
|
*/
|
|
120
|
-
createNewStream(highWaterMark) {
|
|
120
|
+
#createNewStream(highWaterMark) {
|
|
121
121
|
return new Transform({
|
|
122
122
|
objectMode: true,
|
|
123
123
|
highWaterMark,
|
|
@@ -128,7 +128,7 @@ export class SitemapRequestLoader {
|
|
|
128
128
|
* @param url URL to be checked.
|
|
129
129
|
* @returns A matcher function that checks whether the pattern matches the closure URL.
|
|
130
130
|
*/
|
|
131
|
-
matchesUrl(url) {
|
|
131
|
+
#matchesUrl(url) {
|
|
132
132
|
return (patternObject) => {
|
|
133
133
|
const { regexp, glob } = patternObject;
|
|
134
134
|
const matchesRegex = (regexp && url.match(regexp)) || false;
|
|
@@ -141,18 +141,18 @@ export class SitemapRequestLoader {
|
|
|
141
141
|
* @param url URL to be checked.
|
|
142
142
|
* @returns `true` if the URL matches the patterns, `false` otherwise.
|
|
143
143
|
*/
|
|
144
|
-
isUrlMatchingPatterns(url) {
|
|
145
|
-
return (!this.#urlExcludePatternObjects.some(this
|
|
146
|
-
(this.#urlPatternObjects.length === 0 || this.#urlPatternObjects.some(this
|
|
144
|
+
#isUrlMatchingPatterns(url) {
|
|
145
|
+
return (!this.#urlExcludePatternObjects.some(this.#matchesUrl(url)) &&
|
|
146
|
+
(this.#urlPatternObjects.length === 0 || this.#urlPatternObjects.some(this.#matchesUrl(url))));
|
|
147
147
|
}
|
|
148
148
|
/**
|
|
149
149
|
* Adds a URL to the queue of parsed URLs.
|
|
150
150
|
*
|
|
151
151
|
* Blocks if the stream is full until it is drained.
|
|
152
152
|
*/
|
|
153
|
-
async pushNextUrl(url) {
|
|
153
|
+
async #pushNextUrl(url) {
|
|
154
154
|
return new Promise((resolve) => {
|
|
155
|
-
if (this.#closed || (url && !this
|
|
155
|
+
if (this.#closed || (url && !this.#isUrlMatchingPatterns(url))) {
|
|
156
156
|
resolve();
|
|
157
157
|
return;
|
|
158
158
|
}
|
|
@@ -173,7 +173,7 @@ export class SitemapRequestLoader {
|
|
|
173
173
|
* If the stream is empty, blocks until a new URL is pushed.
|
|
174
174
|
* @returns The next URL from the queue or `null` if we have read all URLs.
|
|
175
175
|
*/
|
|
176
|
-
async readNextUrl() {
|
|
176
|
+
async #readNextUrl() {
|
|
177
177
|
return new Promise((resolve) => {
|
|
178
178
|
if (this.#closed) {
|
|
179
179
|
resolve(null);
|
|
@@ -206,7 +206,7 @@ export class SitemapRequestLoader {
|
|
|
206
206
|
*
|
|
207
207
|
* Resolves once all the sitemaps URLs have been fully loaded (sets `isSitemapFullyLoaded` to `true`).
|
|
208
208
|
*/
|
|
209
|
-
async load({ parseSitemapOptions, }) {
|
|
209
|
+
async #load({ parseSitemapOptions, }) {
|
|
210
210
|
while (!this.isSitemapFullyLoaded() && !this.#abortLoading) {
|
|
211
211
|
const sitemapUrl = this.#sitemapParsingProgress.inProgressSitemapUrl ??
|
|
212
212
|
this.#sitemapParsingProgress.pendingSitemapUrls.values().next().value;
|
|
@@ -223,7 +223,7 @@ export class SitemapRequestLoader {
|
|
|
223
223
|
continue;
|
|
224
224
|
}
|
|
225
225
|
if (!this.#sitemapParsingProgress.inProgressEntries.has(item.loc)) {
|
|
226
|
-
await this
|
|
226
|
+
await this.#pushNextUrl(item.loc);
|
|
227
227
|
this.#sitemapParsingProgress.inProgressEntries.add(item.loc);
|
|
228
228
|
}
|
|
229
229
|
}
|
|
@@ -250,8 +250,8 @@ export class SitemapRequestLoader {
|
|
|
250
250
|
...restOptions,
|
|
251
251
|
persistStateKey: options.persistStateKey ?? STATE_PERSISTENCE_KEY,
|
|
252
252
|
});
|
|
253
|
-
await requestList
|
|
254
|
-
void requestList
|
|
253
|
+
await requestList.#restoreState();
|
|
254
|
+
void requestList.#load({
|
|
255
255
|
parseSitemapOptions: { logger: serviceLocator.getLogger(), ...options.parseSitemapOptions, httpClient },
|
|
256
256
|
});
|
|
257
257
|
if (requestList.#persistenceOptions.enable) {
|
|
@@ -328,7 +328,7 @@ export class SitemapRequestLoader {
|
|
|
328
328
|
// Create a new stream, as we have read all the URLs from the current one.
|
|
329
329
|
// Pushing the urls back to the original stream might not be possible if it has been ended.
|
|
330
330
|
const previousStream = this.#urlQueueStream;
|
|
331
|
-
const newStream = this
|
|
331
|
+
const newStream = this.#createNewStream(previousStream.readableHighWaterMark);
|
|
332
332
|
for (const url of urlQueue) {
|
|
333
333
|
newStream.push(url);
|
|
334
334
|
}
|
|
@@ -355,7 +355,7 @@ export class SitemapRequestLoader {
|
|
|
355
355
|
closed: this.#closed,
|
|
356
356
|
});
|
|
357
357
|
}
|
|
358
|
-
async restoreState() {
|
|
358
|
+
async #restoreState() {
|
|
359
359
|
await purgeDefaultStorages({ onlyPurgeOnce: true });
|
|
360
360
|
if (this.#persistStateKey === undefined) {
|
|
361
361
|
return;
|
|
@@ -381,7 +381,7 @@ export class SitemapRequestLoader {
|
|
|
381
381
|
* @inheritDoc
|
|
382
382
|
*/
|
|
383
383
|
async fetchNextRequest() {
|
|
384
|
-
const nextUrl = await this
|
|
384
|
+
const nextUrl = await this.#readNextUrl();
|
|
385
385
|
if (!nextUrl) {
|
|
386
386
|
return null;
|
|
387
387
|
}
|
|
@@ -420,11 +420,11 @@ export class SitemapRequestLoader {
|
|
|
420
420
|
*/
|
|
421
421
|
async markRequestAsHandled(request) {
|
|
422
422
|
this.#handledUrlCount += 1;
|
|
423
|
-
this
|
|
423
|
+
this.#ensureInProgress(request.url);
|
|
424
424
|
this.inProgress.delete(request.url);
|
|
425
425
|
this.#requestData.delete(request.url);
|
|
426
426
|
}
|
|
427
|
-
ensureInProgress(url) {
|
|
427
|
+
#ensureInProgress(url) {
|
|
428
428
|
if (!this.inProgress.has(url)) {
|
|
429
429
|
throw new Error(`The request is not being processed (url: ${url})`);
|
|
430
430
|
}
|
|
@@ -153,7 +153,6 @@ export interface ThrottlingRequestManagerOptions<T extends IRequestManager = IRe
|
|
|
153
153
|
*/
|
|
154
154
|
export declare class ThrottlingRequestManager<T extends IRequestManager = IRequestManager> implements IRequestManager {
|
|
155
155
|
#private;
|
|
156
|
-
private readonly config;
|
|
157
156
|
constructor(options: ThrottlingRequestManagerOptions<T>, config?: Configuration);
|
|
158
157
|
/**
|
|
159
158
|
* The wrapped manager, holding every request whose domain is not throttled. `undefined` until an `inner`
|
|
@@ -91,7 +91,6 @@ const MAX_INNER_MIGRATIONS = 1000;
|
|
|
91
91
|
* @category Sources
|
|
92
92
|
*/
|
|
93
93
|
export class ThrottlingRequestManager {
|
|
94
|
-
config;
|
|
95
94
|
#innerFactory;
|
|
96
95
|
#innerPromise;
|
|
97
96
|
#resolvedInner;
|
|
@@ -104,6 +103,7 @@ export class ThrottlingRequestManager {
|
|
|
104
103
|
#throttleBy;
|
|
105
104
|
#maxThrottledDomains;
|
|
106
105
|
#persistStateKey;
|
|
106
|
+
#config;
|
|
107
107
|
#subManagers = new Map();
|
|
108
108
|
#domainStates = new Map();
|
|
109
109
|
#log;
|
|
@@ -142,12 +142,12 @@ export class ThrottlingRequestManager {
|
|
|
142
142
|
return this.#listedDomains.size > 0 || this.#throttlesEveryDomain;
|
|
143
143
|
}
|
|
144
144
|
constructor(options, config = serviceLocator.getConfiguration()) {
|
|
145
|
-
this
|
|
145
|
+
this.#config = config;
|
|
146
146
|
parseArgument(options, throttlingRequestManagerOptionsSchema, 'ThrottlingRequestManagerOptions');
|
|
147
147
|
if (options.inner === undefined) {
|
|
148
148
|
// Deferred like any other factory, so a manager nobody fetches from opens no storage. The opener is
|
|
149
149
|
// assigned below and read only when this runs.
|
|
150
|
-
this.#innerFactory = () => this.#requestManagerOpener(null, { configuration: this
|
|
150
|
+
this.#innerFactory = () => this.#requestManagerOpener(null, { configuration: this.#config });
|
|
151
151
|
}
|
|
152
152
|
else if (typeof options.inner === 'function') {
|
|
153
153
|
this.#innerFactory = options.inner;
|
|
@@ -301,7 +301,7 @@ export class ThrottlingRequestManager {
|
|
|
301
301
|
subManager = this.#requestManagerOpener(
|
|
302
302
|
// Backends use the alias as a directory name, and an IPv6 literal is full of characters
|
|
303
303
|
// Windows will not accept. Ordinary hostnames survive this untouched.
|
|
304
|
-
{ alias: `throttled-${encodeURIComponent(domain)}` }, { configuration: this
|
|
304
|
+
{ alias: `throttled-${encodeURIComponent(domain)}` }, { configuration: this.#config });
|
|
305
305
|
this.#subManagers.set(domain, subManager);
|
|
306
306
|
this.#ensureDomainState(domain);
|
|
307
307
|
}
|
|
@@ -333,7 +333,7 @@ export class ThrottlingRequestManager {
|
|
|
333
333
|
async #ensureSubManagers() {
|
|
334
334
|
this.#subManagersReady ??= (async () => {
|
|
335
335
|
if (this.#throttlesEveryDomain) {
|
|
336
|
-
this.#domainListStore = await KeyValueStore.open(null, { configuration: this
|
|
336
|
+
this.#domainListStore = await KeyValueStore.open(null, { configuration: this.#config });
|
|
337
337
|
for (const domain of (await this.#domainListStore.getValue(this.#persistStateKey)) ?? []) {
|
|
338
338
|
this.#discoveredDomains.add(domain);
|
|
339
339
|
}
|
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.212",
|
|
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": "^3.0.1",
|
|
43
43
|
"@apify/timeout": "^1.0.1",
|
|
44
44
|
"@apify/utilities": "^3.0.1",
|
|
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.212",
|
|
46
|
+
"@crawlee/http-client": "4.0.0-beta.212",
|
|
47
|
+
"@crawlee/types": "4.0.0-beta.212",
|
|
48
|
+
"@crawlee/utils": "4.0.0-beta.212",
|
|
49
49
|
"@sapphire/async-queue": "^1.5.5",
|
|
50
50
|
"@standard-schema/spec": "^1.0.0",
|
|
51
51
|
"csv-stringify": "^6.5.2",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"zod": "^4.5.4"
|
|
58
58
|
},
|
|
59
59
|
"optionalDependencies": {
|
|
60
|
-
"@crawlee/impit-client": "4.0.0-beta.
|
|
60
|
+
"@crawlee/impit-client": "4.0.0-beta.212"
|
|
61
61
|
},
|
|
62
62
|
"lerna": {
|
|
63
63
|
"command": {
|
|
@@ -66,5 +66,5 @@
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
},
|
|
69
|
-
"gitHead": "
|
|
69
|
+
"gitHead": "171a63a5d7f2a6d74cbce58479204ac20d30b87e"
|
|
70
70
|
}
|