@zenrows/cli 1.4.2 → 1.5.1

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.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: batch-jobs
3
- description: Scale protected fetch/extract over many URLs via Batch (beta). Cloud create/status/results/cancel/wait/retry-failed work with beta access; estimate/validate run locally with no key.
3
+ description: Scale protected fetch/extract over many URLs via Batch. Cloud create/status/results/cancel/wait/retry-failed work with an API key; estimate/validate run locally with no key.
4
4
  version: 0.1.0
5
5
  requires_backend_capabilities: [batch]
6
6
  ---
@@ -11,11 +11,10 @@ Process large workloads reliably and asynchronously. Batch is where Zenrows'
11
11
  high-scale anti-bot advantage becomes obvious — Zenrows wins when the workflow
12
12
  runs over thousands, millions, or recurring sets of URLs.
13
13
 
14
- > Status: **beta**. The Zenrows **Batch** is a real
15
- > product in beta and runs on a separate host
16
- > (`async.api.zenrows.com/v1`). The cloud subcommands work once your account has
17
- > beta access; without it the API returns 403 → `BATCH_ACCESS_DENIED`. The
18
- > toolkit never fakes a cloud run.
14
+ > Zenrows **Batch** runs on a separate host (`async.api.zenrows.com/v1`) and
15
+ > spends the same credits as Fetch. The cloud subcommands work with any active
16
+ > API key; a 403 maps to `BATCH_ACCESS_DENIED`. The toolkit never fakes a
17
+ > cloud run.
19
18
 
20
19
  ## Local (no key, always works)
21
20
  ```
@@ -40,7 +39,7 @@ correctly. The result carries two keys: `html` (the
40
39
  raw page) and `parsed` (the structured data). Validate on a single URL with
41
40
  `zenrows extract <url>` before running the full batch.
42
41
 
43
- ## Cloud (needs a key + beta access)
42
+ ## Cloud (needs a key)
44
43
  ```
45
44
  zenrows batch create jobs.jsonl [--proxy-country cc] [--wait]
46
45
  zenrows batch create jobs.jsonl --manual [--js-render] [--premium-proxy]
@@ -0,0 +1,126 @@
1
+ ---
2
+ name: crawl
3
+ description: Collect the URLs behind one start page with Crawl (new): create a crawl, wait for it, read the kept URLs and optionally each page's HTML, stop it. Use when the user has a listing or section URL but not the item URLs.
4
+ version: 0.1.0
5
+ requires_backend_capabilities: [crawl]
6
+ ---
7
+
8
+ # Crawl (new)
9
+
10
+ Give Crawl one start URL; it follows the links on that page (and on the
11
+ pages behind it, up to the depth you set) and returns the URLs it keeps. Use it
12
+ when you know where the items live (a category page, a blog index, a docs
13
+ section) but not the item URLs themselves. Once you have the URLs, read pages
14
+ with `zenrows fetch` / `zenrows extract`, or ask Crawl for each page's HTML
15
+ with `--output-format html`.
16
+
17
+ Crawl stays on the start URL's registrable domain; subdomains count. An account without Crawl access gets
18
+ 403 `REQS008` → `CRAWL_NOT_ENABLED` ("Crawl is not enabled for this account");
19
+ do not retry it.
20
+
21
+ ## Create, wait, read
22
+
23
+ ```
24
+ zenrows crawl create https://example.com/products/ --depth 1 \
25
+ --max-items 20 --max-pages 25 --include-patterns /product/ --follow --json
26
+ zenrows crawl results <id> --json # every kept URL
27
+ zenrows crawl results <id> --out urls.jsonl # same, as JSONL
28
+ ```
29
+
30
+ - `--depth N` (1 to 100000) is optional: link hops from the start URL. `1` =
31
+ the start page's links; `2` = also the links on each of those pages. Leave
32
+ it out for no depth limit: the crawl follows links until `--max-items` or
33
+ `--max-pages` stops it, or nothing is left to open. A crawl created without
34
+ a depth has no `depth` field in its output.
35
+ - `--max-items` (kept URLs) and `--max-pages` (fetched pages) cap the crawl;
36
+ both default to 100. `--max-pages` bounds the cost: each page is one fetch.
37
+ The local policy `max_pages_per_run` caps `--max-pages` (default 1000);
38
+ above it the CLI refuses with `POLICY_LIMIT_EXCEEDED` before any request.
39
+ - `--include-patterns` / `--exclude-patterns` are substring matches on the
40
+ normalized URL and repeat:
41
+ `--include-patterns /product/ --exclude-patterns ?add-to-cart`.
42
+ - `create` returns at once. `--follow` (or `zenrows crawl wait <id>`) polls
43
+ until the crawl ends or `--timeout` seconds run out (default 600). When the
44
+ time runs out, the command exits 0 and prints the crawl with status
45
+ `running` and the hint `zenrows crawl wait <id>` (under `--json`, in
46
+ `note`). The crawl keeps running;
47
+ it is not stopped. Ctrl-C also stops the wait, not the crawl, and exits 130;
48
+ resume with `zenrows crawl wait <id>`.
49
+ - `results` on a running crawl returns the URLs kept so far, with
50
+ `partial: true`. Read again once the crawl ends. `--limit` sets the page size
51
+ of each request.
52
+
53
+ ## Page HTML
54
+
55
+ ```
56
+ zenrows crawl create <url> --depth 1 --output-format html --max-pages 20 --follow
57
+ zenrows crawl results <id> --json # fetched results carry content_url
58
+ zenrows crawl content <id> <content_id> # one page's HTML (or pass the content_url)
59
+ zenrows crawl download <id> --out pages.jsonl # every URL + HTML, NDJSON
60
+ ```
61
+
62
+ `--output-format html` uses up the page budget: each kept page is one more
63
+ fetch, and `--max-pages` counts it. Raise `--max-pages` to keep the same number
64
+ of URLs. A result's `content_status` is `pending`, `fetched` or `failed`; only
65
+ `fetched` results have content (else `CRAWL_CONTENT_NOT_FOUND`). `download`
66
+ reports the crawl's `status`, and `partial: true` while it runs.
67
+
68
+ ## While it runs, and after
69
+
70
+ ```
71
+ zenrows crawl get <id> # status, coverage, stop_reason / error, one page of results
72
+ zenrows crawl get <id> --cursor <c> --json # the next page; keep polling with next_cursor
73
+ zenrows crawl list # your crawls, newest first (--cursor, --limit)
74
+ zenrows crawl stop <id> # stop it; kept URLs stay readable
75
+ ```
76
+
77
+ A crawl ends `completed` (nothing left, or a cap hit: `stop_reason`
78
+ `max_items` / `max_pages`), `stopped` (you stopped it) or `failed` (`error.code`
79
+ and `error.detail` say why). Only `failed` exits non-zero (`CRAWL_FAILED`).
80
+ `stop` on a crawl that already ended prints the status it ended with.
81
+
82
+ With `--json`, `create`, `get`, `wait` and `stop` print
83
+ `{ok, crawl_id, status, crawl}`; read `coverage`, `stop_reason` and `error`
84
+ under `crawl`. `get` adds `results` and `next_cursor`. `download` prints
85
+ `status: null` when the API sends no status.
86
+
87
+ ## Limits
88
+
89
+ When the account has reached its limit of active jobs (3 by default), shared
90
+ with its Batch jobs, a create gets 429 `too_many_crawls` →
91
+ `CRAWL_TOO_MANY_CRAWLS`; nothing was created. Retry after `retry_after`
92
+ seconds (about 30), or stop one of your crawls or Batch jobs first. Any other
93
+ 429 is `CRAWL_RATE_LIMITED`: requests are being throttled; retry after
94
+ `retry_after` seconds.
95
+
96
+ ## Errors
97
+
98
+ Every Crawl error carries the API's code as `server_code` (when the API sent
99
+ one), and `crawl_id` on any call about one crawl.
100
+
101
+ The CLI retries transient failures, as the Crawl SDKs do: up to 3 retries,
102
+ waiting the `Retry-After` seconds (at most 30) or 250 ms x 2^n (+/-20% jitter,
103
+ at most 10 s). Reads retry on 429, 502, 503, 504 and network errors (a timeout
104
+ counts). `create` retries only with `--idempotency-key`, and only on 502, 503,
105
+ 504 and network errors, never on 429. `stop` retries on 429, 502, 503 (including
106
+ `crawl_busy`) and 504, waiting the `Retry-After` seconds (at most 30) or 1 s.
107
+ The "Retry?" column is for errors that remain after these retries.
108
+
109
+ | Code | Meaning | Retry? |
110
+ | --- | --- | --- |
111
+ | `CRAWL_NOT_ENABLED` | 403 `REQS008`: Crawl is not enabled for this account | no |
112
+ | `AUTH_INVALID` | 401: the API key was rejected | no, log in again |
113
+ | `CRAWL_INSUFFICIENT_CREDITS` | 402: the account is out of credits (claim the account or add credits) | after credits renew or are added |
114
+ | `CRAWL_KEY_CAP_REACHED` | 402 `AUTH014` or `api_key_cap_reached`: this API key reached its credit cap | after the cap resets or is raised |
115
+ | `CRAWL_INVALID_REQUEST` | 400 or 422: fix the request. For `idempotency_key_reused`, send a new key or no key | no, not as is |
116
+ | `CRAWL_REQUEST_IN_FLIGHT` | 409: the same Idempotency-Key is still in flight | yes, once the first request ends |
117
+ | `CRAWL_NOT_FOUND` / `CRAWL_CONTENT_NOT_FOUND` | 404: wrong id, or the page has no content | no |
118
+ | `CRAWL_TOO_MANY_CRAWLS` | 429 `too_many_crawls` on `create`: the account's active-job limit | yes, after `retry_after` |
119
+ | `CRAWL_RATE_LIMITED` | any other 429: requests are being throttled | yes, after `retry_after` |
120
+ | `CRAWL_BUSY` | 503 `crawl_busy` on `stop`: the stop was not saved yet and the crawl still runs | yes, run the stop again after `retry_after` |
121
+ | `CRAWL_FAILED` | the crawl ended `failed`, or another error | 5xx: yes, with backoff |
122
+ | `BACKEND_UNAVAILABLE` | the API could not be reached | yes |
123
+
124
+ Rules: start small (`--depth 1`, low caps) and check the results before a
125
+ deep crawl. Mind the cost ([[cost-control]]). Read errors with
126
+ [[trace-debug]].
@@ -12,7 +12,7 @@ access + extraction**, not generic LLM parsing.
12
12
 
13
13
  ## Methods
14
14
  ```
15
- zenrows extract <url> # extract=auto (default); falls back to Autoparse if domain not enabled
15
+ zenrows extract <url> # extract=auto (default); falls back to Autoparse if the domain is not prepared yet
16
16
  zenrows extract <url> --autoparse # general-purpose Autoparse (any domain)
17
17
  zenrows extract <url> --css '{"title":"h1","price":".price"}' # selector map
18
18
  zenrows extract <url> --outputs emails,links # built-in output filters → JSON
@@ -21,8 +21,8 @@ zenrows extract <url> --validate # fail if not valid JSON
21
21
  ```
22
22
 
23
23
  ## When to use which
24
- - **Extract** (`extract=auto`, default): richest fields on domains enabled for the open beta.
25
- - **Autoparse**: any website; also the automatic fallback when Extract is not enabled for the domain.
24
+ - **Extract** (`extract=auto`, default): richest fields; works on any domain Zenrows has prepared.
25
+ - **Autoparse**: any website; also the automatic fallback when the domain is not prepared for Extract yet.
26
26
  - **CSS**: you know the exact fields/selectors and want determinism.
27
27
  - **Markdown/plaintext**: feed clean content to an LLM yourself.
28
28
 
@@ -45,6 +45,18 @@ zenrows trace export <run-id> # JSON for sharing
45
45
  auto-created Free plan.
46
46
  - `BATCH_FAILED` → the batch run ended `failed`; `failure_reason` and
47
47
  `failure_detail` in `zenrows batch status <id> --json` say why.
48
+ - `CRAWL_NOT_ENABLED` → the API answered 403 `REQS008`: Crawl is not
49
+ enabled for this account. Do not retry; ask Zenrows support for access.
50
+ - `CRAWL_INSUFFICIENT_CREDITS` / `CRAWL_KEY_CAP_REACHED` → Crawl's 402: the
51
+ account is out of credits, or this key reached its credit cap (`AUTH014`).
52
+ Same advice as `POLICY_MAX_CREDITS_EXCEEDED` / `KEY_CREDIT_CAP_REACHED`.
53
+ - `CRAWL_TOO_MANY_CRAWLS` → 429 `too_many_crawls`: the account has reached
54
+ its limit of active jobs (3 by default), shared with its Batch jobs.
55
+ Nothing was created; retry after `retry_after` seconds (see
56
+ `zenrows crawl list`).
57
+ - `CRAWL_FAILED` → the crawl ended `failed`; `error.code` in
58
+ `zenrows crawl get <id> --json` says why, with `error.detail`. See
59
+ [[crawl]].
48
60
  - `PARAM_CONFLICT_AUTO_MANUAL` → drop the managed flags or add `--manual`.
49
61
  - `CAPABILITY_UNAVAILABLE` → the primitive is not available on this account (e.g. beta/invite-only); use the local-spec path where offered.
50
62
 
@@ -34,6 +34,10 @@ If the user has a known URL and wants page content:
34
34
  If the user has a known URL and wants structured data:
35
35
  → Use Extract. (zenrows extract <url> | --autoparse | --css)
36
36
 
37
+ If the user has a start page (listing, index, section) but not the item URLs:
38
+ → Use Crawl. (zenrows crawl create <url> --depth 1 --follow,
39
+ then `zenrows crawl results <id>`)
40
+
37
41
  If the user has many URLs (bulk):
38
42
  → Use Batch. (validate one page with fetch/extract first,
39
43
  then `zenrows batch create <jobs.jsonl>`)
@@ -68,8 +72,9 @@ Run `zenrows status` for the live capability matrix. As of this toolkit:
68
72
  | Primitive | Command | Status |
69
73
  | --- | --- | --- |
70
74
  | Protected Fetch | `zenrows fetch` | available (`GET /v1/`) |
71
- | Extract (extract=auto / Autoparse/CSS/Markdown) | `zenrows extract` | beta (same `/v1/`; extract=auto falls back to autoparse) |
72
- | Batch | `zenrows batch` | beta — runs cloud jobs (create/status/results); cheapest path at scale. Estimate specs locally with no key |
75
+ | Extract (extract=auto / Autoparse/CSS/Markdown) | `zenrows extract` | available (same `/v1/`; extract=auto falls back to autoparse) |
76
+ | Batch | `zenrows batch` | available: runs cloud jobs (create/status/results); cheapest path at scale. Estimate specs locally with no key |
77
+ | Crawl | `zenrows crawl` | new — collect the URLs behind one start page, optionally with each page's HTML |
73
78
  | Browser | `zenrows browser` | available (Browser Sessions REST API / MCP) |
74
79
  | MCP | `zenrows mcp` | available (remote + local server) |
75
80
 
@@ -16,10 +16,10 @@ results carry `html` and `parsed` keys.
16
16
  zenrows batch estimate jobs.example.jsonl # validate the spec + estimate credits
17
17
  ```
18
18
 
19
- ## Cloud (needs a key + Batch beta access)
19
+ ## Cloud (needs a key)
20
20
 
21
- Batch is in **beta**. With beta access the
22
- cloud subcommands run for real; without it the API returns `BATCH_ACCESS_DENIED`.
21
+ The cloud subcommands run with any active API key and spend the same credits
22
+ as Fetch.
23
23
 
24
24
  ```bash
25
25
  zenrows batch create jobs.example.jsonl --wait # submit + wait for the run to finish
@@ -33,5 +33,5 @@ Tasks use Adaptive Stealth Mode (`mode=auto`) by default. Job-level scrape
33
33
  options come from flags (`--js-render`, `--premium-proxy`, `--proxy-country`,
34
34
  `--output`, or `--manual` to turn Adaptive Stealth Mode off); per-line keys
35
35
  override them for that URL.
36
- Without beta access yet, validate/estimate locally or fan out with
37
- `zenrows fetch` per URL on a small sample first.
36
+ Validate/estimate locally, or try `zenrows fetch` per URL on a small sample
37
+ first.
@@ -13,5 +13,5 @@ zenrows extract https://www.scrapingcourse.com/ecommerce/ --autoparse
13
13
  zenrows extract <product-url> --css '{"title":"h1","price":".price"}' --validate
14
14
  ```
15
15
 
16
- Requires `extract` (open beta). Start on one page, confirm the fields, then
16
+ Requires `extract`. Start on one page, confirm the fields, then
17
17
  fan out `zenrows extract` across the rest of your URLs.
@@ -20,7 +20,7 @@ simple per-URL loop).
20
20
  ```
21
21
  zenrows fetch https://competitor.example/products
22
22
  ```
23
- 2. **Validate extraction** on one page (extract is beta; extract=auto falls back to autoparse).
23
+ 2. **Validate extraction** on one page (extract=auto falls back to autoparse on a domain not prepared yet).
24
24
  ```
25
25
  zenrows extract https://competitor.example/p/123 --validate
26
26
  ```