
TikTok Shop Scraper
scrape.ly/store/shelfbright/tiktok-shop-scraperE-commerceSocial media
1 monthly user

Scrape Vivino wines by name or link, or browse Vivino with filters: ratings, vintage ratings, prices in 38 markets, grapes, region, food pairings, taste profiles and reviews. No login needed.
Get Vivino wine data for any wine you name or link: community ratings (per vintage and over all vintages), local prices in 38 markets, grapes, region, style, food pairings, critic scores, drinking window, rankings, taste profiles and reviews. Or browse Vivino's catalogue with filters (wine type, country of origin, grape, rating, price) and get every wine that matches. No login, no browser, results in seconds.
| Field | What it does |
|---|---|
wines | Wine names (Opus One 2019, Dom Pérignon) and Vivino links: wine pages (/w/1911534?year=2019), vintage pages (/wines/159338935) or explore pages (/explore?...). |
maxResults | Most wines to save per explore search (0 = all Vivino lists, about 2,000 per search). |
wineTypes, originCountries, grapes | Explore filters: start a browse of Vivino's catalogue. |
minRating, minPrice, maxPrice, sortBy | Narrow and order explore results. |
searchMode | How a year in a name is used: auto, name_and_vintage (exact vintage only) or name_only. |
maxMatchesPerName | 1 = best match; more returns the next best matches too. |
includeTasteProfile, includeReviews, maxReviewsPerWine | Extra data per wine. |
shipTo, usState | Market for prices and currency. |
{
"wines": [
"Opus One 2019",
"Dom Pérignon",
"https://www.vivino.com/cloudy-bay-sauvignon-blanc/w/18978"
],
"includeTasteProfile": true,
"includeReviews": true,
"maxReviewsPerWine": 20,
"shipTo": "GB"
}
Browse instead of naming wines:
{
"wineTypes": ["red"],
"originCountries": ["it"],
"minRating": 4.2,
"maxPrice": 40,
"sortBy": "highest_rated",
"maxResults": 200,
"shipTo": "DE"
}
One row per wine. The dataset has three table views: Wines, Ratings, taste and prices and Reviews.
| Field | Description |
|---|---|
name, winery, vintage, full_name | Wine, producer and year (vintage is empty for all-vintages data). |
wine_type, region, country, country_code, wine_style | Type and origin. |
grape_varieties, food_pairings, alcohol, closure, wine_description | Wine facts. |
average_rating, ratings_count | Rating of this vintage (all vintages when no year). |
wine_average_rating, wine_ratings_count | Rating over all vintages. |
display_rating, display_rating_scope, vintage_rating_status | The best rating available and what it covers. Vivino hides a vintage's average until it has enough ratings. |
price, currency, price_usd, median_price, discounted_from, discount_percent, price_vintage | Price in the chosen market. |
merchant_url, bottle_volume_ml | Shop offer (explore results). |
critic_scores, awards, rank_global, rank_in_country, rank_in_region, drinking_window_start, drinking_window_end | Scores, rankings and when to drink. |
taste_profile | Body, acidity, tannins, sweetness, fizziness, flavor groups and notes (when enabled). |
reviews | Rating, text, language, date, reviewer, likes (when enabled). |
input, inputSource, searchQuery, matchScore, matchRank, resolution_status | Which input gave the row and how it was matched. |
wineId, vintageId, vivino_url, image_url, label_image_url, bottle_image_url | IDs, link and images. |
{
"wineId": 1136930,
"vintageId": 169250169,
"vivino_url": "https://www.vivino.com/penfolds-grange/w/1136930?year=2018",
"name": "Grange",
"full_name": "Penfolds Grange 2018",
"winery": "Penfolds",
"vintage": 2018,
"wine_type": "Red",
"region": "South Australia",
"country": "Australia",
"country_code": "AU",
"wine_style": "Australian Cabernet - Shiraz",
"grape_varieties": ["Shiraz/Syrah", "Cabernet Sauvignon"],
"food_pairings": ["Beef", "Lamb", "Poultry"],
"alcohol": 13.5,
"average_rating": 4.6,
"ratings_count": 576,
"wine_average_rating": 4.6,
"wine_ratings_count": 30061,
"display_rating": 4.6,
"display_rating_scope": "vintage",
"vintage_rating_status": "published",
"price": 658.9,
"currency": "USD",
"median_price": 688.49,
"drinking_window_start": 2023,
"drinking_window_end": 2033,
"rank_global": 3738,
"taste_profile": {
"body": 4.7,
"acidity": 3.05,
"tannins": 3.23,
"sweetness": 2.1,
"fizziness": null,
"flavor_notes": ["oak", "vanilla", "chocolate", "tobacco", "cedar"]
},
"reviews": [
{
"rating": 4.5,
"note": "Dark fruit, cedar and a very long finish.",
"language": "en",
"created_at": "2025-09-28T17:19:44.000Z",
"user_name": "Jane D.",
"vintage_year": 2018
}
],
"input": "Penfolds Grange 2018",
"inputSource": "search",
"matchScore": 1,
"matchRank": 1,
"resolution_status": "matched",
"shipTo": "US",
"scrapedAt": "2026-10-21T04:35:17.040Z"
}
You pay $3.50 per 1,000 wines (a fraction of a cent per wine), plus a small platform usage fee for the run (compute and proxy traffic, about one to two cents per 1,000 wines in our tests). Taste profiles and reviews are included in the wine price.
Example: 1,000 wines ≈ $3.50 + about $0.01 to $0.02 usage (measured on our test runs) ≈ $3.52.
Wines that are not found, invalid inputs and duplicates are not saved and cost nothing. Set a maximum charge per run in the run options and the run stops cleanly when it is reached.
Is it legal to scrape Vivino? The scraper reads public wine pages and data that anyone can see without an account. You are responsible for how you use the data; check Vivino's terms and the laws that apply to you, especially for reviews, which are written by people.
Do I need a Vivino account or a proxy? No account. Datacenter proxies are on by default and enough for Vivino; the run moves to residential proxies by itself if Vivino starts refusing datacenter addresses.
How many wines can I get? As many names and links as you like in one run. An explore search returns up to about 2,000 wines (Vivino's own limit per search); split big searches by country, type or price to get more.
Why is the vintage rating empty? Vivino publishes a vintage's average only after it has enough ratings. display_rating then falls back to the all-vintages rating and display_rating_scope says so.
Why is the price empty? No shop sells that wine in the chosen market. Try another market (shipTo), for example the wine's home country.
Can I schedule it or use the API? Yes. Schedule runs for price tracking and call the actor through the API from any language; results come back as JSON, CSV or Excel.
matchScore, or raise maxMatchesPerName and pick.maxMatchesPerName goes up to 1,000, the most hits Vivino's wine search returns for one query.maxReviewsPerWine goes up to 2,000. Reviews sit inside the wine's row, which is held in memory until it is saved.merchant_url) and bottle size come with explore results; for named wines Vivino's price feed has no shop link.Every field below can be set in the run form, passed through the API, or saved as a task. Unset fields fall back to the defaults shown.
winesarrayOptionalWines (names or Vivino links)
One wine per line. Type a wine name, with the vintage year if you want that vintage (e.g. 'Opus One 2019'), or paste a Vivino link: a wine page (https://www.vivino.com/opus-one/w/1911534?year=2019), a vintage page (/wines/159338935) or an explore page with your filters (https://www.vivino.com/explore?...). Names and links can be mixed.
maxResultsintegerOptionaldefault 20Max wines per explore search
How many wines to save from each explore search (an explore link or the filters below). Vivino lists up to about 2,000 wines per search. 0 means as many as Vivino lists. Wine names and wine links always give their own match.
Browse Vivino's catalogue without naming wines. Setting a wine type, country of origin or grape starts an explore search; rating and price also narrow explore links. They do not filter the wines you name.
wineTypesarrayOptionalWine types
Only these wine types.
originCountriesarrayOptionalCountries of origin
Only wines made in these countries.
grapesarrayOptionalGrapes
Only wines made with these grapes, by name as Vivino writes them (e.g. Pinot Noir, Nebbiolo, Shiraz/Syrah).
minRatingnumberOptionalMin rating
Only wines with at least this average Vivino rating (1 to 5).
minPricenumberOptionalMin price
Lowest bottle price, in the currency of the market below.
maxPricenumberOptionalMax price
Highest bottle price, in the currency of the market below.
sortByenumOptionaldefault "most_rated"Sort explore results by
Order of explore results.
How wine names are matched to Vivino.
searchModeenumOptionaldefault "auto"Vintage in wine names
Auto: a year in the name picks that vintage, and if Vivino has no such vintage you get the wine's all-vintages data. Exact vintage: skip the wine when the year is not on Vivino. Ignore year: always return the wine's all-vintages data.
maxMatchesPerNameintegerOptionaldefault 1Matches per wine name
1 returns the best match. Raise it to also get the next best matches (for example other wines of the same producer); each one is a separate result. Up to 1,000: Vivino's wine search returns at most 1,000 hits per query.
Extra data per wine, included in the price of the wine.
includeTasteProfilebooleanOptionaldefault falseInclude taste profile
Body, acidity, tannins, sweetness, fizziness and the flavor notes the community mentions.
includeReviewsbooleanOptionaldefault falseInclude reviews
Community reviews of the wine (of the vintage when there is one): rating, text, language, date and reviewer.
maxReviewsPerWineintegerOptionaldefault 10Max reviews per wine
Used when reviews are on. Up to 2,000: the reviews are saved inside the wine's own row, so they are held in memory until that row is saved.
Prices, currency and which shops are shown depend on the country Vivino ships to.
shipToenumOptionaldefault "US"Market (ship to)
Country whose prices and shops you want. Prices come in that market's currency.
usStatestringOptionalUS state
Two-letter state for the United States market (prices differ by state). Empty means CA.
proxyConfigurationobjectOptionaldefault {"useScrapelyProxy":true,"scrapelyProxyGroups":["DATACENTER…Proxy
Datacenter proxies work for Vivino. The run switches to residential proxies by itself if Vivino starts refusing datacenter addresses.
Every run writes its results to a dataset. Preview it in the dashboard, then export it or read it through the API.
| Field | Type | Description |
|---|---|---|
| wineId | integer | null | Vivino wine ID |
| vintageId | integer | null | Vivino vintage ID |
| vivino_url | string | null | Wine page on Vivino |
| name | string | null | Wine name |
| full_name | string | null | Full name with winery and year |
| winery | string | null | Winery / producer |
| vintage | integer | null | Vintage year (empty for all-vintages data) |
| wine_type | string | null | Red, White, Sparkling, Rosé, Dessert or Fortified |
| region | string | null | Wine region |
| country | string | null | Country of origin |
| country_code | string | null | Country of origin code |
| appellation | string | null | Wine style as Vivino names it |
| wine_style | string | null | Wine style |
| grape_varieties | array | null | Grapes |
| food_pairings | array | null | Food pairings |
| alcohol | number | null | Alcohol, % ABV |
| closure | string | null | Closure (cork, screw ...) |
| wine_description | string | null | Description |
| average_rating | number | null | Average rating of this vintage (all vintages when no year) |
| ratings_count | integer | null | Ratings of this vintage |
| reviews_count | integer | null | Written reviews of this vintage |
| wine_average_rating | number | null | Average rating over all vintages |
| wine_ratings_count | integer | null | Ratings over all vintages |
| display_rating | number | null | Best available rating |
| display_ratings_count | integer | null | Ratings behind display_rating |
| display_rating_scope | string | null | vintage or all_vintages |
| vintage_rating_status | string | null | published, below_threshold, unavailable or all_vintages |
| ratings_distribution | object | null | Ratings per star |
| price | number | null | Price in the market currency |
| currency | string | null | Currency |
| price_usd | number | null | Price in US dollars |
| median_price | number | null | Median market price |
| discounted_from | number | null | Price before discount |
| discount_percent | number | null | Discount in percent |
| price_vintage | integer | null | Vintage year the price is for |
| price_type | string | null | Vivino price type |
| merchant_url | string | null | Shop offer link |
| bottle_volume_ml | integer | null | Bottle size, ml |
| is_natural | boolean | null | Natural wine |
| image_url | string | null | Label image |
| label_image_url | string | null | Large label image |
| bottle_image_url | string | null | Bottle image |
| drinking_window_start | integer | null | Drink from (year) |
| drinking_window_end | integer | null | Drink until (year) |
| rank_global | integer | null | Global rank |
| rank_in_country | integer | null | Rank in its country |
| rank_in_region | integer | null | Rank in its region |
| rank_in_winery | integer | null | Rank in its winery |
| critic_scores | array | null | Critic scores |
| awards | array | null | Awards |
| winery_id | integer | null | Winery ID |
| winery_seo_name | string | null | Winery slug |
| region_id | integer | null | Region ID |
| requested_vintage | integer | null | Year asked for in the input |
| shipTo | string | null | Market (ship-to country) |
| taste_profile | object | null | Taste profile (when enabled) |
| reviews | array | null | Reviews (when enabled) |
| inputSource | string | null | search, url or explore |
| searchQuery | string | null | Name searched |
| input | string | null | Your input line |
| matchScore | number | null | Share of the name's words matched (0 to 1) |
| matchRank | integer | null | 1 = best match for the name |
| resolution_status | string | null | matched or wine_only_fallback |
| scrapedAt | string | null | Scraped at (UTC) |
You pay for the events the actor reports, such as each result or page it produces. Platform usage is included in the event prices.
| Event | Charged when | Price |
|---|---|---|
| Wine | One wine saved with its ratings, prices and details (taste profile and reviews included). | $0.0035 |
Run this actor from your own code. Swap in your API token and the examples work as-is.
import { ScrapelyClient } from 'scrapely-client'
const client = new ScrapelyClient({ token: process.env.SCRAPELY_TOKEN })
// Start the actor and wait for the run to finish.
const run = await client.actor('shelfbright/vivino-scraper').call({
"wines": [
"Opus One 2019",
"Dom Pérignon",
"Penfolds Grange 2018",
"https://www.vivino.com/cloudy-bay-sauvignon-blanc/w/18978",
"https://www.vivino.com/chateau-margaux-premier-grand-cru-classe/w/1127795?year=2015"
],
"maxResults": 20,
"proxyConfiguration": {
"useScrapelyProxy": true,
"scrapelyProxyGroups": [
"DATACENTER"
]
}
})
// Read the dataset the run produced.
const { items } = await client.dataset(run.defaultDatasetId).listItems()
console.log(items)Tokens live in your account settings. Keep them server-side: a token carries the full permissions of your account.
Connect the Scrape.ly MCP server once and your agent can run this actor as a tool. Pick your tool:
Fetch scrape.ly/agents.md and run shelfbright/vivino-scraperPaste into Claude Code, Codex, Cursor or any AI agent. It signs you in once in the browser.
{
"mcpServers": {
"scrapely": {
"url": "https://api.scrape.ly/mcp?tools=actors,runs,storage,docs&actors=shelfbright/vivino-scraper"
}
}
}No key in the file: your client opens the browser to sign you in the first time it connects.
No examples yet
The developer hasn't published example inputs for this actor.
Scrape.ly gives you the infrastructure, the tooling, and the team to extract, process, and operationalize web data at any scale. Setup takes minutes. The advantage lasts forever.