scrapingbee-cli 1.4.2__tar.gz → 1.4.3__tar.gz

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.
Files changed (40) hide show
  1. {scrapingbee_cli-1.4.2/src/scrapingbee_cli.egg-info → scrapingbee_cli-1.4.3}/PKG-INFO +2 -2
  2. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/README.md +1 -1
  3. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/pyproject.toml +1 -1
  4. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/__init__.py +2 -2
  5. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/cli.py +1 -0
  6. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/cli_utils.py +1 -1
  7. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/client.py +40 -0
  8. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/commands/amazon.py +155 -0
  9. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/commands/google.py +32 -0
  10. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/credits.py +1 -0
  11. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3/src/scrapingbee_cli.egg-info}/PKG-INFO +2 -2
  12. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/LICENSE +0 -0
  13. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/setup.cfg +0 -0
  14. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/audit.py +0 -0
  15. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/batch.py +0 -0
  16. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/commands/__init__.py +0 -0
  17. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/commands/auth.py +0 -0
  18. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/commands/chatgpt.py +0 -0
  19. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/commands/crawl.py +0 -0
  20. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/commands/export.py +0 -0
  21. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/commands/fast_search.py +0 -0
  22. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/commands/schedule.py +0 -0
  23. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/commands/scrape.py +0 -0
  24. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/commands/tutorial.py +0 -0
  25. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/commands/unsafe.py +0 -0
  26. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/commands/usage.py +0 -0
  27. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/commands/walmart.py +0 -0
  28. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/commands/youtube.py +0 -0
  29. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/config.py +0 -0
  30. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/crawl.py +0 -0
  31. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/exec_gate.py +0 -0
  32. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/extract.py +0 -0
  33. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/tutorial/__init__.py +0 -0
  34. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/tutorial/runner.py +0 -0
  35. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli/tutorial/steps.py +0 -0
  36. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli.egg-info/SOURCES.txt +0 -0
  37. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli.egg-info/dependency_links.txt +0 -0
  38. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli.egg-info/entry_points.txt +0 -0
  39. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli.egg-info/requires.txt +0 -0
  40. {scrapingbee_cli-1.4.2 → scrapingbee_cli-1.4.3}/src/scrapingbee_cli.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scrapingbee-cli
3
- Version: 1.4.2
3
+ Version: 1.4.3
4
4
  Summary: Command-line client for the ScrapingBee API: scrape pages (single or batch), crawl sites, check usage/credits, and use Google Search, Fast Search, Amazon, Walmart, YouTube, and ChatGPT from the terminal.
5
5
  Author: ScrapingBee
6
6
  License-Expression: MIT
@@ -97,7 +97,7 @@ scrapingbee [command] [arguments] [options]
97
97
  | `scrape [url]` | Scrape a URL (HTML, JS, screenshot, extract) |
98
98
  | `crawl` | Crawl sites following links, with AI extraction and save-pattern filtering |
99
99
  | `google` / `fast-search` | Search SERP APIs |
100
- | `amazon-product` / `amazon-search` | Amazon product and search |
100
+ | `amazon-product` / `amazon-pricing` / `amazon-search` | Amazon product, pricing and search |
101
101
  | `walmart-search` / `walmart-product` | Walmart search and product |
102
102
  | `youtube-search` / `youtube-metadata` | YouTube search and video metadata |
103
103
  | `chatgpt` | ChatGPT API (`--search true` for web-enhanced responses) |
@@ -58,7 +58,7 @@ scrapingbee [command] [arguments] [options]
58
58
  | `scrape [url]` | Scrape a URL (HTML, JS, screenshot, extract) |
59
59
  | `crawl` | Crawl sites following links, with AI extraction and save-pattern filtering |
60
60
  | `google` / `fast-search` | Search SERP APIs |
61
- | `amazon-product` / `amazon-search` | Amazon product and search |
61
+ | `amazon-product` / `amazon-pricing` / `amazon-search` | Amazon product, pricing and search |
62
62
  | `walmart-search` / `walmart-product` | Walmart search and product |
63
63
  | `youtube-search` / `youtube-metadata` | YouTube search and video metadata |
64
64
  | `chatgpt` | ChatGPT API (`--search true` for web-enhanced responses) |
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "scrapingbee-cli"
7
- version = "1.4.2"
7
+ version = "1.4.3"
8
8
  description = "Command-line client for the ScrapingBee API: scrape pages (single or batch), crawl sites, check usage/credits, and use Google Search, Fast Search, Amazon, Walmart, YouTube, and ChatGPT from the terminal."
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -3,7 +3,7 @@
3
3
  import platform
4
4
  import sys
5
5
 
6
- __version__ = "1.4.2"
6
+ __version__ = "1.4.3"
7
7
 
8
8
 
9
9
  def user_agent_headers() -> dict[str, str]:
@@ -12,7 +12,7 @@ def user_agent_headers() -> dict[str, str]:
12
12
  Returns a dict of headers:
13
13
  User-Agent: ScrapingBee/CLI
14
14
  User-Agent-Client: scrapingbee-cli
15
- User-Agent-Client-Version: 1.4.2
15
+ User-Agent-Client-Version: 1.4.3
16
16
  User-Agent-Environment: python
17
17
  User-Agent-Environment-Version: 3.14.2
18
18
  User-Agent-OS: Darwin arm64
@@ -137,6 +137,7 @@ def _handle_scraping_config() -> None:
137
137
  "google",
138
138
  "fast-search",
139
139
  "amazon-product",
140
+ "amazon-pricing",
140
141
  "amazon-search",
141
142
  "walmart-search",
142
143
  "walmart-product",
@@ -1231,7 +1231,7 @@ def _validate_page(value: int | None, name: str = "page") -> None:
1231
1231
  raise SystemExit(1)
1232
1232
 
1233
1233
 
1234
- def _validate_price_range(min_price: int | None, max_price: int | None) -> None:
1234
+ def _validate_price_range(min_price: float | None, max_price: float | None) -> None:
1235
1235
  """Validate min_price/max_price: non-negative and min <= max."""
1236
1236
  if min_price is not None and min_price < 0:
1237
1237
  click.echo("min_price must be >= 0", err=True)
@@ -294,6 +294,9 @@ class Client:
294
294
  light_request: bool | None = None,
295
295
  tag: str | None = None,
296
296
  date_range: str | None = None,
297
+ sort_by: str | None = None,
298
+ min_price: float | None = None,
299
+ max_price: float | None = None,
297
300
  retries: int = 3,
298
301
  backoff: float = 2.0,
299
302
  ) -> tuple[bytes, dict, int]:
@@ -310,6 +313,9 @@ class Client:
310
313
  "light_request": self._bool(light_request),
311
314
  "tag": tag,
312
315
  "date_range": date_range,
316
+ "sort_by": sort_by,
317
+ "min_price": min_price,
318
+ "max_price": max_price,
313
319
  }
314
320
  return await self._get_with_retry(
315
321
  "/google",
@@ -378,6 +384,40 @@ class Client:
378
384
  backoff=backoff,
379
385
  )
380
386
 
387
+ async def amazon_pricing(
388
+ self,
389
+ asin: str,
390
+ device: str | None = None,
391
+ domain: str | None = None,
392
+ country: str | None = None,
393
+ zip_code: str | None = None,
394
+ language: str | None = None,
395
+ currency: str | None = None,
396
+ add_html: bool | None = None,
397
+ light_request: bool | None = None,
398
+ tag: str | None = None,
399
+ retries: int = 3,
400
+ backoff: float = 2.0,
401
+ ) -> tuple[bytes, dict, int]:
402
+ params = {
403
+ "asin": asin,
404
+ "device": device,
405
+ "domain": domain,
406
+ "country": country,
407
+ "zip_code": zip_code,
408
+ "language": language,
409
+ "currency": currency,
410
+ "add_html": self._bool(add_html),
411
+ "light_request": self._bool(light_request),
412
+ "tag": tag,
413
+ }
414
+ return await self._get_with_retry(
415
+ "/amazon/pricing",
416
+ params,
417
+ retries=retries,
418
+ backoff=backoff,
419
+ )
420
+
381
421
  async def amazon_search(
382
422
  self,
383
423
  query: str,
@@ -198,6 +198,160 @@ def amazon_product_cmd(
198
198
  asyncio.run(_single())
199
199
 
200
200
 
201
+ @click.command("amazon-pricing")
202
+ @click.argument("asin", required=False)
203
+ @optgroup.group("Locale", help="Device, domain, country, language, and currency")
204
+ @optgroup.option(
205
+ "--device",
206
+ type=click.Choice(["desktop"], case_sensitive=False),
207
+ default=None,
208
+ help="Device: desktop.",
209
+ )
210
+ @optgroup.option(
211
+ "--domain", type=str, default=None, help="Amazon domain (e.g. com, co.uk, de, fr)."
212
+ )
213
+ @optgroup.option("--country", type=str, default=None, help="Country code (e.g. us, gb, de).")
214
+ @optgroup.option(
215
+ "--zip-code", type=str, default=None, help="ZIP code for local availability/pricing."
216
+ )
217
+ @optgroup.option(
218
+ "--language", type=str, default=None, help="Language code (e.g. en_US, es_US, fr_FR)."
219
+ )
220
+ @optgroup.option("--currency", type=str, default=None, help="Currency code (e.g. USD, EUR, GBP).")
221
+ @optgroup.group("Output", help="Response format options")
222
+ @optgroup.option(
223
+ "--add-html", type=str, default=None, help="Include full HTML in response (true/false)."
224
+ )
225
+ @optgroup.option("--light-request", type=str, default=None, help="Light request mode (true/false).")
226
+ @optgroup.option(
227
+ "--tag",
228
+ type=str,
229
+ default=None,
230
+ help="Optional label included in API response headers.",
231
+ )
232
+ @_batch_options
233
+ @click.pass_obj
234
+ def amazon_pricing_cmd(
235
+ obj: dict,
236
+ asin: str | None,
237
+ device: str | None,
238
+ domain: str | None,
239
+ country: str | None,
240
+ zip_code: str | None,
241
+ language: str | None,
242
+ currency: str | None,
243
+ add_html: str | None,
244
+ light_request: str | None,
245
+ tag: str | None,
246
+ **kwargs,
247
+ ) -> None:
248
+ """Fetch Amazon pricing details by ASIN."""
249
+ store_common_options(obj, **kwargs)
250
+ input_file = obj.get("input_file")
251
+ try:
252
+ key = get_api_key(None)
253
+ except ValueError as e:
254
+ click.echo(str(e), err=True)
255
+ raise SystemExit(1)
256
+
257
+ if input_file:
258
+ if asin:
259
+ click.echo("cannot use both --input-file and positional ASIN", err=True)
260
+ raise SystemExit(1)
261
+ try:
262
+ inputs = read_input_file(input_file, input_column=obj.get("input_column"))
263
+ except ValueError as e:
264
+ click.echo(str(e), err=True)
265
+ raise SystemExit(1)
266
+ inputs = prepare_batch_inputs(inputs, obj)
267
+ usage_info = get_batch_usage(None)
268
+ try:
269
+ validate_batch_run(obj["concurrency"], len(inputs), usage_info)
270
+ except ValueError as e:
271
+ click.echo(str(e), err=True)
272
+ raise SystemExit(1)
273
+ concurrency = resolve_batch_concurrency(obj["concurrency"], usage_info, len(inputs))
274
+
275
+ skip_n = (
276
+ _find_completed_n(obj.get("output_dir") or "") if obj.get("resume") else frozenset()
277
+ )
278
+
279
+ async def api_call(client, a):
280
+ return await client.amazon_pricing(
281
+ a,
282
+ device=device,
283
+ domain=domain,
284
+ country=country,
285
+ zip_code=zip_code,
286
+ language=language,
287
+ currency=currency,
288
+ add_html=parse_bool(add_html),
289
+ light_request=parse_bool(light_request),
290
+ tag=tag,
291
+ retries=int(obj.get("retries") or 3),
292
+ backoff=float(obj.get("backoff") or 2.0),
293
+ )
294
+
295
+ run_api_batch(
296
+ key=key,
297
+ inputs=inputs,
298
+ concurrency=concurrency,
299
+ from_user=obj["concurrency"] > 0,
300
+ skip_n=skip_n,
301
+ output_dir=obj.get("output_dir") or None,
302
+ verbose=obj["verbose"],
303
+ show_progress=obj.get("progress", True),
304
+ api_call=api_call,
305
+ on_complete=obj.get("on_complete"),
306
+ output_format=obj.get("output_format"),
307
+ post_process=obj.get("post_process"),
308
+ update_csv_path=input_file if obj.get("update_csv") else None,
309
+ input_column=obj.get("input_column"),
310
+ output_file=obj.get("output_file") or None,
311
+ extract_field=obj.get("extract_field"),
312
+ fields=obj.get("fields"),
313
+ )
314
+ return
315
+
316
+ if not asin:
317
+ click.echo("expected one ASIN, or use --input-file for batch", err=True)
318
+ raise SystemExit(1)
319
+
320
+ async def _single() -> None:
321
+ async with Client(key, BASE_URL) as client:
322
+ data, headers, status_code = await client.amazon_pricing(
323
+ asin,
324
+ device=device,
325
+ domain=domain,
326
+ country=country,
327
+ zip_code=zip_code,
328
+ language=language,
329
+ currency=currency,
330
+ add_html=parse_bool(add_html),
331
+ light_request=parse_bool(light_request),
332
+ tag=tag,
333
+ retries=int(obj.get("retries") or 3),
334
+ backoff=float(obj.get("backoff") or 2.0),
335
+ )
336
+ check_api_response(data, status_code)
337
+ from ..credits import amazon_credits
338
+
339
+ write_output(
340
+ data,
341
+ headers,
342
+ status_code,
343
+ obj["output_file"],
344
+ obj["verbose"],
345
+ smart_extract=obj.get("smart_extract"),
346
+ extract_field=obj.get("extract_field"),
347
+ fields=obj.get("fields"),
348
+ command="amazon-pricing",
349
+ credit_cost=amazon_credits(parse_bool(light_request)),
350
+ )
351
+
352
+ asyncio.run(_single())
353
+
354
+
201
355
  @click.command("amazon-search")
202
356
  @click.argument("query", required=False)
203
357
  @optgroup.group("Pagination & sort", help="Pages and sort order")
@@ -387,4 +541,5 @@ def amazon_search_cmd(
387
541
 
388
542
  def register(cli: click.Group) -> None:
389
543
  cli.add_command(amazon_product_cmd, "amazon-product")
544
+ cli.add_command(amazon_pricing_cmd, "amazon-pricing")
390
545
  cli.add_command(amazon_search_cmd, "amazon-search")
@@ -20,6 +20,7 @@ from ..cli_utils import (
20
20
  NormalizedChoice,
21
21
  _batch_options,
22
22
  _validate_page,
23
+ _validate_price_range,
23
24
  check_api_response,
24
25
  norm_val,
25
26
  parse_bool,
@@ -92,6 +93,27 @@ def _warn_empty_organic(data: bytes, search_type: str | None) -> None:
92
93
  default=None,
93
94
  help="Restrict results to the past hour/day/week/month/year.",
94
95
  )
96
+ @optgroup.group("Shopping", help="Options for --search-type shopping only")
97
+ @optgroup.option(
98
+ "--sort-by",
99
+ type=NormalizedChoice(
100
+ ["relevance", "reviews", "price-asc", "price-desc"], case_sensitive=False
101
+ ),
102
+ default=None,
103
+ help="Sort Shopping results: relevance, reviews, price-asc, price-desc.",
104
+ )
105
+ @optgroup.option(
106
+ "--min-price",
107
+ type=float,
108
+ default=None,
109
+ help="Minimum price filter, in the marketplace's native currency.",
110
+ )
111
+ @optgroup.option(
112
+ "--max-price",
113
+ type=float,
114
+ default=None,
115
+ help="Maximum price filter, in the marketplace's native currency.",
116
+ )
95
117
  @optgroup.group("Filters", help="Autocorrection, extra params, and response format")
96
118
  @optgroup.option("--nfpr", type=str, default=None, help="Disable autocorrection (true/false).")
97
119
  @optgroup.option(
@@ -128,6 +150,9 @@ def google_cmd(
128
150
  light_request: str | None,
129
151
  tag: str | None,
130
152
  date_range: str | None,
153
+ sort_by: str | None,
154
+ min_price: float | None,
155
+ max_price: float | None,
131
156
  **kwargs,
132
157
  ) -> None:
133
158
  """Search Google using the Google Search API."""
@@ -139,6 +164,7 @@ def google_cmd(
139
164
  click.echo(str(e), err=True)
140
165
  raise SystemExit(1)
141
166
  _validate_page(page)
167
+ _validate_price_range(min_price, max_price)
142
168
 
143
169
  if input_file:
144
170
  if query:
@@ -176,6 +202,9 @@ def google_cmd(
176
202
  light_request=parse_bool(light_request),
177
203
  tag=tag,
178
204
  date_range=norm_val(date_range),
205
+ sort_by=norm_val(sort_by),
206
+ min_price=min_price,
207
+ max_price=max_price,
179
208
  retries=int(obj.get("retries") or 3),
180
209
  backoff=float(obj.get("backoff") or 2.0),
181
210
  )
@@ -220,6 +249,9 @@ def google_cmd(
220
249
  light_request=parse_bool(light_request),
221
250
  tag=tag,
222
251
  date_range=norm_val(date_range),
252
+ sort_by=norm_val(sort_by),
253
+ min_price=min_price,
254
+ max_price=max_price,
223
255
  retries=int(obj.get("retries") or 3),
224
256
  backoff=float(obj.get("backoff") or 2.0),
225
257
  )
@@ -12,6 +12,7 @@ ESTIMATED_CREDITS: dict[str, str] = {
12
12
  "google": "10-15",
13
13
  "fast-search": "10",
14
14
  "amazon-product": "5-15",
15
+ "amazon-pricing": "5-15",
15
16
  "amazon-search": "5-15",
16
17
  "walmart-search": "10-15",
17
18
  "walmart-product": "10-15",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scrapingbee-cli
3
- Version: 1.4.2
3
+ Version: 1.4.3
4
4
  Summary: Command-line client for the ScrapingBee API: scrape pages (single or batch), crawl sites, check usage/credits, and use Google Search, Fast Search, Amazon, Walmart, YouTube, and ChatGPT from the terminal.
5
5
  Author: ScrapingBee
6
6
  License-Expression: MIT
@@ -97,7 +97,7 @@ scrapingbee [command] [arguments] [options]
97
97
  | `scrape [url]` | Scrape a URL (HTML, JS, screenshot, extract) |
98
98
  | `crawl` | Crawl sites following links, with AI extraction and save-pattern filtering |
99
99
  | `google` / `fast-search` | Search SERP APIs |
100
- | `amazon-product` / `amazon-search` | Amazon product and search |
100
+ | `amazon-product` / `amazon-pricing` / `amazon-search` | Amazon product, pricing and search |
101
101
  | `walmart-search` / `walmart-product` | Walmart search and product |
102
102
  | `youtube-search` / `youtube-metadata` | YouTube search and video metadata |
103
103
  | `chatgpt` | ChatGPT API (`--search true` for web-enhanced responses) |
File without changes