webcrawlerapi-js 2.2.2 → 2.2.6
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/dist/@types/api.d.ts +2 -1
- package/dist/@types/model.d.ts +11 -0
- package/dist/api.js +28 -7
- package/package.json +1 -1
package/dist/@types/api.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CrawlRequest, Job, JobId, ScrapeRequest, ScrapeResponse, ScrapeResponseError, ScrapeId, JobMarkdownResponse, AgentRunRequest, AgentRun } from "./model";
|
|
1
|
+
import { CrawlRequest, Job, JobId, ScrapeRequest, ScrapeResponse, ScrapeResponseError, ScrapeId, JobMarkdownResponse, MarkdownRequest, MarkdownResponse, AgentRunRequest, AgentRun } from "./model";
|
|
2
2
|
import { JobStatus, ErrorCode } from "./constants";
|
|
3
3
|
import { WebcrawlerApiError } from "./errors";
|
|
4
4
|
export { WebcrawlerApiError, JobStatus, ErrorCode };
|
|
@@ -20,5 +20,6 @@ export declare class WebcrawlerClient {
|
|
|
20
20
|
getJob(jobID: string): Promise<Job>;
|
|
21
21
|
getJobMarkdown(jobID: string): Promise<JobMarkdownResponse>;
|
|
22
22
|
getJobMarkdownContent(jobID: string): Promise<string>;
|
|
23
|
+
markdown(request: MarkdownRequest): Promise<MarkdownResponse>;
|
|
23
24
|
private sendRequest;
|
|
24
25
|
}
|
package/dist/@types/model.d.ts
CHANGED
|
@@ -29,6 +29,8 @@ export interface ScrapeResponse {
|
|
|
29
29
|
page_title?: string;
|
|
30
30
|
structured_data?: any;
|
|
31
31
|
links?: string[];
|
|
32
|
+
/** Server-recommended delay before the next status poll, if provided */
|
|
33
|
+
recommended_pull_delay_ms?: number;
|
|
32
34
|
}
|
|
33
35
|
export interface ScrapeResponseError {
|
|
34
36
|
success: boolean;
|
|
@@ -120,6 +122,15 @@ export interface UploadS3Action extends Action {
|
|
|
120
122
|
export interface JobMarkdownResponse {
|
|
121
123
|
content_url: string;
|
|
122
124
|
}
|
|
125
|
+
export interface MarkdownRequest {
|
|
126
|
+
/** The URL of the webpage to extract the article markdown from. */
|
|
127
|
+
url: string;
|
|
128
|
+
}
|
|
129
|
+
export interface MarkdownResponse {
|
|
130
|
+
success: boolean;
|
|
131
|
+
/** Cleaned article markdown (main content only). */
|
|
132
|
+
markdown?: string;
|
|
133
|
+
}
|
|
123
134
|
export interface AgentRunRequest {
|
|
124
135
|
/** Natural-language task for the agent to complete. */
|
|
125
136
|
prompt: string;
|
package/dist/api.js
CHANGED
|
@@ -24,6 +24,9 @@ const BASE_PATH = "https://api.webcrawlerapi.com";
|
|
|
24
24
|
const initialPullDelayMs = 2000;
|
|
25
25
|
const MaxPullRetries = 100;
|
|
26
26
|
const DEFAULT_POLL_DELAY_SECONDS = 2;
|
|
27
|
+
const SCRAPE_MAX_WAIT_MS = 400 * 1000;
|
|
28
|
+
// Effectively unbounded by count at the 2s default; elapsed time is the real limit
|
|
29
|
+
const SCRAPE_MAX_POLLS = 1000;
|
|
27
30
|
const AgentTerminalStatuses = ["done", "error", "canceled"];
|
|
28
31
|
__exportStar(require("./model"), exports);
|
|
29
32
|
const SCRAPE_VERSION = "v2";
|
|
@@ -183,17 +186,21 @@ class WebcrawlerClient {
|
|
|
183
186
|
return {
|
|
184
187
|
success: false,
|
|
185
188
|
status: status,
|
|
186
|
-
page_status_code: 0
|
|
189
|
+
page_status_code: 0,
|
|
190
|
+
recommended_pull_delay_ms: responseData.recommended_pull_delay_ms
|
|
187
191
|
};
|
|
188
192
|
}
|
|
189
193
|
}
|
|
190
|
-
async scrape(request, maxPolls =
|
|
194
|
+
async scrape(request, maxPolls = SCRAPE_MAX_POLLS) {
|
|
191
195
|
// Start the scraping job
|
|
192
196
|
const scrapeIdResponse = await this.scrapeAsync(request);
|
|
193
197
|
const scrapeId = scrapeIdResponse.id;
|
|
198
|
+
const startedAt = Date.now();
|
|
194
199
|
let polls = 0;
|
|
200
|
+
let delayMs = DEFAULT_POLL_DELAY_SECONDS * 1000;
|
|
195
201
|
let result;
|
|
196
|
-
|
|
202
|
+
// Bounded by both elapsed time (SCRAPE_MAX_WAIT_MS) and maxPolls
|
|
203
|
+
while (polls < maxPolls && Date.now() - startedAt < SCRAPE_MAX_WAIT_MS) {
|
|
197
204
|
result = await this.getScrape(scrapeId);
|
|
198
205
|
// Return immediately if scrape is done
|
|
199
206
|
if ('status' in result && result.status === "done") {
|
|
@@ -203,12 +210,17 @@ class WebcrawlerClient {
|
|
|
203
210
|
if ('error_code' in result) {
|
|
204
211
|
return result;
|
|
205
212
|
}
|
|
206
|
-
//
|
|
207
|
-
|
|
208
|
-
|
|
213
|
+
// Use server-recommended delay when present, otherwise keep the default
|
|
214
|
+
const recommended = result.recommended_pull_delay_ms;
|
|
215
|
+
delayMs = recommended && recommended > 0 ? recommended : DEFAULT_POLL_DELAY_SECONDS * 1000;
|
|
216
|
+
// Don't sleep past the overall deadline
|
|
217
|
+
const remainingMs = SCRAPE_MAX_WAIT_MS - (Date.now() - startedAt);
|
|
218
|
+
if (remainingMs <= 0)
|
|
219
|
+
break;
|
|
220
|
+
await new Promise(resolve => setTimeout(resolve, Math.min(delayMs, remainingMs)));
|
|
209
221
|
polls++;
|
|
210
222
|
}
|
|
211
|
-
// Return the last known state
|
|
223
|
+
// Return the last known state on timeout
|
|
212
224
|
return result;
|
|
213
225
|
}
|
|
214
226
|
async crawl(crawlRequest, maxPolls = MaxPullRetries) {
|
|
@@ -328,6 +340,15 @@ class WebcrawlerClient {
|
|
|
328
340
|
}
|
|
329
341
|
return response.text();
|
|
330
342
|
}
|
|
343
|
+
async markdown(request) {
|
|
344
|
+
const url = `${this.basePath}/markdown`;
|
|
345
|
+
const requestOptions = {
|
|
346
|
+
'method': 'POST',
|
|
347
|
+
'headers': this.getDefaultHeaders(),
|
|
348
|
+
'body': JSON.stringify(request),
|
|
349
|
+
};
|
|
350
|
+
return this.sendRequest(url, requestOptions);
|
|
351
|
+
}
|
|
331
352
|
async sendRequest(url, requestOptions) {
|
|
332
353
|
let response;
|
|
333
354
|
try {
|