@crawlee/core 4.0.0-beta.13 → 4.0.0-beta.130
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -13
- package/autoscaling/autoscaled_pool.d.ts +67 -172
- package/autoscaling/autoscaled_pool.js +182 -329
- package/autoscaling/concurrency_system.d.ts +268 -0
- package/autoscaling/concurrency_system.js +362 -0
- package/autoscaling/cpu_load_signal.d.ts +43 -0
- package/autoscaling/cpu_load_signal.js +47 -0
- package/autoscaling/event_loop_load_signal.d.ts +51 -0
- package/autoscaling/event_loop_load_signal.js +60 -0
- package/autoscaling/index.d.ts +6 -1
- package/autoscaling/index.js +6 -1
- package/autoscaling/load_signal.d.ts +100 -0
- package/autoscaling/load_signal.js +105 -0
- package/autoscaling/memory_load_signal.d.ts +47 -0
- package/autoscaling/memory_load_signal.js +106 -0
- package/autoscaling/snapshotter.d.ts +58 -163
- package/autoscaling/snapshotter.js +45 -263
- package/autoscaling/storage_backend_load_signal.d.ts +56 -0
- package/autoscaling/storage_backend_load_signal.js +73 -0
- package/autoscaling/system_status.d.ts +67 -89
- package/autoscaling/system_status.js +92 -122
- package/autoscaling/weighted_avg.d.ts +5 -0
- package/autoscaling/weighted_avg.js +14 -0
- package/byte_utils.d.ts +17 -0
- package/byte_utils.js +42 -0
- package/configuration.d.ts +96 -223
- package/configuration.js +170 -222
- package/cookie_utils.d.ts +3 -2
- package/cookie_utils.js +18 -7
- package/crawlers/context_pipeline.d.ts +10 -1
- package/crawlers/context_pipeline.js +31 -8
- package/crawlers/crawler_commons.d.ts +90 -129
- package/crawlers/crawler_commons.js +1 -116
- package/crawlers/error_snapshotter.d.ts +2 -5
- package/crawlers/error_snapshotter.js +7 -8
- package/crawlers/error_tracker.d.ts +0 -1
- package/crawlers/error_tracker.js +0 -1
- package/crawlers/index.d.ts +1 -3
- package/crawlers/index.js +0 -3
- package/crawlers/internals/types.d.ts +0 -1
- package/crawlers/internals/types.js +0 -1
- package/crawlers/statistics.d.ts +187 -63
- package/crawlers/statistics.js +354 -164
- package/debug.d.ts +36 -0
- package/debug.js +70 -0
- package/enqueue_links/enqueue_links.d.ts +68 -154
- package/enqueue_links/enqueue_links.js +38 -210
- package/enqueue_links/index.d.ts +0 -1
- package/enqueue_links/index.js +0 -1
- package/enqueue_links/shared.d.ts +52 -26
- package/enqueue_links/shared.js +115 -66
- package/errors.d.ts +72 -4
- package/errors.js +89 -5
- package/events/event_manager.d.ts +35 -9
- package/events/event_manager.js +12 -13
- package/events/index.d.ts +0 -1
- package/events/index.js +0 -1
- package/events/local_event_manager.d.ts +15 -3
- package/events/local_event_manager.js +39 -13
- package/http.d.ts +9 -0
- package/http.js +28 -0
- package/index.d.ts +7 -4
- package/index.js +6 -3
- package/iterables.d.ts +79 -0
- package/iterables.js +134 -0
- package/log.d.ts +82 -3
- package/log.js +106 -1
- package/memory-storage/consts.d.ts +4 -0
- package/memory-storage/consts.js +4 -0
- package/memory-storage/index.d.ts +1 -0
- package/memory-storage/index.js +1 -0
- package/memory-storage/memory-storage.d.ts +38 -0
- package/memory-storage/memory-storage.js +130 -0
- package/memory-storage/resource-clients/common/base-client.d.ts +4 -0
- package/memory-storage/resource-clients/common/base-client.js +6 -0
- package/memory-storage/resource-clients/dataset.d.ts +40 -0
- package/memory-storage/resource-clients/dataset.js +108 -0
- package/memory-storage/resource-clients/key-value-store.d.ts +63 -0
- package/memory-storage/resource-clients/key-value-store.js +201 -0
- package/memory-storage/resource-clients/request-queue.d.ts +77 -0
- package/memory-storage/resource-clients/request-queue.js +409 -0
- package/memory-storage/utils.d.ts +16 -0
- package/memory-storage/utils.js +41 -0
- package/owned_or_injected.d.ts +58 -0
- package/owned_or_injected.js +98 -0
- package/package.json +14 -13
- package/proxy_configuration.d.ts +24 -132
- package/proxy_configuration.js +32 -147
- package/recoverable_state.d.ts +155 -0
- package/recoverable_state.js +231 -0
- package/request.d.ts +80 -16
- package/request.js +147 -68
- package/router.d.ts +193 -21
- package/router.js +188 -43
- package/serialization.d.ts +0 -1
- package/serialization.js +15 -15
- package/service_locator.d.ts +165 -0
- package/service_locator.js +253 -0
- package/session_pool/consts.d.ts +1 -2
- package/session_pool/consts.js +1 -2
- package/session_pool/errors.d.ts +0 -1
- package/session_pool/errors.js +0 -1
- package/session_pool/fingerprint.d.ts +9 -0
- package/session_pool/fingerprint.js +30 -0
- package/session_pool/index.d.ts +0 -2
- package/session_pool/index.js +0 -2
- package/session_pool/session.d.ts +35 -88
- package/session_pool/session.js +101 -159
- package/session_pool/session_pool.d.ts +73 -91
- package/session_pool/session_pool.js +172 -165
- package/storages/batched_adds.d.ts +37 -0
- package/storages/batched_adds.js +73 -0
- package/storages/dataset.d.ts +114 -54
- package/storages/dataset.js +291 -148
- package/storages/index.d.ts +10 -8
- package/storages/index.js +8 -8
- package/storages/key_value_store.d.ts +185 -42
- package/storages/key_value_store.js +445 -169
- package/storages/key_value_store_codec.d.ts +32 -0
- package/storages/key_value_store_codec.js +113 -0
- package/storages/request_dedup_cache.d.ts +22 -0
- package/storages/request_dedup_cache.js +48 -0
- package/storages/request_list.d.ts +52 -115
- package/storages/request_list.js +183 -152
- package/storages/request_loader.d.ts +101 -0
- package/storages/request_loader.js +1 -0
- package/storages/request_manager.d.ts +33 -0
- package/storages/request_manager.js +1 -0
- package/storages/request_manager_tandem.d.ts +97 -0
- package/storages/request_manager_tandem.js +197 -0
- package/storages/request_queue.d.ts +290 -47
- package/storages/request_queue.js +762 -216
- package/storages/{sitemap_request_list.d.ts → sitemap_request_loader.d.ts} +45 -89
- package/storages/sitemap_request_loader.js +438 -0
- package/storages/storage_instance_manager.d.ts +87 -0
- package/storages/storage_instance_manager.js +256 -0
- package/storages/storage_stats.d.ts +48 -0
- package/storages/storage_stats.js +29 -0
- package/storages/throttling_request_manager.d.ts +239 -0
- package/storages/throttling_request_manager.js +646 -0
- package/storages/transaction.d.ts +252 -0
- package/storages/transaction.js +251 -0
- package/storages/utils.d.ts +59 -11
- package/storages/utils.js +75 -15
- package/system-info/cpu-info.d.ts +67 -0
- package/system-info/cpu-info.js +216 -0
- package/system-info/memory-info.d.ts +31 -0
- package/system-info/memory-info.js +115 -0
- package/system-info/ps-tree.d.ts +17 -0
- package/system-info/ps-tree.js +144 -0
- package/system-info/runtime.d.ts +14 -0
- package/system-info/runtime.js +80 -0
- package/typedefs.d.ts +0 -6
- package/typedefs.js +0 -1
- package/url.d.ts +9 -0
- package/url.js +11 -0
- package/validators.d.ts +22 -18
- package/validators.js +13 -18
- package/autoscaling/autoscaled_pool.d.ts.map +0 -1
- package/autoscaling/autoscaled_pool.js.map +0 -1
- package/autoscaling/index.d.ts.map +0 -1
- package/autoscaling/index.js.map +0 -1
- package/autoscaling/snapshotter.d.ts.map +0 -1
- package/autoscaling/snapshotter.js.map +0 -1
- package/autoscaling/system_status.d.ts.map +0 -1
- package/autoscaling/system_status.js.map +0 -1
- package/configuration.d.ts.map +0 -1
- package/configuration.js.map +0 -1
- package/cookie_utils.d.ts.map +0 -1
- package/cookie_utils.js.map +0 -1
- package/crawlers/context_pipeline.d.ts.map +0 -1
- package/crawlers/context_pipeline.js.map +0 -1
- package/crawlers/crawler_commons.d.ts.map +0 -1
- package/crawlers/crawler_commons.js.map +0 -1
- package/crawlers/crawler_utils.d.ts +0 -10
- package/crawlers/crawler_utils.d.ts.map +0 -1
- package/crawlers/crawler_utils.js +0 -12
- package/crawlers/crawler_utils.js.map +0 -1
- package/crawlers/error_snapshotter.d.ts.map +0 -1
- package/crawlers/error_snapshotter.js.map +0 -1
- package/crawlers/error_tracker.d.ts.map +0 -1
- package/crawlers/error_tracker.js.map +0 -1
- package/crawlers/index.d.ts.map +0 -1
- package/crawlers/index.js.map +0 -1
- package/crawlers/internals/types.d.ts.map +0 -1
- package/crawlers/internals/types.js.map +0 -1
- package/crawlers/statistics.d.ts.map +0 -1
- package/crawlers/statistics.js.map +0 -1
- package/enqueue_links/enqueue_links.d.ts.map +0 -1
- package/enqueue_links/enqueue_links.js.map +0 -1
- package/enqueue_links/index.d.ts.map +0 -1
- package/enqueue_links/index.js.map +0 -1
- package/enqueue_links/shared.d.ts.map +0 -1
- package/enqueue_links/shared.js.map +0 -1
- package/errors.d.ts.map +0 -1
- package/errors.js.map +0 -1
- package/events/event_manager.d.ts.map +0 -1
- package/events/event_manager.js.map +0 -1
- package/events/index.d.ts.map +0 -1
- package/events/index.js.map +0 -1
- package/events/local_event_manager.d.ts.map +0 -1
- package/events/local_event_manager.js.map +0 -1
- package/http_clients/base-http-client.d.ts +0 -140
- package/http_clients/base-http-client.d.ts.map +0 -1
- package/http_clients/base-http-client.js +0 -40
- package/http_clients/base-http-client.js.map +0 -1
- package/http_clients/form-data-like.d.ts +0 -67
- package/http_clients/form-data-like.d.ts.map +0 -1
- package/http_clients/form-data-like.js +0 -5
- package/http_clients/form-data-like.js.map +0 -1
- package/http_clients/got-scraping-http-client.d.ts +0 -20
- package/http_clients/got-scraping-http-client.d.ts.map +0 -1
- package/http_clients/got-scraping-http-client.js +0 -82
- package/http_clients/got-scraping-http-client.js.map +0 -1
- package/http_clients/index.d.ts +0 -3
- package/http_clients/index.d.ts.map +0 -1
- package/http_clients/index.js +0 -3
- package/http_clients/index.js.map +0 -1
- package/index.d.ts.map +0 -1
- package/index.js.map +0 -1
- package/log.d.ts.map +0 -1
- package/log.js.map +0 -1
- package/proxy_configuration.d.ts.map +0 -1
- package/proxy_configuration.js.map +0 -1
- package/request.d.ts.map +0 -1
- package/request.js.map +0 -1
- package/router.d.ts.map +0 -1
- package/router.js.map +0 -1
- package/serialization.d.ts.map +0 -1
- package/serialization.js.map +0 -1
- package/session_pool/consts.d.ts.map +0 -1
- package/session_pool/consts.js.map +0 -1
- package/session_pool/errors.d.ts.map +0 -1
- package/session_pool/errors.js.map +0 -1
- package/session_pool/events.d.ts +0 -3
- package/session_pool/events.d.ts.map +0 -1
- package/session_pool/events.js +0 -3
- package/session_pool/events.js.map +0 -1
- package/session_pool/index.d.ts.map +0 -1
- package/session_pool/index.js.map +0 -1
- package/session_pool/session.d.ts.map +0 -1
- package/session_pool/session.js.map +0 -1
- package/session_pool/session_pool.d.ts.map +0 -1
- package/session_pool/session_pool.js.map +0 -1
- package/storages/access_checking.d.ts +0 -13
- package/storages/access_checking.d.ts.map +0 -1
- package/storages/access_checking.js +0 -14
- package/storages/access_checking.js.map +0 -1
- package/storages/dataset.d.ts.map +0 -1
- package/storages/dataset.js.map +0 -1
- package/storages/index.d.ts.map +0 -1
- package/storages/index.js.map +0 -1
- package/storages/key_value_store.d.ts.map +0 -1
- package/storages/key_value_store.js.map +0 -1
- package/storages/request_list.d.ts.map +0 -1
- package/storages/request_list.js.map +0 -1
- package/storages/request_provider.d.ts +0 -308
- package/storages/request_provider.d.ts.map +0 -1
- package/storages/request_provider.js +0 -555
- package/storages/request_provider.js.map +0 -1
- package/storages/request_queue.d.ts.map +0 -1
- package/storages/request_queue.js.map +0 -1
- package/storages/request_queue_v2.d.ts +0 -87
- package/storages/request_queue_v2.d.ts.map +0 -1
- package/storages/request_queue_v2.js +0 -438
- package/storages/request_queue_v2.js.map +0 -1
- package/storages/sitemap_request_list.d.ts.map +0 -1
- package/storages/sitemap_request_list.js +0 -430
- package/storages/sitemap_request_list.js.map +0 -1
- package/storages/storage_manager.d.ts +0 -58
- package/storages/storage_manager.d.ts.map +0 -1
- package/storages/storage_manager.js +0 -105
- package/storages/storage_manager.js.map +0 -1
- package/storages/utils.d.ts.map +0 -1
- package/storages/utils.js.map +0 -1
- package/tsconfig.build.tsbuildinfo +0 -1
- package/typedefs.d.ts.map +0 -1
- package/typedefs.js.map +0 -1
- package/validators.d.ts.map +0 -1
- package/validators.js.map +0 -1
package/request.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { BinaryLike } from 'node:crypto';
|
|
2
|
-
import type { Dictionary } from '@crawlee/types';
|
|
3
|
-
import type {
|
|
4
|
-
import type {
|
|
2
|
+
import type { AllowedHttpMethods, Dictionary } from '@crawlee/types';
|
|
3
|
+
import type { EnqueueStrategyOption } from './enqueue_links/enqueue_links.js';
|
|
4
|
+
import type { SkippedRequestReason } from './enqueue_links/shared.js';
|
|
5
5
|
export declare enum RequestState {
|
|
6
6
|
UNPROCESSED = 0,
|
|
7
7
|
BEFORE_NAV = 1,
|
|
@@ -44,6 +44,7 @@ export declare enum RequestState {
|
|
|
44
44
|
* @category Sources
|
|
45
45
|
*/
|
|
46
46
|
declare class CrawleeRequest<UserData extends Dictionary = Dictionary> {
|
|
47
|
+
#private;
|
|
47
48
|
/** Request ID */
|
|
48
49
|
id?: string;
|
|
49
50
|
/** URL of the web page to crawl. */
|
|
@@ -74,9 +75,12 @@ declare class CrawleeRequest<UserData extends Dictionary = Dictionary> {
|
|
|
74
75
|
errorMessages: string[];
|
|
75
76
|
/** Object with HTTP headers. Key is header name, value is the value. */
|
|
76
77
|
headers?: Record<string, string>;
|
|
77
|
-
/**
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Custom user data assigned to the request.
|
|
80
|
+
*
|
|
81
|
+
* All data stored in `userData` must be JSON-serializable.
|
|
82
|
+
* Storing non-serializable values (e.g. functions, symbols) may result in unexpected results.
|
|
83
|
+
*/
|
|
80
84
|
userData: UserData;
|
|
81
85
|
/**
|
|
82
86
|
* ISO datetime string that indicates the time when the request has been processed.
|
|
@@ -92,14 +96,35 @@ declare class CrawleeRequest<UserData extends Dictionary = Dictionary> {
|
|
|
92
96
|
* @returns The native `fetch` API Request object.
|
|
93
97
|
*/
|
|
94
98
|
intoFetchAPIRequest(): Request;
|
|
95
|
-
/**
|
|
99
|
+
/**
|
|
100
|
+
* Tells the crawler processing this request to skip the navigation and process the request directly.
|
|
101
|
+
*
|
|
102
|
+
* When this is set to `true`, the crawling context will not contain the results of the navigation
|
|
103
|
+
* (e.g. `response`, `body`, `contentType`, `$` or `request.loadedUrl`).
|
|
104
|
+
* Accessing these properties will throw a {@link NavigationSkippedError} at runtime.
|
|
105
|
+
*/
|
|
96
106
|
get skipNavigation(): boolean;
|
|
97
|
-
/**
|
|
107
|
+
/**
|
|
108
|
+
* Tells the crawler processing this request to skip the navigation and process the request directly.
|
|
109
|
+
*
|
|
110
|
+
* When this is set to `true`, the crawling context will not contain the results of the navigation
|
|
111
|
+
* (e.g. `response`, `body`, `contentType`, `$` or `request.loadedUrl`).
|
|
112
|
+
* Accessing these properties will throw a {@link NavigationSkippedError} at runtime.
|
|
113
|
+
*/
|
|
98
114
|
set skipNavigation(value: boolean);
|
|
99
|
-
/**
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
115
|
+
/**
|
|
116
|
+
* Depth of the request in the current crawl tree.
|
|
117
|
+
* Note that this is dependent on the crawler setup and might produce unexpected results when used with multiple crawlers.
|
|
118
|
+
*/
|
|
119
|
+
get crawlDepth(): number;
|
|
120
|
+
/**
|
|
121
|
+
* Depth of the request in the current crawl tree.
|
|
122
|
+
* Note that this is dependent on the crawler setup and might produce unexpected results when used with multiple crawlers.
|
|
123
|
+
*/
|
|
124
|
+
set crawlDepth(value: number);
|
|
125
|
+
/** ID of a session to use for this request. When set, the crawler will fetch this session from the session pool instead of creating a new one. */
|
|
126
|
+
get sessionId(): string | undefined;
|
|
127
|
+
set sessionId(value: string | undefined);
|
|
103
128
|
/** shortcut for getting `request.userData.label` */
|
|
104
129
|
get label(): string | undefined;
|
|
105
130
|
/** shortcut for setting `request.userData.label` */
|
|
@@ -112,6 +137,14 @@ declare class CrawleeRequest<UserData extends Dictionary = Dictionary> {
|
|
|
112
137
|
get state(): RequestState;
|
|
113
138
|
/** Describes the request's current lifecycle state. */
|
|
114
139
|
set state(value: RequestState);
|
|
140
|
+
/**
|
|
141
|
+
* Reason for skipping this request.
|
|
142
|
+
*/
|
|
143
|
+
get skippedReason(): SkippedRequestReason | undefined;
|
|
144
|
+
/**
|
|
145
|
+
* Reason for skipping this request.
|
|
146
|
+
*/
|
|
147
|
+
set skippedReason(value: SkippedRequestReason | undefined);
|
|
115
148
|
private get enqueueStrategy();
|
|
116
149
|
private set enqueueStrategy(value);
|
|
117
150
|
/**
|
|
@@ -129,7 +162,7 @@ declare class CrawleeRequest<UserData extends Dictionary = Dictionary> {
|
|
|
129
162
|
*/
|
|
130
163
|
pushErrorMessage(errorOrMessage: unknown, options?: PushErrorMessageOptions): void;
|
|
131
164
|
/** @internal */
|
|
132
|
-
static computeUniqueKey({ url, method, payload, keepUrlFragment, useExtendedUniqueKey, }: ComputeUniqueKeyOptions): string;
|
|
165
|
+
static computeUniqueKey({ url, method, payload, keepUrlFragment, useExtendedUniqueKey, alwaysEnqueue, }: ComputeUniqueKeyOptions): string;
|
|
133
166
|
/** @internal */
|
|
134
167
|
static hashPayload(payload: BinaryLike): string;
|
|
135
168
|
}
|
|
@@ -150,7 +183,7 @@ export interface RequestOptions<UserData extends Dictionary = Dictionary> {
|
|
|
150
183
|
* The `keepUrlFragment` option determines whether URL hash fragment is included in the `uniqueKey` or not.
|
|
151
184
|
*
|
|
152
185
|
* The `useExtendedUniqueKey` options determines whether method and payload are included in the `uniqueKey`,
|
|
153
|
-
* producing a `uniqueKey` in the following format: `METHOD
|
|
186
|
+
* producing a `uniqueKey` in the following format: `METHOD|payloadHash|normalizedUrl`. This is useful
|
|
154
187
|
* when requests point to the same URL, but with different methods and payloads. For example: form submits.
|
|
155
188
|
*
|
|
156
189
|
* Pass an arbitrary non-empty text value to the `uniqueKey` property
|
|
@@ -174,6 +207,9 @@ export interface RequestOptions<UserData extends Dictionary = Dictionary> {
|
|
|
174
207
|
/**
|
|
175
208
|
* Custom user data assigned to the request. Use this to save any request related data to the
|
|
176
209
|
* request's scope, keeping them accessible on retries, failures etc.
|
|
210
|
+
*
|
|
211
|
+
* All data stored in `userData` must be JSON-serializable.
|
|
212
|
+
* Storing non-serializable values (e.g. functions, symbols) may result in unexpected results.
|
|
177
213
|
*/
|
|
178
214
|
userData?: UserData;
|
|
179
215
|
/**
|
|
@@ -195,17 +231,45 @@ export interface RequestOptions<UserData extends Dictionary = Dictionary> {
|
|
|
195
231
|
* @default false
|
|
196
232
|
*/
|
|
197
233
|
useExtendedUniqueKey?: boolean;
|
|
234
|
+
/**
|
|
235
|
+
* If `true` then a random value is included in the `uniqueKey` computation, ensuring the request
|
|
236
|
+
* is always enqueued even if a request with the same URL (and method/payload) is already present
|
|
237
|
+
* in the queue. Cannot be used together with a custom `uniqueKey`.
|
|
238
|
+
* @default false
|
|
239
|
+
*/
|
|
240
|
+
alwaysEnqueue?: boolean;
|
|
198
241
|
/**
|
|
199
242
|
* The `true` value indicates that the request will not be automatically retried on error.
|
|
200
243
|
* @default false
|
|
201
244
|
*/
|
|
202
245
|
noRetry?: boolean;
|
|
246
|
+
/**
|
|
247
|
+
* ID of a session from the crawler's `SessionPool` to use for this request.
|
|
248
|
+
* When set, the crawler will fetch this session from the pool instead of creating a new one.
|
|
249
|
+
*/
|
|
250
|
+
sessionId?: string;
|
|
203
251
|
/**
|
|
204
252
|
* If set to `true` then the crawler processing this request evaluates
|
|
205
253
|
* the `requestHandler` immediately without prior browser navigation.
|
|
254
|
+
*
|
|
255
|
+
* When enabled, the crawling context will not contain the results of the navigation
|
|
256
|
+
* (e.g. `response`, `body`, `contentType`, `$` or `request.loadedUrl`).
|
|
257
|
+
* Accessing these properties will throw a {@link NavigationSkippedError} at runtime.
|
|
206
258
|
* @default false
|
|
207
259
|
*/
|
|
208
260
|
skipNavigation?: boolean;
|
|
261
|
+
/**
|
|
262
|
+
* Depth of the request in the current crawl tree.
|
|
263
|
+
* Note that this is dependent on the crawler setup and might produce unexpected results when used with multiple crawlers.
|
|
264
|
+
* @default 0
|
|
265
|
+
*/
|
|
266
|
+
crawlDepth?: number;
|
|
267
|
+
/**
|
|
268
|
+
* Reason for skipping this request.
|
|
269
|
+
* This is used to provide more information about why the request was skipped.
|
|
270
|
+
* @internal
|
|
271
|
+
*/
|
|
272
|
+
skippedReason?: SkippedRequestReason;
|
|
209
273
|
/**
|
|
210
274
|
* Maximum number of retries for this request. Allows to override the global `maxRequestRetries` option of `BasicCrawler`.
|
|
211
275
|
*/
|
|
@@ -217,7 +281,7 @@ export interface RequestOptions<UserData extends Dictionary = Dictionary> {
|
|
|
217
281
|
/** @internal */
|
|
218
282
|
lockExpiresAt?: Date;
|
|
219
283
|
/** @internal */
|
|
220
|
-
enqueueStrategy?:
|
|
284
|
+
enqueueStrategy?: EnqueueStrategyOption;
|
|
221
285
|
}
|
|
222
286
|
export interface PushErrorMessageOptions {
|
|
223
287
|
/**
|
|
@@ -232,6 +296,7 @@ interface ComputeUniqueKeyOptions {
|
|
|
232
296
|
payload?: string | Buffer;
|
|
233
297
|
keepUrlFragment?: boolean;
|
|
234
298
|
useExtendedUniqueKey?: boolean;
|
|
299
|
+
alwaysEnqueue?: boolean;
|
|
235
300
|
}
|
|
236
301
|
export type Source = (Partial<RequestOptions> & {
|
|
237
302
|
requestsFromUrl?: string;
|
|
@@ -243,4 +308,3 @@ export interface InternalSource {
|
|
|
243
308
|
regex?: RegExp;
|
|
244
309
|
}
|
|
245
310
|
export { CrawleeRequest as Request };
|
|
246
|
-
//# sourceMappingURL=request.d.ts.map
|
package/request.js
CHANGED
|
@@ -1,31 +1,13 @@
|
|
|
1
1
|
import crypto from 'node:crypto';
|
|
2
2
|
import util from 'node:util';
|
|
3
|
-
import
|
|
4
|
-
import { normalizeUrl } from '@apify/utilities';
|
|
5
|
-
import {
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { cryptoRandomObjectId, normalizeUrl } from '@apify/utilities';
|
|
5
|
+
import { serviceLocator } from './service_locator.js';
|
|
6
6
|
import { keys } from './typedefs.js';
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
loadedUrl: ow.optional.string.url,
|
|
12
|
-
uniqueKey: ow.optional.string,
|
|
13
|
-
method: ow.optional.string,
|
|
14
|
-
payload: ow.optional.any(ow.string, ow.uint8Array),
|
|
15
|
-
noRetry: ow.optional.boolean,
|
|
16
|
-
retryCount: ow.optional.number,
|
|
17
|
-
sessionRotationCount: ow.optional.number,
|
|
18
|
-
maxRetries: ow.optional.number,
|
|
19
|
-
errorMessages: ow.optional.array.ofType(ow.string),
|
|
20
|
-
headers: ow.optional.object,
|
|
21
|
-
userData: ow.optional.object,
|
|
22
|
-
label: ow.optional.string,
|
|
23
|
-
handledAt: ow.optional.any(ow.string.date, ow.date),
|
|
24
|
-
keepUrlFragment: ow.optional.boolean,
|
|
25
|
-
useExtendedUniqueKey: ow.optional.boolean,
|
|
26
|
-
skipNavigation: ow.optional.boolean,
|
|
27
|
-
state: ow.optional.number.greaterThanOrEqual(0).lessThanOrEqual(6),
|
|
28
|
-
};
|
|
7
|
+
import { parseArgument, schemas } from './validators.js';
|
|
8
|
+
const dateString = z.string().refine((value) => !Number.isNaN(Date.parse(value)), {
|
|
9
|
+
message: 'Invalid input: expected a date string',
|
|
10
|
+
});
|
|
29
11
|
export var RequestState;
|
|
30
12
|
(function (RequestState) {
|
|
31
13
|
RequestState[RequestState["UNPROCESSED"] = 0] = "UNPROCESSED";
|
|
@@ -37,6 +19,34 @@ export var RequestState;
|
|
|
37
19
|
RequestState[RequestState["ERROR"] = 6] = "ERROR";
|
|
38
20
|
RequestState[RequestState["SKIPPED"] = 7] = "SKIPPED";
|
|
39
21
|
})(RequestState || (RequestState = {}));
|
|
22
|
+
const requestUrlSchema = z.object({ url: z.string() });
|
|
23
|
+
// new properties on the Request object breaks serialization
|
|
24
|
+
const requestOptionalSchemaShapes = {
|
|
25
|
+
id: z.string().optional(),
|
|
26
|
+
loadedUrl: z.url().optional(),
|
|
27
|
+
uniqueKey: z.string().optional(),
|
|
28
|
+
method: z.string().optional(),
|
|
29
|
+
payload: z.union([z.string(), z.instanceof(Uint8Array)]).optional(),
|
|
30
|
+
noRetry: z.boolean().optional(),
|
|
31
|
+
retryCount: schemas.anyNumber.optional(),
|
|
32
|
+
sessionId: z.string().optional(),
|
|
33
|
+
maxRetries: schemas.anyNumber.optional(),
|
|
34
|
+
errorMessages: schemas.arrayOf(z.string(), 'strings').optional(),
|
|
35
|
+
headers: z.looseObject({}).optional(),
|
|
36
|
+
userData: z.looseObject({}).optional(),
|
|
37
|
+
label: z.string().optional(),
|
|
38
|
+
handledAt: z.union([dateString, z.date()]).optional(),
|
|
39
|
+
keepUrlFragment: z.boolean().optional(),
|
|
40
|
+
useExtendedUniqueKey: z.boolean().optional(),
|
|
41
|
+
alwaysEnqueue: z.boolean().optional(),
|
|
42
|
+
skipNavigation: z.boolean().optional(),
|
|
43
|
+
crawlDepth: schemas.anyNumber
|
|
44
|
+
.refine((value) => value >= 0, 'Expected a number greater than or equal to 0')
|
|
45
|
+
.optional(),
|
|
46
|
+
state: z.enum(RequestState).optional(),
|
|
47
|
+
};
|
|
48
|
+
// Each schema is wrapped in a single-key object so validation errors carry the property name.
|
|
49
|
+
const requestOptionalSchemas = Object.fromEntries(Object.entries(requestOptionalSchemaShapes).map(([key, schema]) => [key, z.object({ [key]: schema })]));
|
|
40
50
|
/**
|
|
41
51
|
* Represents a URL to be crawled, optionally including HTTP method, headers, payload and other metadata.
|
|
42
52
|
* The `Request` object also stores information about errors that occurred during processing of the request.
|
|
@@ -100,8 +110,13 @@ class CrawleeRequest {
|
|
|
100
110
|
/** Object with HTTP headers. Key is header name, value is the value. */
|
|
101
111
|
headers;
|
|
102
112
|
/** Private store for the custom user data assigned to the request. */
|
|
103
|
-
|
|
104
|
-
/**
|
|
113
|
+
#userData = {};
|
|
114
|
+
/**
|
|
115
|
+
* Custom user data assigned to the request.
|
|
116
|
+
*
|
|
117
|
+
* All data stored in `userData` must be JSON-serializable.
|
|
118
|
+
* Storing non-serializable values (e.g. functions, symbols) may result in unexpected results.
|
|
119
|
+
*/
|
|
105
120
|
userData = {};
|
|
106
121
|
/**
|
|
107
122
|
* ISO datetime string that indicates the time when the request has been processed.
|
|
@@ -112,76 +127,89 @@ class CrawleeRequest {
|
|
|
112
127
|
* `Request` parameters including the URL, HTTP method and headers, and others.
|
|
113
128
|
*/
|
|
114
129
|
constructor(options) {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
130
|
+
// A bare URL is a common slip — point at the object form instead of a generic type error.
|
|
131
|
+
if (typeof options === 'string') {
|
|
132
|
+
throw new TypeError(`\`Request\` options must be an object, got the string '${options}'. ` +
|
|
133
|
+
'Did you mean `new Request({ url })`?');
|
|
134
|
+
}
|
|
135
|
+
parseArgument(options, schemas.anyObject, 'RequestOptions');
|
|
136
|
+
parseArgument(options, requestUrlSchema, 'RequestOptions');
|
|
137
|
+
// Full-shape validation is slow, because it checks all predicates
|
|
118
138
|
// even if the validated object has only 1 property.
|
|
119
139
|
// This custom validation loop iterates only over existing
|
|
120
140
|
// properties and speeds up the validation cca 3-fold.
|
|
121
|
-
// See https://github.com/sindresorhus/ow/issues/193
|
|
122
141
|
keys(options).forEach((prop) => {
|
|
123
142
|
// skip url, because it is validated above
|
|
124
143
|
if (prop === 'url') {
|
|
125
144
|
return;
|
|
126
145
|
}
|
|
127
|
-
const
|
|
146
|
+
const schema = requestOptionalSchemas[prop];
|
|
128
147
|
const value = options[prop];
|
|
129
|
-
if (
|
|
130
|
-
|
|
148
|
+
if (schema) {
|
|
149
|
+
parseArgument({ [prop]: value }, schema, 'RequestOptions');
|
|
131
150
|
}
|
|
132
151
|
});
|
|
133
|
-
const { id, url, loadedUrl, uniqueKey, payload, noRetry = false, retryCount = 0,
|
|
152
|
+
const { id, url, loadedUrl, uniqueKey, payload, noRetry = false, retryCount = 0, sessionId, maxRetries, errorMessages = [], headers = {}, userData = {}, label, handledAt, keepUrlFragment = false, useExtendedUniqueKey = false, alwaysEnqueue = false, skipNavigation, enqueueStrategy, crawlDepth, } = options;
|
|
134
153
|
let { method = 'GET' } = options;
|
|
135
154
|
method = method.toUpperCase();
|
|
136
155
|
if (method === 'GET' && payload)
|
|
137
156
|
throw new Error('Request with GET method cannot have a payload.');
|
|
157
|
+
if (uniqueKey && alwaysEnqueue) {
|
|
158
|
+
throw new Error('`alwaysEnqueue` cannot be used together with a custom `uniqueKey`.');
|
|
159
|
+
}
|
|
138
160
|
this.id = id;
|
|
139
161
|
this.url = url;
|
|
140
162
|
this.loadedUrl = loadedUrl;
|
|
141
163
|
this.uniqueKey =
|
|
142
164
|
uniqueKey ||
|
|
143
|
-
CrawleeRequest.computeUniqueKey({
|
|
165
|
+
CrawleeRequest.computeUniqueKey({
|
|
166
|
+
url,
|
|
167
|
+
method,
|
|
168
|
+
payload,
|
|
169
|
+
keepUrlFragment,
|
|
170
|
+
useExtendedUniqueKey,
|
|
171
|
+
alwaysEnqueue,
|
|
172
|
+
});
|
|
144
173
|
this.method = method;
|
|
145
174
|
this.payload = payload;
|
|
146
175
|
this.noRetry = noRetry;
|
|
147
176
|
this.retryCount = retryCount;
|
|
148
|
-
this.sessionRotationCount = sessionRotationCount;
|
|
149
177
|
this.errorMessages = [...errorMessages];
|
|
150
178
|
this.headers = { ...headers };
|
|
151
179
|
this.handledAt = handledAt instanceof Date ? handledAt.toISOString() : handledAt;
|
|
152
180
|
if (label) {
|
|
153
181
|
userData.label = label;
|
|
154
182
|
}
|
|
183
|
+
// Read `__crawlee` explicitly - on a `userData` coming from another Request instance the
|
|
184
|
+
// bag is non-enumerable, so the spread alone would silently drop the internal state
|
|
185
|
+
// (e.g. `skipNavigation`) when a request is re-wrapped after a storage round trip.
|
|
186
|
+
this.#userData = { __crawlee: userData.__crawlee ?? {}, ...userData };
|
|
187
|
+
// `userData` must stay an enumerable own accessor — serialization in the storages relies on it
|
|
155
188
|
Object.defineProperties(this, {
|
|
156
|
-
_userData: {
|
|
157
|
-
value: { __crawlee: {}, ...userData },
|
|
158
|
-
enumerable: false,
|
|
159
|
-
writable: true,
|
|
160
|
-
},
|
|
161
189
|
userData: {
|
|
162
|
-
get: () => this
|
|
190
|
+
get: () => this.#userData,
|
|
163
191
|
set: (value) => {
|
|
164
192
|
Object.defineProperties(value, {
|
|
165
193
|
__crawlee: {
|
|
166
|
-
value: this.
|
|
194
|
+
value: this.#userData.__crawlee,
|
|
167
195
|
enumerable: false,
|
|
168
196
|
writable: true,
|
|
169
197
|
},
|
|
170
198
|
toJSON: {
|
|
171
199
|
value: () => {
|
|
172
|
-
if (Object.keys(this.
|
|
200
|
+
if (Object.keys(this.#userData.__crawlee).length > 0) {
|
|
173
201
|
return {
|
|
174
|
-
...this
|
|
175
|
-
__crawlee: this.
|
|
202
|
+
...this.#userData,
|
|
203
|
+
__crawlee: this.#userData.__crawlee,
|
|
176
204
|
};
|
|
177
205
|
}
|
|
178
|
-
return this
|
|
206
|
+
return this.#userData;
|
|
179
207
|
},
|
|
180
208
|
enumerable: false,
|
|
181
209
|
writable: true,
|
|
182
210
|
},
|
|
183
211
|
});
|
|
184
|
-
this
|
|
212
|
+
this.#userData = value;
|
|
185
213
|
},
|
|
186
214
|
enumerable: true,
|
|
187
215
|
},
|
|
@@ -192,6 +220,10 @@ class CrawleeRequest {
|
|
|
192
220
|
this.skipNavigation = skipNavigation;
|
|
193
221
|
if (maxRetries != null)
|
|
194
222
|
this.maxRetries = maxRetries;
|
|
223
|
+
if (crawlDepth != null)
|
|
224
|
+
this.userData.__crawlee.crawlDepth ??= crawlDepth;
|
|
225
|
+
if (sessionId)
|
|
226
|
+
this.sessionId = sessionId;
|
|
195
227
|
// If it's already set, don't override it (for instance when fetching from storage)
|
|
196
228
|
if (enqueueStrategy) {
|
|
197
229
|
this.enqueueStrategy ??= enqueueStrategy;
|
|
@@ -208,11 +240,23 @@ class CrawleeRequest {
|
|
|
208
240
|
body: this.payload,
|
|
209
241
|
});
|
|
210
242
|
}
|
|
211
|
-
/**
|
|
243
|
+
/**
|
|
244
|
+
* Tells the crawler processing this request to skip the navigation and process the request directly.
|
|
245
|
+
*
|
|
246
|
+
* When this is set to `true`, the crawling context will not contain the results of the navigation
|
|
247
|
+
* (e.g. `response`, `body`, `contentType`, `$` or `request.loadedUrl`).
|
|
248
|
+
* Accessing these properties will throw a {@link NavigationSkippedError} at runtime.
|
|
249
|
+
*/
|
|
212
250
|
get skipNavigation() {
|
|
213
251
|
return this.userData.__crawlee?.skipNavigation ?? false;
|
|
214
252
|
}
|
|
215
|
-
/**
|
|
253
|
+
/**
|
|
254
|
+
* Tells the crawler processing this request to skip the navigation and process the request directly.
|
|
255
|
+
*
|
|
256
|
+
* When this is set to `true`, the crawling context will not contain the results of the navigation
|
|
257
|
+
* (e.g. `response`, `body`, `contentType`, `$` or `request.loadedUrl`).
|
|
258
|
+
* Accessing these properties will throw a {@link NavigationSkippedError} at runtime.
|
|
259
|
+
*/
|
|
216
260
|
set skipNavigation(value) {
|
|
217
261
|
if (!this.userData.__crawlee) {
|
|
218
262
|
this.userData.__crawlee = { skipNavigation: value };
|
|
@@ -221,18 +265,28 @@ class CrawleeRequest {
|
|
|
221
265
|
this.userData.__crawlee.skipNavigation = value;
|
|
222
266
|
}
|
|
223
267
|
}
|
|
224
|
-
/**
|
|
225
|
-
|
|
226
|
-
|
|
268
|
+
/**
|
|
269
|
+
* Depth of the request in the current crawl tree.
|
|
270
|
+
* Note that this is dependent on the crawler setup and might produce unexpected results when used with multiple crawlers.
|
|
271
|
+
*/
|
|
272
|
+
get crawlDepth() {
|
|
273
|
+
return this.userData.__crawlee?.crawlDepth ?? 0;
|
|
227
274
|
}
|
|
228
|
-
/**
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
275
|
+
/**
|
|
276
|
+
* Depth of the request in the current crawl tree.
|
|
277
|
+
* Note that this is dependent on the crawler setup and might produce unexpected results when used with multiple crawlers.
|
|
278
|
+
*/
|
|
279
|
+
set crawlDepth(value) {
|
|
280
|
+
this.userData.__crawlee ??= {};
|
|
281
|
+
this.userData.__crawlee.crawlDepth = value;
|
|
282
|
+
}
|
|
283
|
+
/** ID of a session to use for this request. When set, the crawler will fetch this session from the session pool instead of creating a new one. */
|
|
284
|
+
get sessionId() {
|
|
285
|
+
return this.userData.__crawlee?.sessionId;
|
|
286
|
+
}
|
|
287
|
+
set sessionId(value) {
|
|
288
|
+
this.userData.__crawlee ??= {};
|
|
289
|
+
this.userData.__crawlee.sessionId = value;
|
|
236
290
|
}
|
|
237
291
|
/** shortcut for getting `request.userData.label` */
|
|
238
292
|
get label() {
|
|
@@ -268,6 +322,23 @@ class CrawleeRequest {
|
|
|
268
322
|
this.userData.__crawlee.state = value;
|
|
269
323
|
}
|
|
270
324
|
}
|
|
325
|
+
/**
|
|
326
|
+
* Reason for skipping this request.
|
|
327
|
+
*/
|
|
328
|
+
get skippedReason() {
|
|
329
|
+
return this.userData.__crawlee?.skippedReason;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Reason for skipping this request.
|
|
333
|
+
*/
|
|
334
|
+
set skippedReason(value) {
|
|
335
|
+
if (!this.userData.__crawlee) {
|
|
336
|
+
this.userData.__crawlee = { skippedReason: value };
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
this.userData.__crawlee.skippedReason = value;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
271
342
|
get enqueueStrategy() {
|
|
272
343
|
return this.userData.__crawlee?.enqueueStrategy;
|
|
273
344
|
}
|
|
@@ -330,19 +401,28 @@ class CrawleeRequest {
|
|
|
330
401
|
this.errorMessages.push(message);
|
|
331
402
|
}
|
|
332
403
|
/** @internal */
|
|
333
|
-
static computeUniqueKey({ url, method = 'GET', payload, keepUrlFragment = false, useExtendedUniqueKey = false, }) {
|
|
404
|
+
static computeUniqueKey({ url, method = 'GET', payload, keepUrlFragment = false, useExtendedUniqueKey = false, alwaysEnqueue = false, }) {
|
|
334
405
|
const normalizedMethod = method.toUpperCase();
|
|
335
406
|
const normalizedUrl = normalizeUrl(url, keepUrlFragment) || url; // It returns null when url is invalid, causing weird errors.
|
|
407
|
+
let uniqueKey;
|
|
336
408
|
if (!useExtendedUniqueKey) {
|
|
337
409
|
if (normalizedMethod !== 'GET' && payload) {
|
|
338
|
-
|
|
410
|
+
serviceLocator
|
|
411
|
+
.getLogger()
|
|
412
|
+
.warningOnce(`We've encountered a ${normalizedMethod} Request with a payload. ` +
|
|
339
413
|
'This is fine. Just letting you know that if your requests point to the same URL ' +
|
|
340
414
|
'and differ only in method and payload, you should see the "useExtendedUniqueKey" option of Request constructor.');
|
|
341
415
|
}
|
|
342
|
-
|
|
416
|
+
uniqueKey = normalizedUrl;
|
|
417
|
+
}
|
|
418
|
+
else {
|
|
419
|
+
const payloadHash = payload ? CrawleeRequest.hashPayload(payload) : '';
|
|
420
|
+
uniqueKey = `${normalizedMethod}|${payloadHash}|${normalizedUrl}`;
|
|
421
|
+
}
|
|
422
|
+
if (alwaysEnqueue) {
|
|
423
|
+
uniqueKey = `${cryptoRandomObjectId(17)}|${uniqueKey}`;
|
|
343
424
|
}
|
|
344
|
-
|
|
345
|
-
return `${normalizedMethod}(${payloadHash}):${normalizedUrl}`;
|
|
425
|
+
return uniqueKey;
|
|
346
426
|
}
|
|
347
427
|
/** @internal */
|
|
348
428
|
static hashPayload(payload) {
|
|
@@ -350,4 +430,3 @@ class CrawleeRequest {
|
|
|
350
430
|
}
|
|
351
431
|
}
|
|
352
432
|
export { CrawleeRequest as Request };
|
|
353
|
-
//# sourceMappingURL=request.js.map
|