scrapeunblocker 0.15.1 → 0.17.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/README.md +4 -4
- data/lib/scrapeunblocker/plugins.rb +993 -6
- data/lib/scrapeunblocker/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4a9fdb57b21c1b655ba3ec6bc4c87f0907872ccdf9ad279035e028192b7f4414
|
|
4
|
+
data.tar.gz: adfa7124cb12d1eac3aed2a818070be619a80e8a243e6d1816b34f534cb4601a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c6765faaf5a348e030ea3c102d5574b05d3f0105526b1141d4bb9b2257eb8fb3ec5c9ab96c6b934f8d0d6b2d026eaec0821a247670fb18c9382243ac32fc2206
|
|
7
|
+
data.tar.gz: 806142bbf00967541f0a32b88afa96485416f46505266647b41ee2ed13bbbe53c0c0f50210ec53138c13118ae5df4c9afdb701b2d0e6e601311e07055c95a22b
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.17.0 (2026-10-30)
|
|
4
|
+
|
|
5
|
+
- 29 new plugin methods on `Client`:
|
|
6
|
+
- E-commerce, new sites: `mediamarkt_search(query)` and `mediamarkt_product(product_id)` (MediaMarkt in ten countries and Saturn), `cdiscount_search(query)` and `cdiscount_product(sku)`, `idealo_search(query)` and `idealo_offers(product_id)` (price comparison in six countries), `rakuten_search(query)` and `rakuten_product()` (Rakuten Ichiba, Japan), `indiamart_search(query)` and `indiamart_product()`, `bedbathandbeyond_search(query)` and `bedbathandbeyond_product(product)`, `petco_search(query)` and `petco_product(product)`, `neobits_product(product)`, `lowes_search(query)` and `lowes_product(product_id)`, `menards_search(query)` and `menards_product()`, `grainger_search(query)` and `grainger_product(sku)`.
|
|
7
|
+
- Product pages next to existing searches: `walmart_product()`, `ebay_product()`, `etsy_product()`, `bestbuy_product(sku)`, `target_category(category)` and `target_product(tcin)`, `aliexpress_product(product_id)`.
|
|
8
|
+
- AI: `chatgpt(prompt)` (ChatGPT's answer with the sites it cites).
|
|
9
|
+
- The first argument of the product methods that also take a link, and of the searches that also take a search link, is optional, for calls that pass `url:` instead. `rakuten_product`, `indiamart_product`, `menards_product`, `walmart_product`, `ebay_product` and `etsy_product` take keyword options only (`product_id:` / `sku:` / `item_id:` / `listing_id:` or `url:`).
|
|
10
|
+
- Plugin method comments no longer describe exit or proxy details (`exitProvider`); API responses no longer carry them.
|
|
11
|
+
|
|
12
|
+
No breaking changes.
|
|
13
|
+
|
|
14
|
+
## 0.16.0 (2026-10-29)
|
|
15
|
+
|
|
16
|
+
- Add `maps_reviews`: Google Maps reviews of a place in Google's sort orders (relevant, newest, highest, lowest) with exact ISO dates, original and translated text, authors, photos, owner replies and page tokens. `POST /maps/reviews`.
|
|
17
|
+
|
|
3
18
|
## 0.15.1 (2026-10-29)
|
|
4
19
|
|
|
5
20
|
- `shopee_product` and `shopee_search` docs: describe `availability` and `inStock`, sold-out variations (`models[].available`, `tierIndex`), `categories` as the breadcrumb path plus `browseCategories`, `isPixPrice` (Brazilian Pix prices) and the JSON `{"status": "not_found", ...}` answer for a product that does not exist. Signatures are unchanged.
|
data/README.md
CHANGED
|
@@ -149,11 +149,11 @@ jobs = su.career_site_jobs("https://jobs.ashbyhq.com/ramp", keyword: "engineer")
|
|
|
149
149
|
| Category | Methods |
|
|
150
150
|
| --- | --- |
|
|
151
151
|
| Travel | `skyscanner.flights`, `skyscanner.hotels`, `skyscanner.carhire`, `booking_hotels`, `booking_reviews`, `airbnb_search`, `airbnb_room`, `airbnb_reviews`, `tripadvisor_list`, `tripadvisor_reviews` |
|
|
152
|
-
| Google | `google_local`, `google_images`, `maps_place_details`, `google_trends`, `google_shopping`, `google_jobs`, `google_hotels`, `google_hotels_property`, `google_news`, `google_ads_transparency`, `google_ads_transparency_advertisers`, `google_ai_mode`, `google_lens` |
|
|
153
|
-
| AI | `gemini` |
|
|
152
|
+
| Google | `google_local`, `google_images`, `maps_place_details`, `maps_reviews`, `google_trends`, `google_shopping`, `google_jobs`, `google_hotels`, `google_hotels_property`, `google_news`, `google_ads_transparency`, `google_ads_transparency_advertisers`, `google_ai_mode`, `google_lens` |
|
|
153
|
+
| AI | `gemini`, `chatgpt` |
|
|
154
154
|
| Search engines | `bing_search`, `bing_images`, `duckduckgo_search`, `yahoo_search`, `yahoo_images`, `brave_search`, `brave_images` |
|
|
155
|
-
| E-commerce | `amazon_product`, `amazon_search`, `amazon_bestsellers`, `amazon_reviews`, `amazon_offers`, `amazon_seller`, `walmart_search`, `target_search`, `bestbuy_search`, `homedepot_search`, `costco_search`, `costco_product`, `etsy_search`, `shein_search`, `zalando_search`, `aliexpress_search`, `alibaba_search`, `alibaba_product`, `alibaba1688_search`, `alibaba1688_product`, `tiktok_shop_search`, `tiktok_shop_product`, `tiktok_shop_store`, `oopbuy_search`, `smyths_inventory`, `smyths_details`, `smyths_search`, `smyths_category`, `wish_search`, `wish_product`, `shopee_search`, `shopee_product`, `taobao_search`, `taobao_product`, `flipkart_search`, `flipkart_product`, `lazada_search`, `lazada_product`, `allegro_search`, `allegro_product`, `falabella_search`, `falabella_product`, `magazineluiza_search`, `magazineluiza_product` |
|
|
156
|
-
| Classifieds & Resale | `ebay_search`, `vinted_search`, `leboncoin_search` |
|
|
155
|
+
| E-commerce | `amazon_product`, `amazon_search`, `amazon_bestsellers`, `amazon_reviews`, `amazon_offers`, `amazon_seller`, `walmart_search`, `walmart_product`, `target_search`, `target_category`, `target_product`, `bestbuy_search`, `bestbuy_product`, `homedepot_search`, `costco_search`, `costco_product`, `etsy_search`, `etsy_product`, `shein_search`, `zalando_search`, `aliexpress_search`, `aliexpress_product`, `alibaba_search`, `alibaba_product`, `alibaba1688_search`, `alibaba1688_product`, `tiktok_shop_search`, `tiktok_shop_product`, `tiktok_shop_store`, `oopbuy_search`, `smyths_inventory`, `smyths_details`, `smyths_search`, `smyths_category`, `wish_search`, `wish_product`, `shopee_search`, `shopee_product`, `taobao_search`, `taobao_product`, `flipkart_search`, `flipkart_product`, `lazada_search`, `lazada_product`, `allegro_search`, `allegro_product`, `falabella_search`, `falabella_product`, `magazineluiza_search`, `magazineluiza_product`, `mediamarkt_search`, `mediamarkt_product`, `cdiscount_search`, `cdiscount_product`, `idealo_search`, `idealo_offers`, `rakuten_search`, `rakuten_product`, `indiamart_search`, `indiamart_product`, `bedbathandbeyond_search`, `bedbathandbeyond_product`, `petco_search`, `petco_product`, `neobits_product`, `lowes_search`, `lowes_product`, `menards_search`, `menards_product`, `grainger_search`, `grainger_product` |
|
|
156
|
+
| Classifieds & Resale | `ebay_product`, `ebay_search`, `vinted_search`, `leboncoin_search` |
|
|
157
157
|
| Groceries | `woolworths_search`, `woolworths_category`, `woolworths_specials`, `woolworths_product`, `coles_search`, `coles_category`, `coles_specials`, `coles_product`, `aldi_au_search`, `aldi_au_category`, `aldi_au_specials`, `aldi_au_product`, `kroger_search`, `kroger_product`, `instacart_search`, `instacart_product`, `publix_search`, `publix_product` |
|
|
158
158
|
| Real estate | `zillow_search`, `zillow_detail`, `redfin_search`, `redfin_detail`, `rightmove_search`, `idealista_search`, `idealista_detail`, `immobilienscout24_search` |
|
|
159
159
|
| Vehicles | `mobile_de`, `autoscout24_search` |
|
|
@@ -79,8 +79,8 @@ module ScrapeUnblocker
|
|
|
79
79
|
# `reviewsGated` is `true` and `reviews` is empty; the rating, histogram and customers-say
|
|
80
80
|
# data, including its review excerpts, are still returned. Every field is always present and
|
|
81
81
|
# is `null` when the page does not show it. `proxy_country` defaults to the marketplace's
|
|
82
|
-
# home country; the proxy that served the request is reported as
|
|
83
|
-
#
|
|
82
|
+
# home country; the country of the proxy that served the request is reported as
|
|
83
|
+
# `exitCountry`.
|
|
84
84
|
#
|
|
85
85
|
# @param asin [String] Amazon product id (10-char ASIN, e.g. 'B07PXGQC1Q'; books use their
|
|
86
86
|
# ISBN-10). Give either `asin` (with `marketplace`) or a product `url`.
|
|
@@ -121,8 +121,8 @@ module ScrapeUnblocker
|
|
|
121
121
|
# call with `pages`. Filter with `condition`, `free_shipping` and `prime`. `shippingPrice`
|
|
122
122
|
# is 0 for free delivery and null when Amazon shows no delivery promise for the location.
|
|
123
123
|
# `proxy_country` defaults to the marketplace's home country so prices and delivery are the
|
|
124
|
-
# ones a local shopper sees; the proxy that served the request is reported as
|
|
125
|
-
#
|
|
124
|
+
# ones a local shopper sees; the country of the proxy that served the request is reported as
|
|
125
|
+
# `exitCountry`.
|
|
126
126
|
#
|
|
127
127
|
# @param asin [String] Amazon product id (10-char ASIN, e.g. 'B07VGRJDFY'; books use their
|
|
128
128
|
# ISBN-10). Give either `asin` (with `marketplace`) or a product `url`.
|
|
@@ -230,6 +230,38 @@ module ScrapeUnblocker
|
|
|
230
230
|
})
|
|
231
231
|
end
|
|
232
232
|
|
|
233
|
+
# Scrape one Walmart product's full detail.
|
|
234
|
+
#
|
|
235
|
+
# Fetches one Walmart product page (by `item_id` or `url`) and returns it as JSON: `itemId`,
|
|
236
|
+
# `title`, `brand`, `model`, `upc`, `price`, `wasPrice`, `listPrice`, `unitPrice` (e.g. per
|
|
237
|
+
# ounce, where Walmart shows one), `currency`, `rollback` / `clearance`, `availability` and
|
|
238
|
+
# `inStock`, `condition`, `seller` (name, Walmart or marketplace seller, its rating and
|
|
239
|
+
# review count), `additionalSellerCount`, `fulfillment` (shipping, pickup and delivery:
|
|
240
|
+
# available or not, date, fee, store or place), `returnPolicy`, `rating`, `reviewCount`,
|
|
241
|
+
# `reviewSummary` (star histogram, recommend percentage, aspect scores), the first
|
|
242
|
+
# `reviews`, `categories`, `shortDescription`, `description`, `highlights`,
|
|
243
|
+
# `specifications`, `warranty`, `variantOptions` and every `variants` entry (its own item
|
|
244
|
+
# id, attributes, price, stock), `images` and `videos`. Fulfillment dates and the store are
|
|
245
|
+
# what Walmart quotes for the US location it assigns to the request (`location` names it),
|
|
246
|
+
# not a ZIP code or store you choose. Other sellers' offers are not on the product page:
|
|
247
|
+
# only their count (`additionalSellerCount`) is returned. Companion to
|
|
248
|
+
# `/marketplace/walmart-search`.
|
|
249
|
+
#
|
|
250
|
+
# @param item_id [String] Walmart item id - the number at the end of a product link, e.g.
|
|
251
|
+
# '18638703162' for walmart.com/ip/.../18638703162.
|
|
252
|
+
# @param url [String] Instead of `item_id`: a walmart.com product link, e.g.
|
|
253
|
+
# https://www.walmart.com/ip/HP-15-6-inch-Laptop/18638703162.
|
|
254
|
+
# @param proxy_country [String] Proxy country the request is sent from (ISO-2). Defaults to
|
|
255
|
+
# US: walmart.com refuses most other countries.
|
|
256
|
+
# Calls POST /marketplace/walmart-product.
|
|
257
|
+
def walmart_product(item_id: nil, url: nil, proxy_country: nil)
|
|
258
|
+
post_json("/marketplace/walmart-product", {
|
|
259
|
+
item_id: item_id,
|
|
260
|
+
url: url,
|
|
261
|
+
proxy_country: proxy_country,
|
|
262
|
+
})
|
|
263
|
+
end
|
|
264
|
+
|
|
233
265
|
# Scrape Target product search.
|
|
234
266
|
#
|
|
235
267
|
# Searches Target for `query` and returns the products as JSON: `tcin`, `title`, `brand`,
|
|
@@ -257,6 +289,70 @@ module ScrapeUnblocker
|
|
|
257
289
|
})
|
|
258
290
|
end
|
|
259
291
|
|
|
292
|
+
# Scrape a Target category listing.
|
|
293
|
+
#
|
|
294
|
+
# Lists the products of one Target category (by id or category link; a brand page's id or
|
|
295
|
+
# link works too) as JSON: `category` (id, name, link, and `type`: category or brand),
|
|
296
|
+
# `breadcrumbs`, `totalResults`, `totalPages`, and `products` with `tcin`, `title`, `brand`,
|
|
297
|
+
# `price` (`priceMax` for a family priced as a range), `originalPrice` and `priceType` when
|
|
298
|
+
# on sale, `formattedPrice`, `currency`, `rating`, `ratingCount`, `promotions`, `image` and
|
|
299
|
+
# `url`. Sort with `sort`, start at `page` and collect up to `max_results` across pages
|
|
300
|
+
# (Target serves at most 50 pages of 24). Filters in a category link (...Z<facet>) are not
|
|
301
|
+
# applied. Each page fetched is billed as one request (`pagesFetched`).
|
|
302
|
+
#
|
|
303
|
+
# @param category [String] Target category: its id (e.g. '5xtro', the part after N- in a
|
|
304
|
+
# category link) or a target.com category link, e.g. https://www.target.com/c/coffee-makers-
|
|
305
|
+
# tea-espresso-kitchen-appliances-dining/-/N-5xtro. A brand page (/b/<brand>/-/N-<id>) lists
|
|
306
|
+
# that brand.
|
|
307
|
+
# @param sort [String] Order: relevance, price_low, price_high, rating, best_selling,
|
|
308
|
+
# newest. API default: relevance.
|
|
309
|
+
# @param page [Integer] 1-based page to start from (1-50, 24 products per page). API
|
|
310
|
+
# default: 1.
|
|
311
|
+
# @param max_results [Integer] Products to collect across pages (1-240); each page fetched
|
|
312
|
+
# is billed as one request. API default: 24.
|
|
313
|
+
# Calls POST /marketplace/target-category.
|
|
314
|
+
def target_category(category, sort: nil, page: nil, max_results: nil)
|
|
315
|
+
post_json("/marketplace/target-category", {
|
|
316
|
+
category: category,
|
|
317
|
+
sort: sort,
|
|
318
|
+
page: page,
|
|
319
|
+
max_results: max_results,
|
|
320
|
+
})
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
# Scrape one Target product.
|
|
324
|
+
#
|
|
325
|
+
# Returns one Target product by `tcin` or `url` as JSON: `tcin` (and `parentTcin` when it is
|
|
326
|
+
# one variant of a product family), `title`, `brand`, `url`, `dpci`, `upc`, `productType`,
|
|
327
|
+
# `price` (`priceMax` for a family priced as a range), `originalPrice` / `savings` /
|
|
328
|
+
# `savingsPercent` / `priceType` when on sale, `priceNote` (e.g. 'When purchased online'),
|
|
329
|
+
# `currency` (USD), `promotions`, `rating`, `ratingCount`, `reviewCount`,
|
|
330
|
+
# `ratingDistribution`, `recommendedPercent`, `questionCount`, `description`, `highlights`,
|
|
331
|
+
# `specifications`, `image` / `images`, `category` / `categories`, `selectedVariant` and
|
|
332
|
+
# `variants` (every colour / size with its own TCIN, price, link, image and shipping / store
|
|
333
|
+
# availability), `fulfillment` (sold out, shipping status and delivery dates to `zip`,
|
|
334
|
+
# pickup status, date and quantity at `store_id`, aisle) and `packageDimensions`. Prices are
|
|
335
|
+
# target.com's online prices. Companion to `/marketplace/target-search`, whose `tcin` it
|
|
336
|
+
# takes. One unit per call.
|
|
337
|
+
#
|
|
338
|
+
# @param tcin [String] Target item number (TCIN), e.g. '52580270' (the number after A- in a
|
|
339
|
+
# product link).
|
|
340
|
+
# @param url [String] Instead of `tcin`: a target.com product link, e.g.
|
|
341
|
+
# https://www.target.com/p/hamilton-beach-coffee-maker/-/A-52580270 (a `?preselect=` variant
|
|
342
|
+
# in the link is honoured).
|
|
343
|
+
# @param store_id [String] Target store whose pickup and shelf stock is reported, e.g.
|
|
344
|
+
# '1375' (default 1375, Minneapolis Nicollet Mall).
|
|
345
|
+
# @param zip [String] US ZIP code shipping dates are quoted for (default 55403).
|
|
346
|
+
# Calls POST /marketplace/target-product.
|
|
347
|
+
def target_product(tcin = nil, url: nil, store_id: nil, zip: nil)
|
|
348
|
+
post_json("/marketplace/target-product", {
|
|
349
|
+
tcin: tcin,
|
|
350
|
+
url: url,
|
|
351
|
+
store_id: store_id,
|
|
352
|
+
zip: zip,
|
|
353
|
+
})
|
|
354
|
+
end
|
|
355
|
+
|
|
260
356
|
# Scrape Best Buy product search.
|
|
261
357
|
#
|
|
262
358
|
# Searches Best Buy (US) for `query` and returns the products as JSON: `sku`, `title`,
|
|
@@ -288,6 +384,32 @@ module ScrapeUnblocker
|
|
|
288
384
|
})
|
|
289
385
|
end
|
|
290
386
|
|
|
387
|
+
# Scrape one Best Buy product.
|
|
388
|
+
#
|
|
389
|
+
# Returns one Best Buy (US) product by `sku` or `url` as JSON: `sku`, `title`, `brand`,
|
|
390
|
+
# `model`, `upc`, `productType`, `condition`, `url`, `price`, `originalPrice` / `savings` /
|
|
391
|
+
# `savingsPercent` (when on sale), `currency` (USD), `available` with `availableForShipping`
|
|
392
|
+
# / `availableForPickup` / `availableForDelivery` (nationwide, not for one store or ZIP
|
|
393
|
+
# code), `rating`, `reviewCount`, `description`, `features`, `includedItems`,
|
|
394
|
+
# `specifications` (group / name / value), `image` and `images` (full size), `category` and
|
|
395
|
+
# `categories` (root to leaf), `seller` (Best Buy or a Marketplace seller id),
|
|
396
|
+
# `openBoxOffers` (Excellent / Good / Fair with their prices and links), `dimensions` and
|
|
397
|
+
# `releaseDate`. Companion to `/marketplace/bestbuy-search`, whose `sku` it takes. One unit
|
|
398
|
+
# per call.
|
|
399
|
+
#
|
|
400
|
+
# @param sku [String] Best Buy SKU, e.g. '6613868' (the number after /sku/ in a product
|
|
401
|
+
# link, or its skuId=).
|
|
402
|
+
# @param url [String] Instead of `sku`: a bestbuy.com product link, e.g.
|
|
403
|
+
# https://www.bestbuy.com/product/hp-omnibook-x-flip/JJGQJRKGTJ/sku/6613868 or
|
|
404
|
+
# https://www.bestbuy.com/site/-/6613868.p?skuId=6613868.
|
|
405
|
+
# Calls POST /marketplace/bestbuy-product.
|
|
406
|
+
def bestbuy_product(sku = nil, url: nil)
|
|
407
|
+
post_json("/marketplace/bestbuy-product", {
|
|
408
|
+
sku: sku,
|
|
409
|
+
url: url,
|
|
410
|
+
})
|
|
411
|
+
end
|
|
412
|
+
|
|
291
413
|
# Scrape Home Depot product search.
|
|
292
414
|
#
|
|
293
415
|
# Searches Home Depot for `query` and returns the products as JSON: `itemId`, `title`,
|
|
@@ -416,6 +538,39 @@ module ScrapeUnblocker
|
|
|
416
538
|
})
|
|
417
539
|
end
|
|
418
540
|
|
|
541
|
+
# Scrape one Etsy listing's full detail.
|
|
542
|
+
#
|
|
543
|
+
# Fetches one Etsy listing (by `listing_id` or `url`) and returns it as JSON: `listingId`,
|
|
544
|
+
# `title`, `price` (the lowest price when variations differ, `priceMax` the highest),
|
|
545
|
+
# `originalPrice` / `onSale` / `discountPercent` / `saleEnds` during a sale, `currency` and
|
|
546
|
+
# `shopperRegion`, `availability` and `quantityAvailable`, `rating` and `reviewCount`,
|
|
547
|
+
# `reviewSummary` (item quality, shipping and service scores, recommend percentage, review
|
|
548
|
+
# tags and categories), the first `reviews`, `shop` (name, id, owner, location, rating,
|
|
549
|
+
# review count, sales, years on Etsy, Star Seller), `variations` (each menu with its options
|
|
550
|
+
# and their prices), `description`, `materials`, `highlights`, `category`, `shipping` (cost,
|
|
551
|
+
# origin, ships from, estimated delivery, processing time, returns), `images` and `video`.
|
|
552
|
+
# Prices, shipping cost and VAT follow the shopper location Etsy assigns to the request,
|
|
553
|
+
# which can differ from `proxy_country`: `currency` and `shopperRegion` say which one a
|
|
554
|
+
# response used (e.g. EUR / BE), so read them before comparing prices. Shop review and sales
|
|
555
|
+
# counts are Etsy's rounded figures ("4.7k sales" is 4700). Companion to `/marketplace/etsy-
|
|
556
|
+
# search`.
|
|
557
|
+
#
|
|
558
|
+
# @param listing_id [String] Etsy listing number, e.g. '1702915637' (the number in
|
|
559
|
+
# etsy.com/listing/1702915637/...).
|
|
560
|
+
# @param url [String] Instead of `listing_id`: an etsy.com listing link, e.g.
|
|
561
|
+
# https://www.etsy.com/listing/1702915637/solstice-mug.
|
|
562
|
+
# @param proxy_country [String] Proxy country the request is sent from (ISO-2). Defaults to
|
|
563
|
+
# US. Etsy prices in the currency of the shopper location it assigns, which can differ from
|
|
564
|
+
# this country; `currency` and `shopperRegion` say which one a response used.
|
|
565
|
+
# Calls POST /marketplace/etsy-product.
|
|
566
|
+
def etsy_product(listing_id: nil, url: nil, proxy_country: nil)
|
|
567
|
+
post_json("/marketplace/etsy-product", {
|
|
568
|
+
listing_id: listing_id,
|
|
569
|
+
url: url,
|
|
570
|
+
proxy_country: proxy_country,
|
|
571
|
+
})
|
|
572
|
+
end
|
|
573
|
+
|
|
419
574
|
# Scrape SHEIN product search.
|
|
420
575
|
#
|
|
421
576
|
# Searches SHEIN (US store) for `query` and returns the products as JSON: `id`, `sku`,
|
|
@@ -501,6 +656,40 @@ module ScrapeUnblocker
|
|
|
501
656
|
})
|
|
502
657
|
end
|
|
503
658
|
|
|
659
|
+
# Scrape one AliExpress product.
|
|
660
|
+
#
|
|
661
|
+
# Returns one AliExpress item by `product_id` or `url`, priced in `currency` and shipped to
|
|
662
|
+
# `country`, as JSON: `productId`, `url`, `title`, `price` (the default SKU), `priceMin` /
|
|
663
|
+
# `priceMax` across SKUs, `priceFormatted`, `originalPrice` / `originalPriceMax`, `discount`
|
|
664
|
+
# and `discountPercent`, `currency`, `rating`, `reviewCount`, `soldText` and `orders`,
|
|
665
|
+
# `inStock`, `store` (name, ids, link, country, open since, positive feedback, ratings),
|
|
666
|
+
# `shipping` (each option: method, fee, free, ships from / to, delivery days and dates,
|
|
667
|
+
# deliverable), `skuProperties` (e.g. colour, size, ships from, with images), `variants`
|
|
668
|
+
# (every SKU with its attributes, price, original price, availability, stock and image),
|
|
669
|
+
# `specifications`, `images`, `categoryId` and `descriptionUrl` (the seller's HTML
|
|
670
|
+
# description). One unit per call.
|
|
671
|
+
#
|
|
672
|
+
# @param product_id [String] AliExpress item id, e.g. '1005010503016514' (the number in
|
|
673
|
+
# /item/<id>.html; `productId` from /goods/aliexpress-search).
|
|
674
|
+
# @param url [String] Instead of `product_id`: an AliExpress item link, e.g.
|
|
675
|
+
# https://www.aliexpress.com/item/1005010503016514.html (any storefront: .com, .us, de., fr.
|
|
676
|
+
# ...).
|
|
677
|
+
# @param country [String] Ship-to country (ISO-2, e.g. 'US', 'DE', 'GB'). Shipping options,
|
|
678
|
+
# delivery times and whether the item is sold at all depend on it. API default: US.
|
|
679
|
+
# @param currency [String] Price currency, e.g. 'USD', 'EUR', 'GBP'. One of: USD, EUR, GBP,
|
|
680
|
+
# CAD, AUD, NZD, CHF, SEK, NOK, DKK, PLN, CZK, HUF, RON, BGN, TRY, ILS, AED, SAR, JPY, KRW,
|
|
681
|
+
# SGD, MYR, THB, IDR, PHP, VND, INR, BRL, MXN, CLP, COP, PEN, ZAR, UAH, KZT. API default:
|
|
682
|
+
# USD.
|
|
683
|
+
# Calls POST /goods/aliexpress-product.
|
|
684
|
+
def aliexpress_product(product_id = nil, url: nil, country: nil, currency: nil)
|
|
685
|
+
post_json("/goods/aliexpress-product", {
|
|
686
|
+
product_id: product_id,
|
|
687
|
+
url: url,
|
|
688
|
+
country: country,
|
|
689
|
+
currency: currency,
|
|
690
|
+
})
|
|
691
|
+
end
|
|
692
|
+
|
|
504
693
|
# Scrape Alibaba.com product search results.
|
|
505
694
|
#
|
|
506
695
|
# Searches Alibaba.com for `q` and returns the products as JSON: `productId`, `title`,
|
|
@@ -1286,6 +1475,734 @@ module ScrapeUnblocker
|
|
|
1286
1475
|
})
|
|
1287
1476
|
end
|
|
1288
1477
|
|
|
1478
|
+
# Scrape MediaMarkt search.
|
|
1479
|
+
#
|
|
1480
|
+
# Searches a MediaMarkt shop (`country` de, at, ch, nl, be, es, it = MediaWorld, pl, hu, tr;
|
|
1481
|
+
# `banner=saturn` for Saturn Germany) for `query` and returns `products`, each with
|
|
1482
|
+
# `position`, `productId`, `offerId` (marketplace offers), `title`, `brand`, `ean`, `url`,
|
|
1483
|
+
# `image`, `breadcrumbs`, `price`, `strikePrice` and `strikePriceType` (RRP = manufacturer's
|
|
1484
|
+
# recommended price, LOP = lowest price of the last 30 days), `discountPercent`, `currency`,
|
|
1485
|
+
# `installment`, `marketplace`, `seller` (marketplace seller with rating), `rating`,
|
|
1486
|
+
# `reviewCount`, `availability` (online status, deliverable, store pickup, delivery window
|
|
1487
|
+
# and shipping cost), `energyEfficiency`, `highlights` (key features), `badges`,
|
|
1488
|
+
# `refurbishedFrom` and `sponsored`. Also `total`, `lastPage`, `nextPage` and `listingUrl`
|
|
1489
|
+
# (the category or brand listing MediaMarkt sends this query to, when it does). `sort`
|
|
1490
|
+
# orders the results; `page` and `max_results` page through them (MediaMarkt shows 12 per
|
|
1491
|
+
# page and 30 pages at most). One unit per results page used.
|
|
1492
|
+
#
|
|
1493
|
+
# @param query [String] What to search for, e.g. 'iphone 17' or 'waschmaschine'.
|
|
1494
|
+
# @param country [String] MediaMarkt shop: de, at, ch, nl, be, es, it, pl, hu, tr (default
|
|
1495
|
+
# de; it = MediaWorld). API default: de.
|
|
1496
|
+
# @param banner [String] mediamarkt (default) or saturn (Saturn Germany, with country=de).
|
|
1497
|
+
# API default: mediamarkt.
|
|
1498
|
+
# @param language [String] Site language where the shop has several: be = nl or fr, ch = de,
|
|
1499
|
+
# fr or it. Default: the shop's first.
|
|
1500
|
+
# @param sort [String] Result order: relevance, price_asc, price_desc, rating, bestseller,
|
|
1501
|
+
# newest. API default: relevance.
|
|
1502
|
+
# @param page [Integer] First results page to read (1-30). API default: 1.
|
|
1503
|
+
# @param max_results [Integer] Products to collect across pages, 1-120. A page holds 12
|
|
1504
|
+
# products; each page is one unit. API default: 12.
|
|
1505
|
+
# Calls POST /marketplace/mediamarkt-search.
|
|
1506
|
+
def mediamarkt_search(query, country: nil, banner: nil, language: nil, sort: nil, page: nil, max_results: nil)
|
|
1507
|
+
post_json("/marketplace/mediamarkt-search", {
|
|
1508
|
+
query: query,
|
|
1509
|
+
country: country,
|
|
1510
|
+
banner: banner,
|
|
1511
|
+
language: language,
|
|
1512
|
+
sort: sort,
|
|
1513
|
+
page: page,
|
|
1514
|
+
max_results: max_results,
|
|
1515
|
+
})
|
|
1516
|
+
end
|
|
1517
|
+
|
|
1518
|
+
# Scrape a MediaMarkt product.
|
|
1519
|
+
#
|
|
1520
|
+
# Returns one MediaMarkt / Saturn / MediaWorld product by `product_id` (with `country` /
|
|
1521
|
+
# `banner`) or `url`: `productId`, `title`, `rawTitle`, `brand`, `ean`, `url`,
|
|
1522
|
+
# `breadcrumbs`, `kind`, `price`, `strikePrice`, `strikePriceType`, `discountPercent`,
|
|
1523
|
+
# `currency`, `vatRate`, `installment`, `marketplace`, `seller`, `rating`, `reviewCount`,
|
|
1524
|
+
# `ratingBreakdown` (1-5 stars), `availability` (online status, deliverable, store pickup,
|
|
1525
|
+
# delivery window and shipping cost), `energyEfficiency` (class, label and data sheet),
|
|
1526
|
+
# `highlights`, `specifications` (group / name / value / unit), `images`, `variants`
|
|
1527
|
+
# (dimension, value, product id, price, online status), `badges`, `refurbishedFrom`,
|
|
1528
|
+
# `description` and the latest `reviews`. Store-level stock needs a chosen store and is not
|
|
1529
|
+
# included. One unit per call.
|
|
1530
|
+
#
|
|
1531
|
+
# @param product_id [String] MediaMarkt product number, e.g. 3071615 (the number at the end
|
|
1532
|
+
# of a product link, or `productId` from the search results).
|
|
1533
|
+
# @param url [String] A product link, e.g. https://www.mediamarkt.de/de/product/_apple-
|
|
1534
|
+
# iphone-18-pro-max-256gb-silver-3071615.html. Used instead of `product_id`; its shop and
|
|
1535
|
+
# language win over `country`, `banner` and `language`.
|
|
1536
|
+
# @param country [String] MediaMarkt shop: de, at, ch, nl, be, es, it, pl, hu, tr (default
|
|
1537
|
+
# de; it = MediaWorld). API default: de.
|
|
1538
|
+
# @param banner [String] mediamarkt (default) or saturn (Saturn Germany, with country=de).
|
|
1539
|
+
# API default: mediamarkt.
|
|
1540
|
+
# @param language [String] Site language where the shop has several: be = nl or fr, ch = de,
|
|
1541
|
+
# fr or it. Default: the shop's first.
|
|
1542
|
+
# Calls POST /marketplace/mediamarkt-product.
|
|
1543
|
+
def mediamarkt_product(product_id = nil, url: nil, country: nil, banner: nil, language: nil)
|
|
1544
|
+
post_json("/marketplace/mediamarkt-product", {
|
|
1545
|
+
product_id: product_id,
|
|
1546
|
+
url: url,
|
|
1547
|
+
country: country,
|
|
1548
|
+
banner: banner,
|
|
1549
|
+
language: language,
|
|
1550
|
+
})
|
|
1551
|
+
end
|
|
1552
|
+
|
|
1553
|
+
# Scrape Cdiscount search.
|
|
1554
|
+
#
|
|
1555
|
+
# Searches Cdiscount (France) for `query` and returns `products`, each with `position`,
|
|
1556
|
+
# `productId` (the SKU), `offerId`, `title`, `url`, `image`, `images`, `price`,
|
|
1557
|
+
# `strikePrice` (the crossed-out reference price, only when Cdiscount shows one),
|
|
1558
|
+
# `discountPercent`, `currency` (EUR), `rating`, `reviewCount`, `seller` (id, name,
|
|
1559
|
+
# `isCdiscount`), `marketplace`, `fulfilledByCdiscount`, `cdiscountAVolonte`,
|
|
1560
|
+
# `freeShipping`, `deliveryLabel`, `condition`, `highlights` (key specs), `badges`
|
|
1561
|
+
# (promotions) and `brandId`. Also `total`, `lastPage` and `nextPage`. Search results show
|
|
1562
|
+
# the brand only as an id; the product endpoint has the brand name. `page` and `max_results`
|
|
1563
|
+
# page through the results. One unit per Cdiscount page read.
|
|
1564
|
+
#
|
|
1565
|
+
# @param query [String] What to search for, e.g. 'iphone 15' or 'machine a laver'.
|
|
1566
|
+
# @param page [Integer] First Cdiscount results page to read (1-100). API default: 1.
|
|
1567
|
+
# @param max_results [Integer] Products to collect across pages, 1-300. A page holds about
|
|
1568
|
+
# 47 products; each page is one unit. API default: 47.
|
|
1569
|
+
# Calls POST /marketplace/cdiscount-search.
|
|
1570
|
+
def cdiscount_search(query, page: nil, max_results: nil)
|
|
1571
|
+
post_json("/marketplace/cdiscount-search", {
|
|
1572
|
+
query: query,
|
|
1573
|
+
page: page,
|
|
1574
|
+
max_results: max_results,
|
|
1575
|
+
})
|
|
1576
|
+
end
|
|
1577
|
+
|
|
1578
|
+
# Scrape a Cdiscount product.
|
|
1579
|
+
#
|
|
1580
|
+
# Returns one Cdiscount (France) product by `sku` or `url`: `productId`, `offerId`, `title`,
|
|
1581
|
+
# `brand`, `ean`, `manufacturerReference`, `url`, `breadcrumbs`, `price`, `priceWithoutVat`,
|
|
1582
|
+
# `strikePrice` and `strikePriceType`, `discountPercent`, `ecoParticipation`, `currency`,
|
|
1583
|
+
# `available`, `maxQuantity`, `preorder`, `condition`, `seller` (Cdiscount or the
|
|
1584
|
+
# marketplace seller), `marketplace`, `fulfilledByCdiscount`, `cdiscountAVolonte`,
|
|
1585
|
+
# `delivery` (free shipping, label, ships from), `offers` (count of new and used offers and
|
|
1586
|
+
# the lowest price of each), `rating`, `reviewCount`, `ratingBreakdown` (1-5 stars),
|
|
1587
|
+
# `criteriaRatings`, `highlights`, `specifications` (group / name / value), `description`,
|
|
1588
|
+
# `images`, `videos`, `variants` (attributes, price, url), `energyClass`,
|
|
1589
|
+
# `repairabilityIndex`, `installments`, `badges`, `documents` and the latest `reviews`. The
|
|
1590
|
+
# individual marketplace offers and their sellers' ratings are not included. One unit per
|
|
1591
|
+
# call.
|
|
1592
|
+
#
|
|
1593
|
+
# @param sku [String] Cdiscount product id (SKU), e.g. ip17256black - the part after
|
|
1594
|
+
# f-<number>- in a product link, or `productId` from the search results.
|
|
1595
|
+
# @param url [String] A Cdiscount product link, e.g.
|
|
1596
|
+
# https://www.cdiscount.com/telephonie/telephone-mobile/apple-iphone-17-256gb-
|
|
1597
|
+
# black/f-14404-ip17256black.html. Used instead of `sku`.
|
|
1598
|
+
# Calls POST /marketplace/cdiscount-product.
|
|
1599
|
+
def cdiscount_product(sku = nil, url: nil)
|
|
1600
|
+
post_json("/marketplace/cdiscount-product", {
|
|
1601
|
+
sku: sku,
|
|
1602
|
+
url: url,
|
|
1603
|
+
})
|
|
1604
|
+
end
|
|
1605
|
+
|
|
1606
|
+
# Scrape idealo search.
|
|
1607
|
+
#
|
|
1608
|
+
# Searches idealo (price comparison; `country` de, at, uk, fr, it or es) for `query` and
|
|
1609
|
+
# returns `products`, each with `position`, `type` (product = a price comparison of many
|
|
1610
|
+
# shops, offer = a single shop offer idealo has not matched to a product), `productId`,
|
|
1611
|
+
# `offerId`, `title`, `subtitle`, `characteristics`, `url` (the product's price comparison,
|
|
1612
|
+
# or the shop link of a single offer), `image`, `lowestPrice`, `basePrice` (unit price text,
|
|
1613
|
+
# when idealo shows one), `offerCount`, `usedOnly`, `cheapestShop` (id, name, shipping cost,
|
|
1614
|
+
# delivery, free-return days), `rating` (stars, rounded to half a star by idealo),
|
|
1615
|
+
# `reviewCount`, `testGrade` (the average press test grade, where 1 is best), `energyClass`,
|
|
1616
|
+
# `bargainSavingPercent`, `bestsellerRank`, `categoryId` and `variantOf`. Also `total`,
|
|
1617
|
+
# `productCount`, `lastPage` and `nextPage`, and `currency`. `sort` orders the results
|
|
1618
|
+
# (relevance or price_asc); `page` and `max_results` page through them. Use
|
|
1619
|
+
# `/marketplace/idealo-offers` for all shop offers of one product. One unit per idealo page
|
|
1620
|
+
# read.
|
|
1621
|
+
#
|
|
1622
|
+
# @param query [String] What to search for, e.g. 'iphone 17' or 'kaffeevollautomat'.
|
|
1623
|
+
# @param country [String] idealo site: de, at, uk, fr, it, es (default de; uk =
|
|
1624
|
+
# idealo.co.uk). API default: de.
|
|
1625
|
+
# @param sort [String] Result order: relevance, price_asc (price_asc = cheapest first). API
|
|
1626
|
+
# default: relevance.
|
|
1627
|
+
# @param page [Integer] First idealo results page to read (1-100). API default: 1.
|
|
1628
|
+
# @param max_results [Integer] Products to collect across pages, 1-300. A page holds 60
|
|
1629
|
+
# products; each page is one unit. API default: 60.
|
|
1630
|
+
# Calls POST /marketplace/idealo-search.
|
|
1631
|
+
def idealo_search(query, country: nil, sort: nil, page: nil, max_results: nil)
|
|
1632
|
+
post_json("/marketplace/idealo-search", {
|
|
1633
|
+
query: query,
|
|
1634
|
+
country: country,
|
|
1635
|
+
sort: sort,
|
|
1636
|
+
page: page,
|
|
1637
|
+
max_results: max_results,
|
|
1638
|
+
})
|
|
1639
|
+
end
|
|
1640
|
+
|
|
1641
|
+
# Scrape idealo offers of a product.
|
|
1642
|
+
#
|
|
1643
|
+
# Returns one idealo price comparison by `product_id` or `url` (`country` de, at, uk, fr, it
|
|
1644
|
+
# or es): the product (`productId`, `title`, `brand`, `url`, `images`, `lowestPrice`,
|
|
1645
|
+
# `highestPrice`, `currency`, `offerCount`, `rating`, `reviewCount`, `pros`, `cons`,
|
|
1646
|
+
# `variants` with their own price range and offer count) and `offers`, cheapest first, each
|
|
1647
|
+
# with `position`, `offerKey`, `title` (the shop's own product title), `price`,
|
|
1648
|
+
# `shippingCost`, `totalPrice`, `delivery` (the shop's delivery estimate as idealo prints
|
|
1649
|
+
# it), `carriers`, `freeReturns`, `paymentMethods`, `shop` (id, name, rating, rating count,
|
|
1650
|
+
# marketplace and the marketplace seller), `variantId`, `variantName` and `url` (idealo's
|
|
1651
|
+
# click-out link). Offers are the new-item offers idealo lists by default; `max_results`
|
|
1652
|
+
# collects more than the first 20. One unit for the product and its first 20 offers, plus
|
|
1653
|
+
# one per further block of 20.
|
|
1654
|
+
#
|
|
1655
|
+
# @param product_id [String] idealo product id, e.g. 207643424 (the number in a price
|
|
1656
|
+
# comparison link, or `productId` from the search results).
|
|
1657
|
+
# @param url [String] An idealo price comparison link, e.g.
|
|
1658
|
+
# https://www.idealo.de/preisvergleich/OffersOfProduct/207643424_-iphone-17-apple.html. Used
|
|
1659
|
+
# instead of `product_id`; its site sets the country.
|
|
1660
|
+
# @param country [String] idealo site: de, at, uk, fr, it, es (default de; uk =
|
|
1661
|
+
# idealo.co.uk).
|
|
1662
|
+
# @param max_results [Integer] Offers to collect, 1-200. The first 20 come with the product;
|
|
1663
|
+
# each further block of 20 is one more unit. API default: 20.
|
|
1664
|
+
# Calls POST /marketplace/idealo-offers.
|
|
1665
|
+
def idealo_offers(product_id = nil, url: nil, country: nil, max_results: nil)
|
|
1666
|
+
post_json("/marketplace/idealo-offers", {
|
|
1667
|
+
product_id: product_id,
|
|
1668
|
+
url: url,
|
|
1669
|
+
country: country,
|
|
1670
|
+
max_results: max_results,
|
|
1671
|
+
})
|
|
1672
|
+
end
|
|
1673
|
+
|
|
1674
|
+
# Scrape Rakuten Ichiba (Japan) product search.
|
|
1675
|
+
#
|
|
1676
|
+
# Searches Rakuten Ichiba (rakuten.co.jp) for `query` and returns `products`, each with
|
|
1677
|
+
# `position`, `itemId`, `itemCode`, `shopId` / `shopCode` / `shopName`, `title`, `subtitle`,
|
|
1678
|
+
# `url`, `price` (yen, tax included; `priceMax` when variants are priced differently),
|
|
1679
|
+
# `points` (Rakuten points a signed-out shopper earns) and `pointMultiplier`, `rating`,
|
|
1680
|
+
# `reviewCount`, `shippingFee` / `freeShipping`, `deliveryEstimate`, `nextDayDelivery`,
|
|
1681
|
+
# `unitPrice` / `unitPriceText` / `packCount`, `subscriptionPrice`, `saleEnds`, `ranking`
|
|
1682
|
+
# (daily genre rank), `soldOut`, `used`, `preOrder`, `superDeal`, `hasVariants`, `genreId` /
|
|
1683
|
+
# `genres`, `tags` and `image` / `images`. Rakuten's sponsored results come back in
|
|
1684
|
+
# `sponsored` (same fields). Also `totalResults`, `reachableResults` (how far Rakuten lets
|
|
1685
|
+
# the search be paged), `relatedKeywords` and `nextPage`. Sort with `sort`, filter with
|
|
1686
|
+
# `min_price` / `max_price` / `genre_id`, start at `page` and collect up to `max_results`
|
|
1687
|
+
# across pages (45 per page, each page billed as one request, see `pagesFetched`). `url`
|
|
1688
|
+
# takes a Rakuten search link instead of `query`.
|
|
1689
|
+
#
|
|
1690
|
+
# @param query [String] What to search, in Japanese or English, e.g. 'iphone', 'コーヒー' or
|
|
1691
|
+
# 'ナイキ スニーカー'.
|
|
1692
|
+
# @param sort [String] Order: relevance, price_low, price_high, newest, review_count,
|
|
1693
|
+
# review_score. API default: relevance.
|
|
1694
|
+
# @param page [Integer] 1-based results page to start from (1-150; Rakuten lets a search be
|
|
1695
|
+
# paged through to 6750 items). API default: 1.
|
|
1696
|
+
# @param min_price [Integer] Lowest price, in yen.
|
|
1697
|
+
# @param max_price [Integer] Highest price, in yen.
|
|
1698
|
+
# @param genre_id [String] Limit to one Rakuten genre (category) id, e.g. '100227' (food) -
|
|
1699
|
+
# every result's `genreId` is one.
|
|
1700
|
+
# @param max_results [Integer] Items to collect across pages (1-450); Rakuten serves 45 per
|
|
1701
|
+
# page and each page read is billed as one request. API default: 45.
|
|
1702
|
+
# @param url [String] Instead of `query`: a Rakuten search link, e.g.
|
|
1703
|
+
# https://search.rakuten.co.jp/search/mall/coffee/?s=2 (its keyword, genre, sort, page and
|
|
1704
|
+
# price filter are used).
|
|
1705
|
+
# Calls POST /marketplace/rakuten-search.
|
|
1706
|
+
def rakuten_search(query = nil, sort: nil, page: nil, min_price: nil, max_price: nil, genre_id: nil, max_results: nil, url: nil)
|
|
1707
|
+
post_json("/marketplace/rakuten-search", {
|
|
1708
|
+
query: query,
|
|
1709
|
+
sort: sort,
|
|
1710
|
+
page: page,
|
|
1711
|
+
min_price: min_price,
|
|
1712
|
+
max_price: max_price,
|
|
1713
|
+
genre_id: genre_id,
|
|
1714
|
+
max_results: max_results,
|
|
1715
|
+
url: url,
|
|
1716
|
+
})
|
|
1717
|
+
end
|
|
1718
|
+
|
|
1719
|
+
# Scrape one Rakuten Ichiba (Japan) item's full detail.
|
|
1720
|
+
#
|
|
1721
|
+
# Fetches one Rakuten Ichiba item (by `product_id` '<shopCode>/<itemCode>' or `url`) and
|
|
1722
|
+
# returns it as JSON: `itemId`, `itemCode`, `shopId` / `shopCode` / `shopName`, `url`,
|
|
1723
|
+
# `title`, `tagline`, `description`, `condition`, `price` / `priceMax` (yen, tax included),
|
|
1724
|
+
# `freeShipping`, `available`, `stockQuantity` (when the shop shares it), `deliveryMessage`,
|
|
1725
|
+
# `orderLimit`, `rating`, `reviewCount`, `reviewsUrl`, `genreId`, `breadcrumbs`,
|
|
1726
|
+
# `shopCategories`, `attributes` (name / value / unit), `variantOptions`, `variants` (every
|
|
1727
|
+
# SKU with its options, price, availability, stock, JAN code and image) and `images`. The
|
|
1728
|
+
# top-level price and stock are those of `variant_id` when given. Rakuten points are shown
|
|
1729
|
+
# on search results (`/marketplace/rakuten-search`), not here. Companion to
|
|
1730
|
+
# `/marketplace/rakuten-search`.
|
|
1731
|
+
#
|
|
1732
|
+
# @param product_id [String] The item as '<shopCode>/<itemCode>', e.g. 'dai-one/15-128-a'
|
|
1733
|
+
# (the two path parts of an item link; search results give them as `shopCode` and
|
|
1734
|
+
# `itemCode`).
|
|
1735
|
+
# @param url [String] Instead of `product_id`: a Rakuten item link, e.g.
|
|
1736
|
+
# https://item.rakuten.co.jp/dai-one/15-128-a/ (a `variantId` in it is used).
|
|
1737
|
+
# @param variant_id [String] SKU whose price and stock fill the top-level fields, e.g.
|
|
1738
|
+
# 'r-sku00003161'; by default the item's lowest price and overall availability. Every SKU is
|
|
1739
|
+
# listed in `variants` either way.
|
|
1740
|
+
# Calls POST /marketplace/rakuten-product.
|
|
1741
|
+
def rakuten_product(product_id: nil, url: nil, variant_id: nil)
|
|
1742
|
+
post_json("/marketplace/rakuten-product", {
|
|
1743
|
+
product_id: product_id,
|
|
1744
|
+
url: url,
|
|
1745
|
+
variant_id: variant_id,
|
|
1746
|
+
})
|
|
1747
|
+
end
|
|
1748
|
+
|
|
1749
|
+
# Scrape IndiaMART B2B product search.
|
|
1750
|
+
#
|
|
1751
|
+
# Searches IndiaMART for `query` and returns `products`, each with `position`, `productId`,
|
|
1752
|
+
# `title`, `url` (the IndiaMART product page, or the supplier's catalogue page when
|
|
1753
|
+
# `hasProductPage` is false - only products with a page can be fetched with
|
|
1754
|
+
# `/marketplace/indiamart-product`), `price` (number, null when the supplier asks for a
|
|
1755
|
+
# quote) and `priceText`, `currency`, `unit` (the price is per this unit),
|
|
1756
|
+
# `minOrderQuantity`, `category` / `categoryId`, `specifications` (name / value),
|
|
1757
|
+
# `description`, `image`, `brochureUrl`, `supplier` (`id`, `name`, `city`, `district`,
|
|
1758
|
+
# `state`, `country`, `businessType`, `verifiedExporter`, `trustSeal`, `gstVerified`,
|
|
1759
|
+
# `iecVerified`, `rating`, `ratingCount`, `memberSince`, `exporterSince`, `exportsTo`,
|
|
1760
|
+
# `website`) and `moreFromSupplier` (the supplier's other matching products). IndiaMART
|
|
1761
|
+
# shows visitors outside India its export catalogue, so results are IndiaMART's verified
|
|
1762
|
+
# exporters, 10 a page and 2 pages (up to 20 products per search); `totalResults` is
|
|
1763
|
+
# IndiaMART's own count of all matches. Supplier phone numbers, e-mails and contact names
|
|
1764
|
+
# are not returned. `url` takes an IndiaMART search link instead of `query`.
|
|
1765
|
+
#
|
|
1766
|
+
# @param query [String] What to search, e.g. 'steel pipe', 'cotton t shirt' or 'solar
|
|
1767
|
+
# panel'.
|
|
1768
|
+
# @param page [Integer] 1-based results page to start from (1-2); 10 products a page. API
|
|
1769
|
+
# default: 1.
|
|
1770
|
+
# @param max_results [Integer] Products to collect across pages (1-20); IndiaMART serves 10
|
|
1771
|
+
# per page and shows 2 pages. Each page read is billed as one request. API default: 20.
|
|
1772
|
+
# @param url [String] Instead of `query`: an IndiaMART search link, e.g.
|
|
1773
|
+
# https://dir.indiamart.com/search.mp?ss=steel+pipe (its keyword is used).
|
|
1774
|
+
# Calls POST /marketplace/indiamart-search.
|
|
1775
|
+
def indiamart_search(query = nil, page: nil, max_results: nil, url: nil)
|
|
1776
|
+
post_json("/marketplace/indiamart-search", {
|
|
1777
|
+
query: query,
|
|
1778
|
+
page: page,
|
|
1779
|
+
max_results: max_results,
|
|
1780
|
+
url: url,
|
|
1781
|
+
})
|
|
1782
|
+
end
|
|
1783
|
+
|
|
1784
|
+
# Scrape one IndiaMART product and its supplier.
|
|
1785
|
+
#
|
|
1786
|
+
# Fetches one IndiaMART product (by `product_id` or `url`) and returns it as JSON:
|
|
1787
|
+
# `productId`, `title`, `name`, `url`, `price` (null when the supplier asks for a quote) /
|
|
1788
|
+
# `priceText`, `currency`, `unit`, `minOrderQuantity`, `description`, `specifications` (name
|
|
1789
|
+
# / value), `category` / `categoryId` / `parentCategory` / `group`, `deliveryTime`,
|
|
1790
|
+
# `packagingDetails`, `productionCapacity`, `portOfDispatch`, `paymentTerms`, `image` /
|
|
1791
|
+
# `images`, `brochureUrl` and `supplier` (`id`, `name`, `city`, `state`, `country`,
|
|
1792
|
+
# `businessType`, `additionalBusiness`, `yearEstablished`, `employees`, `annualTurnover`,
|
|
1793
|
+
# `legalStatus`, `gstVerified`, `trustSeal`, `mobileVerified`, `emailVerified`, `rating`,
|
|
1794
|
+
# `ratingCount`, `memberSince`, `topExportCountries`, `website`, `logo`). Supplier phone
|
|
1795
|
+
# numbers, e-mails, people's names and street addresses are not returned. Companion to
|
|
1796
|
+
# `/marketplace/indiamart-search`.
|
|
1797
|
+
#
|
|
1798
|
+
# @param product_id [String] IndiaMART product id, e.g. '2854548650133' (the number at the
|
|
1799
|
+
# end of a /proddetail/ link; search results give it as `productId`).
|
|
1800
|
+
# @param url [String] Instead of `product_id`: an IndiaMART product link, e.g.
|
|
1801
|
+
# https://www.indiamart.com/proddetail/stainless-steel-347h-pipes-2854548650133.html.
|
|
1802
|
+
# Calls POST /marketplace/indiamart-product.
|
|
1803
|
+
def indiamart_product(product_id: nil, url: nil)
|
|
1804
|
+
post_json("/marketplace/indiamart-product", {
|
|
1805
|
+
product_id: product_id,
|
|
1806
|
+
url: url,
|
|
1807
|
+
})
|
|
1808
|
+
end
|
|
1809
|
+
|
|
1810
|
+
# Scrape Bed Bath & Beyond product search.
|
|
1811
|
+
#
|
|
1812
|
+
# Searches Bed Bath & Beyond (bedbathandbeyond.com, US) for `query` and returns the products
|
|
1813
|
+
# as JSON: `productId`, `sku`, `title`, `url`, `image`, `price` (the lowest option price)
|
|
1814
|
+
# and `priceMax` (the top of the range when options differ), `priceText`, `priceType` (SALE
|
|
1815
|
+
# or STANDARD), `currency` (USD), `comparePrice` with `compareType` (MSRP, COMPARE_AT or
|
|
1816
|
+
# WAS), `discountPercent`, `regularPrice`, `hasOptions`, `optionCount`, `rating`,
|
|
1817
|
+
# `reviewCount`, `badge` (e.g. Best Seller), `onSale`, `fastDelivery`, `rewards` (Welcome
|
|
1818
|
+
# Rewards dollars) and `sponsored`. Sort with `sort`, start at `page`, and collect up to
|
|
1819
|
+
# `max_results` across pages (about 60 per page, each page billed as one request, see
|
|
1820
|
+
# `pagesFetched`). Keywords the site maps to a department (e.g. 'rugs') return that
|
|
1821
|
+
# department's listing, named in `redirectedTo`. `url` takes a search link instead of
|
|
1822
|
+
# `query`.
|
|
1823
|
+
#
|
|
1824
|
+
# @param query [String] What to search, e.g. 'bath towels', 'office chair' or 'table lamp'.
|
|
1825
|
+
# @param sort [String] Order: relevance, on_sale, best_selling, price_low, price_high,
|
|
1826
|
+
# rating, newest. API default: relevance.
|
|
1827
|
+
# @param page [Integer] 1-based results page to start from (1-100). API default: 1.
|
|
1828
|
+
# @param max_results [Integer] Products to collect across pages (1-300); the site serves
|
|
1829
|
+
# about 60 per page and each page fetched is billed as one request. API default: 60.
|
|
1830
|
+
# @param url [String] Instead of `query`: a Bed Bath & Beyond search link, e.g.
|
|
1831
|
+
# https://www.bedbathandbeyond.com/search?keywords=towels (its sort and page are used).
|
|
1832
|
+
# Calls POST /marketplace/bedbathandbeyond-search.
|
|
1833
|
+
def bedbathandbeyond_search(query = nil, sort: nil, page: nil, max_results: nil, url: nil)
|
|
1834
|
+
post_json("/marketplace/bedbathandbeyond-search", {
|
|
1835
|
+
query: query,
|
|
1836
|
+
sort: sort,
|
|
1837
|
+
page: page,
|
|
1838
|
+
max_results: max_results,
|
|
1839
|
+
url: url,
|
|
1840
|
+
})
|
|
1841
|
+
end
|
|
1842
|
+
|
|
1843
|
+
# Scrape one Bed Bath & Beyond product's full detail.
|
|
1844
|
+
#
|
|
1845
|
+
# Fetches one Bed Bath & Beyond product (by id or link) and returns it as JSON: `productId`,
|
|
1846
|
+
# `sku`, `url`, `title`, `brand`, `brandUrl`, `manufacturerPartNumber`, `price` with
|
|
1847
|
+
# `priceLabel` (e.g. 'Sale Starts at' when options are priced differently), `comparePrice`
|
|
1848
|
+
# with `compareLabel` (MSRP, Was, At other retailer), `savings`, `savingsPercent`,
|
|
1849
|
+
# `currency` (USD), `inStock`, `rating`, `reviewCount`, `ratingHistogram`, `badge`,
|
|
1850
|
+
# `shortDescription`, `description`, `countryOfOrigin`, `freeShipping`,
|
|
1851
|
+
# `internationalShipping`, `firstListed`, `breadcrumbs`, `specifications` (group / name /
|
|
1852
|
+
# value), `optionCount`, `defaultOptionId`, `options` (up to 100: option id, title, size /
|
|
1853
|
+
# colour attributes, price, regular price, compare price, on-sale flag, stock and quantity
|
|
1854
|
+
# on hand), `images` and `videos`. Prices are those shown to a signed-out shopper. Companion
|
|
1855
|
+
# to `/marketplace/bedbathandbeyond-search`.
|
|
1856
|
+
#
|
|
1857
|
+
# @param product [String] A Bed Bath & Beyond product id (e.g. '5296998', the number before
|
|
1858
|
+
# /product.html) or a product link.
|
|
1859
|
+
# Calls POST /marketplace/bedbathandbeyond-product.
|
|
1860
|
+
def bedbathandbeyond_product(product)
|
|
1861
|
+
post_json("/marketplace/bedbathandbeyond-product", {
|
|
1862
|
+
product: product,
|
|
1863
|
+
})
|
|
1864
|
+
end
|
|
1865
|
+
|
|
1866
|
+
# Scrape Petco product search.
|
|
1867
|
+
#
|
|
1868
|
+
# Searches Petco (petco.com, US) for `query` and returns the products as JSON: `sku`,
|
|
1869
|
+
# `productId`, `title`, `familyName`, `brand`, `url`, `image`, `price`, `listPrice`,
|
|
1870
|
+
# `autoshipPrice` (the Repeat Delivery price), `onSale`, `currency` (USD), `rating`,
|
|
1871
|
+
# `reviewCount`, `description`, `category`, `autoshipEligible`, `pickupEligible`,
|
|
1872
|
+
# `sameDayDeliveryEligible`, `inStoreOnly`, `prescriptionFood`, `attributes` (brand,
|
|
1873
|
+
# flavour, life stage...) and `variations` (every size / colour with its SKU, url and
|
|
1874
|
+
# prices). Sort with `sort`, narrow with `brand`, `fulfillment` (delivery, autoship, pickup,
|
|
1875
|
+
# same_day) and `min_price` / `max_price`, start at `page` and collect up to `max_results`
|
|
1876
|
+
# (48 per page, each page billed as one request, see `pagesFetched`). A term Petco sends to
|
|
1877
|
+
# a brand or category page (e.g. a brand name) returns that page's listing, named in
|
|
1878
|
+
# `redirectedTo`. Prices are the online prices a signed-out shopper sees; store-specific
|
|
1879
|
+
# stock and member (Vital Care) prices are not included.
|
|
1880
|
+
#
|
|
1881
|
+
# @param query [String] What to search, e.g. 'dog food', 'cat litter' or 'fish tank'.
|
|
1882
|
+
# @param sort [String] Order: relevance, price_low, price_high, rating, popular, newest,
|
|
1883
|
+
# name_asc, name_desc. API default: relevance.
|
|
1884
|
+
# @param page [Integer] 1-based results page to start from (1-200), 48 products per page as
|
|
1885
|
+
# on petco.com. API default: 1.
|
|
1886
|
+
# @param max_results [Integer] Products to collect across pages (1-480); each page of 48
|
|
1887
|
+
# fetched is billed as one request. API default: 48.
|
|
1888
|
+
# @param brand [String] Only this brand, as petco.com names it (e.g. 'Purina Pro Plan'; the
|
|
1889
|
+
# `brands` list of a search shows the names).
|
|
1890
|
+
# @param fulfillment [String] Only products offered this way: delivery, autoship, pickup,
|
|
1891
|
+
# same_day.
|
|
1892
|
+
# @param min_price [Float] Lowest price to include (USD).
|
|
1893
|
+
# @param max_price [Float] Highest price to include (USD).
|
|
1894
|
+
# @param url [String] Instead of `query`: a petco.com search link, e.g.
|
|
1895
|
+
# https://www.petco.com/shop/en/petcostore/search?query=dog%20food.
|
|
1896
|
+
# Calls POST /marketplace/petco-search.
|
|
1897
|
+
def petco_search(query = nil, sort: nil, page: nil, max_results: nil, brand: nil, fulfillment: nil, min_price: nil, max_price: nil, url: nil)
|
|
1898
|
+
post_json("/marketplace/petco-search", {
|
|
1899
|
+
query: query,
|
|
1900
|
+
sort: sort,
|
|
1901
|
+
page: page,
|
|
1902
|
+
max_results: max_results,
|
|
1903
|
+
brand: brand,
|
|
1904
|
+
fulfillment: fulfillment,
|
|
1905
|
+
min_price: min_price,
|
|
1906
|
+
max_price: max_price,
|
|
1907
|
+
url: url,
|
|
1908
|
+
})
|
|
1909
|
+
end
|
|
1910
|
+
|
|
1911
|
+
# Scrape one Petco product's full detail.
|
|
1912
|
+
#
|
|
1913
|
+
# Fetches one Petco product (by SKU or link) and returns it as JSON: `sku`, `catEntryId`,
|
|
1914
|
+
# `parentSku`, `url`, `title`, `brand`, `upc`, `price`, `listPrice`, `autoshipPrice`,
|
|
1915
|
+
# `pickupPrice`, `onSale`, `currency` (USD), `availability`, `inStock`, `availableQuantity`
|
|
1916
|
+
# (online stock), `rating`, `reviewCount`, `ratingHistogram`, `recommendedPercent`,
|
|
1917
|
+
# `description`, `highlights`, `ingredients`, `directions`, `specifications` (group / name /
|
|
1918
|
+
# value), `attributes` (size / weight / colour of this variant), `dimensions`, `petType`,
|
|
1919
|
+
# `category`, `breadcrumbs`, fulfillment flags (`autoshipEligible`, `pickupEligible`,
|
|
1920
|
+
# `sameDayDeliveryEligible`, `onlineOnly`, `inStoreOnly`), `prescriptionRequired`,
|
|
1921
|
+
# `discontinued`, `images`, `variants` (every size / colour with its SKU, url, prices and
|
|
1922
|
+
# stock) and the first `reviews` (up to 10). A link's own variant is returned; a SKU picks
|
|
1923
|
+
# that variant. Prices are the online prices a signed-out shopper sees (no member or store
|
|
1924
|
+
# prices). Companion to `/marketplace/petco-search`.
|
|
1925
|
+
#
|
|
1926
|
+
# @param product [String] A Petco SKU (the number a product link ends in, e.g. '3748364') or
|
|
1927
|
+
# a petco.com product link.
|
|
1928
|
+
# Calls POST /marketplace/petco-product.
|
|
1929
|
+
def petco_product(product)
|
|
1930
|
+
post_json("/marketplace/petco-product", {
|
|
1931
|
+
product: product,
|
|
1932
|
+
})
|
|
1933
|
+
end
|
|
1934
|
+
|
|
1935
|
+
# Scrape one Neobits product.
|
|
1936
|
+
#
|
|
1937
|
+
# Fetches one product from Neobits (neobits.com, US B2B electronics and IT reseller) by item
|
|
1938
|
+
# number or link and returns it as JSON: `itemNumber`, `url`, `title`, `brand`, `brandUrl`,
|
|
1939
|
+
# `mfrPartNumber`, `price`, `listPrice`, `savings`, `discountPercent`, `priceDrop`,
|
|
1940
|
+
# `currency` (USD), `stockStatus` (e.g. In Stock, SHIPS SOON), `inStock`, `stockNote`,
|
|
1941
|
+
# `leadTime` (the brand's average lead time when shown), `rating`, `reviewCount`,
|
|
1942
|
+
# `questionCount`, `description`, `specifications` (name / value), `breadcrumbs` and
|
|
1943
|
+
# `images`. Neobits search is not offered: the site gates its search and listing pages
|
|
1944
|
+
# behind a reCAPTCHA for automated traffic.
|
|
1945
|
+
#
|
|
1946
|
+
# @param product [String] A Neobits item number (the 'Item #' on a product page, e.g.
|
|
1947
|
+
# '27956233') or a neobits.com product link (ending in _p<item>.html).
|
|
1948
|
+
# Calls POST /marketplace/neobits-product.
|
|
1949
|
+
def neobits_product(product)
|
|
1950
|
+
post_json("/marketplace/neobits-product", {
|
|
1951
|
+
product: product,
|
|
1952
|
+
})
|
|
1953
|
+
end
|
|
1954
|
+
|
|
1955
|
+
# Scrape Lowe's product search.
|
|
1956
|
+
#
|
|
1957
|
+
# Searches Lowe's (lowes.com, US) for `query` at one store and returns `products`:
|
|
1958
|
+
# `productId` (Lowe's item id), `itemNumber`, `modelNumber`, `brand`, `title`, `url`,
|
|
1959
|
+
# `image`, `rating`, `reviewCount`, `price`, `wasPrice`, `savings`, `savingsPercent` and
|
|
1960
|
+
# `saleEnds` (promotions), `clearance`, `minPrice` / `maxPrice` (items with options),
|
|
1961
|
+
# `priceType` (store, network = Lowe's online price, sos = special order), `currency`,
|
|
1962
|
+
# `availability` (`pickup` with the units on hand at the store, `parcel`, `delivery`,
|
|
1963
|
+
# `expeditedDelivery`), `sponsored`, `marketplace`, `bullets` and `specifications`, plus
|
|
1964
|
+
# `store` (the store the prices and stock are for) and paging totals. Set the store with
|
|
1965
|
+
# `store_id` or `zip` (default: store 1845, Chicago-Brickyard, IL). Results come in Lowe's
|
|
1966
|
+
# own order; `free_delivery` keeps free-delivery items only. Start at `page` and collect up
|
|
1967
|
+
# to `max_results` across pages (24 per page, each page billed as one request, see
|
|
1968
|
+
# `pagesFetched`). A broad keyword Lowe's sends to a category landing page (e.g. patio
|
|
1969
|
+
# furniture) is answered from the landing page's first category tile that names the keyword;
|
|
1970
|
+
# `category` names it (null for a plain search). A landing page without such a tile answers
|
|
1971
|
+
# 404: search a more specific term.
|
|
1972
|
+
#
|
|
1973
|
+
# @param query [String] What to search, e.g. 'cordless drill', 'garden hose' or 'interior
|
|
1974
|
+
# paint'.
|
|
1975
|
+
# @param page [Integer] 1-based results page to start from (1-30, 24 products per page). API
|
|
1976
|
+
# default: 1.
|
|
1977
|
+
# @param max_results [Integer] Products to collect across pages (1-72); each page fetched is
|
|
1978
|
+
# billed as one request. API default: 24.
|
|
1979
|
+
# @param store_id [String] Lowe's store number whose prices and stock to return, e.g.
|
|
1980
|
+
# '1845'. Give this or `zip`; with neither, store 1845 (Chicago-Brickyard, IL) is used. The
|
|
1981
|
+
# store used is named in `store`.
|
|
1982
|
+
# @param zip [String] US ZIP code; the nearest Lowe's store is used, e.g. '60639'.
|
|
1983
|
+
# @param free_delivery [Boolean] Only items Lowe's delivers for free. API default: false.
|
|
1984
|
+
# @param url [String] Instead of `query`: a Lowe's search link, e.g.
|
|
1985
|
+
# https://www.lowes.com/search?searchTerm=garden+hose (its offset and storeId are used).
|
|
1986
|
+
# Calls POST /marketplace/lowes-search.
|
|
1987
|
+
def lowes_search(query = nil, page: nil, max_results: nil, store_id: nil, zip: nil, free_delivery: nil, url: nil)
|
|
1988
|
+
post_json("/marketplace/lowes-search", {
|
|
1989
|
+
query: query,
|
|
1990
|
+
page: page,
|
|
1991
|
+
max_results: max_results,
|
|
1992
|
+
store_id: store_id,
|
|
1993
|
+
zip: zip,
|
|
1994
|
+
free_delivery: free_delivery,
|
|
1995
|
+
url: url,
|
|
1996
|
+
})
|
|
1997
|
+
end
|
|
1998
|
+
|
|
1999
|
+
# Scrape one Lowe's product.
|
|
2000
|
+
#
|
|
2001
|
+
# Fetches one Lowe's product (by `product_id` or `url`) priced for one store and returns it
|
|
2002
|
+
# as JSON: `productId`, `itemNumber`, `modelNumber`, `upc`, `brand`, `title`, `url`,
|
|
2003
|
+
# `rating`, `reviewCount`, `price`, `wasPrice`, `savings`, `savingsPercent`, `saleEnds`,
|
|
2004
|
+
# `clearance`, `priceType`, `currency`, `storeId`, `availability` (`pickup` with the units
|
|
2005
|
+
# on hand at the store and at `nearbyStores`, `parcel`, `delivery`, `expeditedDelivery` with
|
|
2006
|
+
# lead times), `description`, `bullets`, `specifications` (name / value / group), `images`,
|
|
2007
|
+
# `videos`, `documents`, `category`, `dimensions`, `weightLbs`, `buyable` and `status`, plus
|
|
2008
|
+
# `store`. Set the store with `store_id` or `zip` (default: store 1845, Chicago-Brickyard,
|
|
2009
|
+
# IL). Companion to `/marketplace/lowes-search`.
|
|
2010
|
+
#
|
|
2011
|
+
# @param product_id [String] Lowe's item id, e.g. '5016412045' (the number at the end of a
|
|
2012
|
+
# product link; the `productId` of a search result).
|
|
2013
|
+
# @param url [String] Instead of `product_id`: a Lowe's product link, e.g.
|
|
2014
|
+
# https://www.lowes.com/pd/CRAFTSMAN-20-volt-Max-Drill/5016412045.
|
|
2015
|
+
# @param store_id [String] Lowe's store number whose prices and stock to return, e.g.
|
|
2016
|
+
# '1845'. Give this or `zip`; with neither, store 1845 (Chicago-Brickyard, IL) is used. The
|
|
2017
|
+
# store used is named in `store`.
|
|
2018
|
+
# @param zip [String] US ZIP code; the nearest Lowe's store is used, e.g. '60639'.
|
|
2019
|
+
# Calls POST /marketplace/lowes-product.
|
|
2020
|
+
def lowes_product(product_id = nil, url: nil, store_id: nil, zip: nil)
|
|
2021
|
+
post_json("/marketplace/lowes-product", {
|
|
2022
|
+
product_id: product_id,
|
|
2023
|
+
url: url,
|
|
2024
|
+
store_id: store_id,
|
|
2025
|
+
zip: zip,
|
|
2026
|
+
})
|
|
2027
|
+
end
|
|
2028
|
+
|
|
2029
|
+
# Scrape Menards product search.
|
|
2030
|
+
#
|
|
2031
|
+
# Searches Menards (menards.com, US) for `query` and returns `products`: `itemId`, `sku`
|
|
2032
|
+
# (the Menards SKU), `modelNumber` (when Menards lists it), `title`, `brand`, `url`,
|
|
2033
|
+
# `image`, `price` (shelf price before the mail-in rebate), `regularPrice` (everyday low
|
|
2034
|
+
# price), `onSale`, `rebate` and `rebateLabel` (Menards' rebate, usually 11%),
|
|
2035
|
+
# `priceAfterRebate` (null when the maker's advertised-price policy moves it to checkout:
|
|
2036
|
+
# `priceInCheckout` true, `minimumAdvertisedPrice`), `unitOfMeasure`, `currency`,
|
|
2037
|
+
# `availability` (`pickup`, `delivery`, `stockAtStore`, `stockMessage`, `deliveryMessage`),
|
|
2038
|
+
# `variationCount` and `categoryId`, plus `totalResults`, `facets` and `store` (the store
|
|
2039
|
+
# the prices and stock are for). Set the store with `store_id` or `zip`; without one Menards
|
|
2040
|
+
# shows its default online prices and no store stock. Sort with `sort`, filter with
|
|
2041
|
+
# `min_price` / `max_price`, `in_stock_today`, `delivery_eligible` and `pickup_eligible`,
|
|
2042
|
+
# start at `page` and collect up to `max_results` across pages (40 per page, each page
|
|
2043
|
+
# billed as one request, see `pagesFetched`). A keyword Menards sends to a category returns
|
|
2044
|
+
# that category's products (`redirectedTo`); a Menards SKU returns no products and the
|
|
2045
|
+
# product link in `redirectedTo`. A keyword Menards sends to a page of category tiles (e.g.
|
|
2046
|
+
# interior paint) or one with no matches answers 404.
|
|
2047
|
+
#
|
|
2048
|
+
# @param query [String] What to search, e.g. 'cordless drill', 'garden hose' or '2x4
|
|
2049
|
+
# lumber'.
|
|
2050
|
+
# @param sort [String] Order: relevance, price_low, price_high, title_asc, title_desc,
|
|
2051
|
+
# brand_asc, brand_desc. API default: relevance.
|
|
2052
|
+
# @param page [Integer] 1-based results page to start from (1-100, 40 products per page).
|
|
2053
|
+
# API default: 1.
|
|
2054
|
+
# @param max_results [Integer] Products to collect across pages (1-120); each page fetched
|
|
2055
|
+
# is billed as one request. API default: 40.
|
|
2056
|
+
# @param min_price [Float] Lowest price to include (USD).
|
|
2057
|
+
# @param max_price [Float] Highest price to include (USD).
|
|
2058
|
+
# @param store_id [String] Menards store number whose prices and stock to return, e.g.
|
|
2059
|
+
# '3181'. Give this or `zip`; with neither, Menards' default (online) prices are returned
|
|
2060
|
+
# and `stockAtStore` is 0. The store used is named in `store`.
|
|
2061
|
+
# @param zip [String] US ZIP code; the nearest Menards store is used, e.g. '55401'.
|
|
2062
|
+
# @param in_stock_today [Boolean] Only items in stock today at the store (needs `store_id`
|
|
2063
|
+
# or `zip`). API default: false.
|
|
2064
|
+
# @param delivery_eligible [Boolean] Only items eligible for delivery. API default: false.
|
|
2065
|
+
# @param pickup_eligible [Boolean] Only items eligible for in-store pickup. API default:
|
|
2066
|
+
# false.
|
|
2067
|
+
# Calls POST /marketplace/menards-search.
|
|
2068
|
+
def menards_search(query, sort: nil, page: nil, max_results: nil, min_price: nil, max_price: nil, store_id: nil, zip: nil, in_stock_today: nil, delivery_eligible: nil, pickup_eligible: nil)
|
|
2069
|
+
post_json("/marketplace/menards-search", {
|
|
2070
|
+
query: query,
|
|
2071
|
+
sort: sort,
|
|
2072
|
+
page: page,
|
|
2073
|
+
max_results: max_results,
|
|
2074
|
+
min_price: min_price,
|
|
2075
|
+
max_price: max_price,
|
|
2076
|
+
store_id: store_id,
|
|
2077
|
+
zip: zip,
|
|
2078
|
+
in_stock_today: in_stock_today,
|
|
2079
|
+
delivery_eligible: delivery_eligible,
|
|
2080
|
+
pickup_eligible: pickup_eligible,
|
|
2081
|
+
})
|
|
2082
|
+
end
|
|
2083
|
+
|
|
2084
|
+
# Scrape one Menards product.
|
|
2085
|
+
#
|
|
2086
|
+
# Fetches one Menards product (by `url` or `sku`) and returns it as JSON: `itemId`, `sku`,
|
|
2087
|
+
# `modelNumber`, `title`, `brand`, `url`, `price` (shelf price), `regularPrice` (everyday
|
|
2088
|
+
# low price), `onSale` and `saleEnds`, `minimumAdvertisedPrice` and `priceInCheckout` (items
|
|
2089
|
+
# whose maker lets Menards show its price only in checkout: `price` is then null), `rebate`,
|
|
2090
|
+
# `rebateLabel`, `rebateEnds`, `priceAfterRebate`, `offerPrice`, `currency`, `availability`,
|
|
2091
|
+
# `storeId`, `description`, `features`, `specifications` (name / value), `images` and
|
|
2092
|
+
# `breadcrumbs`. Prices are Menards' default online prices (the store in `storeId`); for one
|
|
2093
|
+
# store's prices and stock use `/marketplace/menards-search` with `store_id` or `zip`.
|
|
2094
|
+
#
|
|
2095
|
+
# @param url [String] A Menards product link, e.g.
|
|
2096
|
+
# https://www.menards.com/main/electrical/electrical-tools-accessories/electrical-hand-
|
|
2097
|
+
# tools/southwire-reg-7-1-2-mc-rotary-cutter/mccut/p-60893668339-c-6455.htm (the `url` of a
|
|
2098
|
+
# search result).
|
|
2099
|
+
# @param sku [String] Instead of `url`: the Menards SKU shown on the product page and in
|
|
2100
|
+
# search results, e.g. '3646903'.
|
|
2101
|
+
# Calls POST /marketplace/menards-product.
|
|
2102
|
+
def menards_product(url: nil, sku: nil)
|
|
2103
|
+
post_json("/marketplace/menards-product", {
|
|
2104
|
+
url: url,
|
|
2105
|
+
sku: sku,
|
|
2106
|
+
})
|
|
2107
|
+
end
|
|
2108
|
+
|
|
2109
|
+
# Scrape Grainger product search.
|
|
2110
|
+
#
|
|
2111
|
+
# Searches Grainger (grainger.com, US industrial supplies) for `query` and returns
|
|
2112
|
+
# Grainger's first result rows (up to 25 items, in Grainger's order) as `products`:
|
|
2113
|
+
# `position`, `sku` (Grainger item number), `productId`, `title`, `brand`,
|
|
2114
|
+
# `manufacturerModel`, `url`, `image`, `price` (Grainger's signed-out Web Price),
|
|
2115
|
+
# `priceLabel`, `priceType`, `wasPrice`, `quantityPricing`, `currency`, `status` (e.g.
|
|
2116
|
+
# Sellable) and `specifications` (name / value, e.g. thread size, voltage, material).
|
|
2117
|
+
# Grainger answers a keyword with the product category that matches it best: `category`
|
|
2118
|
+
# names it, `totalResults` counts that category's matches, and `categories` lists the other
|
|
2119
|
+
# matching categories with counts and links (search one of them by passing its link as
|
|
2120
|
+
# `url`). A keyword that leads to a department page (subcategory tiles, no products) is
|
|
2121
|
+
# answered from the subcategory holding the product line that matches it most often:
|
|
2122
|
+
# `category` names that subcategory, `totalAcrossCategories` counts the department and
|
|
2123
|
+
# `categories` lists its subcategories. Only the first result rows are returned (no paging).
|
|
2124
|
+
# Stock is not included: Grainger checks it per ZIP code after the page loads.
|
|
2125
|
+
#
|
|
2126
|
+
# @param query [String] What to search, e.g. 'safety glasses', 'hex bolt', 'cordless drill'
|
|
2127
|
+
# or a manufacturer model.
|
|
2128
|
+
# @param max_results [Integer] Items to return (1-25); Grainger's first result rows for the
|
|
2129
|
+
# keyword. API default: 25.
|
|
2130
|
+
# @param url [String] Instead of `query`: a Grainger search link, e.g.
|
|
2131
|
+
# https://www.grainger.com/search?searchQuery=hex+bolt.
|
|
2132
|
+
# Calls POST /marketplace/grainger-search.
|
|
2133
|
+
def grainger_search(query = nil, max_results: nil, url: nil)
|
|
2134
|
+
post_json("/marketplace/grainger-search", {
|
|
2135
|
+
query: query,
|
|
2136
|
+
max_results: max_results,
|
|
2137
|
+
url: url,
|
|
2138
|
+
})
|
|
2139
|
+
end
|
|
2140
|
+
|
|
2141
|
+
# Scrape one Grainger product.
|
|
2142
|
+
#
|
|
2143
|
+
# Fetches one Grainger item (by `sku`, the Grainger item number, or `url`) and returns it as
|
|
2144
|
+
# JSON: `sku`, `productId`, `title`, `brand`, `manufacturerModel`, `url`, `price` (signed-
|
|
2145
|
+
# out Web Price), `priceLabel`, `priceType`, `wasPrice`, `unitOfMeasure` (e.g. 'pkg. of
|
|
2146
|
+
# 100'), `quantityPricing`, `currency`, `status`, `discontinued`, `sellInfo`,
|
|
2147
|
+
# `shippingWeight`, `description`, `specifications` (name / value, including UNSPSC and
|
|
2148
|
+
# country of origin), `images`, `documents` (spec sheets, drawings), `alternateSkus` and
|
|
2149
|
+
# `breadcrumbs`. Stock is not included: Grainger checks it per ZIP code after the page
|
|
2150
|
+
# loads.
|
|
2151
|
+
#
|
|
2152
|
+
# @param sku [String] Grainger item number, e.g. '1XE66' or '22TA59' (the `sku` of a search
|
|
2153
|
+
# result).
|
|
2154
|
+
# @param url [String] Instead of `sku`: a Grainger product link, e.g.
|
|
2155
|
+
# https://www.grainger.com/product/Hex-Head-Cap-Screw-Stainless-1XE66.
|
|
2156
|
+
# Calls POST /marketplace/grainger-product.
|
|
2157
|
+
def grainger_product(sku = nil, url: nil)
|
|
2158
|
+
post_json("/marketplace/grainger-product", {
|
|
2159
|
+
sku: sku,
|
|
2160
|
+
url: url,
|
|
2161
|
+
})
|
|
2162
|
+
end
|
|
2163
|
+
|
|
2164
|
+
# Scrape one eBay listing's full detail.
|
|
2165
|
+
#
|
|
2166
|
+
# Fetches one eBay listing (by `item_id` + `marketplace`, or `url`) on any supported eBay
|
|
2167
|
+
# site and returns it as JSON: `itemId`, `title`, `status` (active / ended), `price` +
|
|
2168
|
+
# `currency`, `originalPrice` (list or was price), `listingFormat` (buy_it_now, auction,
|
|
2169
|
+
# auction_with_buy_it_now) with `buyItNowPrice`, `currentBid`, `bidCount`, `reserveMet` and
|
|
2170
|
+
# `endsAt`, `listingPrice` / `listingCurrency` when the seller lists in another currency,
|
|
2171
|
+
# `condition` (with `conditionCode` and the seller's `conditionNotes`), `availability`,
|
|
2172
|
+
# `quantityAvailable`, `quantitySold`, `watchers`, `seller` (username, store name, feedback
|
|
2173
|
+
# score, positive percentage, business or private), `shippingRates` (cost per destination
|
|
2174
|
+
# country), `shipping`, `itemLocation`, `delivery`, `importFees`, `returns`, `brand`, `mpn`,
|
|
2175
|
+
# `gtin`, `itemSpecifics`, `categories`, `paymentMethods`, `variationOptions` and
|
|
2176
|
+
# `variations` (each with its own price and stock), `images` and the seller's `description`
|
|
2177
|
+
# as text. Labels and texts follow the site's language (ebay.de answers in German).
|
|
2178
|
+
# Shipping, delivery dates and, on EU sites, VAT-inclusive prices are quoted for the country
|
|
2179
|
+
# the request comes from: pass `proxy_country` to fix it. Companion to `/marketplace/ebay-
|
|
2180
|
+
# search`.
|
|
2181
|
+
#
|
|
2182
|
+
# @param item_id [String] eBay item number, e.g. '335761219642' (the number in
|
|
2183
|
+
# ebay.com/itm/335761219642).
|
|
2184
|
+
# @param url [String] Instead of `item_id`: a listing link on any supported eBay site, e.g.
|
|
2185
|
+
# https://www.ebay.de/itm/860089403886. The site is taken from the link.
|
|
2186
|
+
# @param marketplace [String] eBay site to open `item_id` on (prices, currency and language
|
|
2187
|
+
# follow it). One of: ebay.com, ebay.co.uk, ebay.de, ebay.fr, ebay.it, ebay.es, ebay.nl,
|
|
2188
|
+
# ebay.pl, ebay.at, ebay.ch, ebay.be, ebay.ie, ebay.ca, ebay.com.au, ebay.in, ebay.com.sg,
|
|
2189
|
+
# ebay.com.my, ebay.com.hk. Default ebay.com.
|
|
2190
|
+
# @param include_description [Boolean] Also fetch the seller's description text (a second,
|
|
2191
|
+
# light request). Set false for a faster call without `description`. API default: true.
|
|
2192
|
+
# @param proxy_country [String] Proxy country the request is sent from (ISO-2, e.g. 'US',
|
|
2193
|
+
# 'DE'). eBay quotes shipping, delivery dates and, on EU sites, VAT-inclusive prices for the
|
|
2194
|
+
# visitor's country, so set it to get them for one country.
|
|
2195
|
+
# Calls POST /marketplace/ebay-product.
|
|
2196
|
+
def ebay_product(item_id: nil, url: nil, marketplace: nil, include_description: nil, proxy_country: nil)
|
|
2197
|
+
post_json("/marketplace/ebay-product", {
|
|
2198
|
+
item_id: item_id,
|
|
2199
|
+
url: url,
|
|
2200
|
+
marketplace: marketplace,
|
|
2201
|
+
include_description: include_description,
|
|
2202
|
+
proxy_country: proxy_country,
|
|
2203
|
+
})
|
|
2204
|
+
end
|
|
2205
|
+
|
|
1289
2206
|
# Scrape Vinted product search.
|
|
1290
2207
|
#
|
|
1291
2208
|
# Searches Vinted for `query` and returns the listings as JSON: `title`, `price` and
|
|
@@ -2615,8 +3532,8 @@ module ScrapeUnblocker
|
|
|
2615
3532
|
# `url`, or a raw `feature_id` (0xHEX:0xHEX). Location-neutral - the feature id resolves the
|
|
2616
3533
|
# place directly; `proxy_country` defaults to a US proxy to clear Google's consent wall.
|
|
2617
3534
|
#
|
|
2618
|
-
# @param url [String] A Google Maps place URL
|
|
2619
|
-
#
|
|
3535
|
+
# @param url [String] A Google Maps place URL: a /maps/place/... URL, a maps.app.goo.gl
|
|
3536
|
+
# share link or a maps?cid= link. The place is read out of it.
|
|
2620
3537
|
# @param place_id [String] A Google place_id, e.g. 'ChIJN1t_tDeuEmsRUsoyG83frY4'.
|
|
2621
3538
|
# @param feature_id [String] A Maps feature id '0xHEX:0xHEX', e.g.
|
|
2622
3539
|
# '0x47e66e2964e34e2d:0x8ddca9ee380ef7e0'. Fastest - no resolve step.
|
|
@@ -2638,6 +3555,51 @@ module ScrapeUnblocker
|
|
|
2638
3555
|
})
|
|
2639
3556
|
end
|
|
2640
3557
|
|
|
3558
|
+
# Scrape Google Maps reviews.
|
|
3559
|
+
#
|
|
3560
|
+
# Returns one Google Maps place's reviews as JSON, sorted the way Google sorts them:
|
|
3561
|
+
# `relevant`, `newest`, `highest` or `lowest`. Each review has `rating` (1-5), `date` (exact
|
|
3562
|
+
# ISO 8601, UTC) + `timestamp`, `relativeDate`, `text` (original) + `language`,
|
|
3563
|
+
# `translatedText` (into `hl`, when the review is in another language), `author`, `photos`,
|
|
3564
|
+
# `details` (guided answers such as 'Rooms: 5'), `ownerResponse` and `reviewUrl`. The answer
|
|
3565
|
+
# also carries a `place` summary and `nextPageToken` for paging. Identify the place with
|
|
3566
|
+
# `feature_id` (0xHEX:0xHEX), `place_id` (ChIJ...) or a Maps `url`. Reviews come in pages of
|
|
3567
|
+
# 20; each page fetched is one billed unit.
|
|
3568
|
+
#
|
|
3569
|
+
# @param url [String] A Google Maps place URL: a /maps/place/... URL, a maps.app.goo.gl
|
|
3570
|
+
# share link or a maps?cid= link. The place is read out of it.
|
|
3571
|
+
# @param place_id [String] A Google place_id, e.g. 'ChIJN1t_tDeuEmsRUsoyG83frY4'.
|
|
3572
|
+
# @param feature_id [String] A Maps feature id '0xHEX:0xHEX', e.g.
|
|
3573
|
+
# '0x4776901a5d4813b3:0x2a497c8b414893c'. Fastest - no resolve step.
|
|
3574
|
+
# @param sort [String] Review order: 'relevant' (Google's default), 'newest', 'highest' or
|
|
3575
|
+
# 'lowest'. SerpApi's 'qualityScore', 'newestFirst', 'ratingHigh' and 'ratingLow' are
|
|
3576
|
+
# accepted too. API default: relevant.
|
|
3577
|
+
# @param max_reviews [Integer] How many reviews to return, 1-200. Reviews come in pages of
|
|
3578
|
+
# 20; each page fetched is one billed unit. API default: 20.
|
|
3579
|
+
# @param next_page_token [String] Continue from a previous answer's `nextPageToken` (same
|
|
3580
|
+
# place and sort). When `max_reviews` is not a multiple of 20 the next page can repeat a few
|
|
3581
|
+
# reviews - dedupe on `reviewId`.
|
|
3582
|
+
# @param hl [String] Language for Google's labels and the review translation
|
|
3583
|
+
# (`translatedText`), e.g. 'en', 'de'. The original text is always returned in `text`. API
|
|
3584
|
+
# default: en.
|
|
3585
|
+
# @param gl [String] Google country, ISO-2 lowercase, e.g. 'us'. API default: us.
|
|
3586
|
+
# @param proxy_country [String] Proxy country the request is sent from (ISO-2, e.g. 'US',
|
|
3587
|
+
# 'DE'). Reviews are the same from any country. API default: us.
|
|
3588
|
+
# Calls POST /maps/reviews.
|
|
3589
|
+
def maps_reviews(url: nil, place_id: nil, feature_id: nil, sort: nil, max_reviews: nil, next_page_token: nil, hl: nil, gl: nil, proxy_country: nil)
|
|
3590
|
+
post_json("/maps/reviews", {
|
|
3591
|
+
url: url,
|
|
3592
|
+
place_id: place_id,
|
|
3593
|
+
feature_id: feature_id,
|
|
3594
|
+
sort: sort,
|
|
3595
|
+
max_reviews: max_reviews,
|
|
3596
|
+
next_page_token: next_page_token,
|
|
3597
|
+
hl: hl,
|
|
3598
|
+
gl: gl,
|
|
3599
|
+
proxy_country: proxy_country,
|
|
3600
|
+
})
|
|
3601
|
+
end
|
|
3602
|
+
|
|
2641
3603
|
# Scrape Google Hotels search results (prices, ratings, amenities).
|
|
2642
3604
|
#
|
|
2643
3605
|
# Runs a Google Hotels search for `q` and returns the properties as JSON: `name`, `type`
|
|
@@ -2928,6 +3890,31 @@ module ScrapeUnblocker
|
|
|
2928
3890
|
})
|
|
2929
3891
|
end
|
|
2930
3892
|
|
|
3893
|
+
# Ask ChatGPT and get its answer and cited sites.
|
|
3894
|
+
#
|
|
3895
|
+
# Asks ChatGPT (chatgpt.com, signed out) one question and returns its finished answer:
|
|
3896
|
+
# `answer` (plain text) and `answerMarkdown`, `citations` (the source pills ChatGPT attaches
|
|
3897
|
+
# to claims: `position`, `siteName`, `domain`, `moreSources` - how many further sources the
|
|
3898
|
+
# pill groups - and `citedText`, the answer text it backs), `links` (links written into the
|
|
3899
|
+
# answer: `position`, `title`, `url`, `domain`), `sources` (every site cited or linked,
|
|
3900
|
+
# once), `webSearch` (whether ChatGPT searched the web), `model` (null: signed-out ChatGPT
|
|
3901
|
+
# does not show it) and `conversationId`. Signed-out ChatGPT shows the full URL of a cited
|
|
3902
|
+
# page only on hover, so citations carry the site and domain, not the page URL. `country`
|
|
3903
|
+
# asks from that country. Answers take 15-60 s and vary between identical calls, as they do
|
|
3904
|
+
# for people. One unit per call; a 503 when ChatGPT capacity is busy is not billed.
|
|
3905
|
+
#
|
|
3906
|
+
# @param prompt [String] The question to ask ChatGPT, as a user would type it, e.g. 'best
|
|
3907
|
+
# CRM for small business' (max 2000 characters). Each call starts a new conversation.
|
|
3908
|
+
# @param country [String] Two-letter country code to ask from, e.g. US, GB, DE. ChatGPT
|
|
3909
|
+
# tailors local results to where the visitor is. Leave blank for any location.
|
|
3910
|
+
# Calls POST /ai/chatgpt.
|
|
3911
|
+
def chatgpt(prompt, country: nil)
|
|
3912
|
+
post_json("/ai/chatgpt", {
|
|
3913
|
+
prompt: prompt,
|
|
3914
|
+
country: country,
|
|
3915
|
+
})
|
|
3916
|
+
end
|
|
3917
|
+
|
|
2931
3918
|
# Search Bing.
|
|
2932
3919
|
#
|
|
2933
3920
|
# Searches Bing for `keyword` in a real browser and returns the results page as JSON:
|