webscraping-ai-cli 1.0.2 → 1.2.0
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/.claude-plugin/marketplace.json +14 -4
- package/CHANGELOG.md +40 -0
- package/README.md +56 -30
- package/dist/cli.js +399 -122
- package/dist/cli.js.map +1 -1
- package/package.json +2 -2
- package/plugins/webscraping-ai/.claude-plugin/plugin.json +13 -3
- package/plugins/webscraping-ai/skills/webscraping-ai/SKILL.md +34 -13
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/claude-code-plugin-marketplace.json",
|
|
3
3
|
"name": "webscraping-ai",
|
|
4
|
-
"description": "Official WebScraping.AI plugins for Claude Code — scrape and AI-extract data from any URL.",
|
|
4
|
+
"description": "Official WebScraping.AI plugins for Claude Code — scrape and AI-extract data from any URL, get parsed Google search (SERP) results, and structured data for supported sites.",
|
|
5
5
|
"owner": {
|
|
6
6
|
"name": "WebScraping.AI",
|
|
7
7
|
"url": "https://webscraping.ai"
|
|
@@ -10,10 +10,20 @@
|
|
|
10
10
|
{
|
|
11
11
|
"name": "webscraping-ai",
|
|
12
12
|
"source": "./plugins/webscraping-ai",
|
|
13
|
-
"description": "Fetch HTML, text, selected elements, or AI-extracted data from any URL — including JS-rendered pages — via the WebScraping.AI CLI.",
|
|
14
|
-
"version": "1.
|
|
13
|
+
"description": "Fetch HTML, text, selected elements, or AI-extracted data from any URL — including JS-rendered pages — parsed Google search results, and structured data for supported sites (YouTube, TikTok, X, LinkedIn, Instagram, Reddit, …), via the WebScraping.AI CLI.",
|
|
14
|
+
"version": "1.2.0",
|
|
15
15
|
"category": "web-scraping",
|
|
16
|
-
"keywords": [
|
|
16
|
+
"keywords": [
|
|
17
|
+
"web-scraping",
|
|
18
|
+
"html",
|
|
19
|
+
"text-extraction",
|
|
20
|
+
"ai-extraction",
|
|
21
|
+
"scraping",
|
|
22
|
+
"search",
|
|
23
|
+
"serp",
|
|
24
|
+
"google-search",
|
|
25
|
+
"cli"
|
|
26
|
+
]
|
|
17
27
|
}
|
|
18
28
|
]
|
|
19
29
|
}
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,46 @@ All notable changes to `webscraping-ai-cli` are documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## 1.2.0 — 2026-09-25
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `data <url>` subcommand wrapping the new `/data` endpoint: structured JSON for a page on a supported site (e.g. YouTube, TikTok, X, LinkedIn, Instagram, Reddit; more are added server-side). Flags: `--country` (proxy country, `us` by default), `--transcript` (YouTube videos only; if the transcript fetch itself fails, the whole request fails with a 500, exit 7, not charged), `--transcript-language`, and a repeatable `--param key=value` passed through as-is for site-specific parameters. `-` reads one URL per line from stdin (stops at the first failing item, like every command); `-o` and `--pretty`/`--no-pretty` work as on `serp`. The scrape flags (`--js`, `--proxy`, `--headers`, …) don't apply and aren't registered on it. 15 credits per request.
|
|
13
|
+
- The URL is sent exactly as given and never checked against a list of sites. An unsupported URL or page type returns a 400 that is not charged (exit 3); its message lists what is supported. A blank URL exits 2 before any request.
|
|
14
|
+
- `--param` rejects, with exit 2 before any request: a missing `=` or empty key, a repeated key, `api_key`, `url`, `from_cli`, `__proto__`, and keys that have their own flag (`country`, `transcript`, `transcript_language` — the message names the flag).
|
|
15
|
+
- Bundled agent skill documents when to reach for `data` before scraping a supported site yourself.
|
|
16
|
+
- Smoke script adds a YouTube `data` call (checks `parse_status` `ok`, provider `youtube`, a non-empty `data.title`) and an example.com call that must exit 3 with a server 400 whose message contains `Unsupported URL` (~46 credits per sweep).
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Requires the `webscraping-ai` SDK release after 4.1.0 (adds `data()` and the `params` pass-through on `serp()`/`data()`).
|
|
21
|
+
- `from_cli` is now sent on `serp` and `data`, through the SDK's `params` pass-through (closes the known gap: SDK 4.1.0's `serp()` dropped it).
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- `-o/--output` in stdin batch mode is truncated when the batch starts, so an empty stdin or a failing first item no longer leaves the previous run's content in the file.
|
|
26
|
+
|
|
27
|
+
## 1.1.0 — 2026-09-25
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
|
|
31
|
+
- `serp <query>` subcommand (alias `search`) wrapping the new `/serp` endpoint: parsed Google search results as JSON. Flags: `--engine` (`google`), `--gl`, `--hl`, `--page <n>`. Multi-word queries don't need quoting; `-` reads one query per line from stdin. The scrape flags (`--js`, `--proxy`, `--country`, …) don't apply and aren't registered on it. Flat 15 credits per search.
|
|
32
|
+
- Bundled agent skill documents when to reach for `serp` (query-first research) instead of scraping a search URL.
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- Requires `webscraping-ai` SDK `^4.1.0` (adds `serp()`).
|
|
37
|
+
- `serp --page` is validated strictly (digits only, >= 1): `1.5`, `2abc` and `0` are rejected with exit code 2 before stdin is read or the key is resolved (the server also rejects them with a 400, not billed; checking client-side saves the round trip). Pages are 1–100: the server rejects a `page` above 100 with a 400.
|
|
38
|
+
- `serp` stdin batches skip only blank lines, so `#hashtag` queries are searched rather than dropped as comments. URL commands still treat `#` lines as comments.
|
|
39
|
+
- `serp` sends the query as typed (whitespace-only queries are still rejected). `from_cli` is not sent on `serp`: the SDK forwards only the SERP parameters.
|
|
40
|
+
|
|
41
|
+
### Fixed
|
|
42
|
+
|
|
43
|
+
- `--pretty` / `--no-pretty` no longer fail with "option '--no-pretty' cannot be used with option '--no-pretty'" (a self-conflict on every scrape command and `serp`).
|
|
44
|
+
- `-o/--output` in stdin batch mode kept only the last result; the file is now truncated once and each result appended.
|
|
45
|
+
- Error messages printed to stderr redact the API key and any `api_key=...` pattern (an HTML error body echoing the request URL used to print the key).
|
|
46
|
+
- Smoke script (`npm run smoke`) now checks results, not just exit codes: `serp` needs non-empty `organic_results` and a matching `search_parameters.q`, `selected-multiple` needs a non-empty inner array; signal-killed runs fail; page commands run with `--no-js --proxy datacenter` (~31 credits per sweep); FAIL lines redact the key.
|
|
47
|
+
|
|
8
48
|
## 1.0.2 — 2026-07-17
|
|
9
49
|
|
|
10
50
|
### Changed
|
package/README.md
CHANGED
|
@@ -45,29 +45,43 @@ webscraping-ai selected <url> --selector <css> # One CSS area
|
|
|
45
45
|
webscraping-ai selected-multiple <url> --selector a --selector b ...
|
|
46
46
|
webscraping-ai ask <url> --question "..." # AI question about the page
|
|
47
47
|
webscraping-ai extract <url> --fields '{"title":"...","price":"..."}'
|
|
48
|
+
webscraping-ai serp <query> [--gl us] [--hl en] [--page 1] # Parsed Google results (alias: search)
|
|
49
|
+
webscraping-ai data <url> [--country us] [--transcript] # Structured JSON for a supported site
|
|
48
50
|
webscraping-ai account # Remaining credits / quota
|
|
49
51
|
```
|
|
50
52
|
|
|
53
|
+
`serp` (alias `search`) is query-shaped, not URL-shaped: it takes `--engine` (`google`, the default), `--gl` (country), `--hl` (language), `--page` (1-based, 10 results per page) plus `--api-key`/`--output`/`--pretty`, and none of the scrape flags below. It prints the JSON result (`search_parameters`, `search_information`, `organic_results`, `related_searches`, `pagination`). Flat 15 credits per search; failed searches are not charged. `--page` must be an integer >= 1 (pages are 1–100; the server rejects values above 100 with a 400); anything else is a usage error (exit 2) before any request. Multi-word queries don't need quoting; `-` reads one query per line from stdin, skipping only blank lines (a leading `#` is kept as part of the query, e.g. `#coffee`). The CLI's `from_cli` analytics flag is sent on `serp` through the SDK's `params` pass-through.
|
|
54
|
+
|
|
55
|
+
`data <url>` returns structured JSON for a public page on a supported site — for example a YouTube video, TikTok profile, X post, LinkedIn company, Instagram reel or Reddit thread. Pass the page's normal URL; the site and page kind are detected server-side and echoed in `request_parameters` (`provider`, `type`), next to `parse_status` (`ok`, `parse_failed` or `not_found`) and `data` (shape depends on the site; `null` when nothing parsed). More sites are added on the server over time, so the CLI never checks the URL itself and sends it exactly as given. An unsupported URL or page type returns a 400 that is not charged (exit 3); its message lists what is supported. 15 credits per request, including `parse_failed`/`not_found` results; failed fetches are not charged. None of the scrape flags below apply; `data` has its own:
|
|
56
|
+
|
|
57
|
+
- `--country <code>`: two-letter country code of the proxy used to fetch the page, `us` by default.
|
|
58
|
+
- `--transcript`: YouTube videos only. Also fetch the video's transcript into `data.transcript`. It's null when no matching captions are available. If the transcript fetch itself fails, the whole request fails with a 500 (exit 7) and is not charged.
|
|
59
|
+
- `--transcript-language <code>`: caption language to pick, e.g. `en` or `de`. Without it, English is preferred, then the first available track. If the video has no captions in that language, `data.transcript` is null.
|
|
60
|
+
- `--param key=value` (repeatable): site-specific parameters added after this CLI version, sent as-is. A repeated key, `api_key`, `url`, `from_cli`, `__proto__`, or a key that has its own flag (`country`, `transcript`, `transcript_language` — use the flag) is a usage error (exit 2).
|
|
61
|
+
- `--api-key`, `--output`, `--pretty`/`--no-pretty`.
|
|
62
|
+
|
|
63
|
+
`-` reads one URL per line from stdin (blank and `#` lines skipped). Like every URL command, a batch **stops at the first failing item**: earlier results are already written, the remaining URLs are not requested, and the exit code is that error's. With `-o FILE` the file is truncated when the batch starts, then each result is appended. A blank URL or a bad `--param` is a usage error (exit 2) before any request.
|
|
64
|
+
|
|
51
65
|
Common flags shared by every scrape command:
|
|
52
66
|
|
|
53
|
-
| Flag
|
|
54
|
-
|
|
|
55
|
-
| `--js` / `--no-js`
|
|
56
|
-
| `--proxy TYPE`
|
|
57
|
-
| `--country CC`
|
|
58
|
-
| `--device TYPE`
|
|
59
|
-
| `--timeout MS`
|
|
60
|
-
| `--js-timeout MS`
|
|
61
|
-
| `--wait-for CSS`
|
|
62
|
-
| `--headers JSON`
|
|
63
|
-
| `--custom-proxy URL`
|
|
64
|
-
| `--js-script CODE`
|
|
65
|
-
| `--error-on-404`
|
|
66
|
-
| `--error-on-redirect`
|
|
67
|
-
| `--output FILE`
|
|
68
|
-
| `--pretty / --no-pretty` | Force pretty / single-line JSON
|
|
69
|
-
|
|
70
|
-
`<url>` may be `-` to read URLs from stdin (one per line; lines starting with `#` are ignored).
|
|
67
|
+
| Flag | Purpose |
|
|
68
|
+
| ------------------------ | ---------------------------------------------------- |
|
|
69
|
+
| `--js` / `--no-js` | Toggle JavaScript rendering (default: on) |
|
|
70
|
+
| `--proxy TYPE` | `datacenter` (default), `residential`, `stealth` |
|
|
71
|
+
| `--country CC` | Two-letter proxy country code |
|
|
72
|
+
| `--device TYPE` | `desktop`, `mobile`, `tablet` |
|
|
73
|
+
| `--timeout MS` | Total page-retrieval timeout (max 30000) |
|
|
74
|
+
| `--js-timeout MS` | JS rendering time after page load (max 20000) |
|
|
75
|
+
| `--wait-for CSS` | CSS selector to wait for |
|
|
76
|
+
| `--headers JSON` | HTTP headers to forward; inline JSON or `@file.json` |
|
|
77
|
+
| `--custom-proxy URL` | `http://user:pass@host:port` |
|
|
78
|
+
| `--js-script CODE` | Custom JS to evaluate on the target page |
|
|
79
|
+
| `--error-on-404` | Treat 404 responses as errors |
|
|
80
|
+
| `--error-on-redirect` | Treat redirects as errors |
|
|
81
|
+
| `--output FILE` | Write to FILE instead of stdout |
|
|
82
|
+
| `--pretty / --no-pretty` | Force pretty / single-line JSON |
|
|
83
|
+
|
|
84
|
+
`<url>` may be `-` to read URLs from stdin (one per line; lines starting with `#` are ignored). With `--output FILE`, a stdin batch writes every result to FILE, one after another (the file is truncated once at the start).
|
|
71
85
|
|
|
72
86
|
## Install the AI agent skill
|
|
73
87
|
|
|
@@ -88,18 +102,18 @@ You can also install the skill via the Claude Code [Plugin Marketplace](https://
|
|
|
88
102
|
|
|
89
103
|
## Exit codes
|
|
90
104
|
|
|
91
|
-
| Code | Meaning
|
|
92
|
-
| ---- |
|
|
93
|
-
| 0 | Success
|
|
94
|
-
| 2 | Usage error (commander)
|
|
95
|
-
| 3 | 400 Bad Request from the API
|
|
96
|
-
| 4 | 403 Authentication error
|
|
97
|
-
| 5 | 402 Payment Required (out of credits)
|
|
98
|
-
| 6 | 429 Rate limit
|
|
99
|
-
| 7 | 500 Server error (or wrapped target-page error)
|
|
100
|
-
| 8 | Timeout (504 or local AbortController)
|
|
101
|
-
| 9 | Connection / DNS failure
|
|
102
|
-
| 1 | Anything else
|
|
105
|
+
| Code | Meaning |
|
|
106
|
+
| ---- | ----------------------------------------------- |
|
|
107
|
+
| 0 | Success |
|
|
108
|
+
| 2 | Usage error (commander) |
|
|
109
|
+
| 3 | 400 Bad Request from the API |
|
|
110
|
+
| 4 | 403 Authentication error |
|
|
111
|
+
| 5 | 402 Payment Required (out of credits) |
|
|
112
|
+
| 6 | 429 Rate limit |
|
|
113
|
+
| 7 | 500 Server error (or wrapped target-page error) |
|
|
114
|
+
| 8 | Timeout (504 or local AbortController) |
|
|
115
|
+
| 9 | Connection / DNS failure |
|
|
116
|
+
| 1 | Anything else |
|
|
103
117
|
|
|
104
118
|
Scripts can branch on these without parsing stderr.
|
|
105
119
|
|
|
@@ -118,6 +132,18 @@ cat urls.txt | webscraping-ai extract - \
|
|
|
118
132
|
--fields '{"title":"Product title","price":"Current price"}' \
|
|
119
133
|
--output products.ndjson
|
|
120
134
|
|
|
135
|
+
# Google results for a query, page 2, from Germany in German
|
|
136
|
+
webscraping-ai serp coffee machines --gl de --hl de --page 2
|
|
137
|
+
|
|
138
|
+
# Just the organic result links
|
|
139
|
+
webscraping-ai search "best espresso grinder" | jq -r '.organic_results[].link'
|
|
140
|
+
|
|
141
|
+
# Structured data for a YouTube video, with its transcript
|
|
142
|
+
webscraping-ai data 'https://www.youtube.com/watch?v=dQw4w9WgXcQ' --transcript | jq '.data.title'
|
|
143
|
+
|
|
144
|
+
# Structured data for a list of profile/post URLs, one JSON result per line
|
|
145
|
+
cat social-urls.txt | webscraping-ai data - --no-pretty -o social.ndjson
|
|
146
|
+
|
|
121
147
|
# Headers from a file
|
|
122
148
|
webscraping-ai html https://example.com --headers @./headers.json
|
|
123
149
|
```
|