@toolpath/tool-scraper 0.1.0 → 2.0.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/README.md +41 -11
- package/dist/columns.d.ts +62 -0
- package/dist/columns.js +62 -0
- package/dist/conventions.d.ts +89 -15
- package/dist/conventions.js +108 -15
- package/dist/families/emuge.d.ts +183 -0
- package/dist/families/emuge.js +159 -0
- package/dist/families/harvey.d.ts +1782 -0
- package/dist/families/harvey.js +1328 -0
- package/dist/families/index.js +5 -2
- package/dist/families/kennametal.d.ts +21 -0
- package/dist/families/kennametal.js +10 -0
- package/dist/families/maritool.d.ts +120 -0
- package/dist/families/maritool.js +175 -0
- package/dist/family.d.ts +35 -1
- package/dist/family.js +28 -0
- package/dist/identity.d.ts +18 -0
- package/dist/identity.js +46 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +16 -0
- package/dist/measure.d.ts +112 -0
- package/dist/measure.js +130 -0
- package/dist/node/cli.d.ts +3 -0
- package/dist/node/cli.js +152 -2
- package/dist/node/main.js +0 -0
- package/dist/records.d.ts +169 -12
- package/dist/records.js +116 -5
- package/dist/registry.d.ts +31 -1
- package/dist/registry.js +40 -1
- package/dist/scrape.d.ts +15 -0
- package/dist/scrape.js +24 -0
- package/dist/vendors/destinytool/records.d.ts +13 -3
- package/dist/vendors/destinytool/records.js +41 -37
- package/dist/vendors/emuge/index.d.ts +17 -0
- package/dist/vendors/emuge/index.js +17 -0
- package/dist/vendors/emuge/records.d.ts +150 -0
- package/dist/vendors/emuge/records.js +375 -0
- package/dist/vendors/emuge/scrape.d.ts +227 -0
- package/dist/vendors/emuge/scrape.js +358 -0
- package/dist/vendors/emuge/value.d.ts +75 -0
- package/dist/vendors/emuge/value.js +116 -0
- package/dist/vendors/harvey/catalog.d.ts +53 -0
- package/dist/vendors/harvey/catalog.js +120 -0
- package/dist/vendors/harvey/header.d.ts +89 -0
- package/dist/vendors/harvey/header.js +185 -0
- package/dist/vendors/harvey/index.d.ts +21 -0
- package/dist/vendors/harvey/index.js +21 -0
- package/dist/vendors/harvey/lexicon.d.ts +73 -0
- package/dist/vendors/harvey/lexicon.js +126 -0
- package/dist/vendors/harvey/literal.d.ts +68 -0
- package/dist/vendors/harvey/literal.js +214 -0
- package/dist/vendors/harvey/records.d.ts +79 -0
- package/dist/vendors/harvey/records.js +163 -0
- package/dist/vendors/harvey/scrape.d.ts +187 -0
- package/dist/vendors/harvey/scrape.js +483 -0
- package/dist/vendors/harvey/value.d.ts +74 -0
- package/dist/vendors/harvey/value.js +119 -0
- package/dist/vendors/kennametal/records.d.ts +13 -4
- package/dist/vendors/kennametal/records.js +61 -26
- package/dist/vendors/maritool/catalog.d.ts +81 -0
- package/dist/vendors/maritool/catalog.js +132 -0
- package/dist/vendors/maritool/index.d.ts +10 -0
- package/dist/vendors/maritool/index.js +10 -0
- package/dist/vendors/maritool/scrape.d.ts +297 -0
- package/dist/vendors/maritool/scrape.js +593 -0
- package/dist/vendors/regofix/scrape.d.ts +8 -11
- package/dist/vendors/regofix/scrape.js +21 -36
- package/package.json +31 -7
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MariTool category listings -> toolholding rows.
|
|
3
|
+
*
|
|
4
|
+
* The fifth vendor and the first whose transport needed no discovery at all:
|
|
5
|
+
* `www.maritool.com` is an osCommerce-family storefront that server-renders
|
|
6
|
+
* everything, so the whole transport is a paced `GET`. There is no JSON API,
|
|
7
|
+
* no sitemap and no application bundle to read — see
|
|
8
|
+
* `docs/MARITOOL_CATALOG.md` for what was tried and what the tree looks like.
|
|
9
|
+
*
|
|
10
|
+
* ## Two sources, and both are needed
|
|
11
|
+
*
|
|
12
|
+
* **The roster** is a leaf category's listing page. Every row carries the
|
|
13
|
+
* part number (`Part#:`), the store's `products_id`, the product name and the
|
|
14
|
+
* CAD assets, and the page states its own row total — `(of 51 products)` —
|
|
15
|
+
* which is the second opinion `receipts.checkRows` gets for free from a
|
|
16
|
+
* hand-counted `rows` and which nothing here computes from the rows it just
|
|
17
|
+
* collected.
|
|
18
|
+
*
|
|
19
|
+
* **The geometry** is a `Product Specifications` name/value table on each
|
|
20
|
+
* part's own page, so this is one request per part. The table's labels are
|
|
21
|
+
* MariTool's own and are carried into the CSV verbatim, which is the standing
|
|
22
|
+
* rule; the header is their union in first-seen order, because which keys a
|
|
23
|
+
* part publishes is a function of its style. A shrink-fit holder states
|
|
24
|
+
* `Shank Size` and `Nose Diameter`, a collet chuck states `Collet Size` and
|
|
25
|
+
* `Collet Grip Range`, and a hydraulic chuck states `Hydraulic Type`.
|
|
26
|
+
*
|
|
27
|
+
* ## What the vendor gets wrong
|
|
28
|
+
*
|
|
29
|
+
* Four faults found on 2026-08-29, all reported as warnings rather than
|
|
30
|
+
* fixed — two disagreeing vendor cells cannot say which one is wrong, and a
|
|
31
|
+
* scraper that corrects one becomes a place tool data is authored by hand.
|
|
32
|
+
* This is the same call `vendors/regofix/scrape.ts` made on its three.
|
|
33
|
+
*
|
|
34
|
+
* 1. **`BT40-ER32-60` publishes no `Taper` row at all**, alone among the 529
|
|
35
|
+
* parts in scope. Its row is kept with `taper` and `contact` empty rather
|
|
36
|
+
* than dropped or filled in from its part number: the CSV is a receipt, and
|
|
37
|
+
* the hole is what the vendor published.
|
|
38
|
+
* 2. **`Collet Size` carries a collet *nut* designation on two parts.**
|
|
39
|
+
* `CAT40-ER25-3.0MD` and `BT30-ER25-60M` both state `ER25M`, and `ER25M` is
|
|
40
|
+
* not a collet series — `HSK40E-ER16-3.0M` puts exactly that shape of value
|
|
41
|
+
* in its own `Collet Nut` cell, which is the column it belongs in. The
|
|
42
|
+
* string is written into `CST` as designated, so it joins to no collet
|
|
43
|
+
* family, and it is warned about. Widening it to `ER25` would offer a
|
|
44
|
+
* machinist a collet that may not seat.
|
|
45
|
+
* 3. **`Collet Size` is spaced inconsistently within one style** — `ER 11`
|
|
46
|
+
* and `ER11` are both published. {@link colletSeries} closes the space,
|
|
47
|
+
* because `CST` is a join key and two spellings of one series join to
|
|
48
|
+
* nothing.
|
|
49
|
+
* 4. **Two parts publish no `Product Specifications` table**, both in the
|
|
50
|
+
* CAT50 `Collet Chucks` leaf. They state their geometry as English prose in
|
|
51
|
+
* a `Product Info` bullet list instead — *"Gage length is 100mm (3.93
|
|
52
|
+
* inch)"* — and that is a sentence, not a table. They are skipped with a
|
|
53
|
+
* named warning; a regex over the prose would be this package authoring
|
|
54
|
+
* tool data by hand.
|
|
55
|
+
*
|
|
56
|
+
* ## Where the units are
|
|
57
|
+
*
|
|
58
|
+
* `Gage Length` is metric on some parts and imperial on others **inside one
|
|
59
|
+
* CSV, and inside one category page**: `HSK40E-ER11-40` gages `40mm` where
|
|
60
|
+
* `HSK40E-ER16-3.0M` gages `3.0` inches, and both are rows of
|
|
61
|
+
* `c23_46_1552_1558`. So no MariTool family declares a `unit`, and the gage
|
|
62
|
+
* length is promoted into an `L1_in`/`L1_mm` pair with exactly one cell filled
|
|
63
|
+
* — the shape `regofix.colletRow` already gives `Square_in`/`Square_mm`.
|
|
64
|
+
*
|
|
65
|
+
* **Nothing is converted.** The vendor's own imperial conversion is unusable
|
|
66
|
+
* (its prose calls 40 mm "1.6 inches" where the figure is 1.5748), and
|
|
67
|
+
* computing one here would put a number in the file that the vendor never
|
|
68
|
+
* published. The raw `Gage Length` cell is kept beside the pair.
|
|
69
|
+
*
|
|
70
|
+
* Every other measured cell — `Shank Size`, `Nose Diameter`, `Collet Grip
|
|
71
|
+
* Range` — stays verbatim under MariTool's own label, unsuffixed and
|
|
72
|
+
* unpromoted. That is deliberate: `conventions.dimensionalColumn` takes its
|
|
73
|
+
* suffix from a family's declared `unit`, and these families have none to give
|
|
74
|
+
* it. An adapter choosing `_in` for those cells itself is exactly the mistake
|
|
75
|
+
* a declared `unit` exists to prevent, and `HSK40E-SF.125-45` is the row that
|
|
76
|
+
* proves it — gaged in millimetres, bored in inches.
|
|
77
|
+
*/
|
|
78
|
+
import { type UnitSystem } from '../../conventions.js';
|
|
79
|
+
import type { Fetcher } from '../../fetch.js';
|
|
80
|
+
import { type ScrapeResult, type ScrapedRow, type Warn } from '../../scrape.js';
|
|
81
|
+
export declare const BASE = "https://www.maritool.com";
|
|
82
|
+
/**
|
|
83
|
+
* The CSV columns this adapter builds rather than lifts from a spec table.
|
|
84
|
+
*
|
|
85
|
+
* `products_id` is the store's internal id and an ordinary column: a
|
|
86
|
+
* re-created product would change it, and every guid minted off it with it —
|
|
87
|
+
* which is why identity is the part number. It is carried anyway because it is
|
|
88
|
+
* what a re-fetch of one part is addressed by.
|
|
89
|
+
*/
|
|
90
|
+
export declare const MATERIAL_COLUMN = "Material Number";
|
|
91
|
+
export declare const STORE_ID_COLUMN = "products_id";
|
|
92
|
+
export declare const TAPER_COLUMN = "taper";
|
|
93
|
+
export declare const CLAMPING_COLUMN = "clamping";
|
|
94
|
+
export declare const STYLE_COLUMN = "style";
|
|
95
|
+
/** MariTool's own label for the cell `conventions.GAGE_COLUMNS` is promoted from. */
|
|
96
|
+
export declare const GAGE_LABEL = "Gage Length";
|
|
97
|
+
/** MariTool's own label for the cell {@link COLLET_SERIES_COLUMN} comes from. */
|
|
98
|
+
export declare const COLLET_SIZE_LABEL = "Collet Size";
|
|
99
|
+
/** MariTool's own label for the cell {@link TAPER_FORMS} is looked up by. */
|
|
100
|
+
export declare const TAPER_LABEL = "Taper";
|
|
101
|
+
/**
|
|
102
|
+
* Every `Taper` cell this package is willing to read, and what it means.
|
|
103
|
+
*
|
|
104
|
+
* A closed table rather than a pattern, and keyed on the cell upper-cased
|
|
105
|
+
* because MariTool publishes the dual-contact suffix in two casings
|
|
106
|
+
* (`CAT50 DUAL CONTACT` and `CAT50 Dual Contact` are both in the catalog). An
|
|
107
|
+
* unlisted value throws naming itself: a spindle interface this package cannot
|
|
108
|
+
* name is a guess about which machine a holder fits, which is the call
|
|
109
|
+
* `regofix.CONTACT_BY_FORM` made on `BT-OM 30`.
|
|
110
|
+
*
|
|
111
|
+
* **`contact` is `face` on every HSK size, and MariTool does not say so.** It
|
|
112
|
+
* is the interface's definition rather than a property of the part: an HSK
|
|
113
|
+
* shank is a hollow taper that seats on the flange face at the same time as
|
|
114
|
+
* the cone, which is what DIN 69893 / ISO 12164 specify and what the `A`, `E`
|
|
115
|
+
* and `F` forms vary the flange of rather than the contact. MariTool marks
|
|
116
|
+
* `DUAL CONTACT` only on its 7/24 tapers, where it is an option, and there is
|
|
117
|
+
* nothing to mark on an HSK because there is no single-contact HSK to
|
|
118
|
+
* distinguish it from.
|
|
119
|
+
*/
|
|
120
|
+
export declare const TAPER_FORMS: Record<string, {
|
|
121
|
+
taper: string;
|
|
122
|
+
contact: string;
|
|
123
|
+
}>;
|
|
124
|
+
/**
|
|
125
|
+
* One leaf category to scrape, and how MariTool classifies what is in it.
|
|
126
|
+
*
|
|
127
|
+
* **`clamping` and `style` come from the leaf, not from a family constant.**
|
|
128
|
+
* Each of the five CSVs is one taper and mixes all three holder styles, so
|
|
129
|
+
* neither can be a family fact; and the leaf name is MariTool's own
|
|
130
|
+
* classification of the part, so the column is vendor-stated rather than a
|
|
131
|
+
* coinage. The values live in `families/maritool.ts` beside the cPath they
|
|
132
|
+
* come from.
|
|
133
|
+
*
|
|
134
|
+
* Declared here and re-declared structurally by the config table rather than
|
|
135
|
+
* imported from it, because `families/` must not import an adapter and an
|
|
136
|
+
* adapter must not import the config — `tests/vendor-boundary.test.ts` refuses
|
|
137
|
+
* both directions.
|
|
138
|
+
*/
|
|
139
|
+
export interface LeafTarget {
|
|
140
|
+
/** MariTool's own category path, e.g. `23_25_42`. */
|
|
141
|
+
readonly cPath: string;
|
|
142
|
+
/** How a holder in this leaf grips: `collet`, `shrink`, `hydraulic`. */
|
|
143
|
+
readonly clamping: string;
|
|
144
|
+
/** The product style, as MariTool names the leaf: `er-collet-chuck`. */
|
|
145
|
+
readonly style: string;
|
|
146
|
+
}
|
|
147
|
+
/** One row of a leaf's listing, before its product page has been read. */
|
|
148
|
+
export interface ListingRow {
|
|
149
|
+
/** The store's internal id, from the product link. */
|
|
150
|
+
readonly productsId: string;
|
|
151
|
+
/** The `Part#:` line — the identity, and the guid seed. */
|
|
152
|
+
readonly partNumber: string;
|
|
153
|
+
/** The vendor's own product name, which is where a nose form survives. */
|
|
154
|
+
readonly name: string;
|
|
155
|
+
/** The vendor's own link to this part's page. */
|
|
156
|
+
readonly productUrl: string;
|
|
157
|
+
/** Downloadable assets by their own code — `STP`, `DXF`, `DWG`, `PDF`. */
|
|
158
|
+
readonly assets: Readonly<Record<string, string>>;
|
|
159
|
+
}
|
|
160
|
+
/** One listing page: the vendor's row total, and the rows it rendered. */
|
|
161
|
+
export interface Listing {
|
|
162
|
+
/** What `(of N products)` said. The whole leaf, not this page. */
|
|
163
|
+
readonly total: number;
|
|
164
|
+
readonly rows: ListingRow[];
|
|
165
|
+
}
|
|
166
|
+
/** One product page: its spec table, and what its downloads header calls it. */
|
|
167
|
+
export interface Product {
|
|
168
|
+
/** MariTool's own labels to its own values. Empty where none is published. */
|
|
169
|
+
readonly specs: Record<string, string>;
|
|
170
|
+
/**
|
|
171
|
+
* The part number the downloads header restates, or null where the part
|
|
172
|
+
* publishes no assets and so carries no header.
|
|
173
|
+
*/
|
|
174
|
+
readonly statedPartNumber: string | null;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* A leaf category's listing page.
|
|
178
|
+
*
|
|
179
|
+
* The slug in a rewritten URL is ignored by the store, so this uses the
|
|
180
|
+
* platform's own unrewritten form and invents no slug: three URL forms reach
|
|
181
|
+
* the same page and only this one is derivable from a cPath alone.
|
|
182
|
+
*/
|
|
183
|
+
export declare function categoryUrl(cPath: string, page?: number): string;
|
|
184
|
+
/**
|
|
185
|
+
* One listing page's roster row total and its rendered rows.
|
|
186
|
+
*
|
|
187
|
+
* The rows are read off `<tr class="product-info">`, which is the vendor's own
|
|
188
|
+
* marker for one, and the store id off the product link rather than off the
|
|
189
|
+
* add-to-cart form's hidden input: the link is the first thing in the row and
|
|
190
|
+
* is also what the next request needs.
|
|
191
|
+
*/
|
|
192
|
+
export declare function parseListing(html: string): Listing;
|
|
193
|
+
/** Options every MariTool scrape accepts. */
|
|
194
|
+
export interface MaritoolOptions {
|
|
195
|
+
warn?: Warn;
|
|
196
|
+
/** Milliseconds between requests. Zero in a test, {@link REQUEST_DELAY_MS} live. */
|
|
197
|
+
delayMs?: number;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Every part in one leaf category, paged until the vendor's own count is met.
|
|
201
|
+
*
|
|
202
|
+
* **The count is the gate, and it is the vendor's rather than ours.** A roster
|
|
203
|
+
* that stopped a page early is the failure this package is built to notice,
|
|
204
|
+
* and it cannot be noticed by counting the rows that were collected — that
|
|
205
|
+
* number agrees with itself. `(of N products)` is a second opinion the store
|
|
206
|
+
* computes from its own database, which is the check `regofix.search` gets
|
|
207
|
+
* free from `hits.total`.
|
|
208
|
+
*
|
|
209
|
+
* A page that adds no new row stops the walk rather than looping: a paging
|
|
210
|
+
* parameter the store has stopped honouring answers with page 1 forever.
|
|
211
|
+
*/
|
|
212
|
+
export declare function roster(fetcher: Fetcher, cPath: string, options?: MaritoolOptions): Promise<ListingRow[]>;
|
|
213
|
+
/**
|
|
214
|
+
* One product page's `Product Specifications` table and downloads header.
|
|
215
|
+
*
|
|
216
|
+
* Both are found by their own `<div class="header">` rather than positionally,
|
|
217
|
+
* because a page carries several such blocks and which ones are present varies
|
|
218
|
+
* — 2 of the 529 parts in scope publish no spec table and roughly one in four
|
|
219
|
+
* publishes no downloads.
|
|
220
|
+
*
|
|
221
|
+
* An empty `specs` is a real state and is not an error here: the caller is
|
|
222
|
+
* what decides that a part with no geometry is skipped rather than written
|
|
223
|
+
* with holes.
|
|
224
|
+
*/
|
|
225
|
+
export declare function parseProduct(html: string): Product;
|
|
226
|
+
/** One part's page, fetched through the seam every transport here uses. */
|
|
227
|
+
export declare function fetchProduct(fetcher: Fetcher, url: string): Promise<Product>;
|
|
228
|
+
/** A gage length, read off the cell the vendor printed it in. */
|
|
229
|
+
export interface GageLength {
|
|
230
|
+
readonly value: number;
|
|
231
|
+
readonly unit: UnitSystem;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* A `Gage Length` cell as a number and the unit system it is stated in.
|
|
235
|
+
*
|
|
236
|
+
* **A bare number is inches.** That is the vendor's convention rather than
|
|
237
|
+
* this package guessing: MariTool marks every metric cell `mm` and marks
|
|
238
|
+
* nothing on an imperial one — 363 of the 473 in-scope cells sampled are bare
|
|
239
|
+
* or carry an inch mark, and a gage length of "3.0" millimetres is not a
|
|
240
|
+
* holder. The part number says nothing about it either way: `HSK40E-ER11-40`
|
|
241
|
+
* is millimetres and `HSK40E-ER16-3.0M` is inches, where that `M` is a mini
|
|
242
|
+
* nut.
|
|
243
|
+
*
|
|
244
|
+
* **The nose form is parsed off and given no column.** `120mm Tapered` is 120
|
|
245
|
+
* millimetres, and `Tapered` is not a data type — it is not lost, because the
|
|
246
|
+
* vendor states it in the product name too (*"BT40 ER11 120mm Tapered Nose
|
|
247
|
+
* Collet Chuck Tool Holder"*), and the row carries that name verbatim in
|
|
248
|
+
* `Description`. The raw cell stays in the CSV as well.
|
|
249
|
+
*
|
|
250
|
+
* Refused rather than returned as `NaN`, the rule `regofix.parseSize` holds: a
|
|
251
|
+
* cell this cannot read would otherwise travel into a row as a gage length.
|
|
252
|
+
*/
|
|
253
|
+
export declare function parseGageLength(cell: string): GageLength;
|
|
254
|
+
/**
|
|
255
|
+
* A `Collet Size` cell as the series `CST` joins a collet family on.
|
|
256
|
+
*
|
|
257
|
+
* Only the spacing is closed. MariTool publishes `ER 11` and `ER11` within one
|
|
258
|
+
* style, and two spellings of one series join to nothing — `CST` is the key
|
|
259
|
+
* `families/kennametal.ts` states the holder-to-collet join against, and the
|
|
260
|
+
* collet side of it spells the series without a space.
|
|
261
|
+
*
|
|
262
|
+
* Nothing else is normalised. `ER25M` is written through as designated even
|
|
263
|
+
* though no such collet series exists, because the alternative is to decide on
|
|
264
|
+
* the vendor's behalf that its `M` is the mini nut its `Collet Nut` column
|
|
265
|
+
* carries elsewhere — see this module's docstring. {@link holderRow} warns.
|
|
266
|
+
*/
|
|
267
|
+
export declare function colletSeries(cell: string): string;
|
|
268
|
+
/**
|
|
269
|
+
* One listing row plus its spec table -> one CSV row.
|
|
270
|
+
*
|
|
271
|
+
* The vendor's own labels are carried verbatim and in the order the page
|
|
272
|
+
* states them; what this adds in front of them is the four axes the catalog
|
|
273
|
+
* asks a holder about — `taper`, `contact`, `clamping`, `style` — plus the
|
|
274
|
+
* collet series and the promoted gage length.
|
|
275
|
+
*
|
|
276
|
+
* **No bore column.** A collet chuck grips through a collet and a shrink-fit
|
|
277
|
+
* holder's bore is stated under MariTool's own `Shank Size` label; promoting
|
|
278
|
+
* either to `D1` would make a collet-clamping holder claim a clamping capacity
|
|
279
|
+
* of its own, which is the reason `regofix.holderRow` has no `D1` either. For
|
|
280
|
+
* the same reason `Collet Grip Range` is carried verbatim and never becomes
|
|
281
|
+
* `CCCN`/`CCCX`: it is the ER series' range restated on the holder's page, a
|
|
282
|
+
* pure function of `Collet Size` across every part sampled, and a real one
|
|
283
|
+
* comes from a collet family joined on `CST`.
|
|
284
|
+
*/
|
|
285
|
+
export declare function holderRow(leaf: LeafTarget, listing: ListingRow, specs: Readonly<Record<string, string>>, warn?: Warn): ScrapedRow;
|
|
286
|
+
/**
|
|
287
|
+
* Every in-scope holder under `leaves`, one CSV's worth.
|
|
288
|
+
*
|
|
289
|
+
* One request per leaf page for the roster, then one per part for its
|
|
290
|
+
* geometry, paced by the package's shared politeness delay throughout.
|
|
291
|
+
*
|
|
292
|
+
* **Deduped by `products_id` across leaves.** MariTool lists a handful of
|
|
293
|
+
* parts under two leaves, and a part is one row however many places the store
|
|
294
|
+
* files it. The first leaf to reach it wins, which is what makes the row
|
|
295
|
+
* order below independent of which duplicate was found.
|
|
296
|
+
*/
|
|
297
|
+
export declare function scrapeHolders(fetcher: Fetcher, leaves: readonly LeafTarget[], options?: MaritoolOptions): Promise<ScrapeResult>;
|