webcrawlerapi-js 2.0.4 → 2.0.5
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 +2 -1
- package/dist/@types/api.d.ts +2 -0
- package/dist/api.js +48 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,6 +18,7 @@ Install WebcrawlerAPI js package:
|
|
|
18
18
|
The package is regularly updated with new features and improvements to ensure the best possible scraping experience.
|
|
19
19
|
|
|
20
20
|
## JavaScript Examples
|
|
21
|
+
Use `crawlRawMarkdown` when you want a crawl to finish and immediately return the combined `/job/{id}/markdown` content.
|
|
21
22
|
|
|
22
23
|
### Synchronous Job
|
|
23
24
|
In this mode, the promise will be resolved when all data is ready. Synchronous jobs are perfect for quick scraping tasks where you need immediate results and don't want to handle polling logic. However, for long running jobs we recommend to use async crawling or the webhook.
|
|
@@ -176,4 +177,4 @@ Example of a job response. The response structure is carefully designed to provi
|
|
|
176
177
|
],
|
|
177
178
|
recommended_pull_delay_ms: 5000
|
|
178
179
|
}
|
|
179
|
-
```
|
|
180
|
+
```
|
package/dist/@types/api.d.ts
CHANGED
|
@@ -11,8 +11,10 @@ export declare class WebcrawlerClient {
|
|
|
11
11
|
scrapeAsync(request: ScrapeRequest): Promise<ScrapeId>;
|
|
12
12
|
getScrape(scrapeId: string): Promise<ScrapeResponse | ScrapeResponseError>;
|
|
13
13
|
scrape(request: ScrapeRequest, maxPolls?: number): Promise<ScrapeResponse | ScrapeResponseError>;
|
|
14
|
+
crawlRawMarkdown(crawlRequest: CrawlRequest, actions?: Action | Action[]): Promise<string>;
|
|
14
15
|
crawl(crawlRequest: CrawlRequest, actions?: Action | Action[]): Promise<Job>;
|
|
15
16
|
crawlAsync(crawlRequest: CrawlRequest, actions?: Action | Action[]): Promise<JobId>;
|
|
16
17
|
getJob(jobID: string): Promise<Job>;
|
|
18
|
+
getJobMarkdown(jobID: string): Promise<string>;
|
|
17
19
|
private sendRequest;
|
|
18
20
|
}
|
package/dist/api.js
CHANGED
|
@@ -138,6 +138,20 @@ class WebcrawlerClient {
|
|
|
138
138
|
// Return the last known state if maxPolls is reached
|
|
139
139
|
return result;
|
|
140
140
|
}
|
|
141
|
+
async crawlRawMarkdown(crawlRequest, actions) {
|
|
142
|
+
const markdownRequest = {
|
|
143
|
+
...crawlRequest,
|
|
144
|
+
scrape_type: crawlRequest.scrape_type ?? 'markdown'
|
|
145
|
+
};
|
|
146
|
+
const job = await this.crawl(markdownRequest, actions);
|
|
147
|
+
if (job.status !== constants_1.JobStatus.DONE) {
|
|
148
|
+
throw new errors_1.WebcrawlerApiError('job_not_done', `Job finished with status ${job.status}`, 0);
|
|
149
|
+
}
|
|
150
|
+
if (job.scrape_type !== 'markdown') {
|
|
151
|
+
throw new errors_1.WebcrawlerApiError('invalid_scrape_type', 'CrawlRawMarkdown requires scrape_type to be markdown', 0);
|
|
152
|
+
}
|
|
153
|
+
return this.getJobMarkdown(job.id);
|
|
154
|
+
}
|
|
141
155
|
async crawl(crawlRequest, actions) {
|
|
142
156
|
const url = `${this.basePath}/${this.apiVersion}/crawl`;
|
|
143
157
|
const requestBody = {
|
|
@@ -206,6 +220,40 @@ class WebcrawlerClient {
|
|
|
206
220
|
const job = await this.sendRequest(url, requestOptions);
|
|
207
221
|
return addGetContentMethod(job);
|
|
208
222
|
}
|
|
223
|
+
async getJobMarkdown(jobID) {
|
|
224
|
+
const url = `${this.basePath}/${this.apiVersion}/job/${jobID}/markdown`;
|
|
225
|
+
const requestOptions = {
|
|
226
|
+
'method': 'GET',
|
|
227
|
+
'headers': {
|
|
228
|
+
'Content-Type': 'application/json',
|
|
229
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
230
|
+
"User-Agent": "WebcrawlerAPI-NodeJS-Client",
|
|
231
|
+
'Cache-Control': 'no-cache, no-store, must-revalidate',
|
|
232
|
+
'Pragma': 'no-cache',
|
|
233
|
+
'Expires': '0'
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
let response;
|
|
237
|
+
try {
|
|
238
|
+
response = await fetch(url, requestOptions);
|
|
239
|
+
}
|
|
240
|
+
catch (e) {
|
|
241
|
+
throw new errors_1.WebcrawlerApiError('network_error', `Failed to send request: ${e}`, 0);
|
|
242
|
+
}
|
|
243
|
+
if (!response.ok) {
|
|
244
|
+
try {
|
|
245
|
+
const errorData = await response.json();
|
|
246
|
+
throw (0, errors_1.createErrorFromResponse)(response, errorData);
|
|
247
|
+
}
|
|
248
|
+
catch (e) {
|
|
249
|
+
if (e instanceof errors_1.WebcrawlerApiError) {
|
|
250
|
+
throw e;
|
|
251
|
+
}
|
|
252
|
+
throw new errors_1.WebcrawlerApiError('unknown_error', `Request failed with status ${response.status} ${response.statusText}`, response.status);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return response.text();
|
|
256
|
+
}
|
|
209
257
|
async sendRequest(url, requestOptions) {
|
|
210
258
|
let response;
|
|
211
259
|
try {
|