zenrows 2.0.1 → 2.0.3

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.
@@ -0,0 +1,3 @@
1
+ <svg width="7495" height="1080" viewBox="0 0 7495 1080" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M7115.77 18C7228.28 18.0001 7314.32 42.4821 7373.88 91.4463C7434.77 140.411 7473.82 194.007 7491.03 252.235L7316.3 329.652C7305.72 293.921 7283.21 263.484 7248.8 238.34C7214.38 211.873 7168.05 198.64 7109.81 198.64C7055.54 198.64 7012.52 209.227 6980.75 230.4C6948.99 250.251 6933.1 276.718 6933.1 309.802C6933.1 337.592 6943.69 360.09 6964.87 377.294C6987.37 394.498 7018.48 408.393 7058.19 418.979L7205.12 458.681C7303.07 485.148 7375.87 524.849 7423.52 577.783C7471.17 629.394 7495 690.931 7495 762.393C7495 823.267 7478.45 878.187 7445.36 927.151C7413.59 974.792 7367.27 1012.51 7306.38 1040.3C7245.49 1066.77 7174.01 1080 7091.94 1080C6980.75 1080 6890.08 1056.18 6819.93 1008.54C6749.77 959.574 6700.8 899.361 6673 827.899L6841.77 740.557C6860.3 785.551 6890.74 822.606 6933.1 851.72C6975.46 880.834 7029.73 895.391 7095.91 895.391C7154.15 895.391 7199.82 884.142 7232.91 861.645C7266 839.147 7282.55 808.71 7282.55 770.333C7282.55 713.428 7238.21 672.404 7149.52 647.26L7000.61 605.574C6918.54 583.077 6853.02 548.007 6804.04 500.366C6755.07 451.402 6730.58 389.865 6730.58 315.757C6730.58 225.768 6765.66 153.645 6835.81 99.3867C6905.97 45.1288 6999.29 18 7115.77 18ZM1324.42 0C1425.05 0 1511.77 23.8208 1584.59 71.4619C1658.74 119.103 1715.01 181.963 1753.41 260.041C1791.8 338.119 1811 422.154 1811 512.143V599.484H1026.52C1038.43 686.826 1070.87 754.318 1123.83 801.959C1176.79 849.6 1244.98 873.421 1328.4 873.421C1401.22 873.421 1460.8 858.202 1507.14 827.765C1554.8 797.327 1590.55 756.965 1614.38 706.677L1777.24 790.049C1741.49 866.804 1684.56 931.649 1606.44 984.583C1528.32 1036.19 1433.65 1062 1322.44 1062C1225.78 1062 1138.4 1038.84 1060.28 992.523C983.488 944.882 923.245 880.699 879.553 799.974C837.184 719.249 816 629.26 816 530.008C816 430.755 837.184 340.766 879.553 260.041C921.921 179.316 981.502 115.794 1058.29 69.4766C1136.41 23.1588 1225.12 3.79646e-05 1324.42 0ZM2364.04 18C2435.47 18.0001 2499.62 34.5404 2556.5 67.6201C2614.7 99.3768 2660.33 145.027 2693.4 204.57C2726.47 262.791 2743 328.951 2743 403.05V1062H2534.67V458.624C2534.67 385.848 2514.17 327.627 2473.16 283.962C2432.16 240.297 2377.27 218.464 2308.48 218.464C2239.7 218.464 2184.15 241.62 2141.82 287.932C2099.49 332.92 2078.33 389.818 2078.33 458.624V1062H1870V35.8633H2078.33V158.92C2104.78 116.578 2141.82 82.837 2189.44 57.6963C2238.38 31.2324 2296.58 18 2364.04 18ZM3830 36.0127C3830.33 36.0108 3830.67 36.0072 3831 36.0059V36H4827C5108.16 36 5334 266.385 5334 548C5334 829.615 5108.16 1060 4827 1060H3831V1059.99C3550.45 1058.91 3325 829.18 3325 548C3325 426.676 3366.98 314.932 3437.24 227H3321.48L3161.96 226.515C3076.44 226.515 3033.68 279.435 3033.68 385.276V1062H2861V379.323C2861 281.42 2884.02 200.054 2930.07 135.227C2977.22 69.0759 3050.67 36.0001 3150.45 36H3830V36.0127ZM5652.65 758.367L5876.85 36H6095.1L6317.32 758.367L6511.76 36H6732L6434.38 1062H6214.15L5985.98 335.663L5753.84 1062H5533.6L5234 36H5460.19L5652.65 758.367ZM800.103 200.576L262.068 861.424H814V1044H0V861.424L540.02 200.576H11.9121V18H800.103V200.576ZM3833 236C3663.81 236 3525 374.765 3525 548C3525 721.235 3663.81 860 3833 860H4827C4995.4 860 5134 721.468 5134 548C5134 374.532 4995.4 236 4827 236H3833ZM1328.4 180.64C1250.28 180.64 1184.74 203.136 1131.78 248.131C1080.14 291.802 1047.04 352.676 1032.48 430.755H1596.51C1595.18 389.731 1583.93 350.03 1562.75 311.652C1541.56 273.275 1510.45 242.176 1469.4 218.355C1429.68 193.212 1382.68 180.64 1328.4 180.64Z" fill="#FFFFFF"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg width="7495" height="1080" viewBox="0 0 7495 1080" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M7115.77 18C7228.28 18.0001 7314.32 42.4821 7373.88 91.4463C7434.77 140.411 7473.82 194.007 7491.03 252.235L7316.3 329.652C7305.72 293.921 7283.21 263.484 7248.8 238.34C7214.38 211.873 7168.05 198.64 7109.81 198.64C7055.54 198.64 7012.52 209.227 6980.75 230.4C6948.99 250.251 6933.1 276.718 6933.1 309.802C6933.1 337.592 6943.69 360.09 6964.87 377.294C6987.37 394.498 7018.48 408.393 7058.19 418.979L7205.12 458.681C7303.07 485.148 7375.87 524.849 7423.52 577.783C7471.17 629.394 7495 690.931 7495 762.393C7495 823.267 7478.45 878.187 7445.36 927.151C7413.59 974.792 7367.27 1012.51 7306.38 1040.3C7245.49 1066.77 7174.01 1080 7091.94 1080C6980.75 1080 6890.08 1056.18 6819.93 1008.54C6749.77 959.574 6700.8 899.361 6673 827.899L6841.77 740.557C6860.3 785.551 6890.74 822.606 6933.1 851.72C6975.46 880.834 7029.73 895.391 7095.91 895.391C7154.15 895.391 7199.82 884.142 7232.91 861.645C7266 839.147 7282.55 808.71 7282.55 770.333C7282.55 713.428 7238.21 672.404 7149.52 647.26L7000.61 605.574C6918.54 583.077 6853.02 548.007 6804.04 500.366C6755.07 451.402 6730.58 389.865 6730.58 315.757C6730.58 225.768 6765.66 153.645 6835.81 99.3867C6905.97 45.1288 6999.29 18 7115.77 18ZM1324.42 0C1425.05 0 1511.77 23.8208 1584.59 71.4619C1658.74 119.103 1715.01 181.963 1753.41 260.041C1791.8 338.119 1811 422.154 1811 512.143V599.484H1026.52C1038.43 686.826 1070.87 754.318 1123.83 801.959C1176.79 849.6 1244.98 873.421 1328.4 873.421C1401.22 873.421 1460.8 858.202 1507.14 827.765C1554.8 797.327 1590.55 756.965 1614.38 706.677L1777.24 790.049C1741.49 866.804 1684.56 931.649 1606.44 984.583C1528.32 1036.19 1433.65 1062 1322.44 1062C1225.78 1062 1138.4 1038.84 1060.28 992.523C983.488 944.882 923.245 880.699 879.553 799.974C837.184 719.249 816 629.26 816 530.008C816 430.755 837.184 340.766 879.553 260.041C921.921 179.316 981.502 115.794 1058.29 69.4766C1136.41 23.1588 1225.12 3.79646e-05 1324.42 0ZM2364.04 18C2435.47 18.0001 2499.62 34.5404 2556.5 67.6201C2614.7 99.3768 2660.33 145.027 2693.4 204.57C2726.47 262.791 2743 328.951 2743 403.05V1062H2534.67V458.624C2534.67 385.848 2514.17 327.627 2473.16 283.962C2432.16 240.297 2377.27 218.464 2308.48 218.464C2239.7 218.464 2184.15 241.62 2141.82 287.932C2099.49 332.92 2078.33 389.818 2078.33 458.624V1062H1870V35.8633H2078.33V158.92C2104.78 116.578 2141.82 82.837 2189.44 57.6963C2238.38 31.2324 2296.58 18 2364.04 18ZM3830 36.0127C3830.33 36.0108 3830.67 36.0072 3831 36.0059V36H4827C5108.16 36 5334 266.385 5334 548C5334 829.615 5108.16 1060 4827 1060H3831V1059.99C3550.45 1058.91 3325 829.18 3325 548C3325 426.676 3366.98 314.932 3437.24 227H3321.48L3161.96 226.515C3076.44 226.515 3033.68 279.435 3033.68 385.276V1062H2861V379.323C2861 281.42 2884.02 200.054 2930.07 135.227C2977.22 69.0759 3050.67 36.0001 3150.45 36H3830V36.0127ZM5652.65 758.367L5876.85 36H6095.1L6317.32 758.367L6511.76 36H6732L6434.38 1062H6214.15L5985.98 335.663L5753.84 1062H5533.6L5234 36H5460.19L5652.65 758.367ZM800.103 200.576L262.068 861.424H814V1044H0V861.424L540.02 200.576H11.9121V18H800.103V200.576ZM3833 236C3663.81 236 3525 374.765 3525 548C3525 721.235 3663.81 860 3833 860H4827C4995.4 860 5134 721.468 5134 548C5134 374.532 4995.4 236 4827 236H3833ZM1328.4 180.64C1250.28 180.64 1184.74 203.136 1131.78 248.131C1080.14 291.802 1047.04 352.676 1032.48 430.755H1596.51C1595.18 389.731 1583.93 350.03 1562.75 311.652C1541.56 273.275 1510.45 242.176 1469.4 218.355C1429.68 193.212 1382.68 180.64 1328.4 180.64Z" fill="#7C4FE8"/>
3
+ </svg>
@@ -0,0 +1,20 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ check:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+ - uses: pnpm/action-setup@v4
14
+ - uses: actions/setup-node@v4
15
+ with:
16
+ node-version: 20
17
+ cache: pnpm
18
+ - run: pnpm install --frozen-lockfile
19
+ - run: pnpm check
20
+ - run: pnpm test -- --run
@@ -0,0 +1,38 @@
1
+ name: Release
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: read
10
+ id-token: write
11
+
12
+ jobs:
13
+ publish:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: pnpm/action-setup@v4
18
+ - uses: actions/setup-node@v4
19
+ with:
20
+ node-version: 24
21
+ registry-url: https://registry.npmjs.org
22
+ cache: pnpm
23
+ - run: pnpm install --frozen-lockfile
24
+ - name: Verify tag matches package.json version
25
+ if: github.event_name == 'release'
26
+ run: |
27
+ TAG="${GITHUB_REF_NAME#v}"
28
+ PKG=$(node -p "require('./package.json').version")
29
+ if [ "$TAG" != "$PKG" ]; then
30
+ echo "tag $GITHUB_REF_NAME ($TAG) does not match package.json version $PKG"
31
+ exit 1
32
+ fi
33
+ - run: pnpm check
34
+ - run: pnpm test -- --run
35
+ - run: pnpm build
36
+ - run: npm publish --provenance --access public
37
+ env:
38
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/README.md CHANGED
@@ -1,6 +1,28 @@
1
- # ZenRows Node.js SDK
2
-
3
- SDK to access [ZenRows](https://www.zenrows.com/) API directly from Node.js. ZenRows handles proxies rotation, headless browsers, and CAPTCHAs for you.
1
+ <p align="center">
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset=".github/assets/logo/dark.svg"/>
4
+ <img alt="Zenrows Logo" src=".github/assets/logo/light.svg" width="300" />
5
+ </picture>
6
+ </p>
7
+
8
+ # Zenrows Node.js SDK
9
+
10
+ SDK to access [Zenrows](https://www.zenrows.com/) API directly from Node.js. Zenrows handles proxies rotation, headless browsers, and CAPTCHAs for you.
11
+
12
+ ## Table of Contents
13
+
14
+ - [Installation](#installation)
15
+ - [Usage](#usage)
16
+ - [Adaptive Stealth Mode](#adaptive-stealth-mode)
17
+ - [POST Requests](#post-requests)
18
+ - [Extract](#extract)
19
+ - [Batch](#batch)
20
+ - [Extract in a batch](#extract-in-a-batch)
21
+ - [Concurrency](#concurrency)
22
+ - [An important note about Promise.allSettled() on TypeScript](#an-important-note-about-promiseallsettled-on-typescript)
23
+ - [Examples](#examples)
24
+ - [Contributing](#contributing)
25
+ - [License](#license)
4
26
 
5
27
  ## Installation
6
28
 
@@ -21,6 +43,8 @@ The SDK uses the official [fetch api](https://nodejs.org/dist/latest-v18.x/docs/
21
43
 
22
44
  It also uses [fetch-retry](https://github.com/jonbern/fetch-retry) to automatically retry failed requests (status code 429 and 5XX). Retries are not active by default; you need to specify the number of retries, as shown below. It already includes an exponential back-off retry delay between failed requests.
23
45
 
46
+ > `client.fetch()` is the primary method for the main page-scraping product. `client.get()` still works and is kept as a deprecated alias — new code should call `fetch()`.
47
+
24
48
  ```javascript
25
49
  const { ZenRows } = require("zenrows");
26
50
 
@@ -30,7 +54,7 @@ const url = "https://www.zenrows.com/";
30
54
  (async () => {
31
55
  const client = new ZenRows(apiKey, { retries: 1 });
32
56
 
33
- const response = await client.get(
57
+ const response = await client.fetch(
34
58
  url,
35
59
  {
36
60
  // Our algorithm allows to automatically extract content from any website
@@ -99,6 +123,16 @@ You can also pass optional parameters and headers; the list above is a reference
99
123
 
100
124
  Sending headers to the target URL will overwrite our defaults. Be careful when doing it and contact us if there is any problem.
101
125
 
126
+ ### Adaptive Stealth Mode
127
+
128
+ Set `mode: "auto"` to let Zenrows pick the request configuration for you — it starts with the cheapest viable setup and escalates to `js_render`/`premium_proxy` only when the target needs it, billing only for the configuration that succeeds.
129
+
130
+ ```javascript
131
+ const response = await client.get(url, { mode: "auto" });
132
+ ```
133
+
134
+ Compatible with `proxy_country`, `js_instructions`, and `custom_headers`.
135
+
102
136
  ### POST Requests
103
137
 
104
138
  The SDK also offers POST requests by calling the `client.post` method. It can receive a new parameter `data` that represents the data sent in, for example, a form.
@@ -136,6 +170,89 @@ const url = "https://httpbin.org/anything";
136
170
  })();
137
171
  ```
138
172
 
173
+ ### Extract
174
+
175
+ [Extract](https://docs.zenrows.com) (beta) runs a page through Zenrows' AI-powered structured extraction instead of returning raw HTML. Use `client.extract()` — it's the same request as `fetch()`, with the `extract` param set for you (defaults to `"auto"`; pass `"native"` or `"standard"` for the other contracts).
176
+
177
+ ```javascript
178
+ const { ZenRows } = require("zenrows");
179
+
180
+ const apiKey = "YOUR-API-KEY";
181
+ const url = "https://www.zenrows.com/";
182
+
183
+ (async () => {
184
+ const client = new ZenRows(apiKey);
185
+
186
+ const response = await client.extract(url); // extract: "auto"
187
+ // const response = await client.extract(url, { extract: "native" });
188
+
189
+ const data = await response.json();
190
+ console.log(data);
191
+ })();
192
+ ```
193
+
194
+ ### Batch
195
+
196
+ The [Batch API](https://docs.zenrows.com) (beta) runs many URLs asynchronously as a job, and is reachable via `client.batch`. A job is either **open** — it keeps accepting tasks via `addTasks()` until you `closeJob()` it, useful when you're streaming URLs in over time — or a normal one-shot batch where every task is known upfront.
197
+
198
+ ```javascript
199
+ const { ZenRows } = require("zenrows");
200
+
201
+ const apiKey = "YOUR-API-KEY";
202
+
203
+ (async () => {
204
+ const client = new ZenRows(apiKey);
205
+
206
+ // One-shot batch: every task known upfront.
207
+ const job = await client.batch.submitJob({
208
+ tasks: [{ url: "https://example.com/1" }, { url: "https://example.com/2" }],
209
+ });
210
+
211
+ // Streaming batch: keep the job open, add tasks as they arrive, close when done.
212
+ const streamingJob = await client.batch.submitJob({ status: "open" });
213
+ await client.batch.addTasks(streamingJob.job_id, [{ url: "https://example.com/3" }]);
214
+ // Or close it as part of the last addTasks() call instead of a separate request:
215
+ // await client.batch.addTasks(streamingJob.job_id, [...], { lastBatch: true });
216
+ await client.batch.closeJob(streamingJob.job_id);
217
+
218
+ // Poll for progress and page through results once it's done.
219
+ const status = await client.batch.getJob(job.job_id);
220
+ const { results, next_cursor } = await client.batch.getResults(job.job_id);
221
+
222
+ // Retry only the tasks that failed, inheriting the rest from the previous run.
223
+ await client.batch.rerun(job.job_id, { status: "failed" });
224
+ })();
225
+ ```
226
+
227
+ `client.batch` also exposes `listJobs()`, `deleteJob()`, `stopRun()`, `rerun()`, `listRuns()`, `getRun()`, `deleteRun()`, and `getTaskContent()` (returns the scraped page's raw content as a string, not JSON — the endpoint can return HTML or plain text depending on what the target page served). Scheduling, webhook config, HMAC key rotation, CSV task uploads, and results exports aren't wrapped yet — call the [Batch API](https://docs.zenrows.com) directly for those.
228
+
229
+ #### Extract in a batch
230
+
231
+ Set `extract` in the batch params to run tasks through Extract — structured data instead of raw HTML. It works job-wide or per task, and per-task values win on collision.
232
+
233
+ ```js
234
+ const job = await client.batch.submitRegular(
235
+ [
236
+ // Inherits the job-level params below.
237
+ { url: "https://example.com/products", external_id: "p1" },
238
+ // Overrides them for this task only.
239
+ { url: "https://example.com/raw", zenrows_params: {} },
240
+ ],
241
+ undefined,
242
+ { zenrowsParams: { extract: "auto" } },
243
+ );
244
+ ```
245
+
246
+ An Extract task's result carries two keys — `html` (the raw page) and `parsed` (the structured data). It costs the same as a regular task, so `estimateCost` prices it correctly. `extract_fields` is not supported in Batch yet.
247
+
248
+ The batch client (`ZenRowsBatchClient`) also works standalone, without a `ZenRows` instance — matching the Go and Python SDKs' batch clients:
249
+
250
+ ```javascript
251
+ const { ZenRowsBatchClient } = require("zenrows");
252
+
253
+ const batch = new ZenRowsBatchClient(apiKey, { baseURL: "https://async.api.zenrows.com/v1" }); // baseURL is optional
254
+ ```
255
+
139
256
  ### Concurrency
140
257
 
141
258
  To limit the concurrency, it uses [fastq](https://github.com/mcollina/fastq), which will simultaneously send a maximum of requests. The concurrency is determined by the plan you are in, so take a look at the [pricing](https://www.zenrows.com/pricing) and set it accordingly. Take into account that each client instance will have its own limit, meaning that two different scripts will not share it, and 429 (Too Many Requests) errors might arise.
@@ -155,7 +272,7 @@ const apiKey = "YOUR-API-KEY";
155
272
  // ...
156
273
  ];
157
274
 
158
- const promises = urls.map((url) => client.get(url));
275
+ const promises = urls.map((url) => client.fetch(url));
159
276
 
160
277
  const results = await Promise.allSettled(promises);
161
278
  console.log(results);
@@ -182,7 +299,7 @@ const apiKey = "YOUR-API-KEY";
182
299
  `Promise.allSettled()` does not narrow the type of the array elements in the callback function. This means that you will need to cast the type of the array elements to `PromiseSettledResult<Response>` to access the `status` and `value` properties.
183
300
 
184
301
  ```typescript
185
- const promises = urls.map((url) => client.get(url));
302
+ const promises = urls.map((url) => client.fetch(url));
186
303
 
187
304
  const results = await Promise.allSettled(promises);
188
305