@zenrows/cli 1.6.1 → 1.6.2
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 +4 -1
- package/dist/src/cli/commands/crawl.js +20 -3
- package/dist/src/core/config.js +1 -1
- package/package.json +1 -1
- package/skills/crawl/SKILL.md +8 -1
package/README.md
CHANGED
|
@@ -187,7 +187,10 @@ to open. `--max-items` and `--max-pages` cap the crawl (API default 100 each),
|
|
|
187
187
|
and `--max-pages` bounds the cost, since each page is one fetch. The local policy `max_pages_per_run` caps `--max-pages` (default
|
|
188
188
|
1000). `--output-format html` uses up the page budget: each kept page is one
|
|
189
189
|
more fetch, and `--max-pages` counts it. `--include-patterns` /
|
|
190
|
-
`--exclude-patterns` are repeatable substring filters on the URL.
|
|
190
|
+
`--exclude-patterns` are repeatable substring filters on the URL. A crawl whose
|
|
191
|
+
pages held nothing new to follow ends `completed` with no results and exits 0.
|
|
192
|
+
When patterns were set, it prints a note (under `--json`, in `note`) to check
|
|
193
|
+
them against the URLs the start page links to. `get` and
|
|
191
194
|
`list` read one page and take `--cursor` and `--limit`. `results` follows every
|
|
192
195
|
page (`--limit` is the page size); on a running crawl it returns the URLs kept
|
|
193
196
|
so far, with `partial: true`. `download` reports the crawl's `status` (`null`
|
|
@@ -62,7 +62,8 @@ export const crawl = {
|
|
|
62
62
|
" a crawl still running then is printed, not stopped",
|
|
63
63
|
" --json print structured output: create/get/wait/stop print",
|
|
64
64
|
" {ok, crawl_id, status, crawl}; get adds results and next_cursor;",
|
|
65
|
-
" a wait that runs out
|
|
65
|
+
" a wait that runs out, or a completed crawl with patterns",
|
|
66
|
+
" and 0 results, adds note",
|
|
66
67
|
].join("\n"),
|
|
67
68
|
async run(argv, ctx) {
|
|
68
69
|
const [sub, ...rest] = argv;
|
|
@@ -466,8 +467,8 @@ export function crawlFailure(c) {
|
|
|
466
467
|
}
|
|
467
468
|
const why = [code, c.error?.detail].filter(Boolean).join(": ");
|
|
468
469
|
const next = {
|
|
469
|
-
seed_unreachable: "The start URL could not be fetched (the site may be blocking it). Check it with `zenrows fetch <url>`.",
|
|
470
|
-
no_items_found: "
|
|
470
|
+
seed_unreachable: "The start URL could not be fetched or returned an empty page (the site may be blocking it). Check it with `zenrows fetch <url>`.",
|
|
471
|
+
no_items_found: "The crawl read the start page but found no data it could use, so it had nothing to follow. Start from a listing or product page.",
|
|
471
472
|
};
|
|
472
473
|
return new ToolkitError({
|
|
473
474
|
code: "CRAWL_FAILED",
|
|
@@ -478,6 +479,18 @@ export function crawlFailure(c) {
|
|
|
478
479
|
...ids,
|
|
479
480
|
});
|
|
480
481
|
}
|
|
482
|
+
/**
|
|
483
|
+
* Set only when a crawl with patterns completed and kept nothing. The API ends a
|
|
484
|
+
* crawl whose pages held nothing new to follow `completed`, and does not count
|
|
485
|
+
* the links the patterns rejected, so the patterns are the first thing to check.
|
|
486
|
+
*/
|
|
487
|
+
function noMatchNote(c) {
|
|
488
|
+
const crawl = c;
|
|
489
|
+
const patterns = [...(crawl.include_patterns ?? []), ...(crawl.exclude_patterns ?? [])];
|
|
490
|
+
if (crawl.status !== "completed" || crawl.coverage?.items_found !== 0 || !patterns.length)
|
|
491
|
+
return undefined;
|
|
492
|
+
return "The crawl completed with no results. Check --include-patterns / --exclude-patterns against the URLs the start page links to.";
|
|
493
|
+
}
|
|
481
494
|
/**
|
|
482
495
|
* Print a crawl (or a stop answer), structured under --json, and return the exit
|
|
483
496
|
* code: 1 when it ended `failed`, or `stopped` because credits ran out or the
|
|
@@ -487,6 +500,7 @@ export function crawlFailure(c) {
|
|
|
487
500
|
*/
|
|
488
501
|
function printCrawl(c, json, headline, extra = {}) {
|
|
489
502
|
const err = crawlFailure(c);
|
|
503
|
+
const note = extra.note ?? noMatchNote(c);
|
|
490
504
|
const crawlFields = { ...c };
|
|
491
505
|
// A wait polls with one result to stay cheap; that page is not "the results".
|
|
492
506
|
delete crawlFields.results;
|
|
@@ -498,6 +512,7 @@ function printCrawl(c, json, headline, extra = {}) {
|
|
|
498
512
|
status: c.status,
|
|
499
513
|
crawl: crawlFields,
|
|
500
514
|
...extra,
|
|
515
|
+
note,
|
|
501
516
|
...(err ? { error: err.toJSON() } : {}),
|
|
502
517
|
}, null, 2));
|
|
503
518
|
return err ? 1 : 0;
|
|
@@ -515,6 +530,8 @@ function printCrawl(c, json, headline, extra = {}) {
|
|
|
515
530
|
}
|
|
516
531
|
if (extra.note)
|
|
517
532
|
log.dim(` next: zenrows crawl wait ${c.crawl_id}`);
|
|
533
|
+
else if (note)
|
|
534
|
+
log.warn(` ${note}`);
|
|
518
535
|
if (err)
|
|
519
536
|
printError(err, false);
|
|
520
537
|
return err ? 1 : 0;
|
package/dist/src/core/config.js
CHANGED
|
@@ -14,7 +14,7 @@ export const CONFIG_VERSION = "0.1.0";
|
|
|
14
14
|
* entrypoint) so core modules — telemetry, signup provenance — can read it
|
|
15
15
|
* without an import cycle. `VERSION` in `cli/index.ts` re-exports this.
|
|
16
16
|
*/
|
|
17
|
-
export const CLI_VERSION = "1.6.
|
|
17
|
+
export const CLI_VERSION = "1.6.2"; // x-release-please-version
|
|
18
18
|
/** The User-Agent on every request to a Zenrows API. The gateway reads the version from it. */
|
|
19
19
|
export const CLI_USER_AGENT = `zenrows-cli/${CLI_VERSION}`;
|
|
20
20
|
/** Env var to override the Fetch and Extract API base (local/staging testing). */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zenrows/cli",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.2",
|
|
4
4
|
"description": "Open-source CLI, MCP, skills, templates, workflows, recipes, and evals layer for giving AI agents reliable access to protected web data through Zenrows cloud infrastructure.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
package/skills/crawl/SKILL.md
CHANGED
|
@@ -39,6 +39,10 @@ zenrows crawl results <id> --out urls.jsonl # same, as JSONL
|
|
|
39
39
|
- `--include-patterns` / `--exclude-patterns` are substring matches on the
|
|
40
40
|
normalized URL and repeat:
|
|
41
41
|
`--include-patterns /product/ --exclude-patterns ?add-to-cart`.
|
|
42
|
+
- A crawl whose pages held nothing new to follow (no link, only links to other
|
|
43
|
+
sites, or only links the patterns reject) ends `completed` with no results
|
|
44
|
+
and exits 0. When patterns were set, it prints a note (under `--json`, in
|
|
45
|
+
`note`) to check them against the URLs the start page links to.
|
|
42
46
|
- `create` returns at once. `--follow` (or `zenrows crawl wait <id>`) polls
|
|
43
47
|
until the crawl ends or `--timeout` seconds run out (default 600). When the
|
|
44
48
|
time runs out, the command exits 0 and prints the crawl with status
|
|
@@ -85,7 +89,10 @@ credit cap; the pages fetched before that stay readable. `failed`, and a
|
|
|
85
89
|
`stopped` crawl with an `error`, exit non-zero: `CRAWL_INSUFFICIENT_CREDITS` or
|
|
86
90
|
`CRAWL_KEY_CAP_REACHED` when credits ended it (the same codes a refused
|
|
87
91
|
`create` gets, also when an older deployment reports it `failed`), else
|
|
88
|
-
`CRAWL_FAILED`. `server_code` carries the API's `error.code
|
|
92
|
+
`CRAWL_FAILED`. `server_code` carries the API's `error.code`:
|
|
93
|
+
`seed_unreachable` when the start URL could not be fetched or returned an empty
|
|
94
|
+
page, `no_items_found` when the crawl read the start page but found no data it
|
|
95
|
+
could use.
|
|
89
96
|
`stop` on a crawl that already ended prints the status it ended with.
|
|
90
97
|
|
|
91
98
|
With `--json`, `create`, `get`, `wait` and `stop` print
|