nocode-amazon 0.0.1__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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 wordstotech
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,2 @@
1
+ include README.md
2
+ include LICENSE
@@ -0,0 +1,244 @@
1
+ Metadata-Version: 2.4
2
+ Name: nocode-amazon
3
+ Version: 0.0.1
4
+ Summary: No code Amazon scraper and Amazon API client: search, product, pricing and featured or sponsored placements via ScrapingBee.
5
+ Author: wordstotech
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/ScrapingBee/nocode-amazon
8
+ Project-URL: Repository, https://github.com/ScrapingBee/nocode-amazon
9
+ Project-URL: Documentation, https://www.scrapingbee.com/documentation/
10
+ Keywords: amazon scraper,amazon api,no code scraper,scrape amazon products,amazon product scraper,amazon featured products,web scraping,scrapingbee
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.8
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Internet :: WWW/HTTP
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Classifier: Topic :: Text Processing :: Markup :: HTML
25
+ Requires-Python: >=3.8
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: requests>=2.25.0
29
+ Dynamic: license-file
30
+
31
+ # nocode-amazon
32
+
33
+ A Python client for ScrapingBee's three dedicated Amazon endpoints, plus the helpers that separate paid placements from earned ones.
34
+
35
+ The package name comes from the no code Make and Airtable workflow this grew out of. The library is the code path for people who outgrew the spreadsheet: same data, same public Amazon pages, no visual scenario to maintain.
36
+
37
+ **Verified against the live API on 2026-09-10.** Every parameter name, response field and credit figure below came back from a real call. Where the documentation and the API disagreed, the API won and the difference is noted.
38
+
39
+ ```bash
40
+ pip install nocode-amazon
41
+ ```
42
+
43
+ Requires Python 3.8 or newer and `requests`.
44
+
45
+ ## Authentication
46
+
47
+ Header based, on every request:
48
+
49
+ ```
50
+ Authorization: Bearer YOUR_API_KEY
51
+ ```
52
+
53
+ The `api_key` query parameter still answers but the current documentation marks it deprecated. This client sends the header.
54
+
55
+ ```python
56
+ from nocode_amazon import AmazonScraper
57
+
58
+ bee = AmazonScraper("YOUR_API_KEY")
59
+ ```
60
+
61
+ Get a key and 1,000 free credits from [ScrapingBee](https://www.scrapingbee.com/). Full reference: [Amazon API documentation](https://www.scrapingbee.com/documentation/amazon/).
62
+
63
+ ---
64
+
65
+ ## Endpoint reference
66
+
67
+ ### `search(query, pages=1, **params)`
68
+
69
+ `GET /api/v1/amazon/search`. **5 credits per page.**
70
+
71
+ Amazon search results as structured JSON. No HTML, no selectors.
72
+
73
+ ```python
74
+ page = bee.search("fitness tracker")
75
+ page["products_count"] # 23
76
+ page["products"] # list of product dicts
77
+ page["refinements"] # Amazon's own facets for this query
78
+ page["url"] # the Amazon URL that was fetched
79
+ page["page"] # 1
80
+ ```
81
+
82
+ Live call on `fitness tracker` returned 23 products and a `refinements` object with 53 facet groups, including `brands`, `band_color`, `band_material_type`, `battery_average_life`, `battery_charge_time` and `case_diameter`.
83
+
84
+ Optional parameters, all verified present on the endpoint:
85
+
86
+ | Parameter | Notes |
87
+ |---|---|
88
+ | `pages` | Pages to fetch. Billed per page |
89
+ | `sort_by` | `featured`, `most_recent`, `price_low_to_high`, `price_high_to_low`, `average_review`, `bestsellers` |
90
+ | `category_id` | Restrict to one Amazon category |
91
+ | `merchant_id` | Restrict to one seller |
92
+ | `domain` | Marketplace top level domain: `com`, `co.uk`, `de`, `in` |
93
+ | `country` | Proxy geolocation |
94
+ | `currency` | ISO 4217 display currency |
95
+ | `language` | ISO language code |
96
+ | `device` | `desktop` or `mobile` |
97
+ | `zip_code` | Postal code. Changes prices and delivery promises |
98
+ | `light_request` | Default `True` at 5 credits. `False` forces a browser at 15 |
99
+ | `add_html` | Include the raw page alongside the JSON |
100
+ | `autoselect_variant` | Pick a variant automatically |
101
+ | `screenshot` | Capture the page. Always 15 credits, ignores `light_request` |
102
+ | `tag` | Your own label, returned in the response headers |
103
+
104
+ Related landing pages: [Amazon search API](https://www.scrapingbee.com/scrapers/amazon-search-api/), [Amazon keyword scraper API](https://www.scrapingbee.com/scrapers/amazon-keyword-scraper-api/), [Amazon organic results API](https://www.scrapingbee.com/scrapers/amazon-organic-results-api/), [Amazon filters API](https://www.scrapingbee.com/scrapers/amazon-filters-api/), [Amazon related searches API](https://www.scrapingbee.com/scrapers/amazon-related-searches-api/), [Amazon spell check API](https://www.scrapingbee.com/scrapers/amazon-spell-check-api/), [Amazon zip code API](https://www.scrapingbee.com/scrapers/amazon-zip-code-api/).
105
+
106
+ ### `product(asin, **params)`
107
+
108
+ `GET /api/v1/amazon/product`. **5 credits.**
109
+
110
+ **The wire parameter is `query`, not `asin`.** The value has to be a valid 10 character ASIN, but the field is named `query`. This client takes `asin` as its argument name and sends `query` for you.
111
+
112
+ ```python
113
+ detail = bee.product("B0GTMTZF3V")
114
+ detail["brand"] # 'Fitbit'
115
+ detail["price"] # 99.99
116
+ detail["currency"] # 'USD'
117
+ detail["rating"] # 4.3
118
+ detail["reviews_count"] # 2036
119
+ ```
120
+
121
+ The live response carried **56 top level keys**. The ones worth knowing:
122
+
123
+ | Field | Contents |
124
+ |---|---|
125
+ | `bullet_points` | The feature bullets, newline separated |
126
+ | `category` | A `ladder` of breadcrumb steps, each with `name` and `url` |
127
+ | `featured_merchant` | `name`, `seller_id`, `shipped_from`, `is_amazon_fulfilled` |
128
+ | `product_details` | Spec table as key and value pairs, including `best_sellers_rank` |
129
+ | `technical_details` | The second spec table |
130
+ | `rating_stars_distribution` | Review counts per star rating |
131
+ | `sales_rank` | Category rank entries |
132
+ | `variations` | Other sizes, colours and configurations |
133
+ | `images` | Image URLs |
134
+ | `delivery` | Delivery promises with type and date |
135
+ | `pricing_url` | The offer listing page for this ASIN |
136
+ | `parent_asin` | The variation parent |
137
+ | `discount_percentage`, `price_strikethrough`, `coupon` | Promotion state |
138
+ | `stock`, `max_quantity` | Availability |
139
+
140
+ Related: [Amazon ASIN API](https://www.scrapingbee.com/scrapers/amazon-asin-api/), [Amazon image API](https://www.scrapingbee.com/scrapers/amazon-image-api/), [Amazon review API](https://www.scrapingbee.com/scrapers/amazon-review-api/), [Amazon best sellers API](https://www.scrapingbee.com/scrapers/amazon-best-sellers-api/), [Amazon video results API](https://www.scrapingbee.com/scrapers/amazon-video-results-api/), [Amazon URL API](https://www.scrapingbee.com/scrapers/amazon-ulr-api/).
141
+
142
+ ### `pricing(asin, **params)`
143
+
144
+ `GET /api/v1/amazon/pricing`. **5 credits.**
145
+
146
+ **This endpoint takes `asin` on the wire.** Search and product both take `query`. Pricing does not, and it rejects `query` explicitly:
147
+
148
+ ```json
149
+ {"errors": {"query": {"asin": ["Missing data for required field."], "query": ["Unknown field."]}}}
150
+ ```
151
+
152
+ That rejected call was billed **0 credits**, confirmed by `spb-cost: 0` on the response. This client raises `ScrapingBeeError` with the API's own error dict in `.payload`, so the offending field is never a guess.
153
+
154
+ ```python
155
+ offers = bee.pricing("B0GTMTZF3V")
156
+ for offer in offers["pricing"]:
157
+ print(offer["seller"], offer["price"], offer["condition"])
158
+ ```
159
+
160
+ Each offer carries `seller`, `seller_id`, `seller_link`, `condition`, `price`, `price_shipping`, `currency`, `rating_count` and a `delivery_options` list.
161
+
162
+ Related: [Amazon offers API](https://www.scrapingbee.com/scrapers/amazon-offers-api/), [Amazon seller API](https://www.scrapingbee.com/scrapers/amazon-seller-api/), [Amazon vendor API](https://www.scrapingbee.com/scrapers/amazon-vendor-api/), [Amazon shipping API](https://www.scrapingbee.com/scrapers/amazon-shipping-api/).
163
+
164
+ ### `usage()`
165
+
166
+ `GET /api/v1/usage`. **Free.**
167
+
168
+ ```python
169
+ bee.usage()
170
+ # {'max_api_credit': 1000000, 'used_api_credit': 353946,
171
+ # 'max_concurrency': 100, 'current_concurrency': 0,
172
+ # 'renewal_subscription_date': '2026-09-21T12:06:28'}
173
+ ```
174
+
175
+ Call this before a large run. Note it lags by minutes, so do not read it immediately afterwards to compute what a batch cost.
176
+
177
+ ---
178
+
179
+ ## Placement helpers
180
+
181
+ Amazon search markup gives every card the same classes, so CSS selectors cannot tell a paid slot from an earned rank. The endpoint labels each result instead, which turns the problem into a filter.
182
+
183
+ Per product placement fields:
184
+
185
+ | Field | Type | Meaning |
186
+ |---|---|---|
187
+ | `is_sponsored` | bool | Paid placement |
188
+ | `sponsored_position` | int or None | Rank among the ads |
189
+ | `organic_position` | int or None | Rank among earned results |
190
+ | `is_amazons_choice` | bool | Amazon's Choice badge |
191
+ | `best_seller` | bool | Best Seller badge |
192
+ | `sales_volume` | str | For example `10K+ bought in past month` |
193
+
194
+ ```python
195
+ page = bee.search("fitness tracker", sort_by="featured")
196
+
197
+ AmazonScraper.featured(page) # sponsored, ordered by ad slot
198
+ AmazonScraper.organic(page) # earned, ordered by organic rank
199
+ AmazonScraper.badged(page) # Amazon's Choice or Best Seller
200
+ AmazonScraper.facets(page) # the refinements object
201
+ ```
202
+
203
+ Two live runs on the same query returned 7 featured of 24 products, then 9 of 26. Paid density moves between requests, so measure it rather than assuming a fixed ratio.
204
+
205
+ `is_prime` came back `False` on every row of both pages, so verify it against your own target category before building a Prime filter on it.
206
+
207
+ ---
208
+
209
+ ## Credit cost
210
+
211
+ Measured from `spb-cost` response headers, not quoted from a pricing page. This client stores the value on `bee.last_cost` after every call.
212
+
213
+ | Call | Credits |
214
+ |---|---|
215
+ | Search, default light request | 5 per page |
216
+ | Search, `light_request=False` | 15 per page |
217
+ | Product, default | 5 |
218
+ | Product, `light_request=False` | 15 |
219
+ | Pricing | 5 |
220
+ | Any screenshot | 15 |
221
+ | Rejected request | 0 |
222
+ | `usage()` | 0 |
223
+
224
+ Light requests skip the browser. They were sufficient for search, product and pricing on every call made here. Turn them off when you need review text or other content that appears only after JavaScript runs.
225
+
226
+ Failed requests are retried inside the API for up to 30 seconds, so set client timeouts above that. This client defaults to 60 seconds.
227
+
228
+ Plan tiers: [ScrapingBee pricing](https://www.scrapingbee.com/pricing).
229
+
230
+ ---
231
+
232
+ ## Scope
233
+
234
+ Public Amazon listing and product pages. Nothing in this package signs in, and scraping under login credentials is prohibited by ScrapingBee's terms of service.
235
+
236
+ ## Related features
237
+
238
+ [AI web scraping](https://www.scrapingbee.com/features/ai-web-scraping-api/), [data extraction rules](https://www.scrapingbee.com/features/data-extraction/), [Amazon feature page](https://www.scrapingbee.com/features/amazon/), [screenshots](https://www.scrapingbee.com/features/screenshot/), [markdown scraper](https://www.scrapingbee.com/features/markdown-scraper/), [Make integration](https://www.scrapingbee.com/features/make/), [n8n integration](https://www.scrapingbee.com/features/n8n/), [Zapier integration](https://www.scrapingbee.com/features/zapier/).
239
+
240
+ The no code version of this workflow, with the Make scenario and the extraction rules, is at [github.com/ScrapingBee/nocode-amazon](https://github.com/ScrapingBee/nocode-amazon).
241
+
242
+ ## License
243
+
244
+ MIT
@@ -0,0 +1,214 @@
1
+ # nocode-amazon
2
+
3
+ A Python client for ScrapingBee's three dedicated Amazon endpoints, plus the helpers that separate paid placements from earned ones.
4
+
5
+ The package name comes from the no code Make and Airtable workflow this grew out of. The library is the code path for people who outgrew the spreadsheet: same data, same public Amazon pages, no visual scenario to maintain.
6
+
7
+ **Verified against the live API on 2026-09-10.** Every parameter name, response field and credit figure below came back from a real call. Where the documentation and the API disagreed, the API won and the difference is noted.
8
+
9
+ ```bash
10
+ pip install nocode-amazon
11
+ ```
12
+
13
+ Requires Python 3.8 or newer and `requests`.
14
+
15
+ ## Authentication
16
+
17
+ Header based, on every request:
18
+
19
+ ```
20
+ Authorization: Bearer YOUR_API_KEY
21
+ ```
22
+
23
+ The `api_key` query parameter still answers but the current documentation marks it deprecated. This client sends the header.
24
+
25
+ ```python
26
+ from nocode_amazon import AmazonScraper
27
+
28
+ bee = AmazonScraper("YOUR_API_KEY")
29
+ ```
30
+
31
+ Get a key and 1,000 free credits from [ScrapingBee](https://www.scrapingbee.com/). Full reference: [Amazon API documentation](https://www.scrapingbee.com/documentation/amazon/).
32
+
33
+ ---
34
+
35
+ ## Endpoint reference
36
+
37
+ ### `search(query, pages=1, **params)`
38
+
39
+ `GET /api/v1/amazon/search`. **5 credits per page.**
40
+
41
+ Amazon search results as structured JSON. No HTML, no selectors.
42
+
43
+ ```python
44
+ page = bee.search("fitness tracker")
45
+ page["products_count"] # 23
46
+ page["products"] # list of product dicts
47
+ page["refinements"] # Amazon's own facets for this query
48
+ page["url"] # the Amazon URL that was fetched
49
+ page["page"] # 1
50
+ ```
51
+
52
+ Live call on `fitness tracker` returned 23 products and a `refinements` object with 53 facet groups, including `brands`, `band_color`, `band_material_type`, `battery_average_life`, `battery_charge_time` and `case_diameter`.
53
+
54
+ Optional parameters, all verified present on the endpoint:
55
+
56
+ | Parameter | Notes |
57
+ |---|---|
58
+ | `pages` | Pages to fetch. Billed per page |
59
+ | `sort_by` | `featured`, `most_recent`, `price_low_to_high`, `price_high_to_low`, `average_review`, `bestsellers` |
60
+ | `category_id` | Restrict to one Amazon category |
61
+ | `merchant_id` | Restrict to one seller |
62
+ | `domain` | Marketplace top level domain: `com`, `co.uk`, `de`, `in` |
63
+ | `country` | Proxy geolocation |
64
+ | `currency` | ISO 4217 display currency |
65
+ | `language` | ISO language code |
66
+ | `device` | `desktop` or `mobile` |
67
+ | `zip_code` | Postal code. Changes prices and delivery promises |
68
+ | `light_request` | Default `True` at 5 credits. `False` forces a browser at 15 |
69
+ | `add_html` | Include the raw page alongside the JSON |
70
+ | `autoselect_variant` | Pick a variant automatically |
71
+ | `screenshot` | Capture the page. Always 15 credits, ignores `light_request` |
72
+ | `tag` | Your own label, returned in the response headers |
73
+
74
+ Related landing pages: [Amazon search API](https://www.scrapingbee.com/scrapers/amazon-search-api/), [Amazon keyword scraper API](https://www.scrapingbee.com/scrapers/amazon-keyword-scraper-api/), [Amazon organic results API](https://www.scrapingbee.com/scrapers/amazon-organic-results-api/), [Amazon filters API](https://www.scrapingbee.com/scrapers/amazon-filters-api/), [Amazon related searches API](https://www.scrapingbee.com/scrapers/amazon-related-searches-api/), [Amazon spell check API](https://www.scrapingbee.com/scrapers/amazon-spell-check-api/), [Amazon zip code API](https://www.scrapingbee.com/scrapers/amazon-zip-code-api/).
75
+
76
+ ### `product(asin, **params)`
77
+
78
+ `GET /api/v1/amazon/product`. **5 credits.**
79
+
80
+ **The wire parameter is `query`, not `asin`.** The value has to be a valid 10 character ASIN, but the field is named `query`. This client takes `asin` as its argument name and sends `query` for you.
81
+
82
+ ```python
83
+ detail = bee.product("B0GTMTZF3V")
84
+ detail["brand"] # 'Fitbit'
85
+ detail["price"] # 99.99
86
+ detail["currency"] # 'USD'
87
+ detail["rating"] # 4.3
88
+ detail["reviews_count"] # 2036
89
+ ```
90
+
91
+ The live response carried **56 top level keys**. The ones worth knowing:
92
+
93
+ | Field | Contents |
94
+ |---|---|
95
+ | `bullet_points` | The feature bullets, newline separated |
96
+ | `category` | A `ladder` of breadcrumb steps, each with `name` and `url` |
97
+ | `featured_merchant` | `name`, `seller_id`, `shipped_from`, `is_amazon_fulfilled` |
98
+ | `product_details` | Spec table as key and value pairs, including `best_sellers_rank` |
99
+ | `technical_details` | The second spec table |
100
+ | `rating_stars_distribution` | Review counts per star rating |
101
+ | `sales_rank` | Category rank entries |
102
+ | `variations` | Other sizes, colours and configurations |
103
+ | `images` | Image URLs |
104
+ | `delivery` | Delivery promises with type and date |
105
+ | `pricing_url` | The offer listing page for this ASIN |
106
+ | `parent_asin` | The variation parent |
107
+ | `discount_percentage`, `price_strikethrough`, `coupon` | Promotion state |
108
+ | `stock`, `max_quantity` | Availability |
109
+
110
+ Related: [Amazon ASIN API](https://www.scrapingbee.com/scrapers/amazon-asin-api/), [Amazon image API](https://www.scrapingbee.com/scrapers/amazon-image-api/), [Amazon review API](https://www.scrapingbee.com/scrapers/amazon-review-api/), [Amazon best sellers API](https://www.scrapingbee.com/scrapers/amazon-best-sellers-api/), [Amazon video results API](https://www.scrapingbee.com/scrapers/amazon-video-results-api/), [Amazon URL API](https://www.scrapingbee.com/scrapers/amazon-ulr-api/).
111
+
112
+ ### `pricing(asin, **params)`
113
+
114
+ `GET /api/v1/amazon/pricing`. **5 credits.**
115
+
116
+ **This endpoint takes `asin` on the wire.** Search and product both take `query`. Pricing does not, and it rejects `query` explicitly:
117
+
118
+ ```json
119
+ {"errors": {"query": {"asin": ["Missing data for required field."], "query": ["Unknown field."]}}}
120
+ ```
121
+
122
+ That rejected call was billed **0 credits**, confirmed by `spb-cost: 0` on the response. This client raises `ScrapingBeeError` with the API's own error dict in `.payload`, so the offending field is never a guess.
123
+
124
+ ```python
125
+ offers = bee.pricing("B0GTMTZF3V")
126
+ for offer in offers["pricing"]:
127
+ print(offer["seller"], offer["price"], offer["condition"])
128
+ ```
129
+
130
+ Each offer carries `seller`, `seller_id`, `seller_link`, `condition`, `price`, `price_shipping`, `currency`, `rating_count` and a `delivery_options` list.
131
+
132
+ Related: [Amazon offers API](https://www.scrapingbee.com/scrapers/amazon-offers-api/), [Amazon seller API](https://www.scrapingbee.com/scrapers/amazon-seller-api/), [Amazon vendor API](https://www.scrapingbee.com/scrapers/amazon-vendor-api/), [Amazon shipping API](https://www.scrapingbee.com/scrapers/amazon-shipping-api/).
133
+
134
+ ### `usage()`
135
+
136
+ `GET /api/v1/usage`. **Free.**
137
+
138
+ ```python
139
+ bee.usage()
140
+ # {'max_api_credit': 1000000, 'used_api_credit': 353946,
141
+ # 'max_concurrency': 100, 'current_concurrency': 0,
142
+ # 'renewal_subscription_date': '2026-09-21T12:06:28'}
143
+ ```
144
+
145
+ Call this before a large run. Note it lags by minutes, so do not read it immediately afterwards to compute what a batch cost.
146
+
147
+ ---
148
+
149
+ ## Placement helpers
150
+
151
+ Amazon search markup gives every card the same classes, so CSS selectors cannot tell a paid slot from an earned rank. The endpoint labels each result instead, which turns the problem into a filter.
152
+
153
+ Per product placement fields:
154
+
155
+ | Field | Type | Meaning |
156
+ |---|---|---|
157
+ | `is_sponsored` | bool | Paid placement |
158
+ | `sponsored_position` | int or None | Rank among the ads |
159
+ | `organic_position` | int or None | Rank among earned results |
160
+ | `is_amazons_choice` | bool | Amazon's Choice badge |
161
+ | `best_seller` | bool | Best Seller badge |
162
+ | `sales_volume` | str | For example `10K+ bought in past month` |
163
+
164
+ ```python
165
+ page = bee.search("fitness tracker", sort_by="featured")
166
+
167
+ AmazonScraper.featured(page) # sponsored, ordered by ad slot
168
+ AmazonScraper.organic(page) # earned, ordered by organic rank
169
+ AmazonScraper.badged(page) # Amazon's Choice or Best Seller
170
+ AmazonScraper.facets(page) # the refinements object
171
+ ```
172
+
173
+ Two live runs on the same query returned 7 featured of 24 products, then 9 of 26. Paid density moves between requests, so measure it rather than assuming a fixed ratio.
174
+
175
+ `is_prime` came back `False` on every row of both pages, so verify it against your own target category before building a Prime filter on it.
176
+
177
+ ---
178
+
179
+ ## Credit cost
180
+
181
+ Measured from `spb-cost` response headers, not quoted from a pricing page. This client stores the value on `bee.last_cost` after every call.
182
+
183
+ | Call | Credits |
184
+ |---|---|
185
+ | Search, default light request | 5 per page |
186
+ | Search, `light_request=False` | 15 per page |
187
+ | Product, default | 5 |
188
+ | Product, `light_request=False` | 15 |
189
+ | Pricing | 5 |
190
+ | Any screenshot | 15 |
191
+ | Rejected request | 0 |
192
+ | `usage()` | 0 |
193
+
194
+ Light requests skip the browser. They were sufficient for search, product and pricing on every call made here. Turn them off when you need review text or other content that appears only after JavaScript runs.
195
+
196
+ Failed requests are retried inside the API for up to 30 seconds, so set client timeouts above that. This client defaults to 60 seconds.
197
+
198
+ Plan tiers: [ScrapingBee pricing](https://www.scrapingbee.com/pricing).
199
+
200
+ ---
201
+
202
+ ## Scope
203
+
204
+ Public Amazon listing and product pages. Nothing in this package signs in, and scraping under login credentials is prohibited by ScrapingBee's terms of service.
205
+
206
+ ## Related features
207
+
208
+ [AI web scraping](https://www.scrapingbee.com/features/ai-web-scraping-api/), [data extraction rules](https://www.scrapingbee.com/features/data-extraction/), [Amazon feature page](https://www.scrapingbee.com/features/amazon/), [screenshots](https://www.scrapingbee.com/features/screenshot/), [markdown scraper](https://www.scrapingbee.com/features/markdown-scraper/), [Make integration](https://www.scrapingbee.com/features/make/), [n8n integration](https://www.scrapingbee.com/features/n8n/), [Zapier integration](https://www.scrapingbee.com/features/zapier/).
209
+
210
+ The no code version of this workflow, with the Make scenario and the extraction rules, is at [github.com/ScrapingBee/nocode-amazon](https://github.com/ScrapingBee/nocode-amazon).
211
+
212
+ ## License
213
+
214
+ MIT
@@ -0,0 +1,38 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "nocode-amazon"
7
+ version = "0.0.1"
8
+ description = "No code Amazon scraper and Amazon API client: search, product, pricing and featured or sponsored placements via ScrapingBee."
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+ license = { text = "MIT" }
12
+ authors = [{ name = "wordstotech" }]
13
+ keywords = ["amazon scraper", "amazon api", "no code scraper", "scrape amazon products", "amazon product scraper", "amazon featured products", "web scraping", "scrapingbee"]
14
+ dependencies = ["requests>=2.25.0"]
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Intended Audience :: Developers",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Operating System :: OS Independent",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.8",
22
+ "Programming Language :: Python :: 3.9",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Programming Language :: Python :: 3.13",
27
+ "Topic :: Internet :: WWW/HTTP",
28
+ "Topic :: Software Development :: Libraries :: Python Modules",
29
+ "Topic :: Text Processing :: Markup :: HTML",
30
+ ]
31
+
32
+ [project.urls]
33
+ Homepage = "https://github.com/ScrapingBee/nocode-amazon"
34
+ Repository = "https://github.com/ScrapingBee/nocode-amazon"
35
+ Documentation = "https://www.scrapingbee.com/documentation/"
36
+
37
+ [tool.setuptools.packages.find]
38
+ where = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,6 @@
1
+ """No code Amazon scraper, plus a client for the ScrapingBee Amazon API."""
2
+
3
+ from .client import AmazonScraper, ScrapingBeeError
4
+
5
+ __all__ = ["AmazonScraper", "ScrapingBeeError"]
6
+ __version__ = "0.0.1"
@@ -0,0 +1,205 @@
1
+ """ScrapingBee Amazon API client.
2
+
3
+ Every endpoint, parameter name and credit figure here was verified against
4
+ the live API on 2026-09-10. Auth is the Authorization Bearer header, which
5
+ is what the current documentation uses. The api_key query parameter still
6
+ answers but is marked deprecated.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from typing import Any, Dict, List, Optional
12
+
13
+ import requests
14
+
15
+ __all__ = ["AmazonScraper", "ScrapingBeeError"]
16
+
17
+ BASE_URL = "https://app.scrapingbee.com/api/v1"
18
+
19
+
20
+ class ScrapingBeeError(RuntimeError):
21
+ """Raised when the API returns a validation error or a failed request."""
22
+
23
+ def __init__(self, message: str, status: Optional[int] = None,
24
+ payload: Any = None) -> None:
25
+ super().__init__(message)
26
+ self.status = status
27
+ self.payload = payload
28
+
29
+
30
+ class AmazonScraper:
31
+ """Client for the three dedicated ScrapingBee Amazon endpoints.
32
+
33
+ >>> bee = AmazonScraper("YOUR_API_KEY")
34
+ >>> page = bee.search("fitness tracker")
35
+ >>> len(bee.featured(page))
36
+ 3
37
+
38
+ Credit cost, measured live: 5 per call on a light request, 15 with
39
+ ``light_request=False``, 15 for any screenshot, 0 for a rejected
40
+ request. Search bills per page.
41
+ """
42
+
43
+ def __init__(self, api_key: str, base_url: str = BASE_URL,
44
+ timeout: int = 60, session: Optional[requests.Session] = None) -> None:
45
+ if not api_key:
46
+ raise ValueError("api_key is required")
47
+ self.api_key = api_key
48
+ self.base_url = base_url.rstrip("/")
49
+ self.timeout = timeout
50
+ self._session = session or requests.Session()
51
+ self.last_cost: Optional[int] = None
52
+
53
+ # ------------------------------------------------------------------ core
54
+
55
+ def _get(self, path: str, params: Dict[str, Any]) -> Dict[str, Any]:
56
+ clean = {k: v for k, v in params.items() if v is not None}
57
+ for key, value in list(clean.items()):
58
+ if isinstance(value, bool):
59
+ clean[key] = "true" if value else "false"
60
+
61
+ response = self._session.get(
62
+ f"{self.base_url}/{path}",
63
+ headers={"Authorization": f"Bearer {self.api_key}"},
64
+ params=clean,
65
+ timeout=self.timeout,
66
+ )
67
+
68
+ # Cost arrives as a response header. Names are lowercased over HTTP/2.
69
+ cost = response.headers.get("spb-cost")
70
+ self.last_cost = int(cost) if cost and cost.isdigit() else None
71
+
72
+ try:
73
+ body = response.json()
74
+ except ValueError:
75
+ raise ScrapingBeeError(
76
+ f"non JSON response ({response.status_code})",
77
+ response.status_code,
78
+ response.text[:500],
79
+ ) from None
80
+
81
+ # The API names the offending field, so surface it rather than a guess.
82
+ if isinstance(body, dict) and "errors" in body:
83
+ raise ScrapingBeeError(
84
+ f"API rejected the request: {body['errors']}",
85
+ response.status_code,
86
+ body["errors"],
87
+ )
88
+ response.raise_for_status()
89
+ return body
90
+
91
+ # ------------------------------------------------------------- endpoints
92
+
93
+ def search(self, query: str, pages: int = 1, *, sort_by: Optional[str] = None,
94
+ category_id: Optional[str] = None, merchant_id: Optional[str] = None,
95
+ country: Optional[str] = None, currency: Optional[str] = None,
96
+ domain: Optional[str] = None, language: Optional[str] = None,
97
+ device: Optional[str] = None, zip_code: Optional[str] = None,
98
+ light_request: Optional[bool] = None, add_html: Optional[bool] = None,
99
+ autoselect_variant: Optional[bool] = None,
100
+ screenshot: Optional[bool] = None,
101
+ tag: Optional[str] = None) -> Dict[str, Any]:
102
+ """Amazon search results. 5 credits per page.
103
+
104
+ Returns ``products``, ``products_count``, ``refinements``, ``url``
105
+ and ``page``. ``sort_by`` accepts ``featured``, ``most_recent``,
106
+ ``price_low_to_high``, ``price_high_to_low``, ``average_review``
107
+ and ``bestsellers``.
108
+
109
+ ``domain`` selects the marketplace, for example ``co.uk`` or ``in``.
110
+ ``zip_code`` matters because Amazon prices and delivery promises are
111
+ postal code dependent.
112
+ """
113
+ return self._get("amazon/search", {
114
+ "query": query, "pages": pages, "sort_by": sort_by,
115
+ "category_id": category_id, "merchant_id": merchant_id,
116
+ "country": country, "currency": currency, "domain": domain,
117
+ "language": language, "device": device, "zip_code": zip_code,
118
+ "light_request": light_request, "add_html": add_html,
119
+ "autoselect_variant": autoselect_variant,
120
+ "screenshot": screenshot, "tag": tag,
121
+ })
122
+
123
+ def product(self, asin: str, *, country: Optional[str] = None,
124
+ currency: Optional[str] = None, domain: Optional[str] = None,
125
+ language: Optional[str] = None, device: Optional[str] = None,
126
+ zip_code: Optional[str] = None, light_request: Optional[bool] = None,
127
+ add_html: Optional[bool] = None, screenshot: Optional[bool] = None,
128
+ tag: Optional[str] = None) -> Dict[str, Any]:
129
+ """Structured product detail. 5 credits.
130
+
131
+ Note the wire parameter is ``query``, not ``asin``, even though the
132
+ value must be a 10 character ASIN. Sending ``asin`` here is rejected.
133
+
134
+ The live response carries 56 top level keys, including ``price``,
135
+ ``brand``, ``rating``, ``reviews_count``, ``bullet_points``,
136
+ ``category`` as a breadcrumb ladder, ``featured_merchant``,
137
+ ``rating_stars_distribution``, ``sales_rank``, ``variations`` and
138
+ ``technical_details``.
139
+ """
140
+ return self._get("amazon/product", {
141
+ "query": asin, "country": country, "currency": currency,
142
+ "domain": domain, "language": language, "device": device,
143
+ "zip_code": zip_code, "light_request": light_request,
144
+ "add_html": add_html, "screenshot": screenshot, "tag": tag,
145
+ })
146
+
147
+ def pricing(self, asin: str, *, country: Optional[str] = None,
148
+ currency: Optional[str] = None, domain: Optional[str] = None,
149
+ language: Optional[str] = None, device: Optional[str] = None,
150
+ zip_code: Optional[str] = None, light_request: Optional[bool] = None,
151
+ add_html: Optional[bool] = None,
152
+ tag: Optional[str] = None) -> Dict[str, Any]:
153
+ """Seller offers for one ASIN. 5 credits.
154
+
155
+ This endpoint takes ``asin`` on the wire, unlike search and product,
156
+ which both take ``query``. Sending ``query`` returns
157
+ ``{"errors": {"query": {"asin": ["Missing data for required field."],
158
+ "query": ["Unknown field."]}}}`` and bills 0 credits.
159
+
160
+ Each entry in ``pricing`` has ``seller``, ``seller_id``,
161
+ ``condition``, ``price``, ``price_shipping``, ``currency``,
162
+ ``rating_count`` and ``delivery_options``.
163
+ """
164
+ return self._get("amazon/pricing", {
165
+ "asin": asin, "country": country, "currency": currency,
166
+ "domain": domain, "language": language, "device": device,
167
+ "zip_code": zip_code, "light_request": light_request,
168
+ "add_html": add_html, "tag": tag,
169
+ })
170
+
171
+ def usage(self) -> Dict[str, Any]:
172
+ """Account credit usage. Free, no credits charged."""
173
+ return self._get("usage", {})
174
+
175
+ # -------------------------------------------------------------- helpers
176
+
177
+ @staticmethod
178
+ def featured(page: Dict[str, Any]) -> List[Dict[str, Any]]:
179
+ """Paid placements from a search response, ordered by ad slot.
180
+
181
+ The endpoint labels every result, so this is a filter rather than a
182
+ parsing problem. CSS selectors cannot make this distinction because
183
+ every card shares the same markup.
184
+ """
185
+ ads = [p for p in page.get("products", []) if p.get("is_sponsored")]
186
+ return sorted(ads, key=lambda p: p.get("sponsored_position") or 0)
187
+
188
+ @staticmethod
189
+ def organic(page: Dict[str, Any]) -> List[Dict[str, Any]]:
190
+ """Earned results from a search response, ordered by organic rank."""
191
+ rows = [p for p in page.get("products", []) if not p.get("is_sponsored")]
192
+ return sorted(rows, key=lambda p: p.get("organic_position") or 0)
193
+
194
+ @staticmethod
195
+ def badged(page: Dict[str, Any]) -> List[Dict[str, Any]]:
196
+ """Results carrying an Amazon's Choice or Best Seller badge."""
197
+ return [
198
+ p for p in page.get("products", [])
199
+ if p.get("is_amazons_choice") or p.get("best_seller")
200
+ ]
201
+
202
+ @staticmethod
203
+ def facets(page: Dict[str, Any]) -> Dict[str, Any]:
204
+ """Amazon's own filter facets for the query, from ``refinements``."""
205
+ return page.get("refinements") or {}
@@ -0,0 +1,244 @@
1
+ Metadata-Version: 2.4
2
+ Name: nocode-amazon
3
+ Version: 0.0.1
4
+ Summary: No code Amazon scraper and Amazon API client: search, product, pricing and featured or sponsored placements via ScrapingBee.
5
+ Author: wordstotech
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/ScrapingBee/nocode-amazon
8
+ Project-URL: Repository, https://github.com/ScrapingBee/nocode-amazon
9
+ Project-URL: Documentation, https://www.scrapingbee.com/documentation/
10
+ Keywords: amazon scraper,amazon api,no code scraper,scrape amazon products,amazon product scraper,amazon featured products,web scraping,scrapingbee
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.8
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Internet :: WWW/HTTP
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Classifier: Topic :: Text Processing :: Markup :: HTML
25
+ Requires-Python: >=3.8
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: requests>=2.25.0
29
+ Dynamic: license-file
30
+
31
+ # nocode-amazon
32
+
33
+ A Python client for ScrapingBee's three dedicated Amazon endpoints, plus the helpers that separate paid placements from earned ones.
34
+
35
+ The package name comes from the no code Make and Airtable workflow this grew out of. The library is the code path for people who outgrew the spreadsheet: same data, same public Amazon pages, no visual scenario to maintain.
36
+
37
+ **Verified against the live API on 2026-09-10.** Every parameter name, response field and credit figure below came back from a real call. Where the documentation and the API disagreed, the API won and the difference is noted.
38
+
39
+ ```bash
40
+ pip install nocode-amazon
41
+ ```
42
+
43
+ Requires Python 3.8 or newer and `requests`.
44
+
45
+ ## Authentication
46
+
47
+ Header based, on every request:
48
+
49
+ ```
50
+ Authorization: Bearer YOUR_API_KEY
51
+ ```
52
+
53
+ The `api_key` query parameter still answers but the current documentation marks it deprecated. This client sends the header.
54
+
55
+ ```python
56
+ from nocode_amazon import AmazonScraper
57
+
58
+ bee = AmazonScraper("YOUR_API_KEY")
59
+ ```
60
+
61
+ Get a key and 1,000 free credits from [ScrapingBee](https://www.scrapingbee.com/). Full reference: [Amazon API documentation](https://www.scrapingbee.com/documentation/amazon/).
62
+
63
+ ---
64
+
65
+ ## Endpoint reference
66
+
67
+ ### `search(query, pages=1, **params)`
68
+
69
+ `GET /api/v1/amazon/search`. **5 credits per page.**
70
+
71
+ Amazon search results as structured JSON. No HTML, no selectors.
72
+
73
+ ```python
74
+ page = bee.search("fitness tracker")
75
+ page["products_count"] # 23
76
+ page["products"] # list of product dicts
77
+ page["refinements"] # Amazon's own facets for this query
78
+ page["url"] # the Amazon URL that was fetched
79
+ page["page"] # 1
80
+ ```
81
+
82
+ Live call on `fitness tracker` returned 23 products and a `refinements` object with 53 facet groups, including `brands`, `band_color`, `band_material_type`, `battery_average_life`, `battery_charge_time` and `case_diameter`.
83
+
84
+ Optional parameters, all verified present on the endpoint:
85
+
86
+ | Parameter | Notes |
87
+ |---|---|
88
+ | `pages` | Pages to fetch. Billed per page |
89
+ | `sort_by` | `featured`, `most_recent`, `price_low_to_high`, `price_high_to_low`, `average_review`, `bestsellers` |
90
+ | `category_id` | Restrict to one Amazon category |
91
+ | `merchant_id` | Restrict to one seller |
92
+ | `domain` | Marketplace top level domain: `com`, `co.uk`, `de`, `in` |
93
+ | `country` | Proxy geolocation |
94
+ | `currency` | ISO 4217 display currency |
95
+ | `language` | ISO language code |
96
+ | `device` | `desktop` or `mobile` |
97
+ | `zip_code` | Postal code. Changes prices and delivery promises |
98
+ | `light_request` | Default `True` at 5 credits. `False` forces a browser at 15 |
99
+ | `add_html` | Include the raw page alongside the JSON |
100
+ | `autoselect_variant` | Pick a variant automatically |
101
+ | `screenshot` | Capture the page. Always 15 credits, ignores `light_request` |
102
+ | `tag` | Your own label, returned in the response headers |
103
+
104
+ Related landing pages: [Amazon search API](https://www.scrapingbee.com/scrapers/amazon-search-api/), [Amazon keyword scraper API](https://www.scrapingbee.com/scrapers/amazon-keyword-scraper-api/), [Amazon organic results API](https://www.scrapingbee.com/scrapers/amazon-organic-results-api/), [Amazon filters API](https://www.scrapingbee.com/scrapers/amazon-filters-api/), [Amazon related searches API](https://www.scrapingbee.com/scrapers/amazon-related-searches-api/), [Amazon spell check API](https://www.scrapingbee.com/scrapers/amazon-spell-check-api/), [Amazon zip code API](https://www.scrapingbee.com/scrapers/amazon-zip-code-api/).
105
+
106
+ ### `product(asin, **params)`
107
+
108
+ `GET /api/v1/amazon/product`. **5 credits.**
109
+
110
+ **The wire parameter is `query`, not `asin`.** The value has to be a valid 10 character ASIN, but the field is named `query`. This client takes `asin` as its argument name and sends `query` for you.
111
+
112
+ ```python
113
+ detail = bee.product("B0GTMTZF3V")
114
+ detail["brand"] # 'Fitbit'
115
+ detail["price"] # 99.99
116
+ detail["currency"] # 'USD'
117
+ detail["rating"] # 4.3
118
+ detail["reviews_count"] # 2036
119
+ ```
120
+
121
+ The live response carried **56 top level keys**. The ones worth knowing:
122
+
123
+ | Field | Contents |
124
+ |---|---|
125
+ | `bullet_points` | The feature bullets, newline separated |
126
+ | `category` | A `ladder` of breadcrumb steps, each with `name` and `url` |
127
+ | `featured_merchant` | `name`, `seller_id`, `shipped_from`, `is_amazon_fulfilled` |
128
+ | `product_details` | Spec table as key and value pairs, including `best_sellers_rank` |
129
+ | `technical_details` | The second spec table |
130
+ | `rating_stars_distribution` | Review counts per star rating |
131
+ | `sales_rank` | Category rank entries |
132
+ | `variations` | Other sizes, colours and configurations |
133
+ | `images` | Image URLs |
134
+ | `delivery` | Delivery promises with type and date |
135
+ | `pricing_url` | The offer listing page for this ASIN |
136
+ | `parent_asin` | The variation parent |
137
+ | `discount_percentage`, `price_strikethrough`, `coupon` | Promotion state |
138
+ | `stock`, `max_quantity` | Availability |
139
+
140
+ Related: [Amazon ASIN API](https://www.scrapingbee.com/scrapers/amazon-asin-api/), [Amazon image API](https://www.scrapingbee.com/scrapers/amazon-image-api/), [Amazon review API](https://www.scrapingbee.com/scrapers/amazon-review-api/), [Amazon best sellers API](https://www.scrapingbee.com/scrapers/amazon-best-sellers-api/), [Amazon video results API](https://www.scrapingbee.com/scrapers/amazon-video-results-api/), [Amazon URL API](https://www.scrapingbee.com/scrapers/amazon-ulr-api/).
141
+
142
+ ### `pricing(asin, **params)`
143
+
144
+ `GET /api/v1/amazon/pricing`. **5 credits.**
145
+
146
+ **This endpoint takes `asin` on the wire.** Search and product both take `query`. Pricing does not, and it rejects `query` explicitly:
147
+
148
+ ```json
149
+ {"errors": {"query": {"asin": ["Missing data for required field."], "query": ["Unknown field."]}}}
150
+ ```
151
+
152
+ That rejected call was billed **0 credits**, confirmed by `spb-cost: 0` on the response. This client raises `ScrapingBeeError` with the API's own error dict in `.payload`, so the offending field is never a guess.
153
+
154
+ ```python
155
+ offers = bee.pricing("B0GTMTZF3V")
156
+ for offer in offers["pricing"]:
157
+ print(offer["seller"], offer["price"], offer["condition"])
158
+ ```
159
+
160
+ Each offer carries `seller`, `seller_id`, `seller_link`, `condition`, `price`, `price_shipping`, `currency`, `rating_count` and a `delivery_options` list.
161
+
162
+ Related: [Amazon offers API](https://www.scrapingbee.com/scrapers/amazon-offers-api/), [Amazon seller API](https://www.scrapingbee.com/scrapers/amazon-seller-api/), [Amazon vendor API](https://www.scrapingbee.com/scrapers/amazon-vendor-api/), [Amazon shipping API](https://www.scrapingbee.com/scrapers/amazon-shipping-api/).
163
+
164
+ ### `usage()`
165
+
166
+ `GET /api/v1/usage`. **Free.**
167
+
168
+ ```python
169
+ bee.usage()
170
+ # {'max_api_credit': 1000000, 'used_api_credit': 353946,
171
+ # 'max_concurrency': 100, 'current_concurrency': 0,
172
+ # 'renewal_subscription_date': '2026-09-21T12:06:28'}
173
+ ```
174
+
175
+ Call this before a large run. Note it lags by minutes, so do not read it immediately afterwards to compute what a batch cost.
176
+
177
+ ---
178
+
179
+ ## Placement helpers
180
+
181
+ Amazon search markup gives every card the same classes, so CSS selectors cannot tell a paid slot from an earned rank. The endpoint labels each result instead, which turns the problem into a filter.
182
+
183
+ Per product placement fields:
184
+
185
+ | Field | Type | Meaning |
186
+ |---|---|---|
187
+ | `is_sponsored` | bool | Paid placement |
188
+ | `sponsored_position` | int or None | Rank among the ads |
189
+ | `organic_position` | int or None | Rank among earned results |
190
+ | `is_amazons_choice` | bool | Amazon's Choice badge |
191
+ | `best_seller` | bool | Best Seller badge |
192
+ | `sales_volume` | str | For example `10K+ bought in past month` |
193
+
194
+ ```python
195
+ page = bee.search("fitness tracker", sort_by="featured")
196
+
197
+ AmazonScraper.featured(page) # sponsored, ordered by ad slot
198
+ AmazonScraper.organic(page) # earned, ordered by organic rank
199
+ AmazonScraper.badged(page) # Amazon's Choice or Best Seller
200
+ AmazonScraper.facets(page) # the refinements object
201
+ ```
202
+
203
+ Two live runs on the same query returned 7 featured of 24 products, then 9 of 26. Paid density moves between requests, so measure it rather than assuming a fixed ratio.
204
+
205
+ `is_prime` came back `False` on every row of both pages, so verify it against your own target category before building a Prime filter on it.
206
+
207
+ ---
208
+
209
+ ## Credit cost
210
+
211
+ Measured from `spb-cost` response headers, not quoted from a pricing page. This client stores the value on `bee.last_cost` after every call.
212
+
213
+ | Call | Credits |
214
+ |---|---|
215
+ | Search, default light request | 5 per page |
216
+ | Search, `light_request=False` | 15 per page |
217
+ | Product, default | 5 |
218
+ | Product, `light_request=False` | 15 |
219
+ | Pricing | 5 |
220
+ | Any screenshot | 15 |
221
+ | Rejected request | 0 |
222
+ | `usage()` | 0 |
223
+
224
+ Light requests skip the browser. They were sufficient for search, product and pricing on every call made here. Turn them off when you need review text or other content that appears only after JavaScript runs.
225
+
226
+ Failed requests are retried inside the API for up to 30 seconds, so set client timeouts above that. This client defaults to 60 seconds.
227
+
228
+ Plan tiers: [ScrapingBee pricing](https://www.scrapingbee.com/pricing).
229
+
230
+ ---
231
+
232
+ ## Scope
233
+
234
+ Public Amazon listing and product pages. Nothing in this package signs in, and scraping under login credentials is prohibited by ScrapingBee's terms of service.
235
+
236
+ ## Related features
237
+
238
+ [AI web scraping](https://www.scrapingbee.com/features/ai-web-scraping-api/), [data extraction rules](https://www.scrapingbee.com/features/data-extraction/), [Amazon feature page](https://www.scrapingbee.com/features/amazon/), [screenshots](https://www.scrapingbee.com/features/screenshot/), [markdown scraper](https://www.scrapingbee.com/features/markdown-scraper/), [Make integration](https://www.scrapingbee.com/features/make/), [n8n integration](https://www.scrapingbee.com/features/n8n/), [Zapier integration](https://www.scrapingbee.com/features/zapier/).
239
+
240
+ The no code version of this workflow, with the Make scenario and the extraction rules, is at [github.com/ScrapingBee/nocode-amazon](https://github.com/ScrapingBee/nocode-amazon).
241
+
242
+ ## License
243
+
244
+ MIT
@@ -0,0 +1,11 @@
1
+ LICENSE
2
+ MANIFEST.in
3
+ README.md
4
+ pyproject.toml
5
+ src/nocode_amazon/__init__.py
6
+ src/nocode_amazon/client.py
7
+ src/nocode_amazon.egg-info/PKG-INFO
8
+ src/nocode_amazon.egg-info/SOURCES.txt
9
+ src/nocode_amazon.egg-info/dependency_links.txt
10
+ src/nocode_amazon.egg-info/requires.txt
11
+ src/nocode_amazon.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ requests>=2.25.0
@@ -0,0 +1 @@
1
+ nocode_amazon