@nitpicker/crawler 0.13.0 → 0.14.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/lib/archive/archive-accessor.d.ts +56 -0
- package/lib/archive/archive-accessor.js +72 -0
- package/lib/archive/archive.d.ts +11 -0
- package/lib/archive/archive.js +13 -0
- package/lib/archive/create-adjunct-tables.d.ts +7 -0
- package/lib/archive/create-adjunct-tables.js +150 -0
- package/lib/archive/create-entity-tables.d.ts +14 -0
- package/lib/archive/create-entity-tables.js +32 -1
- package/lib/archive/database.d.ts +55 -1
- package/lib/archive/database.js +81 -0
- package/lib/archive/db-ops/analysis/replace-page-templates.d.ts +20 -0
- package/lib/archive/db-ops/analysis/replace-page-templates.js +52 -0
- package/lib/archive/db-ops/config/info-column-allowlist.js +1 -0
- package/lib/archive/db-ops/lifecycle/init.d.ts +16 -10
- package/lib/archive/db-ops/lifecycle/init.js +20 -10
- package/lib/archive/db-ops/meta/get-audios-of-page.d.ts +11 -0
- package/lib/archive/db-ops/meta/get-audios-of-page.js +15 -0
- package/lib/archive/db-ops/meta/get-buttons-of-page.d.ts +11 -0
- package/lib/archive/db-ops/meta/get-buttons-of-page.js +15 -0
- package/lib/archive/db-ops/meta/get-canvases-of-page.d.ts +11 -0
- package/lib/archive/db-ops/meta/get-canvases-of-page.js +15 -0
- package/lib/archive/db-ops/meta/get-headings-of-page.d.ts +11 -0
- package/lib/archive/db-ops/meta/get-headings-of-page.js +15 -0
- package/lib/archive/db-ops/meta/get-iframes-of-page.d.ts +11 -0
- package/lib/archive/db-ops/meta/get-iframes-of-page.js +15 -0
- package/lib/archive/db-ops/meta/get-main-content-images-of-page.d.ts +11 -0
- package/lib/archive/db-ops/meta/get-main-content-images-of-page.js +15 -0
- package/lib/archive/db-ops/meta/get-main-content-tables-of-page.d.ts +11 -0
- package/lib/archive/db-ops/meta/get-main-content-tables-of-page.js +15 -0
- package/lib/archive/db-ops/meta/get-videos-of-page.d.ts +11 -0
- package/lib/archive/db-ops/meta/get-videos-of-page.js +15 -0
- package/lib/archive/db-ops/pages/read/build-page-query.js +1 -1
- package/lib/archive/db-ops/pages/reset/repromote-external-pages.js +19 -10
- package/lib/archive/db-ops/pages/reset/reset-failed-pages.d.ts +5 -3
- package/lib/archive/db-ops/pages/reset/reset-failed-pages.js +13 -3
- package/lib/archive/db-ops/pages/write/insert-audios.d.ts +14 -0
- package/lib/archive/db-ops/pages/write/insert-audios.js +25 -0
- package/lib/archive/db-ops/pages/write/insert-buttons.d.ts +14 -0
- package/lib/archive/db-ops/pages/write/insert-buttons.js +29 -0
- package/lib/archive/db-ops/pages/write/insert-canvases.d.ts +14 -0
- package/lib/archive/db-ops/pages/write/insert-canvases.js +26 -0
- package/lib/archive/db-ops/pages/write/insert-headings.d.ts +15 -0
- package/lib/archive/db-ops/pages/write/insert-headings.js +27 -0
- package/lib/archive/db-ops/pages/write/insert-iframes.d.ts +14 -0
- package/lib/archive/db-ops/pages/write/insert-iframes.js +28 -0
- package/lib/archive/db-ops/pages/write/insert-main-content-images.d.ts +20 -0
- package/lib/archive/db-ops/pages/write/insert-main-content-images.js +32 -0
- package/lib/archive/db-ops/pages/write/insert-main-content-tables.d.ts +14 -0
- package/lib/archive/db-ops/pages/write/insert-main-content-tables.js +29 -0
- package/lib/archive/db-ops/pages/write/insert-page.js +15 -2
- package/lib/archive/db-ops/pages/write/insert-videos.d.ts +14 -0
- package/lib/archive/db-ops/pages/write/insert-videos.js +28 -0
- package/lib/archive/db-ops/pages/write/update-page.js +21 -0
- package/lib/archive/init-schema.js +2 -1
- package/lib/archive/meta/compute-main-contents-denormalized.d.ts +22 -0
- package/lib/archive/meta/compute-main-contents-denormalized.js +63 -0
- package/lib/archive/meta/types.d.ts +263 -0
- package/lib/archive/migrate-info-main-content-selector.d.ts +11 -0
- package/lib/archive/migrate-info-main-content-selector.js +24 -0
- package/lib/archive/migrate-main-contents-columns.d.ts +21 -0
- package/lib/archive/migrate-main-contents-columns.js +50 -0
- package/lib/archive/page.d.ts +144 -2
- package/lib/archive/page.js +195 -0
- package/lib/archive/types.d.ts +39 -0
- package/lib/crawler/crawler.js +4 -2
- package/lib/crawler/fetch-destination.js +2 -0
- package/lib/crawler/link-to-page-data.js +2 -0
- package/lib/crawler/resource-to-page-data.js +2 -0
- package/lib/crawler/types.d.ts +5 -0
- package/lib/crawler-orchestrator.js +2 -0
- package/package.json +3 -3
package/lib/archive/page.js
CHANGED
|
@@ -60,6 +60,23 @@ const FLAT_META_COLUMNS = [
|
|
|
60
60
|
'tag_count',
|
|
61
61
|
'jsonld_count',
|
|
62
62
|
'tags_providers_csv',
|
|
63
|
+
'main_content_node_name',
|
|
64
|
+
'main_content_id',
|
|
65
|
+
'main_content_role',
|
|
66
|
+
'main_content_selector',
|
|
67
|
+
'main_content_class_list',
|
|
68
|
+
'main_content_word_count',
|
|
69
|
+
'main_content_body_word_count',
|
|
70
|
+
'main_content_heading_count',
|
|
71
|
+
'main_content_image_count',
|
|
72
|
+
'main_content_table_count',
|
|
73
|
+
'main_content_button_count',
|
|
74
|
+
'main_content_iframe_count',
|
|
75
|
+
'main_content_video_count',
|
|
76
|
+
'main_content_audio_count',
|
|
77
|
+
'main_content_canvas_count',
|
|
78
|
+
'scroll_height_desktop',
|
|
79
|
+
'scroll_height_mobile',
|
|
63
80
|
];
|
|
64
81
|
/**
|
|
65
82
|
* Represents a crawled page stored in the archive.
|
|
@@ -171,6 +188,104 @@ export default class Page {
|
|
|
171
188
|
get lastCrawledAt() {
|
|
172
189
|
return this.#raw.lastCrawledAt;
|
|
173
190
|
}
|
|
191
|
+
/**
|
|
192
|
+
* Detected main-content element's `nodeName` (e.g. `'MAIN'`), or null when
|
|
193
|
+
* no main region was found or the page was not fully rendered.
|
|
194
|
+
*/
|
|
195
|
+
get mainContentNodeName() {
|
|
196
|
+
return this.#raw.main_content_node_name;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Detected main-content element's `id`, or null.
|
|
200
|
+
*/
|
|
201
|
+
get mainContentId() {
|
|
202
|
+
return this.#raw.main_content_id;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Detected main-content element's `role` attribute, or null.
|
|
206
|
+
*/
|
|
207
|
+
get mainContentRole() {
|
|
208
|
+
return this.#raw.main_content_role;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Diagnostic tag+id+class selector for the detected main-content element, or null.
|
|
212
|
+
*/
|
|
213
|
+
get mainContentSelector() {
|
|
214
|
+
return this.#raw.main_content_selector;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Detected main-content element's CSS classes, or null when no main region
|
|
218
|
+
* was found. Parsed from the JSON-encoded `main_content_class_list` column.
|
|
219
|
+
*/
|
|
220
|
+
get mainContentClassList() {
|
|
221
|
+
if (this.#raw.main_content_class_list === null) {
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
224
|
+
return JSON.parse(this.#raw.main_content_class_list);
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Character count of the main region's text content (denormalised
|
|
228
|
+
* aggregate written at scrape time), or null.
|
|
229
|
+
*/
|
|
230
|
+
get mainContentWordCount() {
|
|
231
|
+
return this.#raw.main_content_word_count;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Character count of `document.body`'s text content (denormalised
|
|
235
|
+
* aggregate written at scrape time), or null.
|
|
236
|
+
*/
|
|
237
|
+
get mainContentBodyWordCount() {
|
|
238
|
+
return this.#raw.main_content_body_word_count;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Number of headings within the main region (denormalised aggregate), or null.
|
|
242
|
+
*/
|
|
243
|
+
get mainContentHeadingCount() {
|
|
244
|
+
return this.#raw.main_content_heading_count;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Number of images within the main region (denormalised aggregate), or null.
|
|
248
|
+
*/
|
|
249
|
+
get mainContentImageCount() {
|
|
250
|
+
return this.#raw.main_content_image_count;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Number of tables within the main region (denormalised aggregate), or null.
|
|
254
|
+
*/
|
|
255
|
+
get mainContentTableCount() {
|
|
256
|
+
return this.#raw.main_content_table_count;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Number of button-like elements within the main region (denormalised
|
|
260
|
+
* aggregate), or null.
|
|
261
|
+
*/
|
|
262
|
+
get mainContentButtonCount() {
|
|
263
|
+
return this.#raw.main_content_button_count;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Number of iframes within the main region (denormalised aggregate), or null.
|
|
267
|
+
*/
|
|
268
|
+
get mainContentIframeCount() {
|
|
269
|
+
return this.#raw.main_content_iframe_count;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Number of videos within the main region (denormalised aggregate), or null.
|
|
273
|
+
*/
|
|
274
|
+
get mainContentVideoCount() {
|
|
275
|
+
return this.#raw.main_content_video_count;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Number of audios within the main region (denormalised aggregate), or null.
|
|
279
|
+
*/
|
|
280
|
+
get mainContentAudioCount() {
|
|
281
|
+
return this.#raw.main_content_audio_count;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Number of canvases within the main region (denormalised aggregate), or null.
|
|
285
|
+
*/
|
|
286
|
+
get mainContentCanvasCount() {
|
|
287
|
+
return this.#raw.main_content_canvas_count;
|
|
288
|
+
}
|
|
174
289
|
/**
|
|
175
290
|
* Iterable view over every flat meta column (~47 fields). Returns a frozen
|
|
176
291
|
* record so consumers can pick fields by name without re-enumerating
|
|
@@ -280,6 +395,20 @@ export default class Page {
|
|
|
280
395
|
get robots_raw() {
|
|
281
396
|
return this.#raw.robots_raw;
|
|
282
397
|
}
|
|
398
|
+
/**
|
|
399
|
+
* `document.body.scrollHeight` at the desktop-compact preset (denormalised
|
|
400
|
+
* aggregate written at scrape time), or null.
|
|
401
|
+
*/
|
|
402
|
+
get scrollHeightDesktop() {
|
|
403
|
+
return this.#raw.scroll_height_desktop;
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* `document.body.scrollHeight` at the mobile-small preset (denormalised
|
|
407
|
+
* aggregate written at scrape time), or null.
|
|
408
|
+
*/
|
|
409
|
+
get scrollHeightMobile() {
|
|
410
|
+
return this.#raw.scroll_height_mobile;
|
|
411
|
+
}
|
|
283
412
|
/**
|
|
284
413
|
* The reason this page was skipped during crawling, or null if it was not skipped.
|
|
285
414
|
*/
|
|
@@ -376,6 +505,39 @@ export default class Page {
|
|
|
376
505
|
}
|
|
377
506
|
return this.#archive.getAnchorsOnPage(this.#raw.id);
|
|
378
507
|
}
|
|
508
|
+
/**
|
|
509
|
+
* Retrieves the audios within this page's detected main content region
|
|
510
|
+
* from `page_main_content_audios`. Lazy — runs a single SELECT per call.
|
|
511
|
+
* @returns Ordered audio rows.
|
|
512
|
+
*/
|
|
513
|
+
async getAudios() {
|
|
514
|
+
return this.#archive.getAudiosOfPage(this.#raw.id);
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* Retrieves the button-like elements within this page's detected main
|
|
518
|
+
* content region from `page_main_content_buttons`. Lazy — runs a single
|
|
519
|
+
* SELECT per call.
|
|
520
|
+
* @returns Ordered button rows.
|
|
521
|
+
*/
|
|
522
|
+
async getButtons() {
|
|
523
|
+
return this.#archive.getButtonsOfPage(this.#raw.id);
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Retrieves the canvases within this page's detected main content region
|
|
527
|
+
* from `page_main_content_canvases`. Lazy — runs a single SELECT per call.
|
|
528
|
+
* @returns Ordered canvas rows.
|
|
529
|
+
*/
|
|
530
|
+
async getCanvases() {
|
|
531
|
+
return this.#archive.getCanvasesOfPage(this.#raw.id);
|
|
532
|
+
}
|
|
533
|
+
/**
|
|
534
|
+
* Retrieves the headings within this page's detected main content region
|
|
535
|
+
* from `page_main_content_headings`. Lazy — runs a single SELECT per call.
|
|
536
|
+
* @returns Ordered heading rows.
|
|
537
|
+
*/
|
|
538
|
+
async getHeadings() {
|
|
539
|
+
return this.#archive.getHeadingsOfPage(this.#raw.id);
|
|
540
|
+
}
|
|
379
541
|
/**
|
|
380
542
|
* Thin wrapper that forwards this page's id to the accessor's
|
|
381
543
|
* BLOB-read path. Lets callers hold a `Page` reference and ask for its
|
|
@@ -391,6 +553,14 @@ export default class Page {
|
|
|
391
553
|
async getHtml() {
|
|
392
554
|
return this.#archive.getHtmlOfPage(this.#raw.id);
|
|
393
555
|
}
|
|
556
|
+
/**
|
|
557
|
+
* Retrieves the iframes within this page's detected main content region
|
|
558
|
+
* from `page_main_content_iframes`. Lazy — runs a single SELECT per call.
|
|
559
|
+
* @returns Ordered iframe rows.
|
|
560
|
+
*/
|
|
561
|
+
async getIframes() {
|
|
562
|
+
return this.#archive.getIframesOfPage(this.#raw.id);
|
|
563
|
+
}
|
|
394
564
|
/**
|
|
395
565
|
* Retrieves the JSON-LD entries for this page from `page_jsonld`.
|
|
396
566
|
* Lazy — runs a single SELECT per call. Returns entries in insertion
|
|
@@ -400,6 +570,23 @@ export default class Page {
|
|
|
400
570
|
async getJsonLd() {
|
|
401
571
|
return this.#archive.getJsonLdOfPage(this.#raw.id);
|
|
402
572
|
}
|
|
573
|
+
/**
|
|
574
|
+
* Retrieves the images within this page's detected main content region
|
|
575
|
+
* from `page_main_content_images`. Lazy — runs a single SELECT per call.
|
|
576
|
+
* Distinct from the whole-page image scan (`image_items`).
|
|
577
|
+
* @returns Ordered image rows.
|
|
578
|
+
*/
|
|
579
|
+
async getMainContentImages() {
|
|
580
|
+
return this.#archive.getMainContentImagesOfPage(this.#raw.id);
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* Retrieves the tables within this page's detected main content region
|
|
584
|
+
* from `page_main_content_tables`. Lazy — runs a single SELECT per call.
|
|
585
|
+
* @returns Ordered table rows.
|
|
586
|
+
*/
|
|
587
|
+
async getMainContentTables() {
|
|
588
|
+
return this.#archive.getMainContentTablesOfPage(this.#raw.id);
|
|
589
|
+
}
|
|
403
590
|
/**
|
|
404
591
|
* Retrieves the referrers (incoming links) pointing to this page.
|
|
405
592
|
* Uses pre-loaded data if available, otherwise queries the database.
|
|
@@ -447,6 +634,14 @@ export default class Page {
|
|
|
447
634
|
async getTags() {
|
|
448
635
|
return this.#archive.getTagsOfPage(this.#raw.id);
|
|
449
636
|
}
|
|
637
|
+
/**
|
|
638
|
+
* Retrieves the videos within this page's detected main content region
|
|
639
|
+
* from `page_main_content_videos`. Lazy — runs a single SELECT per call.
|
|
640
|
+
* @returns Ordered video rows.
|
|
641
|
+
*/
|
|
642
|
+
async getVideos() {
|
|
643
|
+
return this.#archive.getVideosOfPage(this.#raw.id);
|
|
644
|
+
}
|
|
450
645
|
/**
|
|
451
646
|
* Checks whether this page is an internal HTML page (not external and has `text/html` content type).
|
|
452
647
|
* @returns `true` if this is an internal HTML page, `false` otherwise.
|
package/lib/archive/types.d.ts
CHANGED
|
@@ -67,6 +67,11 @@ export interface Config extends Required<Pick<ParseURLOptions, 'disableQueries'>
|
|
|
67
67
|
userAgent: string;
|
|
68
68
|
/** Whether robots.txt restrictions were ignored during crawling. */
|
|
69
69
|
ignoreRobots: boolean;
|
|
70
|
+
/**
|
|
71
|
+
* CSS selector overriding beholder's automatic main-content-region
|
|
72
|
+
* detection, or `null`/omitted to use the automatic heuristic.
|
|
73
|
+
*/
|
|
74
|
+
mainContentSelector?: string | null;
|
|
70
75
|
}
|
|
71
76
|
/**
|
|
72
77
|
* Provenance of a page or resource row — which crawler channel originally
|
|
@@ -292,6 +297,40 @@ export interface DB_Page {
|
|
|
292
297
|
jsonld_count: number | null;
|
|
293
298
|
/** Sorted unique provider names, comma-separated (empty string when none). */
|
|
294
299
|
tags_providers_csv: string | null;
|
|
300
|
+
/** Detected main-content element's `nodeName` (e.g. `'MAIN'`), or null. */
|
|
301
|
+
main_content_node_name: string | null;
|
|
302
|
+
/** Detected main-content element's `id`, or null. */
|
|
303
|
+
main_content_id: string | null;
|
|
304
|
+
/** Detected main-content element's `role` attribute, or null. */
|
|
305
|
+
main_content_role: string | null;
|
|
306
|
+
/** Diagnostic tag+id+class selector for the detected element, or null. */
|
|
307
|
+
main_content_selector: string | null;
|
|
308
|
+
/** JSON-encoded array of the detected element's CSS classes, or null. */
|
|
309
|
+
main_content_class_list: string | null;
|
|
310
|
+
/** Character count of the main region's text content, or null. */
|
|
311
|
+
main_content_word_count: number | null;
|
|
312
|
+
/** Character count of `document.body`'s text content, or null. */
|
|
313
|
+
main_content_body_word_count: number | null;
|
|
314
|
+
/** Number of headings within the main region, or null. */
|
|
315
|
+
main_content_heading_count: number | null;
|
|
316
|
+
/** Number of images within the main region, or null. */
|
|
317
|
+
main_content_image_count: number | null;
|
|
318
|
+
/** Number of tables within the main region, or null. */
|
|
319
|
+
main_content_table_count: number | null;
|
|
320
|
+
/** Number of button-like elements within the main region, or null. */
|
|
321
|
+
main_content_button_count: number | null;
|
|
322
|
+
/** Number of iframes within the main region, or null. */
|
|
323
|
+
main_content_iframe_count: number | null;
|
|
324
|
+
/** Number of videos within the main region, or null. */
|
|
325
|
+
main_content_video_count: number | null;
|
|
326
|
+
/** Number of audios within the main region, or null. */
|
|
327
|
+
main_content_audio_count: number | null;
|
|
328
|
+
/** Number of canvases within the main region, or null. */
|
|
329
|
+
main_content_canvas_count: number | null;
|
|
330
|
+
/** `document.body.scrollHeight` at the desktop-compact preset, or null. */
|
|
331
|
+
scroll_height_desktop: number | null;
|
|
332
|
+
/** `document.body.scrollHeight` at the mobile-small preset, or null. */
|
|
333
|
+
scroll_height_mobile: number | null;
|
|
295
334
|
/** JSON-serialised nested Meta sub-objects not flattened above. */
|
|
296
335
|
meta_extras: string | null;
|
|
297
336
|
/** JSON-serialized network logs captured during scraping, or null if not collected. */
|
package/lib/crawler/crawler.js
CHANGED
|
@@ -149,6 +149,7 @@ class Crawler extends EventEmitter {
|
|
|
149
149
|
verbose: options?.verbose ?? false,
|
|
150
150
|
userAgent: options?.userAgent || `Nitpicker/${pkg.version}`,
|
|
151
151
|
ignoreRobots: options?.ignoreRobots ?? false,
|
|
152
|
+
mainContentSelector: options?.mainContentSelector ?? null,
|
|
152
153
|
lookupResource: options?.lookupResource ?? null,
|
|
153
154
|
lookupPageSource: options?.lookupPageSource ?? null,
|
|
154
155
|
inventoryMode: options?.inventoryMode ?? null,
|
|
@@ -1355,8 +1356,8 @@ class Crawler extends EventEmitter {
|
|
|
1355
1356
|
// sub-resource requests issued from the same page —
|
|
1356
1357
|
// including cross-origin requests to a different hostname
|
|
1357
1358
|
// sharing the same IP / port (e.g. an embedded
|
|
1358
|
-
// `<img src="http://127.0.0.1:
|
|
1359
|
-
// `localhost:
|
|
1359
|
+
// `<img src="http://127.0.0.1:PORT/…">` loaded from a
|
|
1360
|
+
// `localhost:PORT` page) — get the cached `Authorization`
|
|
1360
1361
|
// header re-attached by the network stack. The
|
|
1361
1362
|
// `Fetch.authRequired` event never fires for these
|
|
1362
1363
|
// pre-emptive attachments, so neither `page.authenticate`
|
|
@@ -1399,6 +1400,7 @@ class Crawler extends EventEmitter {
|
|
|
1399
1400
|
metadataOnly,
|
|
1400
1401
|
retries: this.#options.retry,
|
|
1401
1402
|
headCheckResult,
|
|
1403
|
+
mainContentSelector: this.#options.mainContentSelector,
|
|
1402
1404
|
});
|
|
1403
1405
|
// Image dom-path capture runs here — after the scrape completed but
|
|
1404
1406
|
// while `page` is still alive — because beholder's image metadata
|
package/lib/crawler/types.d.ts
CHANGED
|
@@ -129,6 +129,11 @@ export interface CrawlerOptions extends Required<Pick<ParseURLOptions, 'disableQ
|
|
|
129
129
|
userAgent: string;
|
|
130
130
|
/** Whether to ignore robots.txt restrictions. */
|
|
131
131
|
ignoreRobots: boolean;
|
|
132
|
+
/**
|
|
133
|
+
* CSS selector overriding beholder's automatic main-content-region
|
|
134
|
+
* detection, or `null`/undefined to use the automatic heuristic.
|
|
135
|
+
*/
|
|
136
|
+
mainContentSelector?: string | null;
|
|
132
137
|
/**
|
|
133
138
|
* Lookup for previously captured sub-resources, or `null` to disable the
|
|
134
139
|
* resource-reuse optimization. See {@link ResourceLookup}.
|
|
@@ -109,6 +109,7 @@ export class CrawlerOrchestrator extends EventEmitter {
|
|
|
109
109
|
verbose: options?.verbose ?? false,
|
|
110
110
|
userAgent: options?.userAgent || defaultUserAgent,
|
|
111
111
|
ignoreRobots: options?.ignoreRobots ?? false,
|
|
112
|
+
mainContentSelector: options?.mainContentSelector ?? null,
|
|
112
113
|
// Let the crawler reuse sub-resource data captured during page
|
|
113
114
|
// rendering instead of issuing a redundant HEAD pre-flight.
|
|
114
115
|
lookupResource: async (urls) => {
|
|
@@ -337,6 +338,7 @@ export class CrawlerOrchestrator extends EventEmitter {
|
|
|
337
338
|
disableQueries,
|
|
338
339
|
userAgent: options?.userAgent || defaultUserAgent,
|
|
339
340
|
ignoreRobots: options?.ignoreRobots ?? false,
|
|
341
|
+
mainContentSelector: options?.mainContentSelector ?? null,
|
|
340
342
|
});
|
|
341
343
|
const orchestrator = new CrawlerOrchestrator(archive, {
|
|
342
344
|
...options,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nitpicker/crawler",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "Web crawler engine with headless browser rendering and archive storage",
|
|
5
5
|
"author": "D-ZERO",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"clean": "tsc --build --clean"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@d-zero/beholder": "
|
|
30
|
+
"@d-zero/beholder": "4.0.0",
|
|
31
31
|
"@d-zero/dealer": "1.9.4",
|
|
32
32
|
"@d-zero/fs": "0.2.6",
|
|
33
33
|
"@d-zero/shared": "0.22.2",
|
|
@@ -48,5 +48,5 @@
|
|
|
48
48
|
"@types/tar": "7.0.87",
|
|
49
49
|
"@types/unzipper": "0.10.11"
|
|
50
50
|
},
|
|
51
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "98222c2bbce55ab6d253787a251f040b51c7a9a0"
|
|
52
52
|
}
|