@crawlee/jsdom 4.0.0-beta.122 → 4.0.0-beta.124
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/jsdom-crawler.d.ts +10 -25
- package/internals/jsdom-crawler.js +21 -46
- package/package.json +5 -5
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AddRequestsBatchedResult, CrawlingContext, EnqueueLinksOptions, ErrorHandler, ExtractLinksOptions, GetUserDataFromRequest, HttpCrawlerOptions, InternalHttpCrawlingContext, InternalHttpHook, RequestHandler, RouterHandler, RouterRoutes, RouteSchemas, RoutesFromSchemas } from '@crawlee/http';
|
|
2
2
|
import { HttpCrawler } from '@crawlee/http';
|
|
3
|
-
import type {
|
|
3
|
+
import type { Dictionary } from '@crawlee/types';
|
|
4
4
|
import { type CheerioRoot } from '@crawlee/utils/internal';
|
|
5
|
-
import { type RobotsTxtFile } from '@crawlee/utils';
|
|
6
5
|
import type { DOMWindow } from 'jsdom';
|
|
7
6
|
import { VirtualConsole } from 'jsdom';
|
|
8
7
|
import { z } from 'zod';
|
|
@@ -56,9 +55,13 @@ JSONData extends Dictionary = any> extends InternalHttpCrawlingContext<UserData,
|
|
|
56
55
|
*/
|
|
57
56
|
parseWithCheerio(selector?: string, timeoutMs?: number): Promise<CheerioRoot>;
|
|
58
57
|
/**
|
|
59
|
-
*
|
|
58
|
+
* Extracts URLs from the parsed DOM, without adding them to the request queue.
|
|
60
59
|
*/
|
|
61
|
-
|
|
60
|
+
extractLinks(options?: ExtractLinksOptions): Promise<string[]>;
|
|
61
|
+
/**
|
|
62
|
+
* Helper function for extracting URLs from the parsed DOM and adding them to the request queue.
|
|
63
|
+
*/
|
|
64
|
+
enqueueLinks(options?: EnqueueLinksOptions): Promise<AddRequestsBatchedResult>;
|
|
62
65
|
}
|
|
63
66
|
export type JSDOMRequestHandler<UserData extends Dictionary = any, // with default to Dictionary we cant use a typed router in untyped crawler
|
|
64
67
|
JSONData extends Dictionary = any> = RequestHandler<JSDOMCrawlingContext<UserData, JSONData>>;
|
|
@@ -185,7 +188,8 @@ export declare class JSDOMCrawler<ContextExtension = Dictionary<never>, Extended
|
|
|
185
188
|
readonly body: string;
|
|
186
189
|
readonly document: Document;
|
|
187
190
|
} & {
|
|
188
|
-
|
|
191
|
+
extractLinks: (options?: ExtractLinksOptions) => Promise<string[]>;
|
|
192
|
+
enqueueLinks: (options?: EnqueueLinksOptions) => Promise<AddRequestsBatchedResult>;
|
|
189
193
|
waitForSelector(selector: string, timeoutMs?: number): Promise<void>;
|
|
190
194
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
191
195
|
parseWithCheerio(selector?: string, _timeoutMs?: number): Promise<import("cheerio").CheerioAPI>;
|
|
@@ -209,24 +213,6 @@ export declare class JSDOMCrawler<ContextExtension = Dictionary<never>, Extended
|
|
|
209
213
|
private parseContent;
|
|
210
214
|
private addHelpers;
|
|
211
215
|
}
|
|
212
|
-
interface EnqueueLinksInternalOptions {
|
|
213
|
-
options?: EnqueueLinksOptions;
|
|
214
|
-
window: DOMWindow | null;
|
|
215
|
-
requestManager: IRequestManager;
|
|
216
|
-
robotsTxtFile?: RobotsTxtFile;
|
|
217
|
-
onSkippedRequest?: SkippedRequestCallback;
|
|
218
|
-
originalRequestUrl: string;
|
|
219
|
-
finalRequestUrl?: string;
|
|
220
|
-
}
|
|
221
|
-
interface BoundEnqueueLinksInternalOptions {
|
|
222
|
-
enqueueLinks: BasicCrawlingContext['enqueueLinks'];
|
|
223
|
-
options?: EnqueueLinksOptions;
|
|
224
|
-
window: DOMWindow | null;
|
|
225
|
-
originalRequestUrl: string;
|
|
226
|
-
finalRequestUrl?: string;
|
|
227
|
-
}
|
|
228
|
-
/** @internal */
|
|
229
|
-
export declare function domCrawlerEnqueueLinks(options: EnqueueLinksInternalOptions | BoundEnqueueLinksInternalOptions): Promise<unknown>;
|
|
230
216
|
/**
|
|
231
217
|
* Creates new {@link Router} instance that works based on request labels.
|
|
232
218
|
* This instance can then serve as a `requestHandler` of your {@link JSDOMCrawler}.
|
|
@@ -254,4 +240,3 @@ export declare function domCrawlerEnqueueLinks(options: EnqueueLinksInternalOpti
|
|
|
254
240
|
export declare function createJSDOMRouter<Context extends JSDOMCrawlingContext = JSDOMCrawlingContext, Routes extends Record<keyof Routes, Dictionary> = Record<string, GetUserDataFromRequest<Context['request']>>>(routes?: RouterRoutes<Context, Routes>): RouterHandler<Context, Routes>;
|
|
255
241
|
export declare function createJSDOMRouter<Context extends JSDOMCrawlingContext = JSDOMCrawlingContext, UserData extends Dictionary = GetUserDataFromRequest<Context['request']>>(routes?: RouterRoutes<Context, Record<string, UserData>>): RouterHandler<Context, Record<string, UserData>>;
|
|
256
242
|
export declare function createJSDOMRouter<Context extends JSDOMCrawlingContext = JSDOMCrawlingContext, const Schemas extends RouteSchemas = RouteSchemas>(schemas: Schemas): RouterHandler<Context, RoutesFromSchemas<Schemas>>;
|
|
257
|
-
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EnqueueStrategy, HttpCrawler, NavigationSkippedError, parseArgument, resolveBaseUrlForEnqueueLinksFiltering, Router, tryAbsoluteURL, } from '@crawlee/http';
|
|
2
2
|
import { sleep } from '@crawlee/utils';
|
|
3
3
|
import { JSDOM, ResourceLoader, VirtualConsole } from 'jsdom';
|
|
4
4
|
import { z } from 'zod';
|
|
@@ -214,20 +214,28 @@ export class JSDOMCrawler extends HttpCrawler {
|
|
|
214
214
|
}
|
|
215
215
|
}
|
|
216
216
|
async addHelpers(crawlingContext) {
|
|
217
|
+
const addRequests = crawlingContext.addRequests;
|
|
218
|
+
const extractLinks = async (options) => {
|
|
219
|
+
if (!crawlingContext.window) {
|
|
220
|
+
throw new Error('Cannot extract links because the JSDOM is not available.');
|
|
221
|
+
}
|
|
222
|
+
return extractUrlsFromWindow(crawlingContext.window, options?.selector ?? 'a', options?.baseUrl ?? crawlingContext.request.loadedUrl ?? crawlingContext.request.url);
|
|
223
|
+
};
|
|
217
224
|
return {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
limit: await this.calculateEnqueuedRequestLimit(enqueueOptions?.limit),
|
|
223
|
-
},
|
|
224
|
-
window: crawlingContext.window,
|
|
225
|
-
requestManager: await this.getRequestManager(),
|
|
226
|
-
robotsTxtFile: await this.getRobotsTxtFileForUrl(crawlingContext.request.url),
|
|
227
|
-
onSkippedRequest: this.handleSkippedRequest,
|
|
228
|
-
originalRequestUrl: crawlingContext.request.url,
|
|
225
|
+
extractLinks,
|
|
226
|
+
enqueueLinks: async (options = {}) => {
|
|
227
|
+
const baseUrl = resolveBaseUrlForEnqueueLinksFiltering({
|
|
228
|
+
enqueueStrategy: options.strategy,
|
|
229
229
|
finalRequestUrl: crawlingContext.request.loadedUrl,
|
|
230
|
-
|
|
230
|
+
originalRequestUrl: crawlingContext.request.url,
|
|
231
|
+
userProvidedBaseUrl: options.baseUrl,
|
|
232
|
+
});
|
|
233
|
+
const urls = await extractLinks(options);
|
|
234
|
+
return addRequests(urls, {
|
|
235
|
+
...options,
|
|
236
|
+
baseUrl,
|
|
237
|
+
strategy: options.strategy ?? EnqueueStrategy.SameHostname,
|
|
238
|
+
});
|
|
231
239
|
},
|
|
232
240
|
async waitForSelector(selector, timeoutMs = 5_000) {
|
|
233
241
|
const cheerio = await import('cheerio');
|
|
@@ -252,39 +260,6 @@ export class JSDOMCrawler extends HttpCrawler {
|
|
|
252
260
|
};
|
|
253
261
|
}
|
|
254
262
|
}
|
|
255
|
-
/** @internal */
|
|
256
|
-
function containsEnqueueLinks(options) {
|
|
257
|
-
return !!options.enqueueLinks;
|
|
258
|
-
}
|
|
259
|
-
/** @internal */
|
|
260
|
-
export async function domCrawlerEnqueueLinks(options) {
|
|
261
|
-
const { options: enqueueLinksOptions, window, originalRequestUrl, finalRequestUrl } = options;
|
|
262
|
-
if (!window) {
|
|
263
|
-
throw new Error('Cannot enqueue links because the JSDOM is not available.');
|
|
264
|
-
}
|
|
265
|
-
const baseUrl = resolveBaseUrlForEnqueueLinksFiltering({
|
|
266
|
-
enqueueStrategy: enqueueLinksOptions?.strategy,
|
|
267
|
-
finalRequestUrl,
|
|
268
|
-
originalRequestUrl,
|
|
269
|
-
userProvidedBaseUrl: enqueueLinksOptions?.baseUrl,
|
|
270
|
-
});
|
|
271
|
-
const urls = extractUrlsFromWindow(window, enqueueLinksOptions?.selector ?? 'a', enqueueLinksOptions?.baseUrl ?? finalRequestUrl ?? originalRequestUrl);
|
|
272
|
-
if (containsEnqueueLinks(options)) {
|
|
273
|
-
return options.enqueueLinks({
|
|
274
|
-
urls,
|
|
275
|
-
baseUrl,
|
|
276
|
-
...enqueueLinksOptions,
|
|
277
|
-
});
|
|
278
|
-
}
|
|
279
|
-
return enqueueLinks({
|
|
280
|
-
requestManager: options.requestManager,
|
|
281
|
-
robotsTxtFile: options.robotsTxtFile,
|
|
282
|
-
onSkippedRequest: options.onSkippedRequest,
|
|
283
|
-
urls,
|
|
284
|
-
baseUrl,
|
|
285
|
-
...enqueueLinksOptions,
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
263
|
/**
|
|
289
264
|
* Extracts URLs from a given Window object.
|
|
290
265
|
* @ignore
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crawlee/jsdom",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.124",
|
|
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"
|
|
@@ -49,9 +49,9 @@
|
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"@apify/timeout": "^0.4.4",
|
|
51
51
|
"@apify/utilities": "^2.7.10",
|
|
52
|
-
"@crawlee/http": "4.0.0-beta.
|
|
53
|
-
"@crawlee/types": "4.0.0-beta.
|
|
54
|
-
"@crawlee/utils": "4.0.0-beta.
|
|
52
|
+
"@crawlee/http": "4.0.0-beta.124",
|
|
53
|
+
"@crawlee/types": "4.0.0-beta.124",
|
|
54
|
+
"@crawlee/utils": "4.0.0-beta.124",
|
|
55
55
|
"@types/jsdom": "^21.1.7",
|
|
56
56
|
"cheerio": "^1.0.0",
|
|
57
57
|
"jsdom": "^26.1.0",
|
|
@@ -65,5 +65,5 @@
|
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
},
|
|
68
|
-
"gitHead": "
|
|
68
|
+
"gitHead": "0694ee1b94c755b98141671baa93cc363f2bf8e3"
|
|
69
69
|
}
|