Vivino Wine Data Scraper: ratings, prices & taste profiles avatar

Vivino Wine Data Scraper: ratings, prices & taste profiles

Pricing

from $2.00 / 1,000 wine result extracteds

Go to Apify Store
Vivino Wine Data Scraper: ratings, prices & taste profiles

Vivino Wine Data Scraper: ratings, prices & taste profiles

Extract wine ratings, prices, taste profiles, reviews, and grape varieties from Vivino. Search by wine name or URL. Fast HTTP-only approach with no browser needed. Export JSON, CSV, or Excel.

Pricing

from $2.00 / 1,000 wine result extracteds

Rating

4.9

(7)

Developer

MrBridge

MrBridge

Maintained by Community

Actor stats

2

Bookmarked

154

Total users

34

Monthly active users

a day ago

Last modified

Share

What does Vivino Wine Data Scraper do?

Vivino Wine Data Scraper is an Apify Actor that extracts structured wine data from Vivino, the world's largest wine marketplace with 60M+ users. Provide a mix of wine names and Vivino URLs; the scraper auto-detects each entry and returns ratings, prices, taste profiles, reviews, and full wine details in JSON or CSV.

No browser, no Vivino account, no API key, no rate limits.

Key capabilities:

  • Mixed input, auto-routed: paste wine names (with or without vintage) and Vivino URLs in any combination
  • Taste profiles: body, acidity, tannins, sweetness, fizziness, flavor notes, food pairings
  • User reviews: up to 100 per wine with ratings, comments, and dates
  • Market-specific pricing: pick a shipping destination and currency for local prices and wine availability
  • Streaming + dedup: up to 250 wines per run, no duplicates across URLs and names
  • Pay-per-event: pay per result returned in the dataset (~$0.003 each), not compute time

Which Vivino scraper should I use?

NeedBest scraperWhat it does
Look up specific wines by name or URLVivino Wine Data Scraper (this one)Search by name or paste Vivino URLs; returns ratings, prices, taste profiles, and reviews
Browse wines by region (all wines from Bordeaux, Italy, and more)Vivino Wine ScraperBrowse and extract all wines from a region or category on Vivino

In short: use this Actor when you know which wines you want. Use the Vivino Wine Scraper when you want to discover wines in a region.

Why scrape Vivino?

Vivino has over 60 million users and 12+ million wines cataloged. Common uses:

  • Wine merchants and retailers: monitor pricing across markets, compare ratings, watch what competitors stock
  • Sommeliers and buyers: pick wines for the list based on community ratings and taste profiles
  • Market researchers: analyze trends in wine ratings, pricing, and consumer preferences by region
  • Wine collectors: track ratings and prices for wines in your cellar or wishlist
  • E-commerce platforms: enrich product catalogs with Vivino ratings, taste profiles, and images
  • Data journalists: build visualizations and stories on top of a 12M-wine dataset

What data does this scraper extract?

Data PointDescriptionAlways included
Wine nameFull name as listed on VivinoYes
Winery / ProducerProducer nameYes
Vintage yearHarvest yearYes
Wine typeRed, White, Rosé, Sparkling, Dessert, FortifiedYes
Region & CountryWine region and country of originYes
Grape varietiesList of grape varietalsYes
Average ratingVivino community rating (1-5)Yes
Ratings countNumber of ratings on VivinoYes
PricePrice in your selected currencyWhen available*
Vivino URLDirect link to the wine pageYes
ImageWine bottle image URLWhen available*
Food pairingsRecommended food pairings (Beef, Lamb, Pasta)Yes
DescriptionWine description textYes
Alcohol contentABV percentageWhen available*
Taste profileBody, acidity, tannins, sweetness, fizziness, flavor notesOptional (on by default)
User reviewsRating, comment, date, usernameOptional (off by default)

*Price depends on market availability for your Ship To country; alcohol and image availability vary by extraction path (name searches resolved via Vivino's catalog API may lack alcohol). Missing values are null.

How to use Vivino Wine Data Scraper

  1. Open Vivino Wine Data Scraper on Apify (a free account is needed only at run time).
  2. In the Wines field, paste a mix of wine names and Vivino URLs (one per line). The scraper auto-detects each entry.
  3. Optionally adjust localization (Country Code, Currency Code, Ship To Country) for market-specific prices.
  4. Click Start. Download results from the Dataset tab in JSON, CSV, Excel, or XML.

Matching modes: Basic vs Advanced

When you search by wine name, the Actor matches your text to Vivino's catalog. The matchingMode setting controls how hard it works:

  • Basic (default) — fast and predictable. Use it when your wine names already read like Vivino: full producer name, correct spelling, optional vintage. Examples: Domaine Leflaive Puligny-Montrachet 2022, Opus One 2019. A clean catalogue export usually falls here. About 6 seconds per wine.
  • Advanced — runs the full fallback cascade for names that differ from Vivino: last-name/first-name order (Bachelet Jean Claude), an omitted & Fils, abbreviations, or a cuvée stated without its appellation. It tries extra winery-slug variants, parses producer pages, and re-searches with shortened queries to recover micro-domaine wines that Basic misses. This costs time — about 15-25 seconds per wine on hard names — so reach for it when a Basic run leaves too many NAME_SEARCH_ERROR rows.

Both modes share the same matching gates, so neither bills a wrong cuvée: an unresolved name becomes an unbilled error row, never a mismatched (billed) wine. Direct Vivino URLs ignore this setting — they always resolve to exactly one wine.

Why a run is capped at 250 wines

Each run accepts at most 250 wines. The reason is Advanced throughput: at 15-25 seconds per hard name, ~250 wines fills roughly half of the 3-hour run timeout, leaving comfortable margin to finish. A single 670-wine Advanced run, by contrast, runs into the timeout and processes only part of the list.

Memory is not the constraint — the Actor streams one wine at a time, so peak memory stays around 350-390 MB whatever the list size (the 1024 MB default leaves wide headroom). The cap is purely about finishing within the timeout.

For larger catalogues, split into batches of ≤250 wines and run them in parallel — via the API, one Task per batch, or scheduled runs. Parallel batches finish far sooner than one long sequential run and keep Vivino rate-limiting low.

Input parameters

ParameterTypeDefaultDescription
winesarraysampleMixed list of Vivino URLs and wine names, max 250 per run. Auto-detected per entry.
searchModestringautoVintage handling: auto, name_and_vintage, name_only
matchingModestringbasicName-matching effort: basic (fast; names match Vivino) or advanced (full cascade for messy or divergent names). See Matching modes.
includeTasteProfilebooleantrueFetch taste profile (body, acidity, tannins, sweetness, fizziness, flavor notes)
includeReviewsbooleanfalseFetch user reviews (increases cost)
maxReviewsPerWineinteger10Maximum reviews per wine (1-100)
shipTostring--Shipping destination country (ISO 3166-1 alpha-2). Controls wine visibility per market. Example: ES, US, FR
countryCodestringFRCountry for pricing and wine-origin filtering (ISO 3166-1 alpha-2)
currencyCodestringEURCurrency for prices (ISO 4217)

Example input

{
"wines": [
"Château Margaux 2015",
"https://www.vivino.com/cloudy-bay-sauvignon-blanc/w/18978",
"Opus One",
"Penfolds Grange 2018",
"Dom Pérignon"
],
"includeTasteProfile": true,
"includeReviews": false,
"shipTo": "FR",
"countryCode": "FR",
"currencyCode": "EUR"
}

Output format

Each wine produces one dataset item. The structure:

{
"wineId": 13548,
"vintageId": 167890,
"vivino_url": "https://www.vivino.com/chateau-margaux-margaux/w/13548?year=2015",
"name": "Chateau Margaux Margaux",
"winery": "Chateau Margaux",
"vintage": 2015,
"wine_type": "Red",
"region": "Margaux",
"country": "France",
"appellation": "French Margaux",
"grape_varieties": ["Cabernet Sauvignon", "Merlot"],
"average_rating": 4.2,
"ratings_count": 12345,
"price": 450.0,
"currency": "EUR",
"taste_profile": {
"body": 4.2,
"acidity": 3.8,
"tannins": 4.5,
"sweetness": 1.1,
"fizziness": null,
"flavor_notes": ["black fruit", "oak", "spices", "earth", "tobacco"]
},
"reviews": [
{
"rating": 4.5,
"note": "Excellent wine with deep fruit flavors and a long finish.",
"created_at": "2024-03-15T10:30:00.000Z",
"user_name": "WineLover42",
"vintage_year": 2015
}
],
"image_url": "https://images.vivino.com/thumbs/chateau-margaux_375x500.png",
"scrapedAt": "2026-03-03T12:00:00.000Z",
"inputSource": "url",
"searchQuery": null,
"shipTo": null
}

taste_profile is omitted when includeTasteProfile: false. reviews is omitted when includeReviews: false. inputSource is "url" or "search".

Error rows

Inputs that fail to resolve to a wine (no Vivino match, too-short query, URL parse error) still produce a dataset row so every billed event is traceable. Error rows carry two additional fields:

{
"searchQuery": "Nonexistent Wine 9999",
"inputSource": "search",
"name": "Unknown",
"winery": "Unknown",
"error": "NAME_SEARCH_ERROR",
"errorMessage": "No match found for \"Nonexistent Wine 9999\"",
"scrapedAt": "2026-03-03T12:00:00.000Z"
}

error is one of URL_PROCESSING_ERROR (URL could not be parsed or page fetch failed) or NAME_SEARCH_ERROR (no Vivino match, too-short query, or empty result). Dataset views include a dedicated "Errors" tab for filtering. Error rows are never billed.

Alternative candidates on uncertain matches

When a wine name search is uncertain — the best match scored low, or the runner-up is almost as good a fit — the Actor also delivers one or two alternative candidates (other cuvées from the same producer) so you can pick the right one. These extra rows:

  • are fully enriched (taste profile and reviews follow the same includeTasteProfile / includeReviews settings as the primary row);
  • carry "isAlternative": true and share the primary row's searchQuery;
  • expose a matchScore (higher = more confident) on every name-search row, so you can rank the primary against its alternatives;
  • are never billed — you pay only for the single primary result per input.
{ "searchQuery": "Domaine Leflaive Puligny Montrachet", "name": "Puligny-Montrachet Clavoillon", "matchScore": 4.34, "isAlternative": false }
{ "searchQuery": "Domaine Leflaive Puligny Montrachet", "name": "Puligny-Montrachet Les Pucelles", "matchScore": 4.34, "isAlternative": true }

Confident matches (a clear best result) produce no alternatives. Alternatives apply to name searches only — direct Vivino URL inputs always resolve to exactly one wine.

Diagnostic _strategy field

Every row carries an optional _strategy string indicating which code path produced it:

ValueMeaning
urlURL input, direct fetch of /seo/w/{id} HTML
s1Strategy 1: winery slug → winery ID → explore by winery
winery-entriesStrategy 1.5: explore-by-winery empty → matched against the winery page's own wine list (micro-producers)
s2-discovered-slugStrategy 2.1: search page surfaced a better winery slug, retried Strategy 1
s2-entriesStrategy 2.2: search page wine entries, per-entry HTML fetch
s2-shortenedStrategy 2.3: shortened-query retry (Vivino search ranker buried the wine under sibling cuvees)
errorError row (see Error rows above)

Safe to ignore in client integrations. Useful for debugging matching anomalies.

Run summary in Key-Value Store

Every run writes a JSON summary to the default Key-Value Store under the key last-run-summary:

{
"startedAt": "2026-03-03T12:00:00.000Z",
"finishedAt": "2026-03-03T12:02:34.000Z",
"durationMs": 154000,
"input": { "count": 10, "urlCount": 2, "nameCount": 8, "searchMode": "auto", "matchingMode": "basic", "shipTo": "FR" },
"output": { "processed": 10, "strategies": { "s1": 4, "s2-entries": 4, "url": 2 } },
"cache": { "hits": 6, "misses": 14 },
"resilience": { "rateLimit429Trips": 0, "strategy2Fallbacks": 4, "chargeFailures": 0, "chargeLimitReached": false }
}

Useful for offline drift detection and capacity planning.

How much does scraping Vivino cost?

TierCostWhat you get
Per result~$0.003/winePay only for extracted data, not compute time
Free tier$5 free credits/month~1,600 wines per month
Starter plan$29/month~9,600 wines per month

This Actor uses pay-per-event pricing: no startup fee, and you pay only per result returned in the dataset (one wine = one event). Start with $5 free credits.

WinesCost
100~$0.30
500~$1.50
1,000~$3.00
10,000~$30.00

Estimates based on event pricing only. Actual costs may include minimal platform compute fees. The free $5 credit covers both.

What is not charged: error rows (no match, bad URL, too-short query) and any alternative candidates surfaced on uncertain matches (see Output format). You pay for one primary result per input, nothing else. You can also cap spend per run with ACTOR_MAX_TOTAL_CHARGE_USD in the Apify Console.

Memory recommendation: leave the 1024 MB default. The Actor streams one wine at a time, so peak memory stays around 350-390 MB whatever the list size — the default covers every run, including Advanced matching, with wide headroom. There is no need to raise it.

Cap your run cost: set the ACTOR_MAX_TOTAL_CHARGE_USD environment variable in the Run options to enforce a hard ceiling per run. The Actor stops gracefully (graceful exit, dataset preserved) as soon as the cap is reached.

Tips & troubleshooting

  • Include vintage years in wine names for precise matching (Chateau Margaux 2015 rather than Chateau Margaux).
  • Start without reviews to minimize cost. Add them later if needed.
  • Use Ship To Country for market-specific wine availability (ES for Spain-only listings). Use Country Code for pricing currency.
  • For large catalogues: split into batches of ≤250 wines (the per-run cap) and run them in parallel — far faster than one long run, and gentler on Vivino's rate limiting.
  • Use Advanced matching when a Basic run leaves many NAME_SEARCH_ERROR rows (messy or last-name-first producer names); keep Basic for clean lists to stay fast.

Common issues

  • "No results found" for a wine name: check for typos, try with or without the vintage year, or set searchMode: "name_only" to ignore vintage filtering. Very niche or new wines may not be in Vivino.
  • Empty price field: prices depend on countryCode and shipTo; not all wines have prices in every market. Try the wine's country of origin (IT for Italian wines).
  • Wrong wine returned for a name search: include the full producer name (Chateau Margaux Margaux rather than Margaux) and the vintage year.
  • Run timed out on a large list: a run accepts up to 250 wines; split larger catalogues into ≤250-wine batches and run them in parallel.
  • Rate-limited: split large volumes into smaller batches across parallel or scheduled runs.

Integrate into your workflow

Send results to Google Sheets, Airtable, your database, or your own API.

API integration

Call this Actor programmatically using the Apify API. Get your API token from Settings → Integrations.

cURL:

curl "https://api.apify.com/v2/acts/mrbridge~vivino-wine-data-scraper/run-sync-get-dataset-items" \
-X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_APIFY_TOKEN" \
-d '{
"wines": ["Chateau Margaux 2015", "Opus One 2019"],
"includeTasteProfile": true
}'

Node.js:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('mrbridge/vivino-wine-data-scraper').call({
wines: ['Chateau Margaux 2015', 'Opus One 2019'],
includeTasteProfile: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Python:

from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("mrbridge/vivino-wine-data-scraper").call(run_input={
"wines": ["Chateau Margaux 2015", "Opus One 2019"],
"includeTasteProfile": True,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(f"{item['name']} - {item['average_rating']}★ - {item['price']} {item['currency']}")

Export formats, schedules, webhooks

  • Export formats: append ?format=json|csv|xlsx|xml to the dataset URL. Filter columns with ?fields=name,average_rating,price,currency or exclude them with ?omit=reviews,image_url.
  • Scheduled runs: create a Task with your saved input, then in the Schedules tab set a cron expression (e.g. 0 8 * * 1 for every Monday at 8 AM UTC). Ideal for weekly price tracking.
  • Webhooks: set up an endpoint in the Integrations tab on event "Run succeeded" to receive datasetId and run metadata; no polling.

No-code integrations

PlatformWhat it does
Google SheetsExport wine data to a sheet automatically
AirtableSync wines to a base with field mapping
ZapierTrigger Zaps on run completion → push to 5,000+ apps
MakeVisual workflows: scrape → transform → insert into DB
n8nSelf-hosted workflow automation with the Apify trigger node

Setup for each: see the Apify Integrations docs. Actor ID for run-actor steps: qRSfN5MBLbaEbSU6n.

FAQ

Does Vivino have an official API? No, Vivino does not provide a public API. This scraper uses Vivino's internal endpoints to extract data.

How fast is the scraper? Throughput depends on enrichment and matching mode. By URL or with Basic matching and taste profiles only, expect ~30-50 wines per minute. With reviews and shipTo both enabled (extra HTTP fetches per wine and a dual-search), throughput drops to ~5-10 wines per minute. Advanced matching adds fallback fetches on hard names, so it runs at roughly 15-25 seconds per wine. Vivino's own rate limiting can slow large batches; the scraper handles this automatically with retries and cooldowns.

Can I scrape large volumes? Yes. Deduplication is automatic within a run. Each run accepts up to 250 wines; for larger catalogues, split into ≤250-wine batches and run them in parallel or on a schedule.

What if a wine is not found? The scraper logs a warning and continues with the next wine. Check for typos or try with or without the vintage year.

Can I use this scraper via MCP? Yes, through the standard Apify MCP integration. Add mrbridge/vivino-wine-data-scraper to your MCP client config (Claude Desktop, Cursor, and more) and call the scraper with a JSON input. The Actor doesn't expose its own MCP server endpoint; it works as a tool inside Apify's catalog-wide MCP server.

What regions and countries are supported? All wines on Vivino are supported worldwide. Use the Country Code setting (e.g. FR, US, GB, DE, IT) to get prices in your local market.

Is my data stored? Results stay in your Apify dataset for 31 days (default retention), fully under your control. No wine data is shared with third parties, no Vivino account or personal data is involved, and requests are stateless and GDPR-compliant.

Web scraping of publicly available data is generally considered legal, as confirmed by the 2022 US Ninth Circuit ruling in hiQ Labs v. LinkedIn. This scraper only accesses pages any visitor can see on Vivino.com without logging in, and never extracts private user data, direct messages, or paid features.

Review Apify's web scraping legality guide and ensure your specific use case complies with Vivino's Terms of Service and applicable laws (GDPR in the EU, particularly if you store review text from identifiable users).

Provided as-is for personal and commercial use; usage must comply with Vivino's Terms of Service. Not affiliated with or endorsed by Vivino.

Your feedback

We're always working on improving the performance of this Actor. If you have technical feedback for Vivino Wine Data Scraper or simply found a bug, please create an issue on the Actor's Issues tab on Apify Console.

For faster support on matching problems: include your run ID in the issue, and consider enabling Settings → Login & Privacy → Share run data with developers in your Apify account — it lets the maintainer open your run directly (input, log, results) and diagnose a wrong or missing match in minutes instead of guesswork. You can turn the setting off again at any time.

More free wine-data tools and studies at mr-bridge.com.

Related Actors: Vivino Wine Scraper (browse wines by region), Millesima Wine Scraper (wine prices and critic ratings), Wine-Searcher Scraper from List (popularity, critic scores, prices from Wine-Searcher).