Vivino Wine Scraper $1.2💰 Ratings, Prices, Reviews & Offers
Pricing
from $1.20 / 1,000 wine results
Vivino Wine Scraper $1.2💰 Ratings, Prices, Reviews & Offers
From $1.2/1K. Scrape Vivino.com for wine ratings, prices, taste profiles, food pairings, grapes, and reviews. Search by wine names or URLs, or discover wines by type, price, rating, country, and grape. Returns 50+ fields, including multi-merchant offers and value scores.
Pricing
from $1.20 / 1,000 wine results
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
1
Bookmarked
5
Total users
1
Monthly active users
14 days ago
Last modified
Categories
Share
Vivino Wine Data Scraper
Pull structured wine data from Vivino: ratings, prices, taste profiles, food pairings, grapes, value scores, and user reviews. Look up a list of wine names or paste Vivino URLs, or skip the list entirely and discover wines by type, price, rating, origin country, and grape, with full sorting. Fast, returns clean ready-to-use fields, and runs on any Apify plan.
Why this scraper
- Two ways to work: a mixed list of wine names and URLs (one record each), or a filter-and-sort discovery mode that walks the catalog with no list at all.
- 50+ fields per wine, including a full taste profile, multi-merchant price offers, and Vivino value and competitiveness scores.
- Real filters and real sort: wine type, minimum rating, price range, origin country, grape, sorted by rating, price, or popularity.
- Optional taste profile and user reviews per wine (reviews keep the language, reviewer alias, and tagged note).
- Market aware: choose the pricing country and currency, and echo a ship-to country on every record.
- Low cost and reliable: runs on every Apify plan, with automatic retries for large jobs.
- Resume & recurring updates: turn on Incremental mode to get only NEW, UPDATED, and REAPPEARED wines on every scheduled run, or resume one specific interrupted run with
resumeFromRunId.
Data you get
Sample shape, values are illustrative placeholders, not from a live listing.
| Field | Example |
|---|---|
| wineId | 1234567 |
| vintageId | 89012345 |
| name | Sample Winery Reserve Red 2019 |
| winery | Sample Winery |
| vintage | 2019 |
| wine_type | Red |
| region | Sample Region |
| country | France |
| country_code | fr |
| appellation | Sample Appellation |
| grape_varieties | ["Cabernet Sauvignon", "Merlot"] |
| average_rating | 4.3 |
| ratings_count | 1200 |
| wine_average_rating | 4.2 |
| wine_ratings_count | 25000 |
| price | 49.9 |
| currency | EUR |
| merchant_url | https://www.vivino.com/checkout/... |
| discount_percent | 10 |
| bottle_volume_ml | 750 |
| vfm_score | 4.1 |
| vfm_category | great |
| cmp_score | 3.8 |
| is_natural | false |
| image_url | https://images.vivino.com/thumbs/000000000_pb_x960.png |
| label_image_url | https://images.vivino.com/thumbs/000000000_pl_375x500.png |
| food_pairings | ["Beef", "Lamb", "Game"] |
| description | Style description text appears here. |
| taste_profile | { body, acidity, tannins, sweetness, fizziness, intensity, flavor_notes, flavor_groups } |
| reviews | [ { rating, note, language, user_name, created_at } ] |
| prices | [ { amount, currency, merchant_url, discount_percent } ] |
| vivino_url | https://www.vivino.com/sample-winery-reserve-red/w/1234567?year=2019 |
How to use
Look up wines by name (one record per wine you list):
{"mode": "lookup","wines": ["Opus One 2019", "Dom Pérignon", "Cloudy Bay Sauvignon Blanc"],"countryCode": "US","currencyCode": "USD"}
Look up wines by URL, with taste profile and reviews:
{"mode": "lookup","wines": ["https://www.vivino.com/cloudy-bay-sauvignon-blanc/w/18978","https://www.vivino.com/chateau-margaux-premier-grand-cru-classe/w/1127795?year=2015"],"includeTasteProfile": true,"includeReviews": true,"maxReviewsPerWine": 20}
Discover top-rated French reds between 50 and 150, sorted by rating (collects up to maxItems):
{"mode": "discovery","wineTypes": ["Red"],"originCountries": ["fr"],"minRating": 4,"priceMin": 50,"priceMax": 150,"sortBy": "rating_desc","countryCode": "US","currencyCode": "USD","maxItems": 50}
Input parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| mode | string | lookup | lookup: scrape the wines you list. discovery: find wines by filter + sort. |
| wines | array | sample | Lookup mode: mixed list of wine names and Vivino URLs (one record each). |
| searchMode | string | auto | Vintage handling for name lookups: auto, name_and_vintage, name_only. |
| matchingMode | string | basic | basic takes the top match; advanced also surfaces one alternative candidate. The alternative is a normal record: it counts toward maxItems, gets the same taste/reviews enrichment, and is billed the same as any other row. |
| wineTypes | array | [] | Discovery filter: Red, White, Sparkling, Rosé, Dessert, Fortified. |
| minRating | integer | (none) | Discovery filter: minimum Vivino average rating (1 to 4.5). |
| priceMin / priceMax | integer | (none) | Discovery price range in the selected currency. |
| originCountries | array | [] | Discovery filter by wine origin (ISO alpha-2 codes, e.g. fr, it, us). |
| grapes | array | [] | Discovery filter by Vivino grape IDs. |
| sortBy | string | relevance | relevance, rating_desc, rating_asc, price_asc, price_desc, popularity. |
| includeTasteProfile | boolean | true | Fetch body, acidity, tannins, sweetness, fizziness, intensity, flavor notes. |
| includeReviews | boolean | false | Fetch user reviews per wine. |
| maxReviewsPerWine | integer | 10 | Maximum reviews per wine (1 to 100). |
| countryCode | string | FR | Market country for pricing (ISO alpha-2). |
| currencyCode | string | EUR | Currency for prices (ISO 4217). |
| shipTo | string | (none) | Optional ship-to country, echoed on each record. |
| maxItems | integer | 20 | The only cap on records. Set 0 for unlimited. |
| maxPages | integer | (none) | Discovery mode only: optional bound on pages walked. Leave empty to walk every result page; the run still stops at Max wines. |
| proxy | object | Apify Proxy | Proxy settings. Works on all plans; Residential is recommended for large runs. |
| resumeFromRunId | string | (none) | Continue one specific previous run/dataset: wines already collected there are skipped, so this run only appends new ones. For recurring daily monitoring of the same wine list or filters, use Incremental mode instead, see "Resume & recurring updates" below. |
| incrementalMode | boolean | false | Daily/recurring monitoring of the same wine list or discovery filters. First run returns everything as NEW; later runs return only NEW/UPDATED/REAPPEARED by default. See "Resume & recurring updates" below. |
| stateKey | string | (none) | Optional name for a monitoring campaign, so its incremental state stays stable or is deliberately shared. Auto-derived from your wine list / discovery filters and enrichment settings when left empty. |
| emitUnchanged | boolean | false | Incremental mode only. Also return wines unchanged since the last run, marked UNCHANGED. Adds and bills extra rows you already have. |
| emitExpired | boolean | false | Incremental mode only. Also return wines from a previous run no longer found, marked EXPIRED, once a run has fully scanned the tracked wines/filters (not capped, not a resume). Adds and bills extra synthetic rows. |
Resume & recurring updates
There are two different things here, pick the one that matches what you're doing:
| Need | Use |
|---|---|
| A run stopped and should continue | resumeFromRunId (or the automatic same-run checkpoint, no input needed) |
| Run the same wine list or discovery filters every day and receive only changes | incrementalMode |
| Keep separate daily campaigns for similar searches | distinct stateKey values |
| Run a normal full snapshot | leave both off |
Resume (resumeFromRunId) continues one specific interrupted or previous large run: paste a run ID or dataset ID and this run skips wines already collected there, returning only the remaining new ones. An automatic same-run checkpoint also protects against platform migrations/Resurrects without any input needed.
Incremental mode (incrementalMode) is for a schedule, for example daily: the actor remembers the previous run of the same wine list or discovery filters by itself, so you never paste a run ID. The first run returns everything as NEW. Later runs return only NEW, UPDATED, and REAPPEARED wines by default, unchanged wines are suppressed (and not charged). Turn on emitUnchanged or emitExpired only when you also want those rows returned (and billed for). State is isolated per wine list / discovery filter and enrichment setup automatically; set stateKey to name or deliberately share a monitoring campaign.
Every record returned in incremental mode also carries:
| Field | Description |
|---|---|
| changeType | NEW, UPDATED, UNCHANGED, REAPPEARED, or EXPIRED |
| changedFields | Top-level fields that changed since last seen; non-empty only for UPDATED |
| firstSeenAt | When this wine was first observed by this monitoring campaign |
| lastSeenAt | When this wine was last observed |
Scheduled-run example, same wine list, run daily:
Day 1 (first run ever for this list):
{ "mode": "lookup", "wines": ["Opus One 2019"], "incrementalMode": true }
Every wine comes back with "changeType": "NEW".
Day 2 (the schedule fires again, identical input):
{ "mode": "lookup", "wines": ["Opus One 2019"], "incrementalMode": true }
A wine whose price/rating/availability changed comes back as "changeType": "UPDATED" with changedFields listing what changed; a wine that vanished and came back comes back as "changeType": "REAPPEARED"; a wine that is still there, unchanged, is not returned at all (suppressed, not charged) unless emitUnchanged is on.
Read this before you schedule a discovery run: Vivino's answers vary per request
Vivino tailors what it returns to where the request appears to come from, and that location is not guaranteed to be identical from one run to the next. Two things follow, and both were measured on this actor with three back to back identical runs of a maxItems: 3 US/USD red wine discovery walk, minutes apart:
- The discovery result set itself moves. The three runs returned three different sets of wines. Only one wine out of three appeared in all three runs.
- A wine that does appear twice can come back as a different vintage from a different merchant. That one repeated wine was reported
UPDATEDon runs 2 and 3, withchangedFieldslistingaverage_rating,cmp_score,cmp_tier,discounted_from,merchant_url,name,price,prices,ratings_count,vintageandvintageId. On run 3 it flipped straight back to the vintage and the price it had on run 1.
So a scheduled discovery run reports a substantial share of NEW and UPDATED rows every time, and those rows are returned and billed. That is variance in what Vivino serves, not a fault in change detection: the actor is correctly reporting that the record it just received is not the record it stored.
Nothing is excluded from change detection except scrapedAt. Excluding the price fields was considered and measured to be ineffective: on the repeated wine above, vintage, vintageId, name, average_rating and ratings_count moved too, so dropping price, prices and merchant_url from the comparison would still have produced UPDATED, while permanently hiding the real price drops that are the main reason to monitor a wine on a schedule.
For stable, low noise scheduled monitoring:
- Prefer lookup mode over discovery mode. Give an explicit wine list, and ideally paste Vivino URLs carrying a
?year=, which pins the vintage. A pinned vintage removes the wholevintage/vintageId/name/average_rating/ratings_countchurn above. A separate measurement of one wine in lookup mode two minutes apart moved onlyprice,pricesandmerchant_url. - Set
countryCodeandcurrencyCodeexplicitly and keep them identical on every run of a campaign, so every run asks for the same market. - Run on Apify Residential proxy with the proxy country pinned to that same
countryCode, so exits stay inside one market instead of moving between markets. - Read
changedFieldsbefore acting on a row. A row whosechangedFieldsnamesvintage,vintageIdornameis a different vintage of the same wine, not a change to the wine you were watching. A row that names onlyprice,prices,merchant_urland the offer fields derived from them (currency,discounted_from,discount_percent,is_on_sale,discount_amount,bottle_volume_ml,vfm_score,vfm_category,cmp_score,cmp_tier) was most likely quoted by a different merchant rather than repriced. - Leave
emitUnchangedoff (the default), so wines that genuinely did not move are neither returned nor billed.
Send results into your apps (MCP connectors)
Optionally pipe each record into the apps you already use through Model Context Protocol (MCP) connectors. Authorize a connector under Apify, Settings, API & Integrations, then select it in the input. For Notion, also set the parent page URL. The connector receives a condensed, human-readable summary per wine (a title plus key fields as plain text), not the full JSON; the complete record always stays in the Apify dataset. Leave the connectors field empty to skip this entirely; it never changes the dataset output.
Output example
Sample shape, values are illustrative placeholders, not from a live listing.
{"wineId": 1234567,"vintageId": 89012345,"name": "Sample Winery Reserve Red 2019","winery": "Sample Winery","vintage": 2019,"wine_type": "Red","region": "Sample Region","country": "France","country_code": "fr","grape_varieties": ["Cabernet Sauvignon", "Merlot"],"average_rating": 4.3,"ratings_count": 1200,"price": 49.9,"currency": "EUR","vfm_category": "great","is_natural": false,"food_pairings": ["Beef", "Lamb"],"taste_profile": {"body": 5,"acidity": 3.1,"tannins": 3.8,"sweetness": 1.6,"fizziness": null,"intensity": 3.7,"flavor_notes": ["black fruit", "oak", "leather"]},"reviews": [{ "rating": 4.5, "note": "Sample review text.", "language": "en", "user_name": "reviewer", "created_at": "2026-01-01T00:00:00.000Z" }],"vivino_url": "https://www.vivino.com/sample-winery-reserve-red/w/1234567?year=2019","scrapedAt": "2026-01-01T00:00:00.000Z","inputSource": "search"}
Plan requirement
The actor runs on every Apify plan, including Free. For large jobs, the Residential proxy option gives the most consistent results; it is included on the Apify Starter plan and above. Select it in the proxy input when you need maximum reliability.