@zenrows/mcp 2.2.3 → 2.2.4
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/server.js +13 -13
- package/dist/tools/batch.js +16 -16
- package/dist/tools/browser.js +29 -29
- package/dist/tools/extract.js +13 -10
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -48,24 +48,24 @@ Examples:
|
|
|
48
48
|
url: z.string().url().describe("The webpage URL to scrape"),
|
|
49
49
|
js_render: z
|
|
50
50
|
.boolean()
|
|
51
|
-
.
|
|
51
|
+
.nullish()
|
|
52
52
|
.default(false)
|
|
53
53
|
.describe("Enable JavaScript rendering via headless browser. Required for SPAs " +
|
|
54
54
|
"(React, Vue, Angular) and pages that load content dynamically."),
|
|
55
55
|
premium_proxy: z
|
|
56
56
|
.boolean()
|
|
57
|
-
.
|
|
57
|
+
.nullish()
|
|
58
58
|
.default(false)
|
|
59
59
|
.describe("Use premium residential proxies to bypass anti-bot protection. " +
|
|
60
60
|
"Required for heavily protected sites. Implies higher credit cost."),
|
|
61
61
|
proxy_country: z
|
|
62
62
|
.string()
|
|
63
|
-
.
|
|
63
|
+
.nullish()
|
|
64
64
|
.describe("Country for geo-targeted scraping. ISO 3166-1 alpha-2 code (e.g. 'US', 'GB', 'DE'). " +
|
|
65
65
|
"Requires premium_proxy=true."),
|
|
66
66
|
response_type: z
|
|
67
67
|
.enum(["markdown", "plaintext", "pdf", "html"])
|
|
68
|
-
.
|
|
68
|
+
.nullish()
|
|
69
69
|
.default("markdown")
|
|
70
70
|
.describe("Output format. 'markdown' (default) preserves structure and is ideal for LLMs. " +
|
|
71
71
|
"'plaintext' strips all formatting for pure text extraction. " +
|
|
@@ -74,18 +74,18 @@ Examples:
|
|
|
74
74
|
"Ignored when autoparse, css_extractor, outputs, or screenshot params are set."),
|
|
75
75
|
autoparse: z
|
|
76
76
|
.boolean()
|
|
77
|
-
.
|
|
77
|
+
.nullish()
|
|
78
78
|
.describe("Automatically extract structured data from the page into JSON. " +
|
|
79
79
|
"Best for product pages, articles, and listings."),
|
|
80
80
|
css_extractor: z
|
|
81
81
|
.string()
|
|
82
|
-
.
|
|
82
|
+
.nullish()
|
|
83
83
|
.describe("Extract specific elements using CSS selectors. " +
|
|
84
84
|
'JSON object mapping names to selectors, e.g. \'{"title":"h1","price":".price-tag"}\'. ' +
|
|
85
85
|
"Returns JSON instead of full page content."),
|
|
86
86
|
wait_for: z
|
|
87
87
|
.string()
|
|
88
|
-
.
|
|
88
|
+
.nullish()
|
|
89
89
|
.describe("CSS selector to wait for before capturing. Use when key content loads " +
|
|
90
90
|
"after the initial page render. Requires js_render=true."),
|
|
91
91
|
wait: z
|
|
@@ -93,33 +93,33 @@ Examples:
|
|
|
93
93
|
.int()
|
|
94
94
|
.min(0)
|
|
95
95
|
.max(30000)
|
|
96
|
-
.
|
|
96
|
+
.nullish()
|
|
97
97
|
.describe("Milliseconds to wait after page load before capturing content. " +
|
|
98
98
|
"Max 30000 (30s). Requires js_render=true."),
|
|
99
99
|
js_instructions: z
|
|
100
100
|
.string()
|
|
101
|
-
.
|
|
101
|
+
.nullish()
|
|
102
102
|
.describe("JSON array of browser interactions to run before scraping. Requires js_render=true. " +
|
|
103
103
|
'Example: [{"click":"#load-more"},{"wait":1000},{"wait_for":".results"}]'),
|
|
104
104
|
outputs: z
|
|
105
105
|
.string()
|
|
106
|
-
.
|
|
106
|
+
.nullish()
|
|
107
107
|
.describe("Comma-separated list of data types to extract as structured JSON. " +
|
|
108
108
|
"Available: emails, headings, links, menus, images, videos, audios. " +
|
|
109
109
|
"Use '*' for all types. Returns JSON instead of full page content."),
|
|
110
110
|
screenshot: z
|
|
111
111
|
.boolean()
|
|
112
|
-
.
|
|
112
|
+
.nullish()
|
|
113
113
|
.describe("Capture an above-the-fold screenshot of the page. " +
|
|
114
114
|
"Returns an image instead of text content. Useful for visual verification or debugging."),
|
|
115
115
|
screenshot_fullpage: z
|
|
116
116
|
.boolean()
|
|
117
|
-
.
|
|
117
|
+
.nullish()
|
|
118
118
|
.describe("Capture a full-page screenshot including content below the fold. " +
|
|
119
119
|
"Returns an image instead of text content."),
|
|
120
120
|
screenshot_selector: z
|
|
121
121
|
.string()
|
|
122
|
-
.
|
|
122
|
+
.nullish()
|
|
123
123
|
.describe("Capture a screenshot of a specific element using a CSS selector. " +
|
|
124
124
|
'Example: ".product-card". Returns an image instead of text content.'),
|
|
125
125
|
},
|
package/dist/tools/batch.js
CHANGED
|
@@ -49,11 +49,11 @@ function normalizeParams(obj) {
|
|
|
49
49
|
}
|
|
50
50
|
const taskSchema = z.object({
|
|
51
51
|
url: z.string().url().describe("Target URL for this task"),
|
|
52
|
-
external_id: z.string().
|
|
53
|
-
metadata: z.unknown().
|
|
52
|
+
external_id: z.string().nullish().describe("Optional stable id echoed back on results"),
|
|
53
|
+
metadata: z.unknown().nullish().describe("Opaque per-task metadata carried through to results"),
|
|
54
54
|
zenrows_params: z
|
|
55
55
|
.record(z.union([z.string(), z.number(), z.boolean()]))
|
|
56
|
-
.
|
|
56
|
+
.nullish()
|
|
57
57
|
.describe("Per-task Zenrows scrape params (js_render, premium_proxy, extract, autoparse, …)"),
|
|
58
58
|
});
|
|
59
59
|
export function registerBatchTools(server, apiKey) {
|
|
@@ -71,30 +71,30 @@ If you get BATCH_ACCESS_DENIED, the account lacks Batch beta access.`,
|
|
|
71
71
|
inputSchema: {
|
|
72
72
|
tasks: z
|
|
73
73
|
.array(taskSchema)
|
|
74
|
-
.
|
|
74
|
+
.nullish()
|
|
75
75
|
.describe("List of tasks (each needs a url). Prefer this over urls when you need per-task params."),
|
|
76
76
|
urls: z
|
|
77
77
|
.array(z.string().url())
|
|
78
|
-
.
|
|
78
|
+
.nullish()
|
|
79
79
|
.describe("Shorthand: list of URLs (converted to tasks). Ignored when tasks is provided."),
|
|
80
|
-
js_render: z.boolean().
|
|
81
|
-
premium_proxy: z.boolean().
|
|
80
|
+
js_render: z.boolean().nullish().describe("Job-level js_render for all tasks"),
|
|
81
|
+
premium_proxy: z.boolean().nullish().describe("Job-level premium_proxy for all tasks"),
|
|
82
82
|
proxy_country: z
|
|
83
83
|
.string()
|
|
84
|
-
.
|
|
84
|
+
.nullish()
|
|
85
85
|
.describe("Job-level ISO country code (requires premium_proxy or mode=auto)"),
|
|
86
|
-
response_type: z.enum(["markdown", "plaintext", "html", "pdf"]).
|
|
86
|
+
response_type: z.enum(["markdown", "plaintext", "html", "pdf"]).nullish().describe("Job-level response_type"),
|
|
87
87
|
zenrows_params: z
|
|
88
88
|
.record(z.union([z.string(), z.number(), z.boolean()]))
|
|
89
|
-
.
|
|
89
|
+
.nullish()
|
|
90
90
|
.describe("Additional job-level zenrows_params merged with the flags above"),
|
|
91
|
-
wait: z.boolean().
|
|
91
|
+
wait: z.boolean().nullish().describe("If true, poll until the job reaches a terminal state before returning"),
|
|
92
92
|
wait_timeout_ms: z
|
|
93
93
|
.number()
|
|
94
94
|
.int()
|
|
95
95
|
.min(1000)
|
|
96
96
|
.max(3_600_000)
|
|
97
|
-
.
|
|
97
|
+
.nullish()
|
|
98
98
|
.describe("Max wait time when wait=true (default 600000)"),
|
|
99
99
|
},
|
|
100
100
|
}, async (params) => {
|
|
@@ -121,7 +121,7 @@ If you get BATCH_ACCESS_DENIED, the account lacks Batch beta access.`,
|
|
|
121
121
|
const task = { url: t.url };
|
|
122
122
|
if (t.external_id)
|
|
123
123
|
task.external_id = t.external_id;
|
|
124
|
-
if (t.metadata
|
|
124
|
+
if (t.metadata != null)
|
|
125
125
|
task.metadata = t.metadata;
|
|
126
126
|
if (t.zenrows_params)
|
|
127
127
|
task.zenrows_params = normalizeParams(t.zenrows_params);
|
|
@@ -180,11 +180,11 @@ Each row may include task_id, external_id, status, and a short-lived result_url
|
|
|
180
180
|
Download result_url soon — presigned links expire.`,
|
|
181
181
|
inputSchema: {
|
|
182
182
|
job_id: z.string().describe("Batch job id"),
|
|
183
|
-
status: z.enum(["successful", "failed", "all"]).
|
|
183
|
+
status: z.enum(["successful", "failed", "all"]).nullish().describe("Filter results by status (default: all)"),
|
|
184
184
|
},
|
|
185
185
|
}, async ({ job_id, status }) => {
|
|
186
186
|
try {
|
|
187
|
-
const results = await listResults(job_id, { ...call, status });
|
|
187
|
+
const results = await listResults(job_id, { ...call, status: status ?? undefined });
|
|
188
188
|
return json({ ok: true, job_id, count: results.length, results });
|
|
189
189
|
}
|
|
190
190
|
catch (e) {
|
|
@@ -223,7 +223,7 @@ Download result_url soon — presigned links expire.`,
|
|
|
223
223
|
.int()
|
|
224
224
|
.min(1000)
|
|
225
225
|
.max(3_600_000)
|
|
226
|
-
.
|
|
226
|
+
.nullish()
|
|
227
227
|
.describe("Max wait time in ms (default 600000)"),
|
|
228
228
|
},
|
|
229
229
|
}, async ({ job_id, timeout_ms }) => {
|
package/dist/tools/browser.js
CHANGED
|
@@ -38,11 +38,11 @@ When to use options:
|
|
|
38
38
|
url: z.string().url().describe("The URL to navigate to"),
|
|
39
39
|
proxy_country: z
|
|
40
40
|
.string()
|
|
41
|
-
.
|
|
41
|
+
.nullish()
|
|
42
42
|
.describe("ISO 3166-1 alpha-2 country code for geo-targeted proxy (e.g. 'US', 'GB', 'DE')"),
|
|
43
43
|
proxy_region: z
|
|
44
44
|
.string()
|
|
45
|
-
.
|
|
45
|
+
.nullish()
|
|
46
46
|
.describe("World region code for geo-targeted proxy (eu=Europe, na=North America, ap=Asia Pacific, sa=South America, af=Africa, me=Middle East)"),
|
|
47
47
|
},
|
|
48
48
|
}, async (params) => {
|
|
@@ -194,7 +194,7 @@ When to use options:
|
|
|
194
194
|
session_id: sessionId,
|
|
195
195
|
selector: z.string().describe("CSS selector of the input element"),
|
|
196
196
|
text: z.string().describe("Text to type"),
|
|
197
|
-
clear_first: z.boolean().
|
|
197
|
+
clear_first: z.boolean().nullish().describe("Clear existing content before typing (default false)"),
|
|
198
198
|
},
|
|
199
199
|
}, async ({ session_id, selector, text, clear_first }) => {
|
|
200
200
|
const fetch = tfetch("browser_type");
|
|
@@ -340,7 +340,7 @@ When to use options:
|
|
|
340
340
|
inputSchema: {
|
|
341
341
|
session_id: sessionId,
|
|
342
342
|
direction: z.enum(["up", "down", "left", "right"]).describe("Scroll direction"),
|
|
343
|
-
distance: z.number().int().positive().
|
|
343
|
+
distance: z.number().int().positive().nullish().describe("Pixels to scroll (default 500)"),
|
|
344
344
|
},
|
|
345
345
|
}, async ({ session_id, direction, distance }) => {
|
|
346
346
|
const fetch = tfetch("browser_scroll");
|
|
@@ -442,7 +442,7 @@ labels, and states — everything needed to drive browser interactions.`,
|
|
|
442
442
|
description: "Get the visible text content of an element or the entire page body.",
|
|
443
443
|
inputSchema: {
|
|
444
444
|
session_id: sessionId,
|
|
445
|
-
selector: z.string().
|
|
445
|
+
selector: z.string().nullish().describe("CSS selector of the element (omit for full page body text)"),
|
|
446
446
|
},
|
|
447
447
|
}, async ({ session_id, selector }) => {
|
|
448
448
|
const fetch = tfetch("browser_get_text");
|
|
@@ -487,7 +487,7 @@ labels, and states — everything needed to drive browser interactions.`,
|
|
|
487
487
|
description: "Get the HTML source of an element or the full page.",
|
|
488
488
|
inputSchema: {
|
|
489
489
|
session_id: sessionId,
|
|
490
|
-
selector: z.string().
|
|
490
|
+
selector: z.string().nullish().describe("CSS selector of the element (omit for full page HTML)"),
|
|
491
491
|
},
|
|
492
492
|
}, async ({ session_id, selector }) => {
|
|
493
493
|
const fetch = tfetch("browser_get_html");
|
|
@@ -537,11 +537,11 @@ labels, and states — everything needed to drive browser interactions.`,
|
|
|
537
537
|
session_id: sessionId,
|
|
538
538
|
full_page: z
|
|
539
539
|
.boolean()
|
|
540
|
-
.
|
|
540
|
+
.nullish()
|
|
541
541
|
.describe("Capture full page including content below the fold (default false)"),
|
|
542
542
|
selector: z
|
|
543
543
|
.string()
|
|
544
|
-
.
|
|
544
|
+
.nullish()
|
|
545
545
|
.describe("CSS selector to capture only a specific element (overrides full_page)"),
|
|
546
546
|
},
|
|
547
547
|
}, async ({ session_id, full_page, selector }) => {
|
|
@@ -573,9 +573,9 @@ labels, and states — everything needed to drive browser interactions.`,
|
|
|
573
573
|
description: "Render the current page as a PDF document.",
|
|
574
574
|
inputSchema: {
|
|
575
575
|
session_id: sessionId,
|
|
576
|
-
print_background: z.boolean().
|
|
577
|
-
landscape: z.boolean().
|
|
578
|
-
scale: z.number().min(0.1).max(2).
|
|
576
|
+
print_background: z.boolean().nullish().describe("Print background graphics (default false)"),
|
|
577
|
+
landscape: z.boolean().nullish().describe("Landscape orientation (default false)"),
|
|
578
|
+
scale: z.number().min(0.1).max(2).nullish().describe("Page scale factor (default 1)"),
|
|
579
579
|
},
|
|
580
580
|
}, async ({ session_id, print_background, landscape, scale }) => {
|
|
581
581
|
const fetch = tfetch("browser_generate_pdf");
|
|
@@ -614,7 +614,7 @@ labels, and states — everything needed to drive browser interactions.`,
|
|
|
614
614
|
selector: z.string().describe("CSS selector to wait for"),
|
|
615
615
|
visible: z
|
|
616
616
|
.boolean()
|
|
617
|
-
.
|
|
617
|
+
.nullish()
|
|
618
618
|
.describe("Also require the element to be visible, not just present in the DOM (default false)"),
|
|
619
619
|
},
|
|
620
620
|
}, async ({ session_id, selector, visible }) => {
|
|
@@ -642,7 +642,7 @@ labels, and states — everything needed to drive browser interactions.`,
|
|
|
642
642
|
.int()
|
|
643
643
|
.min(1000)
|
|
644
644
|
.max(60000)
|
|
645
|
-
.
|
|
645
|
+
.nullish()
|
|
646
646
|
.describe("How long to wait in milliseconds (default 30000, max 60000)"),
|
|
647
647
|
},
|
|
648
648
|
}, async ({ session_id, timeout_ms }) => {
|
|
@@ -722,11 +722,11 @@ labels, and states — everything needed to drive browser interactions.`,
|
|
|
722
722
|
.array(z.object({
|
|
723
723
|
name: z.string(),
|
|
724
724
|
value: z.string(),
|
|
725
|
-
domain: z.string().
|
|
726
|
-
path: z.string().
|
|
727
|
-
expires: z.number().
|
|
728
|
-
http_only: z.boolean().
|
|
729
|
-
secure: z.boolean().
|
|
725
|
+
domain: z.string().nullish(),
|
|
726
|
+
path: z.string().nullish(),
|
|
727
|
+
expires: z.number().nullish().describe("Unix timestamp"),
|
|
728
|
+
http_only: z.boolean().nullish(),
|
|
729
|
+
secure: z.boolean().nullish(),
|
|
730
730
|
}))
|
|
731
731
|
.describe("Array of cookie objects to set"),
|
|
732
732
|
},
|
|
@@ -769,8 +769,8 @@ labels, and states — everything needed to drive browser interactions.`,
|
|
|
769
769
|
inputSchema: {
|
|
770
770
|
session_id: sessionId,
|
|
771
771
|
action: z.enum(["get", "set", "clear"]).describe("Operation: get a value, set a value, or clear all"),
|
|
772
|
-
key: z.string().
|
|
773
|
-
value: z.string().
|
|
772
|
+
key: z.string().nullish().describe("Storage key (required for get and set)"),
|
|
773
|
+
value: z.string().nullish().describe("Value to store (required for set)"),
|
|
774
774
|
},
|
|
775
775
|
}, async ({ session_id, action, key, value }) => {
|
|
776
776
|
const fetch = tfetch("browser_local_storage");
|
|
@@ -794,7 +794,7 @@ labels, and states — everything needed to drive browser interactions.`,
|
|
|
794
794
|
description: "Open a new browser tab. Returns a tab_id to use with browser_switch_tab.",
|
|
795
795
|
inputSchema: {
|
|
796
796
|
session_id: sessionId,
|
|
797
|
-
url: z.string().url().
|
|
797
|
+
url: z.string().url().nullish().describe("URL to open in the new tab (opens blank tab if omitted)"),
|
|
798
798
|
},
|
|
799
799
|
}, async ({ session_id, url }) => {
|
|
800
800
|
const fetch = tfetch("browser_new_tab");
|
|
@@ -841,7 +841,7 @@ labels, and states — everything needed to drive browser interactions.`,
|
|
|
841
841
|
type: z.literal("type"),
|
|
842
842
|
selector: z.string(),
|
|
843
843
|
text: z.string(),
|
|
844
|
-
clear_first: z.boolean().
|
|
844
|
+
clear_first: z.boolean().nullish(),
|
|
845
845
|
}),
|
|
846
846
|
z.object({ type: z.literal("fill"), selector: z.string(), value: z.string() }),
|
|
847
847
|
z.object({ type: z.literal("select"), selector: z.string(), value: z.string() }),
|
|
@@ -852,25 +852,25 @@ labels, and states — everything needed to drive browser interactions.`,
|
|
|
852
852
|
z.object({
|
|
853
853
|
type: z.literal("scroll"),
|
|
854
854
|
direction: z.enum(["up", "down", "left", "right"]),
|
|
855
|
-
distance: z.number().
|
|
855
|
+
distance: z.number().nullish(),
|
|
856
856
|
}),
|
|
857
857
|
z.object({ type: z.literal("drag"), source_selector: z.string(), target_selector: z.string() }),
|
|
858
858
|
z.object({ type: z.literal("get_accessibility_tree") }),
|
|
859
859
|
z.object({ type: z.literal("get_url") }),
|
|
860
860
|
z.object({ type: z.literal("get_title") }),
|
|
861
|
-
z.object({ type: z.literal("get_text"), selector: z.string().
|
|
861
|
+
z.object({ type: z.literal("get_text"), selector: z.string().nullish() }),
|
|
862
862
|
z.object({ type: z.literal("get_attribute"), selector: z.string(), attribute: z.string() }),
|
|
863
|
-
z.object({ type: z.literal("get_html"), selector: z.string().
|
|
863
|
+
z.object({ type: z.literal("get_html"), selector: z.string().nullish() }),
|
|
864
864
|
z.object({ type: z.literal("query_selector_all"), selector: z.string() }),
|
|
865
865
|
z.object({
|
|
866
866
|
type: z.literal("screenshot"),
|
|
867
|
-
full_page: z.boolean().
|
|
868
|
-
selector: z.string().
|
|
867
|
+
full_page: z.boolean().nullish(),
|
|
868
|
+
selector: z.string().nullish(),
|
|
869
869
|
}),
|
|
870
870
|
z.object({
|
|
871
871
|
type: z.literal("wait_for_selector"),
|
|
872
872
|
selector: z.string(),
|
|
873
|
-
visible: z.boolean().
|
|
873
|
+
visible: z.boolean().nullish(),
|
|
874
874
|
}),
|
|
875
875
|
z.object({ type: z.literal("wait_for_navigation") }),
|
|
876
876
|
z.object({ type: z.literal("wait"), ms: z.number().int().min(0).max(30000) }),
|
|
@@ -1112,7 +1112,7 @@ For proper image rendering, use browser_screenshot directly.`,
|
|
|
1112
1112
|
.min(1)
|
|
1113
1113
|
.max(50)
|
|
1114
1114
|
.describe("Ordered list of actions to perform. Each action has a 'type' field plus type-specific parameters."),
|
|
1115
|
-
stop_on_error: z.boolean().
|
|
1115
|
+
stop_on_error: z.boolean().nullish().describe("Stop executing on the first failed action (default true)"),
|
|
1116
1116
|
},
|
|
1117
1117
|
}, async ({ session_id, actions, stop_on_error = true }) => {
|
|
1118
1118
|
const fetch = tfetch("browser_batch");
|
package/dist/tools/extract.js
CHANGED
|
@@ -161,6 +161,9 @@ export async function runExtract(apiKey, params, options = {}) {
|
|
|
161
161
|
...(html !== undefined ? { html } : {}),
|
|
162
162
|
};
|
|
163
163
|
}
|
|
164
|
+
function withoutNulls(params) {
|
|
165
|
+
return Object.fromEntries(Object.entries(params).filter(([, v]) => v !== null));
|
|
166
|
+
}
|
|
164
167
|
export function registerExtractTool(server, apiKey, getClientName) {
|
|
165
168
|
server.registerTool("extract", {
|
|
166
169
|
annotations: {
|
|
@@ -184,39 +187,39 @@ For full-page markdown/HTML/screenshots, use scrape instead.`,
|
|
|
184
187
|
url: z.string().url().describe("The webpage URL to extract from"),
|
|
185
188
|
mode: z
|
|
186
189
|
.enum(["auto", "autoparse", "css"])
|
|
187
|
-
.
|
|
190
|
+
.nullish()
|
|
188
191
|
.default("auto")
|
|
189
192
|
.describe("Extraction mode: auto (extract=auto, default), autoparse, or css (requires css_extractor)"),
|
|
190
193
|
css_extractor: z
|
|
191
194
|
.string()
|
|
192
|
-
.
|
|
195
|
+
.nullish()
|
|
193
196
|
.describe('Required when mode=css. JSON map of field→selector, e.g. \'{"title":"h1","price":".price"}\''),
|
|
194
|
-
js_render: z.boolean().
|
|
197
|
+
js_render: z.boolean().nullish().describe("Enable headless JS rendering (SPAs / dynamic content)"),
|
|
195
198
|
premium_proxy: z
|
|
196
199
|
.boolean()
|
|
197
|
-
.
|
|
200
|
+
.nullish()
|
|
198
201
|
.describe("Use premium residential proxies (anti-bot). Higher credit cost."),
|
|
199
202
|
proxy_country: z
|
|
200
203
|
.string()
|
|
201
|
-
.
|
|
204
|
+
.nullish()
|
|
202
205
|
.describe("ISO 3166-1 alpha-2 country code. Requires premium_proxy or mode_auto."),
|
|
203
|
-
mode_auto: z.boolean().
|
|
204
|
-
wait_for: z.string().
|
|
206
|
+
mode_auto: z.boolean().nullish().describe("Enable Adaptive Stealth Mode (mode=auto) for tougher sites"),
|
|
207
|
+
wait_for: z.string().nullish().describe("CSS selector to wait for before extracting. Requires js_render."),
|
|
205
208
|
wait: z
|
|
206
209
|
.number()
|
|
207
210
|
.int()
|
|
208
211
|
.min(0)
|
|
209
212
|
.max(30000)
|
|
210
|
-
.
|
|
213
|
+
.nullish()
|
|
211
214
|
.describe("Milliseconds to wait after load. Requires js_render."),
|
|
212
215
|
fallback_autoparse: z
|
|
213
216
|
.boolean()
|
|
214
|
-
.
|
|
217
|
+
.nullish()
|
|
215
218
|
.default(true)
|
|
216
219
|
.describe("When mode=auto and the domain is not in Extract open beta (AUTH010), retry once with autoparse (default true)"),
|
|
217
220
|
},
|
|
218
221
|
}, async (params) => {
|
|
219
|
-
const outcome = await runExtract(apiKey, params, { getClientName });
|
|
222
|
+
const outcome = await runExtract(apiKey, withoutNulls(params), { getClientName });
|
|
220
223
|
if (!outcome.ok)
|
|
221
224
|
return err(outcome.errorText);
|
|
222
225
|
return json({
|