scrapeunblocker 0.13.0 → 0.14.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 +12 -0
- data/README.md +3 -3
- data/lib/scrapeunblocker/client.rb +31 -0
- data/lib/scrapeunblocker/plugins.rb +660 -48
- 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: d657c2dc1b9947fc1ed1d603a8d99c68ba61beaa9c8bc275ecaa32d574de5284
|
|
4
|
+
data.tar.gz: 97ee9d6183e046f644f67866023baec457cdcdb6375a5a925ee34c0504d04194
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a57f2edc6ba0017b291c625dbe6bcd2693af112769b23df3c1a3d7e1bfed7456c301f90e5547d73dad9261495c84194e4dbc0c368facd3917d25177832e6bd9a
|
|
7
|
+
data.tar.gz: ce221c9032035405e0eac225eb61f1bf85f5fc8b9edee5e25e738adfd278b8a42a0d0e58af71d0006b10e4cba0e9e3d30394648deebb5617d5e8436e1b1ea5d5
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.14.0 (2026-10-23)
|
|
4
|
+
|
|
5
|
+
- 16 new plugin methods on `Client`:
|
|
6
|
+
- Google: `google_hotels(q)` (Google Hotels search with stay prices, ratings and amenities), `google_hotels_property(property_token)` (one property's prices from every booking site), `google_news(q)` (a search, or a section with `topic:`), `google_ads_transparency` (an advertiser's ads from the Ads Transparency Center, picked with `advertiser:` or `domain:`) and `google_ads_transparency_advertisers(q)` (advertiser lookup by name).
|
|
7
|
+
- E-commerce: `shopee_search(q)` and `shopee_product(url)` (Shopee in eight markets, `country:`), `taobao_search(q)` and `taobao_product(item_id)` (Taobao and Tmall), `smyths_inventory(code)`, `smyths_details(code)`, `smyths_search(query)` and `smyths_category(category)` (Smyths Toys UK), `wish_search(query)` and `wish_product(product)`.
|
|
8
|
+
- Jobs: `upwork_jobs(q)`.
|
|
9
|
+
- The first argument of `google_news`, `shopee_search`, `shopee_product`, `taobao_search`, `taobao_product` and `upwork_jobs` is optional, for calls that pass another input instead: `google_news(topic: "technology")`, `shopee_product(shop_id: ..., item_id: ...)`, `taobao_product(url: ...)`, `upwork_jobs(sort: "recency")` for the newest jobs. `google_news` takes the API's `when:` window as is (`google_news("tesla", when: "1d")`).
|
|
10
|
+
- `temu_search` and `temu_product` are deprecated: Temu's plugin is unlisted. They are kept for compatibility with the same signatures, now defined on `Client` instead of `ScrapeUnblocker::Plugins`, and are no longer listed in the README.
|
|
11
|
+
- `google_shopping` docs: result cards also carry `currencyCode` and Google's own product ids (`productId`, `catalogId`, `offerId`).
|
|
12
|
+
|
|
13
|
+
No breaking changes.
|
|
14
|
+
|
|
3
15
|
## 0.13.0 (2026-10-23)
|
|
4
16
|
|
|
5
17
|
- New `get_markdown(url, main_content_only: true, ...)` returns the rendered page as clean Markdown for LLMs, agents and RAG pipelines: headings, lists, tables, absolute links, images with their alt text and code blocks, without scripts, styles, navigation, footers, forms or hidden elements. It sends `markdown=true` to `/getPageSource`, is billed like an HTML call, and returns a UTF-8 `String`.
|
data/README.md
CHANGED
|
@@ -149,14 +149,14 @@ 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` |
|
|
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` |
|
|
153
153
|
| Search engines | `bing_search`, `bing_images`, `duckduckgo_search`, `yahoo_search`, `yahoo_images`, `brave_search`, `brave_images` |
|
|
154
|
-
| E-commerce | `amazon_product`, `amazon_search`, `amazon_bestsellers`, `amazon_reviews`, `walmart_search`, `target_search`, `bestbuy_search`, `homedepot_search`, `etsy_search`, `
|
|
154
|
+
| E-commerce | `amazon_product`, `amazon_search`, `amazon_bestsellers`, `amazon_reviews`, `walmart_search`, `target_search`, `bestbuy_search`, `homedepot_search`, `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` |
|
|
155
155
|
| Classifieds & Resale | `ebay_search`, `vinted_search`, `leboncoin_search` |
|
|
156
156
|
| 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` |
|
|
157
157
|
| Real estate | `zillow_search`, `zillow_detail`, `redfin_search`, `redfin_detail`, `rightmove_search`, `idealista_search`, `idealista_detail`, `immobilienscout24_search` |
|
|
158
158
|
| Vehicles | `mobile_de`, `autoscout24_search` |
|
|
159
|
-
| Jobs | `indeed_jobs`, `glassdoor_jobs`, `glassdoor_reviews`, `glassdoor_salaries`, `naukri_jobs`, `wellfound_jobs`, `wellfound_job`, `wellfound_company`, `wellfound_company_search`, `career_site_jobs` |
|
|
159
|
+
| Jobs | `indeed_jobs`, `glassdoor_jobs`, `glassdoor_reviews`, `glassdoor_salaries`, `naukri_jobs`, `wellfound_jobs`, `wellfound_job`, `wellfound_company`, `wellfound_company_search`, `career_site_jobs`, `upwork_jobs` |
|
|
160
160
|
| Reviews & Companies | `trustpilot_reviews`, `g2_reviews`, `g2_search`, `capterra_reviews`, `capterra_search`, `product_hunt`, `crunchbase_company`, `crunchbase_search` |
|
|
161
161
|
| Local & Maps | `yelp_search`, `yelp_business`, `yelp_reviews`, `naver_place_search`, `naver_place_details` |
|
|
162
162
|
| Apps | `google_play_app`, `google_play_search`, `app_store_app`, `app_store_search`, `app_store_reviews` |
|
|
@@ -307,6 +307,37 @@ module ScrapeUnblocker
|
|
|
307
307
|
url: url, max_comments: max_comments, proxy_country: proxy_country)
|
|
308
308
|
end
|
|
309
309
|
|
|
310
|
+
# Search Temu by keyword. Returns the matching product urls (about 40 per
|
|
311
|
+
# page); fetch each url's data with #temu_product.
|
|
312
|
+
#
|
|
313
|
+
# @deprecated Temu's plugin is unlisted; kept for compatibility.
|
|
314
|
+
# @param keyword [String] Search phrase, e.g. 'kids toys' or 'phone case'.
|
|
315
|
+
# @param limit [Integer] Max product urls to return (one search page carries ~40). API
|
|
316
|
+
# default: 40.
|
|
317
|
+
# @param sort [String] Result order, using Temu's own sort: `relevance` (default),
|
|
318
|
+
# `best_selling`, `recent`, `price_asc` or `price_desc`.
|
|
319
|
+
# Calls POST /goods/temu-search.
|
|
320
|
+
def temu_search(keyword, limit: nil, sort: nil)
|
|
321
|
+
post_json("/goods/temu-search", {
|
|
322
|
+
keyword: keyword,
|
|
323
|
+
limit: limit,
|
|
324
|
+
sort: sort,
|
|
325
|
+
})
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
# Scrape a Temu product page.
|
|
329
|
+
#
|
|
330
|
+
# @deprecated Temu's plugin is unlisted; kept for compatibility.
|
|
331
|
+
# @param url [String] Full Temu product url, e.g.
|
|
332
|
+
# 'https://www.temu.com/xyz-g-601099512345678.html'. Must be a product page (its path ends
|
|
333
|
+
# in `-g-<id>.html`).
|
|
334
|
+
# Calls POST /goods/temu-product.
|
|
335
|
+
def temu_product(url)
|
|
336
|
+
post_json("/goods/temu-product", {
|
|
337
|
+
url: url,
|
|
338
|
+
})
|
|
339
|
+
end
|
|
340
|
+
|
|
310
341
|
def post_json(path, params)
|
|
311
342
|
JSON.parse(request(path, params)[:body])
|
|
312
343
|
end
|
|
@@ -310,48 +310,6 @@ module ScrapeUnblocker
|
|
|
310
310
|
})
|
|
311
311
|
end
|
|
312
312
|
|
|
313
|
-
# Search Temu by keyword.
|
|
314
|
-
#
|
|
315
|
-
# Searches Temu for `keyword` and returns the matching product urls (~40 per page). This is
|
|
316
|
-
# discovery only - fetch each url's data (name, price, rating, reviews, images) through
|
|
317
|
-
# `POST /goods/temu-product`. Use `sort` to pick Temu's own result order (relevance,
|
|
318
|
-
# best_selling, recent, price_asc, price_desc). Response time is typically ~2s.
|
|
319
|
-
#
|
|
320
|
-
# @param keyword [String] Search phrase, e.g. 'kids toys' or 'phone case'.
|
|
321
|
-
# @param limit [Integer] Max product urls to return (one search page carries ~40). API
|
|
322
|
-
# default: 40.
|
|
323
|
-
# @param sort [String] Result order, using Temu's own sort: `relevance` (default),
|
|
324
|
-
# `best_selling` (top sales), `recent` (most recent), `price_asc` (price low to high) or
|
|
325
|
-
# `price_desc` (price high to low). API default: relevance.
|
|
326
|
-
# Calls POST /goods/temu-search.
|
|
327
|
-
def temu_search(keyword, limit: nil, sort: nil)
|
|
328
|
-
post_json("/goods/temu-search", {
|
|
329
|
-
keyword: keyword,
|
|
330
|
-
limit: limit,
|
|
331
|
-
sort: sort,
|
|
332
|
-
})
|
|
333
|
-
end
|
|
334
|
-
|
|
335
|
-
# Scrape a Temu product page.
|
|
336
|
-
#
|
|
337
|
-
# Fetches a single Temu product and returns it as JSON: `name`, `description`, `brand`,
|
|
338
|
-
# `sku`, `price`, `priceCurrency`, `availability`, `itemCondition`, `rating`, `reviewCount`,
|
|
339
|
-
# `variantGroupId`, `images`, `reviews` (per-review rating and date; Temu masks the review
|
|
340
|
-
# text and author name in this document) and `video` (a `{contentUrl, thumbnailUrl,
|
|
341
|
-
# uploadDate}` object when the product ships one, else null). Temu serves product data only
|
|
342
|
-
# to search-engine crawlers, so this reads the ld+json SEO document rather than a browser
|
|
343
|
-
# render. The url must be a product page (path ends in `-g-<id>.html`).
|
|
344
|
-
#
|
|
345
|
-
# @param url [String] Full Temu product url, e.g.
|
|
346
|
-
# 'https://www.temu.com/xyz-g-601099512345678.html'. Must be a product page (its path ends
|
|
347
|
-
# in `-g-<id>.html`); search/category urls have no product data and are rejected.
|
|
348
|
-
# Calls POST /goods/temu-product.
|
|
349
|
-
def temu_product(url)
|
|
350
|
-
post_json("/goods/temu-product", {
|
|
351
|
-
url: url,
|
|
352
|
-
})
|
|
353
|
-
end
|
|
354
|
-
|
|
355
313
|
# Scrape AliExpress search results.
|
|
356
314
|
#
|
|
357
315
|
# Searches AliExpress for `keyword` and returns the products as JSON: `title`, product
|
|
@@ -535,6 +493,60 @@ module ScrapeUnblocker
|
|
|
535
493
|
})
|
|
536
494
|
end
|
|
537
495
|
|
|
496
|
+
# Scrape Wish product search.
|
|
497
|
+
#
|
|
498
|
+
# Searches Wish (wish.com) for `query` and returns `products`: `id`, `name`, `url`, `price`,
|
|
499
|
+
# `originalPrice` (crossed-out price, when discounted), `currency`, `priceText`, `priceUsd`
|
|
500
|
+
# (Wish's USD value, comparable across markets), `shipping`, `rating`, `ratingCount`,
|
|
501
|
+
# `numBought`, `inventory`, `colors`, `sizes`, `merchant` (`id`, `name`, `rating`,
|
|
502
|
+
# `ratingCount`, `feedback`, `country`), `originCountry`, `shipsFrom`, `tileText`,
|
|
503
|
+
# `isWishPick`, `position`, `image` and `thumbnail`, plus `totalResults` and `nextPage`.
|
|
504
|
+
# Wish shows the catalogue and prices of the request's country (`proxy_country`, default
|
|
505
|
+
# US). Collects up to `max_results` from `page` on, billed one unit per page.
|
|
506
|
+
#
|
|
507
|
+
# @param query [String] What to search for, e.g. 'yoga mat' or 'phone case', or a
|
|
508
|
+
# wish.com/search/... link.
|
|
509
|
+
# @param page [Integer] 1-based results page to start from (1-300, up to 30 products per
|
|
510
|
+
# page). API default: 1.
|
|
511
|
+
# @param max_results [Integer] Products to collect across pages, 1-300. Each page fetched is
|
|
512
|
+
# billed one unit. API default: 30.
|
|
513
|
+
# @param proxy_country [String] Proxy country the request is sent from (ISO-2, e.g. 'US',
|
|
514
|
+
# 'GB', 'DE'). Wish shows the catalogue, prices and currency of that country. Default 'US'
|
|
515
|
+
# (prices in USD).
|
|
516
|
+
# Calls POST /marketplace/wish-search.
|
|
517
|
+
def wish_search(query, page: nil, max_results: nil, proxy_country: nil)
|
|
518
|
+
post_json("/marketplace/wish-search", {
|
|
519
|
+
query: query,
|
|
520
|
+
page: page,
|
|
521
|
+
max_results: max_results,
|
|
522
|
+
proxy_country: proxy_country,
|
|
523
|
+
})
|
|
524
|
+
end
|
|
525
|
+
|
|
526
|
+
# Scrape one Wish product.
|
|
527
|
+
#
|
|
528
|
+
# One Wish (wish.com) product as JSON: `id`, `name`, `url`, `price` (cheapest available
|
|
529
|
+
# variant), `originalPrice`, `currency`, `priceUsd`, `priceRange`, `shipping`, `inStock`,
|
|
530
|
+
# `rating`, `ratingCount`, `description`, `attributes`, `badges`, `images`, `merchant`
|
|
531
|
+
# (`id`, `name`, `handle`, `rating`, `ratingCount`, `tier`), `shipsFrom`, `shipsTo`,
|
|
532
|
+
# `deliveryEstimate`, `returnPolicy`, `variants` (`id`, `color`, `size`, `price`,
|
|
533
|
+
# `originalPrice`, `priceUsd`, `shipping`, `inventory`, `available`) and `topReviews`
|
|
534
|
+
# (`rating`, `comment`, `date`, `variant`, `upvotes`, `country`; no reviewer names). Prices
|
|
535
|
+
# are those of the request's country (`proxy_country`, default US). One unit per call.
|
|
536
|
+
#
|
|
537
|
+
# @param product [String] A Wish product id ('5f96ad46b3f6480c7b9d7b52') or a product link
|
|
538
|
+
# (https://www.wish.com/product/..., /c/...).
|
|
539
|
+
# @param proxy_country [String] Proxy country the request is sent from (ISO-2, e.g. 'US',
|
|
540
|
+
# 'GB', 'DE'). Wish shows the catalogue, prices and currency of that country. Default 'US'
|
|
541
|
+
# (prices in USD).
|
|
542
|
+
# Calls POST /marketplace/wish-product.
|
|
543
|
+
def wish_product(product, proxy_country: nil)
|
|
544
|
+
post_json("/marketplace/wish-product", {
|
|
545
|
+
product: product,
|
|
546
|
+
proxy_country: proxy_country,
|
|
547
|
+
})
|
|
548
|
+
end
|
|
549
|
+
|
|
538
550
|
# Search TikTok Shop products by keyword or category.
|
|
539
551
|
#
|
|
540
552
|
# Lists TikTok Shop (US) products for a keyword (`q`) or a category (`category`, URL or id).
|
|
@@ -613,6 +625,158 @@ module ScrapeUnblocker
|
|
|
613
625
|
})
|
|
614
626
|
end
|
|
615
627
|
|
|
628
|
+
# Scrape Shopee product search.
|
|
629
|
+
#
|
|
630
|
+
# Searches a Shopee market (Singapore, Indonesia, Malaysia, Thailand, Vietnam, Philippines,
|
|
631
|
+
# Taiwan or Brazil - `country`) for `q` and returns one page of results: up to 40
|
|
632
|
+
# `products`, each with `position`, `itemId`, `shopId`, `name`, `url`, `image`, `price`,
|
|
633
|
+
# `originalPrice` (when Shopee shows the crossed-out price), `discountPercent`, `currency`,
|
|
634
|
+
# `rating` (average stars), `location` (where the seller ships from) and `labels` (promotion
|
|
635
|
+
# badges). `sort` orders the results, `min_price` / `max_price` filter them, `shop_id` keeps
|
|
636
|
+
# one shop's products (or lists the shop without `q`), and `url` takes a Shopee search or
|
|
637
|
+
# category link instead. Shopee shows one page per search, so run several sort orders or
|
|
638
|
+
# price ranges for more products. `price` is what Shopee shows a signed-out shopper, which
|
|
639
|
+
# can be a promotional or new-customer price (see `labels`). Not available: stock, units
|
|
640
|
+
# sold, rating counts and reviews (Shopee does not publish them on the pages these endpoints
|
|
641
|
+
# read). One unit per call.
|
|
642
|
+
#
|
|
643
|
+
# @param q [String] What to search for, e.g. 'iphone case' or 'air fryer'. Optional with
|
|
644
|
+
# `shop_id`.
|
|
645
|
+
# @param country [String] Shopee market: 'sg' (shopee.sg), 'id' (shopee.co.id), 'my'
|
|
646
|
+
# (shopee.com.my), 'th' (shopee.co.th), 'vn' (shopee.vn), 'ph' (shopee.ph), 'tw'
|
|
647
|
+
# (shopee.tw), 'br' (shopee.com.br). Default 'sg'. Prices are in that market's currency.
|
|
648
|
+
# @param shop_id [String] Only this shop's products (the number in a shop's links, e.g.
|
|
649
|
+
# 442800909). Without `q` it lists the shop.
|
|
650
|
+
# @param url [String] A Shopee search or category link (e.g.
|
|
651
|
+
# https://shopee.sg/search?keyword=lego or https://shopee.sg/Cases-Covers-
|
|
652
|
+
# cat.11013350.11013434.11027839), used as it is; `q`, `country`, `shop_id`, `sort` and the
|
|
653
|
+
# price filters are then ignored.
|
|
654
|
+
# @param sort [String] Result order: relevance, sales, newest, price_asc, price_desc. API
|
|
655
|
+
# default: relevance.
|
|
656
|
+
# @param min_price [Integer] Lowest price, in the market's currency.
|
|
657
|
+
# @param max_price [Integer] Highest price, in the market's currency.
|
|
658
|
+
# @param max_results [Integer] Products to return, 1-40 (one Shopee results page). API
|
|
659
|
+
# default: 40.
|
|
660
|
+
# Calls POST /marketplace/shopee-search.
|
|
661
|
+
def shopee_search(q = nil, country: nil, shop_id: nil, url: nil, sort: nil, min_price: nil, max_price: nil, max_results: nil)
|
|
662
|
+
post_json("/marketplace/shopee-search", {
|
|
663
|
+
q: q,
|
|
664
|
+
country: country,
|
|
665
|
+
shop_id: shop_id,
|
|
666
|
+
url: url,
|
|
667
|
+
sort: sort,
|
|
668
|
+
min_price: min_price,
|
|
669
|
+
max_price: max_price,
|
|
670
|
+
max_results: max_results,
|
|
671
|
+
})
|
|
672
|
+
end
|
|
673
|
+
|
|
674
|
+
# Scrape one Shopee product.
|
|
675
|
+
#
|
|
676
|
+
# One Shopee product as JSON, from a product link (`url`) or `shop_id` + `item_id` +
|
|
677
|
+
# `country`: `title`, `price`, `originalPrice`, `discountPercent`, `currency`, `rating`
|
|
678
|
+
# (average stars), `labels`, `images`, `shopLocation` and `shop` (`name`, `username`, `url`,
|
|
679
|
+
# `rating`, `ratingCount`, `followers`, `itemCount`, `responseRatePercent`,
|
|
680
|
+
# `isOfficialShop`, `isPreferredPlusSeller`, `location`, `joinedAt`). With `dataLevel: full`
|
|
681
|
+
# it also has `description`, `brand`, `condition`, `categories`, `videos`, `variations`
|
|
682
|
+
# (option names), `models` (`modelId`, `name`), `attributes`, `isOfficialShop`,
|
|
683
|
+
# `isPreOrder`, `estimatedShippingDays` and `createdAt`; `dataLevel: meta` means Shopee
|
|
684
|
+
# showed only the product's title and main image (some markets), with price, rating and shop
|
|
685
|
+
# still included. `price` is what Shopee shows a signed-out shopper, which can be a
|
|
686
|
+
# promotional or new-customer price (see `labels`). Not available: stock, units sold, rating
|
|
687
|
+
# counts and reviews (Shopee does not publish them on the pages these endpoints read). One
|
|
688
|
+
# unit per call.
|
|
689
|
+
#
|
|
690
|
+
# @param url [String] A Shopee product link, e.g. https://shopee.sg/Beats-
|
|
691
|
+
# iPhone-17-Case-i.442800909.40270108836 or
|
|
692
|
+
# https://shopee.co.id/product/1426163997/40581375446.
|
|
693
|
+
# @param shop_id [String] Instead of `url`: the shop id (the first number after '-i.' in a
|
|
694
|
+
# product link).
|
|
695
|
+
# @param item_id [String] Instead of `url`: the item id (the second number after '-i.').
|
|
696
|
+
# @param country [String] With `shop_id` + `item_id`: Shopee market: 'sg' (shopee.sg), 'id'
|
|
697
|
+
# (shopee.co.id), 'my' (shopee.com.my), 'th' (shopee.co.th), 'vn' (shopee.vn), 'ph'
|
|
698
|
+
# (shopee.ph), 'tw' (shopee.tw), 'br' (shopee.com.br). Default 'sg'. Prices are in that
|
|
699
|
+
# market's currency.
|
|
700
|
+
# Calls POST /marketplace/shopee-product.
|
|
701
|
+
def shopee_product(url = nil, shop_id: nil, item_id: nil, country: nil)
|
|
702
|
+
post_json("/marketplace/shopee-product", {
|
|
703
|
+
url: url,
|
|
704
|
+
shop_id: shop_id,
|
|
705
|
+
item_id: item_id,
|
|
706
|
+
country: country,
|
|
707
|
+
})
|
|
708
|
+
end
|
|
709
|
+
|
|
710
|
+
# Scrape Taobao / Tmall keyword or category listings.
|
|
711
|
+
#
|
|
712
|
+
# Returns the products Taobao lists for a keyword `q` (or a `category`) as JSON: `products`
|
|
713
|
+
# (`position`, `itemId`, `title`, `url`, `image`, `price` in yuan with `currency` CNY,
|
|
714
|
+
# `priceLabel` (Taobao's price tag, e.g. 优惠价), `localPrices` (the same price in the
|
|
715
|
+
# storefront's currency, HKD and TWD), `shopId`, `shopName`, `descriptionMatchScore`,
|
|
716
|
+
# `freeShipping`, `categoryId`, `rootCategoryId`, `sellingPoints`, `reviewHighlights`),
|
|
717
|
+
# `totalResults` (how many listings Taobao reports), and `filterOptions` (brand and property
|
|
718
|
+
# facets; pass an option's `filter` value back as `filter`). Sort by relevance, sales or
|
|
719
|
+
# price and filter by a yuan price range (products whose listed price falls outside it are
|
|
720
|
+
# left out and counted in `droppedOutsidePriceRange`). Taobao shows signed-out visitors only
|
|
721
|
+
# the first 20 products of a list, so one call returns up to 20 (narrow with price ranges
|
|
722
|
+
# and filters to reach more). When Taobao has no list for the keyword, the call answers with
|
|
723
|
+
# the list of the closest keyword Taobao itself suggests and says so: `keywordSubstituted`
|
|
724
|
+
# true and `matchedKeyword`. Text comes in Chinese as sellers write it. Companion to
|
|
725
|
+
# `/marketplace/taobao-product`. One unit per call.
|
|
726
|
+
#
|
|
727
|
+
# @param q [String] Keyword, in Chinese or English, e.g. '手机壳', '连衣裙', 'phone case' (Chinese
|
|
728
|
+
# keywords match far more listings). A Taobao search or list link works too. Give `q` or
|
|
729
|
+
# `category`.
|
|
730
|
+
# @param category [String] A Taobao category id, e.g. '50005050', or a category list link
|
|
731
|
+
# (https://www.taobao.com/list/category/50005050.htm). Returns the category's best sellers;
|
|
732
|
+
# sort and filters apply to keyword searches only.
|
|
733
|
+
# @param sort [String] Order: relevance, sales, price_asc, price_desc (price in yuan). API
|
|
734
|
+
# default: relevance.
|
|
735
|
+
# @param price_min [Float] Only products at or above this many yuan (CNY).
|
|
736
|
+
# @param price_max [Float] Only products at or below this many yuan (CNY).
|
|
737
|
+
# @param filter [String] One brand or property filter, as the `filter` value of an option in
|
|
738
|
+
# `filterOptions` of an earlier answer, e.g. '20000-88634403'.
|
|
739
|
+
# Calls POST /marketplace/taobao-search.
|
|
740
|
+
def taobao_search(q = nil, category: nil, sort: nil, price_min: nil, price_max: nil, filter: nil)
|
|
741
|
+
post_json("/marketplace/taobao-search", {
|
|
742
|
+
q: q,
|
|
743
|
+
category: category,
|
|
744
|
+
sort: sort,
|
|
745
|
+
price_min: price_min,
|
|
746
|
+
price_max: price_max,
|
|
747
|
+
filter: filter,
|
|
748
|
+
})
|
|
749
|
+
end
|
|
750
|
+
|
|
751
|
+
# Scrape one Taobao / Tmall item.
|
|
752
|
+
#
|
|
753
|
+
# Returns one Taobao or Tmall item (by `item_id` or `url`) as JSON: `itemId`, `url`,
|
|
754
|
+
# `platform` (taobao / tmall), `title` (`titleTruncated` when Taobao shortens it, as it does
|
|
755
|
+
# for Tmall items), `price`, `originalPrice` and `priceMax` (for a price range) in yuan with
|
|
756
|
+
# `currency` CNY, `image`, `location` (ships from), `categoryId`, `rootCategoryId`,
|
|
757
|
+
# `categoryPath`, `freeShipping`, `paymentMethods`, `sellableLanguages`, `rating` (positive
|
|
758
|
+
# / neutral / negative split and counts; Taobao items only, Tmall does not publish it),
|
|
759
|
+
# `latestReview` (`rating`, `content`, `date`, `variant`, `hasMedia`, `followUps`; no
|
|
760
|
+
# reviewer identity, so no review photo or video URLs) and `shop` (`shopId`, `name`, `url`,
|
|
761
|
+
# `logo`, `sellerType` B = Tmall / C = Taobao, `creditLevel`, `openedAt`, `itemCount`,
|
|
762
|
+
# `scores` for description, service and delivery). This is what Taobao shows signed-out
|
|
763
|
+
# visitors: variants (SKUs), stock and monthly sales need a Taobao login and are not
|
|
764
|
+
# included. Companion to `/marketplace/taobao-search`. One unit per call.
|
|
765
|
+
#
|
|
766
|
+
# @param item_id [String] Numeric Taobao or Tmall item id, e.g. '765833709683' (the `id` in
|
|
767
|
+
# item.taobao.com/item.htm?id=...).
|
|
768
|
+
# @param url [String] Taobao or Tmall item link, e.g.
|
|
769
|
+
# 'https://item.taobao.com/item.htm?id=765833709683' or
|
|
770
|
+
# 'https://detail.tmall.com/item.htm?id=1081364414020' (world.taobao.com, mobile and
|
|
771
|
+
# overseas item links work too). Either item_id or url is required.
|
|
772
|
+
# Calls POST /marketplace/taobao-product.
|
|
773
|
+
def taobao_product(item_id = nil, url: nil)
|
|
774
|
+
post_json("/marketplace/taobao-product", {
|
|
775
|
+
item_id: item_id,
|
|
776
|
+
url: url,
|
|
777
|
+
})
|
|
778
|
+
end
|
|
779
|
+
|
|
616
780
|
# Scrape Vinted product search.
|
|
617
781
|
#
|
|
618
782
|
# Searches Vinted for `query` and returns the listings as JSON: `title`, `price` and
|
|
@@ -1136,6 +1300,188 @@ module ScrapeUnblocker
|
|
|
1136
1300
|
})
|
|
1137
1301
|
end
|
|
1138
1302
|
|
|
1303
|
+
# Smyths Toys UK product stock, price, details and listings.
|
|
1304
|
+
#
|
|
1305
|
+
# Smyths Toys UK (smythstoys.com) as JSON, in four modes. `mode=product` (the default when
|
|
1306
|
+
# `code` is given) returns one product's stock and price as the JSON Smyths' own storefront
|
|
1307
|
+
# reads (`/api/uk/en-gb/product/product-inventory`), unchanged: `code`, `type`, `prices`
|
|
1308
|
+
# (`price`, `value`, `wasPrice`, `thenPrice`, `rrpPrice`, `discountedPercentage`),
|
|
1309
|
+
# `hdSection` (home delivery: `stockStatus`, `stockMessage`, `isAvailableForDelivery`,
|
|
1310
|
+
# `isPreOrder`, `expectedStockDate`, delivery messages), `ccSection` (click & collect: the
|
|
1311
|
+
# same stock fields plus `storeName`, `deliveryMessage`, `storeClosed`), `ageSuitabilities`,
|
|
1312
|
+
# `carrierType`, marketing messages and decals. `code` takes a product code (`225095`), a
|
|
1313
|
+
# product or bundle page link or a product-inventory link; one product is one billed
|
|
1314
|
+
# request. `mode=details&code=` returns the JSON Smyths' product page is built from
|
|
1315
|
+
# (`/api/uk/en-gb/product`, a bundle's from `/api/uk/en-gb/b`), unchanged, one billed
|
|
1316
|
+
# request: `name`, `brand`, `ean`, `description` (HTML), `webFeatures` (the key features
|
|
1317
|
+
# list), the safety warnings `euWarning`, `safetyText`, `urgentSafetyTextHeading` and
|
|
1318
|
+
# `urgentSafetyTextDescription`, `productImages` (the gallery: `thumbnail`, `original` and
|
|
1319
|
+
# `zoom` per `galleryIndex`, videos as `youtubeUrl`), `prices`, `averageRating`,
|
|
1320
|
+
# `numberOfReviews`, `breadcrumb`, `categoryHierarchy`, `ageSuitabilities`,
|
|
1321
|
+
# `assemblyRequired` and more; a bundle adds `subProducts`. `url` and `breadcrumb` paths are
|
|
1322
|
+
# relative to https://www.smythstoys.com/uk/en-gb. `mode=search&query=` and
|
|
1323
|
+
# `mode=category&category=` find product codes: they return `products` (`code`, `name`,
|
|
1324
|
+
# `url`, `prices` with the same fields, `currency`, `image`, `averageRating`, `productType`
|
|
1325
|
+
# - `BUNDLE` for bundles - and `decals`) with `totalResults`, `totalPages` and `nextPage`,
|
|
1326
|
+
# 60 per page; a category also returns its `title`, `breadcrumbs` and `subcategories`
|
|
1327
|
+
# (`code`, `name`, `count`). Smyths' search returns its best 240 matches at most, a category
|
|
1328
|
+
# every product it holds. Listings collect up to `max_results` from `page` on, billed one
|
|
1329
|
+
# unit per page.
|
|
1330
|
+
#
|
|
1331
|
+
# @param code [String] mode=product and mode=details: product code ('225095'), product or
|
|
1332
|
+
# bundle page link, or product-inventory link.
|
|
1333
|
+
# @param bundle [Boolean] mode=product and mode=details: ask for a bundle. A bundle page
|
|
1334
|
+
# link sets it, and a code Smyths does not answer as a product is asked again as a bundle.
|
|
1335
|
+
# API default: false.
|
|
1336
|
+
# Calls POST /marketplace/smyths-inventory.
|
|
1337
|
+
def smyths_inventory(code, bundle: nil)
|
|
1338
|
+
post_json("/marketplace/smyths-inventory", {
|
|
1339
|
+
mode: "product",
|
|
1340
|
+
code: code,
|
|
1341
|
+
bundle: bundle,
|
|
1342
|
+
})
|
|
1343
|
+
end
|
|
1344
|
+
|
|
1345
|
+
# Smyths Toys UK product stock, price, details and listings.
|
|
1346
|
+
#
|
|
1347
|
+
# Smyths Toys UK (smythstoys.com) as JSON, in four modes. `mode=product` (the default when
|
|
1348
|
+
# `code` is given) returns one product's stock and price as the JSON Smyths' own storefront
|
|
1349
|
+
# reads (`/api/uk/en-gb/product/product-inventory`), unchanged: `code`, `type`, `prices`
|
|
1350
|
+
# (`price`, `value`, `wasPrice`, `thenPrice`, `rrpPrice`, `discountedPercentage`),
|
|
1351
|
+
# `hdSection` (home delivery: `stockStatus`, `stockMessage`, `isAvailableForDelivery`,
|
|
1352
|
+
# `isPreOrder`, `expectedStockDate`, delivery messages), `ccSection` (click & collect: the
|
|
1353
|
+
# same stock fields plus `storeName`, `deliveryMessage`, `storeClosed`), `ageSuitabilities`,
|
|
1354
|
+
# `carrierType`, marketing messages and decals. `code` takes a product code (`225095`), a
|
|
1355
|
+
# product or bundle page link or a product-inventory link; one product is one billed
|
|
1356
|
+
# request. `mode=details&code=` returns the JSON Smyths' product page is built from
|
|
1357
|
+
# (`/api/uk/en-gb/product`, a bundle's from `/api/uk/en-gb/b`), unchanged, one billed
|
|
1358
|
+
# request: `name`, `brand`, `ean`, `description` (HTML), `webFeatures` (the key features
|
|
1359
|
+
# list), the safety warnings `euWarning`, `safetyText`, `urgentSafetyTextHeading` and
|
|
1360
|
+
# `urgentSafetyTextDescription`, `productImages` (the gallery: `thumbnail`, `original` and
|
|
1361
|
+
# `zoom` per `galleryIndex`, videos as `youtubeUrl`), `prices`, `averageRating`,
|
|
1362
|
+
# `numberOfReviews`, `breadcrumb`, `categoryHierarchy`, `ageSuitabilities`,
|
|
1363
|
+
# `assemblyRequired` and more; a bundle adds `subProducts`. `url` and `breadcrumb` paths are
|
|
1364
|
+
# relative to https://www.smythstoys.com/uk/en-gb. `mode=search&query=` and
|
|
1365
|
+
# `mode=category&category=` find product codes: they return `products` (`code`, `name`,
|
|
1366
|
+
# `url`, `prices` with the same fields, `currency`, `image`, `averageRating`, `productType`
|
|
1367
|
+
# - `BUNDLE` for bundles - and `decals`) with `totalResults`, `totalPages` and `nextPage`,
|
|
1368
|
+
# 60 per page; a category also returns its `title`, `breadcrumbs` and `subcategories`
|
|
1369
|
+
# (`code`, `name`, `count`). Smyths' search returns its best 240 matches at most, a category
|
|
1370
|
+
# every product it holds. Listings collect up to `max_results` from `page` on, billed one
|
|
1371
|
+
# unit per page.
|
|
1372
|
+
#
|
|
1373
|
+
# @param code [String] mode=product and mode=details: product code ('225095'), product or
|
|
1374
|
+
# bundle page link, or product-inventory link.
|
|
1375
|
+
# @param bundle [Boolean] mode=product and mode=details: ask for a bundle. A bundle page
|
|
1376
|
+
# link sets it, and a code Smyths does not answer as a product is asked again as a bundle.
|
|
1377
|
+
# API default: false.
|
|
1378
|
+
# Calls POST /marketplace/smyths-inventory.
|
|
1379
|
+
def smyths_details(code, bundle: nil)
|
|
1380
|
+
post_json("/marketplace/smyths-inventory", {
|
|
1381
|
+
mode: "details",
|
|
1382
|
+
code: code,
|
|
1383
|
+
bundle: bundle,
|
|
1384
|
+
})
|
|
1385
|
+
end
|
|
1386
|
+
|
|
1387
|
+
# Smyths Toys UK product stock, price, details and listings.
|
|
1388
|
+
#
|
|
1389
|
+
# Smyths Toys UK (smythstoys.com) as JSON, in four modes. `mode=product` (the default when
|
|
1390
|
+
# `code` is given) returns one product's stock and price as the JSON Smyths' own storefront
|
|
1391
|
+
# reads (`/api/uk/en-gb/product/product-inventory`), unchanged: `code`, `type`, `prices`
|
|
1392
|
+
# (`price`, `value`, `wasPrice`, `thenPrice`, `rrpPrice`, `discountedPercentage`),
|
|
1393
|
+
# `hdSection` (home delivery: `stockStatus`, `stockMessage`, `isAvailableForDelivery`,
|
|
1394
|
+
# `isPreOrder`, `expectedStockDate`, delivery messages), `ccSection` (click & collect: the
|
|
1395
|
+
# same stock fields plus `storeName`, `deliveryMessage`, `storeClosed`), `ageSuitabilities`,
|
|
1396
|
+
# `carrierType`, marketing messages and decals. `code` takes a product code (`225095`), a
|
|
1397
|
+
# product or bundle page link or a product-inventory link; one product is one billed
|
|
1398
|
+
# request. `mode=details&code=` returns the JSON Smyths' product page is built from
|
|
1399
|
+
# (`/api/uk/en-gb/product`, a bundle's from `/api/uk/en-gb/b`), unchanged, one billed
|
|
1400
|
+
# request: `name`, `brand`, `ean`, `description` (HTML), `webFeatures` (the key features
|
|
1401
|
+
# list), the safety warnings `euWarning`, `safetyText`, `urgentSafetyTextHeading` and
|
|
1402
|
+
# `urgentSafetyTextDescription`, `productImages` (the gallery: `thumbnail`, `original` and
|
|
1403
|
+
# `zoom` per `galleryIndex`, videos as `youtubeUrl`), `prices`, `averageRating`,
|
|
1404
|
+
# `numberOfReviews`, `breadcrumb`, `categoryHierarchy`, `ageSuitabilities`,
|
|
1405
|
+
# `assemblyRequired` and more; a bundle adds `subProducts`. `url` and `breadcrumb` paths are
|
|
1406
|
+
# relative to https://www.smythstoys.com/uk/en-gb. `mode=search&query=` and
|
|
1407
|
+
# `mode=category&category=` find product codes: they return `products` (`code`, `name`,
|
|
1408
|
+
# `url`, `prices` with the same fields, `currency`, `image`, `averageRating`, `productType`
|
|
1409
|
+
# - `BUNDLE` for bundles - and `decals`) with `totalResults`, `totalPages` and `nextPage`,
|
|
1410
|
+
# 60 per page; a category also returns its `title`, `breadcrumbs` and `subcategories`
|
|
1411
|
+
# (`code`, `name`, `count`). Smyths' search returns its best 240 matches at most, a category
|
|
1412
|
+
# every product it holds. Listings collect up to `max_results` from `page` on, billed one
|
|
1413
|
+
# unit per page.
|
|
1414
|
+
#
|
|
1415
|
+
# @param query [String] mode=search: what to search for, e.g. 'lego star wars'. Smyths
|
|
1416
|
+
# returns its best 240 matches at most - list a category to get every product of a range.
|
|
1417
|
+
# @param sort [String] Listing order. search: relevance, bestsellers, price_asc, price_desc,
|
|
1418
|
+
# rating_desc, newest (the first is the default). category: bestsellers, price_asc,
|
|
1419
|
+
# price_desc, rating_desc, newest (the first is the default).
|
|
1420
|
+
# @param page [Integer] 1-based listing page to start from (60 products per page). API
|
|
1421
|
+
# default: 1.
|
|
1422
|
+
# @param max_results [Integer] Products to collect across pages, 1-600. Each page fetched is
|
|
1423
|
+
# billed one unit. API default: 60.
|
|
1424
|
+
# Calls POST /marketplace/smyths-inventory.
|
|
1425
|
+
def smyths_search(query, sort: nil, page: nil, max_results: nil)
|
|
1426
|
+
post_json("/marketplace/smyths-inventory", {
|
|
1427
|
+
mode: "search",
|
|
1428
|
+
query: query,
|
|
1429
|
+
sort: sort,
|
|
1430
|
+
page: page,
|
|
1431
|
+
max_results: max_results,
|
|
1432
|
+
})
|
|
1433
|
+
end
|
|
1434
|
+
|
|
1435
|
+
# Smyths Toys UK product stock, price, details and listings.
|
|
1436
|
+
#
|
|
1437
|
+
# Smyths Toys UK (smythstoys.com) as JSON, in four modes. `mode=product` (the default when
|
|
1438
|
+
# `code` is given) returns one product's stock and price as the JSON Smyths' own storefront
|
|
1439
|
+
# reads (`/api/uk/en-gb/product/product-inventory`), unchanged: `code`, `type`, `prices`
|
|
1440
|
+
# (`price`, `value`, `wasPrice`, `thenPrice`, `rrpPrice`, `discountedPercentage`),
|
|
1441
|
+
# `hdSection` (home delivery: `stockStatus`, `stockMessage`, `isAvailableForDelivery`,
|
|
1442
|
+
# `isPreOrder`, `expectedStockDate`, delivery messages), `ccSection` (click & collect: the
|
|
1443
|
+
# same stock fields plus `storeName`, `deliveryMessage`, `storeClosed`), `ageSuitabilities`,
|
|
1444
|
+
# `carrierType`, marketing messages and decals. `code` takes a product code (`225095`), a
|
|
1445
|
+
# product or bundle page link or a product-inventory link; one product is one billed
|
|
1446
|
+
# request. `mode=details&code=` returns the JSON Smyths' product page is built from
|
|
1447
|
+
# (`/api/uk/en-gb/product`, a bundle's from `/api/uk/en-gb/b`), unchanged, one billed
|
|
1448
|
+
# request: `name`, `brand`, `ean`, `description` (HTML), `webFeatures` (the key features
|
|
1449
|
+
# list), the safety warnings `euWarning`, `safetyText`, `urgentSafetyTextHeading` and
|
|
1450
|
+
# `urgentSafetyTextDescription`, `productImages` (the gallery: `thumbnail`, `original` and
|
|
1451
|
+
# `zoom` per `galleryIndex`, videos as `youtubeUrl`), `prices`, `averageRating`,
|
|
1452
|
+
# `numberOfReviews`, `breadcrumb`, `categoryHierarchy`, `ageSuitabilities`,
|
|
1453
|
+
# `assemblyRequired` and more; a bundle adds `subProducts`. `url` and `breadcrumb` paths are
|
|
1454
|
+
# relative to https://www.smythstoys.com/uk/en-gb. `mode=search&query=` and
|
|
1455
|
+
# `mode=category&category=` find product codes: they return `products` (`code`, `name`,
|
|
1456
|
+
# `url`, `prices` with the same fields, `currency`, `image`, `averageRating`, `productType`
|
|
1457
|
+
# - `BUNDLE` for bundles - and `decals`) with `totalResults`, `totalPages` and `nextPage`,
|
|
1458
|
+
# 60 per page; a category also returns its `title`, `breadcrumbs` and `subcategories`
|
|
1459
|
+
# (`code`, `name`, `count`). Smyths' search returns its best 240 matches at most, a category
|
|
1460
|
+
# every product it holds. Listings collect up to `max_results` from `page` on, billed one
|
|
1461
|
+
# unit per page.
|
|
1462
|
+
#
|
|
1463
|
+
# @param category [String] mode=category: a category code ('SM060101') or a category page
|
|
1464
|
+
# link (https://www.smythstoys.com/uk/en-gb/toys/action-figures-and-playsets/c/SM060101).
|
|
1465
|
+
# The top categories are Toys SM0601, Baby SM0602, Outdoor SM0603 and Gaming & Tech SM0604;
|
|
1466
|
+
# each listing names its subcategories.
|
|
1467
|
+
# @param sort [String] Listing order. search: relevance, bestsellers, price_asc, price_desc,
|
|
1468
|
+
# rating_desc, newest (the first is the default). category: bestsellers, price_asc,
|
|
1469
|
+
# price_desc, rating_desc, newest (the first is the default).
|
|
1470
|
+
# @param page [Integer] 1-based listing page to start from (60 products per page). API
|
|
1471
|
+
# default: 1.
|
|
1472
|
+
# @param max_results [Integer] Products to collect across pages, 1-600. Each page fetched is
|
|
1473
|
+
# billed one unit. API default: 60.
|
|
1474
|
+
# Calls POST /marketplace/smyths-inventory.
|
|
1475
|
+
def smyths_category(category, sort: nil, page: nil, max_results: nil)
|
|
1476
|
+
post_json("/marketplace/smyths-inventory", {
|
|
1477
|
+
mode: "category",
|
|
1478
|
+
category: category,
|
|
1479
|
+
sort: sort,
|
|
1480
|
+
page: page,
|
|
1481
|
+
max_results: max_results,
|
|
1482
|
+
})
|
|
1483
|
+
end
|
|
1484
|
+
|
|
1139
1485
|
# Scrape Booking.com hotels.
|
|
1140
1486
|
#
|
|
1141
1487
|
# Searches Booking.com for `location` and returns the properties as JSON: `name`, `price`
|
|
@@ -1418,11 +1764,13 @@ module ScrapeUnblocker
|
|
|
1418
1764
|
# Scrape Google Shopping product listings.
|
|
1419
1765
|
#
|
|
1420
1766
|
# Runs the Google Shopping vertical (`udm=28`) for `q` and returns the product cards as
|
|
1421
|
-
# JSON: `title`, `price`, `currency`, `
|
|
1422
|
-
# `
|
|
1423
|
-
#
|
|
1424
|
-
#
|
|
1425
|
-
# `
|
|
1767
|
+
# JSON: `title`, `price`, `currency`, `currencyCode`, `originalPrice`, `discount`,
|
|
1768
|
+
# `merchant`, `rating`, `reviewCount` and Google's own ids for the product (`productId`,
|
|
1769
|
+
# `catalogId`, `offerId` - stable across searches, for tracking one product). Set
|
|
1770
|
+
# `proxy_country`/`gl` to target a market (prices/merchants are region-specific) and
|
|
1771
|
+
# `min_price`/`max_price` to filter. One render returns the first page of products (v1).
|
|
1772
|
+
# Note: Google Shopping exposes no per-product URL, so `url` is omitted and `image` is best-
|
|
1773
|
+
# effort.
|
|
1426
1774
|
#
|
|
1427
1775
|
# @param q [String] Product search term, e.g. 'wireless headphones'.
|
|
1428
1776
|
# @param gl [String] Market of search, ISO-2, e.g. 'us', 'de'. Sets prices/merchants. API
|
|
@@ -1559,6 +1907,208 @@ module ScrapeUnblocker
|
|
|
1559
1907
|
})
|
|
1560
1908
|
end
|
|
1561
1909
|
|
|
1910
|
+
# Scrape Google Hotels search results (prices, ratings, amenities).
|
|
1911
|
+
#
|
|
1912
|
+
# Runs a Google Hotels search for `q` and returns the properties as JSON: `name`, `type`
|
|
1913
|
+
# (hotel / vacation_rental), `propertyToken`, `price` for the stay (`perNight`,
|
|
1914
|
+
# `perNightWithTaxes`, `total`, `totalWithTaxes`, `taxes`, Google's `display` string),
|
|
1915
|
+
# `deal`, `rating`, `reviews`, `ratingsBreakdown`, `reviewTopics`, `hotelClass`, `stars`,
|
|
1916
|
+
# `amenities`, `description`, `website`, `latitude`/`longitude`, `nearbyPlaces`,
|
|
1917
|
+
# `thumbnail`, `images` and `mapsUrl`, plus the page's sponsored `ads`. A query naming one
|
|
1918
|
+
# hotel returns just that hotel (`matchedProperty`). Set the stay with
|
|
1919
|
+
# `check_in`/`check_out`, the party with `adults` and `children` (ages), and `currency`,
|
|
1920
|
+
# `hl` (language) and `gl` (market). `applied` echoes the dates, currency and place Google
|
|
1921
|
+
# actually used. Collect up to `max_results` across pages (each Google page is billed as one
|
|
1922
|
+
# request, see `pagesFetched`); `nextPageToken` continues the list. Pass a `propertyToken`
|
|
1923
|
+
# to `/travel/google-hotels-property` for every booking site's price.
|
|
1924
|
+
#
|
|
1925
|
+
# @param q [String] What to search, as on Google Hotels: a place ('hotels in Paris',
|
|
1926
|
+
# 'Lisbon'), an area or landmark, or a hotel name.
|
|
1927
|
+
# @param check_in [String] Check-in date, YYYY-MM-DD. Leave check_in and check_out empty for
|
|
1928
|
+
# Google's default stay.
|
|
1929
|
+
# @param check_out [String] Check-out date, YYYY-MM-DD (stays of up to 30 nights).
|
|
1930
|
+
# @param adults [Integer] Number of adults (1-10). API default: 2.
|
|
1931
|
+
# @param children [String] Ages of the children, comma-separated, e.g. '7,10' (up to 6).
|
|
1932
|
+
# @param currency [String] Price currency, ISO 4217 (USD, EUR, GBP, ...). API default: USD.
|
|
1933
|
+
# @param hl [String] Language of names, amenities and price formats, e.g. 'en', 'de', 'fr'.
|
|
1934
|
+
# API default: en.
|
|
1935
|
+
# @param gl [String] Market (2-letter country). Google localizes the booking sites to it.
|
|
1936
|
+
# API default: us.
|
|
1937
|
+
# @param page_token [String] `nextPageToken` of a previous response, to continue where it
|
|
1938
|
+
# stopped.
|
|
1939
|
+
# @param max_results [Integer] Properties to collect (1-100). Google serves about 20 per
|
|
1940
|
+
# page; each page is billed as one request. API default: 20.
|
|
1941
|
+
# Calls POST /travel/google-hotels.
|
|
1942
|
+
def google_hotels(q, check_in: nil, check_out: nil, adults: nil, children: nil, currency: nil, hl: nil, gl: nil, page_token: nil, max_results: nil)
|
|
1943
|
+
post_json("/travel/google-hotels", {
|
|
1944
|
+
q: q,
|
|
1945
|
+
check_in: check_in,
|
|
1946
|
+
check_out: check_out,
|
|
1947
|
+
adults: adults,
|
|
1948
|
+
children: children,
|
|
1949
|
+
currency: currency,
|
|
1950
|
+
hl: hl,
|
|
1951
|
+
gl: gl,
|
|
1952
|
+
page_token: page_token,
|
|
1953
|
+
max_results: max_results,
|
|
1954
|
+
})
|
|
1955
|
+
end
|
|
1956
|
+
|
|
1957
|
+
# Scrape one Google Hotels property: prices from every booking site.
|
|
1958
|
+
#
|
|
1959
|
+
# Returns one property from Google Hotels as JSON, identified by the `property_token` of a
|
|
1960
|
+
# `/travel/google-hotels` result: `offers` from every booking site Google lists for the stay
|
|
1961
|
+
# (`provider`, `official` for the hotel's own site, `perNight`/`perNightWithTaxes`,
|
|
1962
|
+
# `total`/`totalWithTaxes`, a Google `link` to book), `rooms` with room-level rates and
|
|
1963
|
+
# free-cancellation deadlines where Google shows them, the lowest `price`, `address`,
|
|
1964
|
+
# `phone`, `website`, `description` and `about`, `rating`, `reviews`, `ratingsBreakdown`,
|
|
1965
|
+
# `reviewTopics`, `hotelClass`, `latitude`/`longitude`, `nearbyPlaces`, `images`, `placeId`
|
|
1966
|
+
# and `mapsUrl`. Set the stay with `check_in`/`check_out`, the party with
|
|
1967
|
+
# `adults`/`children`, and `currency`, `hl`, `gl`. Billed as one request.
|
|
1968
|
+
#
|
|
1969
|
+
# @param property_token [String] `propertyToken` of a /travel/google-hotels result.
|
|
1970
|
+
# @param check_in [String] Check-in date, YYYY-MM-DD. Leave check_in and check_out empty for
|
|
1971
|
+
# Google's default stay.
|
|
1972
|
+
# @param check_out [String] Check-out date, YYYY-MM-DD (stays of up to 30 nights).
|
|
1973
|
+
# @param adults [Integer] Number of adults (1-10). API default: 2.
|
|
1974
|
+
# @param children [String] Ages of the children, comma-separated, e.g. '7,10' (up to 6).
|
|
1975
|
+
# @param currency [String] Price currency, ISO 4217 (USD, EUR, GBP, ...). API default: USD.
|
|
1976
|
+
# @param hl [String] Language, e.g. 'en', 'de', 'fr'. API default: en.
|
|
1977
|
+
# @param gl [String] Market (2-letter country). Google localizes the booking sites to it.
|
|
1978
|
+
# API default: us.
|
|
1979
|
+
# Calls POST /travel/google-hotels-property.
|
|
1980
|
+
def google_hotels_property(property_token, check_in: nil, check_out: nil, adults: nil, children: nil, currency: nil, hl: nil, gl: nil)
|
|
1981
|
+
post_json("/travel/google-hotels-property", {
|
|
1982
|
+
property_token: property_token,
|
|
1983
|
+
check_in: check_in,
|
|
1984
|
+
check_out: check_out,
|
|
1985
|
+
adults: adults,
|
|
1986
|
+
children: children,
|
|
1987
|
+
currency: currency,
|
|
1988
|
+
hl: hl,
|
|
1989
|
+
gl: gl,
|
|
1990
|
+
})
|
|
1991
|
+
end
|
|
1992
|
+
|
|
1993
|
+
# Scrape Google News (search or section).
|
|
1994
|
+
#
|
|
1995
|
+
# Searches Google News for `q`, or lists a section with `topic` (world, nation, business,
|
|
1996
|
+
# technology, entertainment, sports, science, health, top, or a topic id), and returns
|
|
1997
|
+
# `articles`: `position`, `title`, `url` (the publisher's article URL), `source`,
|
|
1998
|
+
# `sourceUrl`, `publishedAt` (ISO 8601 UTC), `imageUrl` (+ `imageWidth`/`imageHeight`),
|
|
1999
|
+
# `authors`, `googleNewsId` and `googleNewsUrl`. Metadata only - no article text. Narrow a
|
|
2000
|
+
# search with `when` (e.g. '1d') or `after`/`before` dates; pick the edition with `hl` and
|
|
2001
|
+
# `gl`. Google News answers a search with up to about 100 articles (no paging - use date
|
|
2002
|
+
# windows to go further back). One unit per call.
|
|
2003
|
+
#
|
|
2004
|
+
# @param q [String] Search query, e.g. 'tesla' or '"web scraping"'. Google News operators
|
|
2005
|
+
# work: quotes, OR, -word, site:reuters.com, intitle:. Pass either `q` or `topic`.
|
|
2006
|
+
# @param topic [String] A section instead of a search: world, nation, business, technology,
|
|
2007
|
+
# entertainment, sports, science, health, or top (the edition's headlines). A Google News
|
|
2008
|
+
# topic id (the 'CAAq...' part of a news.google.com/topics/ URL) also works.
|
|
2009
|
+
# @param hl [String] Language of the Google News edition, e.g. 'en', 'en-GB', 'de', 'fr',
|
|
2010
|
+
# 'pt-BR'. API default: en.
|
|
2011
|
+
# @param gl [String] Country of the Google News edition (2-letter code), e.g. 'us', 'gb',
|
|
2012
|
+
# 'de'. API default: us.
|
|
2013
|
+
# @param when [String] Only articles from the last period: '1h' to '720h', '1d', '7d', '2w',
|
|
2014
|
+
# '1m', '1y'. Search (`q`) only.
|
|
2015
|
+
# @param after [String] Only articles published after this date (YYYY-MM-DD). Search only.
|
|
2016
|
+
# @param before [String] Only articles published before this date (YYYY-MM-DD). Search only.
|
|
2017
|
+
# @param max_results [Integer] Most articles to return, 1-250. Google News returns up to
|
|
2018
|
+
# about 100 articles for a search and about 250 for a section; one call is billed one unit
|
|
2019
|
+
# whatever the count. API default: 100.
|
|
2020
|
+
# Calls POST /search/google-news.
|
|
2021
|
+
def google_news(q = nil, topic: nil, hl: nil, gl: nil, when: nil, after: nil, before: nil, max_results: nil)
|
|
2022
|
+
post_json("/search/google-news", {
|
|
2023
|
+
q: q,
|
|
2024
|
+
topic: topic,
|
|
2025
|
+
hl: hl,
|
|
2026
|
+
gl: gl,
|
|
2027
|
+
when: binding.local_variable_get(:when),
|
|
2028
|
+
after: after,
|
|
2029
|
+
before: before,
|
|
2030
|
+
max_results: max_results,
|
|
2031
|
+
})
|
|
2032
|
+
end
|
|
2033
|
+
|
|
2034
|
+
# Scrape Google ads (Ads Transparency Center).
|
|
2035
|
+
#
|
|
2036
|
+
# Returns an advertiser's Google ads (Search, YouTube, Display, Shopping, Maps, Play) from
|
|
2037
|
+
# the Google Ads Transparency Center for competitor analysis: per ad `creativeId`,
|
|
2038
|
+
# `advertiserId`/`advertiserName`, `format` (text/image/video), `firstShown`, `lastShown`,
|
|
2039
|
+
# `daysShown`, `matchedDomain`, the preview (`imageUrl` with size, or `previewUrl`),
|
|
2040
|
+
# `googleCreativeId`, `googleCustomerId`, `adGroupId` and `adUrl`. Pick ads by `advertiser`
|
|
2041
|
+
# (name or id) or `domain`; filter with `region`, `platform`, `format` and
|
|
2042
|
+
# `date_from`/`date_to`. `include_details` adds per-region reach and targeting,
|
|
2043
|
+
# `include_preview` the ad's texts and YouTube video. Collects up to `max_results` (continue
|
|
2044
|
+
# with `page_token`); billed one unit per page of up to 100 ads, plus one per detail and per
|
|
2045
|
+
# preview fetched (`callUnits`).
|
|
2046
|
+
#
|
|
2047
|
+
# @param advertiser [String] Advertiser to pull ads for: a name (e.g. 'Nike') - resolved to
|
|
2048
|
+
# the best-matching advertiser, reported in `advertisersUsed` (a single brand name no
|
|
2049
|
+
# advertiser is named like falls back to its domain) - or an advertiser id
|
|
2050
|
+
# ('AR16735076323512287233'). Comma-separate up to 10. Pass `advertiser` or `domain`.
|
|
2051
|
+
# @param domain [String] Website the ads point to, e.g. 'nike.com' (ads of every advertiser
|
|
2052
|
+
# for that domain).
|
|
2053
|
+
# @param region [String] Where the ads were shown: a 2-letter country code ('US', 'DE'), a
|
|
2054
|
+
# comma list of them, or 'anywhere' (default).
|
|
2055
|
+
# @param platform [String] Only ads shown on these platforms (comma list): search, youtube,
|
|
2056
|
+
# maps, play, shopping.
|
|
2057
|
+
# @param format [String] Only one ad format: text, image or video.
|
|
2058
|
+
# @param date_from [String] Only ads shown on or after this date (YYYY-MM-DD).
|
|
2059
|
+
# @param date_to [String] Only ads shown on or before this date (YYYY-MM-DD).
|
|
2060
|
+
# @param sort [String] Order of the ads: 'last_shown' (most recently shown first). API
|
|
2061
|
+
# default: last_shown.
|
|
2062
|
+
# @param max_results [Integer] Ads to collect, 1-1000. Pages of up to 100 are fetched as
|
|
2063
|
+
# needed; each page is billed one unit. API default: 100.
|
|
2064
|
+
# @param page_token [String] Continue a previous call: its `nextPageToken`.
|
|
2065
|
+
# @param include_details [Boolean] Add `details` per ad: regions shown with first/last date
|
|
2066
|
+
# (plus impressions per platform for EU regions), EU reach, disclosed targeting and all
|
|
2067
|
+
# preview variations. One unit per ad, for up to 300 ads per call. API default: false.
|
|
2068
|
+
# @param include_preview [Boolean] Add `preview` per ad: what it shows - headline,
|
|
2069
|
+
# description and display URL of text ads, product title and merchant of shopping ads, image
|
|
2070
|
+
# URLs, the YouTube video of video ads. One unit per ad that has a preview script, for up to
|
|
2071
|
+
# 40 ads per call. Search text ads often exist only as an image (`imageUrl`). API default:
|
|
2072
|
+
# false.
|
|
2073
|
+
# Calls POST /ads/google-ads-transparency.
|
|
2074
|
+
def google_ads_transparency(advertiser: nil, domain: nil, region: nil, platform: nil, format: nil, date_from: nil, date_to: nil, sort: nil, max_results: nil, page_token: nil, include_details: nil, include_preview: nil)
|
|
2075
|
+
post_json("/ads/google-ads-transparency", {
|
|
2076
|
+
advertiser: advertiser,
|
|
2077
|
+
domain: domain,
|
|
2078
|
+
region: region,
|
|
2079
|
+
platform: platform,
|
|
2080
|
+
format: format,
|
|
2081
|
+
date_from: date_from,
|
|
2082
|
+
date_to: date_to,
|
|
2083
|
+
sort: sort,
|
|
2084
|
+
max_results: max_results,
|
|
2085
|
+
page_token: page_token,
|
|
2086
|
+
include_details: include_details,
|
|
2087
|
+
include_preview: include_preview,
|
|
2088
|
+
})
|
|
2089
|
+
end
|
|
2090
|
+
|
|
2091
|
+
# Look up Google advertisers (Ads Transparency Center).
|
|
2092
|
+
#
|
|
2093
|
+
# Finds advertisers on the Google Ads Transparency Center by name: `advertisers`
|
|
2094
|
+
# (`advertiserId` to use with /ads/google-ads-transparency, `name`, `country`,
|
|
2095
|
+
# `creativesMin`/`creativesMax` - how many ads they ran - and `verified`) and matching
|
|
2096
|
+
# website `domains`. One unit per call.
|
|
2097
|
+
#
|
|
2098
|
+
# @param q [String] Advertiser name or brand to look up, e.g. 'nike'.
|
|
2099
|
+
# @param region [String] Count ads shown in these regions only: a 2-letter country code, a
|
|
2100
|
+
# comma list, or 'anywhere' (default).
|
|
2101
|
+
# @param max_results [Integer] Most advertisers (and domains) to return, 1-50. API default:
|
|
2102
|
+
# 10.
|
|
2103
|
+
# Calls POST /ads/google-ads-transparency-advertisers.
|
|
2104
|
+
def google_ads_transparency_advertisers(q, region: nil, max_results: nil)
|
|
2105
|
+
post_json("/ads/google-ads-transparency-advertisers", {
|
|
2106
|
+
q: q,
|
|
2107
|
+
region: region,
|
|
2108
|
+
max_results: max_results,
|
|
2109
|
+
})
|
|
2110
|
+
end
|
|
2111
|
+
|
|
1562
2112
|
# Search Bing.
|
|
1563
2113
|
#
|
|
1564
2114
|
# Searches Bing for `keyword` in a real browser and returns the results page as JSON:
|
|
@@ -2575,6 +3125,68 @@ module ScrapeUnblocker
|
|
|
2575
3125
|
})
|
|
2576
3126
|
end
|
|
2577
3127
|
|
|
3128
|
+
# Scrape Upwork job posts.
|
|
3129
|
+
#
|
|
3130
|
+
# Searches Upwork jobs for `q` (or lists the newest jobs without it) and returns `jobs`:
|
|
3131
|
+
# `id`, `ciphertext`, `url`, `title`, `description` (full text), `publishedAt`, `createdAt`,
|
|
3132
|
+
# `renewedAt`, `jobType` (hourly / fixed), `hourlyMin`, `hourlyMax`, `budget` (fixed price),
|
|
3133
|
+
# `currency`, `experienceLevel`, `duration`, `workload`, `skills`, plus `totalResults` and
|
|
3134
|
+
# `nextStart`. Filter with `job_type`, `experience`, `budget`, `hourly_rate`,
|
|
3135
|
+
# `client_hires`, `workload`, `duration`, `location`, `category`, `contract_to_hire`; sort
|
|
3136
|
+
# by `relevance` or `recency`. `details=true` adds, per job: `proposals`, `interviewing`,
|
|
3137
|
+
# `invitesSent`, `hired`, `positionsToHire`, `lastClientActivity`, `category`,
|
|
3138
|
+
# `qualifications` and `client` (`country`, `city`, `timezone`, `paymentVerified`, `rating`,
|
|
3139
|
+
# `reviews`, `totalSpent`, `hires`, `memberSince`; no client names). A private listing is
|
|
3140
|
+
# marked `privateListing: true` without those fields. Upwork shows signed-out visitors the
|
|
3141
|
+
# first 5000 results of a search. Billing: one unit per results page of up to 50 jobs, plus
|
|
3142
|
+
# one per job page fetched with `details=true` (`callUnits`).
|
|
3143
|
+
#
|
|
3144
|
+
# @param q [String] What to search for, e.g. 'python' or 'logo design'. Leave empty with
|
|
3145
|
+
# sort=recency for the newest jobs.
|
|
3146
|
+
# @param job_type [String] hourly or fixed.
|
|
3147
|
+
# @param experience [String] Experience level, comma list of: entry, intermediate, expert.
|
|
3148
|
+
# @param budget [String] Fixed-price budget in USD, comma list of ranges like '100-499',
|
|
3149
|
+
# '1000-4999' or '5000-'.
|
|
3150
|
+
# @param hourly_rate [String] Hourly rate in USD, e.g. '25-50' or '40-'.
|
|
3151
|
+
# @param client_hires [String] Client's past hires, comma list of: 0, 1-9, 10-.
|
|
3152
|
+
# @param workload [String] part_time (under 30 hrs/week) or full_time.
|
|
3153
|
+
# @param duration [String] Project length, comma list of: week, month, semester, ongoing
|
|
3154
|
+
# (under a month, 1-3 months, 3-6 months, over 6 months).
|
|
3155
|
+
# @param location [String] Client location, comma list of regions or countries as Upwork
|
|
3156
|
+
# names them, e.g. 'Europe' or 'United States'.
|
|
3157
|
+
# @param category [String] Job category, comma list of names (Accounting & Consulting, Admin
|
|
3158
|
+
# Support, Customer Service, Data Science & Analytics, Design & Creative, Engineering &
|
|
3159
|
+
# Architecture, It & Networking, Legal, Sales & Marketing, Translation, Web, Mobile &
|
|
3160
|
+
# Software Dev, Writing) or category ids.
|
|
3161
|
+
# @param contract_to_hire [Boolean] Only contract-to-hire jobs. API default: false.
|
|
3162
|
+
# @param sort [String] relevance (default with q) or recency (default without q).
|
|
3163
|
+
# @param start [Integer] 0-based position of the first job, 0-4999 (Upwork shows signed-out
|
|
3164
|
+
# visitors the first 5000 results); `nextStart` continues. API default: 0.
|
|
3165
|
+
# @param max_results [Integer] Jobs to collect, 1-5000. Each results page (up to 50 jobs) is
|
|
3166
|
+
# billed one unit. API default: 50.
|
|
3167
|
+
# @param details [Boolean] Add each job's page: proposals, client stats, qualifications. Up
|
|
3168
|
+
# to 100 jobs; one more unit per job page fetched. API default: false.
|
|
3169
|
+
# Calls POST /jobs/upwork.
|
|
3170
|
+
def upwork_jobs(q = nil, job_type: nil, experience: nil, budget: nil, hourly_rate: nil, client_hires: nil, workload: nil, duration: nil, location: nil, category: nil, contract_to_hire: nil, sort: nil, start: nil, max_results: nil, details: nil)
|
|
3171
|
+
post_json("/jobs/upwork", {
|
|
3172
|
+
q: q,
|
|
3173
|
+
job_type: job_type,
|
|
3174
|
+
experience: experience,
|
|
3175
|
+
budget: budget,
|
|
3176
|
+
hourly_rate: hourly_rate,
|
|
3177
|
+
client_hires: client_hires,
|
|
3178
|
+
workload: workload,
|
|
3179
|
+
duration: duration,
|
|
3180
|
+
location: location,
|
|
3181
|
+
category: category,
|
|
3182
|
+
contract_to_hire: contract_to_hire,
|
|
3183
|
+
sort: sort,
|
|
3184
|
+
start: start,
|
|
3185
|
+
max_results: max_results,
|
|
3186
|
+
details: details,
|
|
3187
|
+
})
|
|
3188
|
+
end
|
|
3189
|
+
|
|
2578
3190
|
# Scrape Trustpilot company reviews.
|
|
2579
3191
|
#
|
|
2580
3192
|
# Returns a company's Trustpilot profile and reviews as JSON. `company` is the reviewed
|
|
@@ -3313,7 +3925,7 @@ module ScrapeUnblocker
|
|
|
3313
3925
|
# @param video [String] Video id (dQw4w9WgXcQ) or any YouTube video URL.
|
|
3314
3926
|
# @param lang [String] Preferred caption language code, e.g. 'en'. Omit for the
|
|
3315
3927
|
# default/first track. A prefix like 'en' matches 'en-US'.
|
|
3316
|
-
# @param format [String] Output shape:
|
|
3928
|
+
# @param format [String] Output shape: text, segments. 'segments' returns timestamps; 'text'
|
|
3317
3929
|
# returns only the joined plaintext. API default: segments.
|
|
3318
3930
|
# @param proxy_country [String] Proxy country the request is sent from (ISO-2, e.g. 'US',
|
|
3319
3931
|
# 'DE') for the watch page. Defaults to US.
|