Viator Scraper icon

Viator Scraper

Collect Viator.com tour and activity results from destinations, categories, search pages, or pasted URLs. Returns product codes, prices, ratings,…

Start using this actor on Apify ↗Need a custom scraper?Contact us ↗

Viator Scraper at a glance

Viator Scraper is a ready-to-run Apify actor from abotapi for collecting travel data. Its documented output includes name, product code, url, price and currency, which you can export as JSON, CSV or Excel or read through the Apify API. It costs $2.60 per 1,000 results on the Apify Free plan and from $1.50 on paid plans, with smaller per-run or optional feature charges listed on Apify.

Runs on
Apify cloud: console, API, schedules and integrations
Data type
Travel, Automation, Ecommerce
Pricing
$2.60 per 1,000 results (Free plan), from $1.50 on paid plans
Output
Documented below · JSON, CSV, Excel
Inputs
26 options

Collect Viator.com tour and activity results from destinations, categories, search pages, or pasted URLs. Returns product codes, prices, ratings, reviews, images, availability, source context, and optional detail fields.

What Viator Scraper can do

  • Two ways to find data. Pick a destination and category preset (7 destinations, 6 categories), or type any destination name, or paste Viator destination, category or product URLs directly. No need to build URLs by hand.
  • Filters and sort work everywhere. Keyword, price range, currency, minimum rating, minimum reviews and availability all narrow and reorder results in both search mode and URL mode, including a pasted URL's results.
  • Optional detail enrichment. Turn on Fetch details to open each product's own page for its full description, complete image list, up to Max reviews per product reviews (newest first across all sources, with language, title, helpful votes, photos and owner responses where present) and itinerary stops. Rows are still saved when a product page can't be opened.
  • Nothing lost on a failed run. Every matching row is written to the dataset as soon as it's found, so a run that stops partway through still keeps what it already collected.
  • Deduplicated pagination. Listing pages are walked until Max items is reached or a page repeats an earlier page's results, and the same product is never saved twice.
  • Cost control built in. Max items and Max pages cap a run before it starts, and detail enrichment is billed only for the product pages that are successfully enriched.

Choose what to collect

These inputs let you configure Viator Scraper – Tours, Activities, Prices & Availability. Open the actor on Apify to enter your values and review the current options.

Supported input fields
InputWhat it controls
modestring · requiredChoose destination/category search or URL list mode.

Choices: search, url

maxItemsinteger · requiredMaximum matching rows to save. Fewer rows can be returned when the selected source and filters match fewer live records.
destinationstringSearch mode destination preset. It selects the Viator listing page that search mode walks, so it applies in search mode only and is ignored in URL mode.

Choices: boston, new_york, las_vegas, london, paris, rome, sydney

destinationQuerystringOptional. Type a destination name (for example Lisbon) instead of using the list above. The name is looked up on Viator and used only when it resolves to a destination page with a matching name; otherwise the run stops with a clear message. Leave empty to use the destination list. Search mode only; ignored in URL mode. Category still applies.
categorystringSearch mode category preset. It selects the Viator listing page that search mode walks, so it applies in search mode only and is ignored in URL mode.

Choices: tours_sightseeing, bus_tours, day_trips, walking_tours, food_drink, attractions_tickets

urlsarrayViator destination page, category listing, or single product URLs (a product URL returns one row for that exact product, with description, images, reviews and itinerary only when Fetch details is on). A search-results link works only when Viator redirects it to a destination page; free-text activity searches are not supported. Used only in URL mode; left untouched it scrapes one example of each supported shape. The filter and sort fields in the next section still apply to every row a pasted URL returns.
keywordstringOptional keyword that must appear in the activity name, URL, destination, or category text. Leave empty to keep all results. Applies in both search mode and URL mode, including a pasted listing URL.
Show 19 more inputs
More input fields
InputWhat it controls
minPricenumberMinimum listed price. Leave empty for no minimum. Applies in both search mode and URL mode, including a pasted listing URL.
maxPricenumberMaximum listed price. Leave empty for no maximum. Applies in both search mode and URL mode, including a pasted listing URL.
currencystringKeep only rows with this currency, or Any to keep all returned currencies. Applies in both search mode and URL mode, including a pasted listing URL.

Choices: , USD, AUD, EUR, GBP, CAD, NZD, SGD

minRatingnumberMinimum aggregate rating. Applies in both search mode and URL mode, including a pasted listing URL.
minReviewsintegerMinimum review count. Applies in both search mode and URL mode, including a pasted listing URL.
availabilitystringFilter by availability value. Applies in both search mode and URL mode, including a pasted listing URL.

Choices: , InStock

sortBystringChoose the result order: price, rating, review count, or original source order. Applies in both search mode and URL mode, including a pasted listing URL. A price, rating or review-count sort is applied across all crawled pages: the run keeps crawling until it holds Max items matching rows (or reaches Max pages or the end of the results), then sorts them together. Source order saves each page as it is read.

Choices: source, price_asc, price_desc, rating_desc, reviews_desc

fetchDetailsbooleanTry product pages for additional fields when available. Results are still saved if detail pages are unavailable.
maxReviewsPerProductintegerMost reviews to keep per product when Fetch details is on (newest first across all sources, each with its language). If the full review list cannot be read, up to 30 reviews from the product page are kept instead.
maxPagesintegerNo page limit when set to 0. The run stops at Max items, or earlier if the results end.
resumeFromRunIdstringOptional. ID of a previous run of this actor (or a dataset ID). Products already in that dataset are skipped, so this run returns only products it did not have. Combine both datasets for the full set. For recurring monitoring of the same search, use Incremental mode below.
incrementalModebooleanTurn on for daily or recurring monitoring. The first run returns every matching product as NEW. Later runs return only NEW, UPDATED and REAPPEARED products; each row gets changeType, changedFields, firstSeenAt and lastSeenAt. A product is UPDATED when a real field changes (price, rating, review count, name and similar); scrapedAt, the listing rank (position) and the review bodies never count as changes (review count and rating do). Prices are shown in the local currency of the connection used, so a run that lands on a different country can read as UPDATED on offerPrice and offerCurrency; pick a Currency filter or add those two fields to the ignore list below if that is not wanted. State is kept separately for each mode, destination, category, URL set and filter setup; use State key to name or deliberately share a campaign. Unchanged and expired rows are only returned (and billed as result rows) when you turn those options on.
stateKeystringOptional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently configured runs. Leave empty to derive a key from the mode, destination, category, URLs and filters, so different searches never mix state.
emitUnchangedbooleanOff by default. Turn on to also return products that did not change since the last run, marked UNCHANGED. This returns and bills extra rows you already have.
emitExpiredbooleanOff by default. Turn on to also return products that were seen in an earlier run but are no longer found, marked EXPIRED. Only produced when the run scanned every source to a confirmed end of results: not when Max items or Max pages cut it short, and not when Resume was used. This returns and bills extra rows.
ignoreFieldsForChangesarrayOutput field names that should NOT make a product count as UPDATED, for example image or locationName. Use a dotted path to ignore a field inside a nested object. Ignored fields are still returned in the output.
mcpConnectorsarrayOptionally send the scraped tours into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify → Settings → Integrations, then select it here. The connector receives a condensed, human-readable summary per tour (name + key fields), not the full JSON. The complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com).
notionParentPageUrlstringURL (or id) of the Notion page under which tour pages are created. Required to enable the Notion export; ignored by other connectors.
maxNotifyListingsintegerCap on items written to each connector per run. Does not affect the dataset.

Fields in the output

The documented dataset includes the fields below. Availability can depend on the source page and selected mode.

nameName (text)
productCodeProduct code (text)
urlURL (link)
offerPricePrice (number)
offerCurrencyCurrency (text)
ratingValueRating (number)
reviewCountReviews (number)
locationNameLocation (text)
imageImage (image)
detailStatusDetail status (text)
descriptionDescription (text)
imagesImages (array)
Show 20 more fields
itineraryStopCountItinerary stops (number)
itineraryStopsItinerary (array)
breadcrumbsBreadcrumbs (array)
addressLocalityCity (text)
addressCountryNameCountry (text)
priceValidUntilPrice valid until (text)
availabilityAvailability (text)
detailErrorDetail error (text)
reviews.author_nameAuthor (text)
reviews.ratingRating (number)
reviews.review_dateDate (text)
reviews.titleTitle (text)
reviews.textReview (text)
reviews.helpful_votesHelpful votes (number)
reviews.owner_responseOwner response (text)
reviews.sourceSource (text)
changeTypeChange (text)
changedFieldsChanged fields (array)
firstSeenAtFirst seen (date)
lastSeenAtLast seen (date)

Example output

An example from this actor’s documentation. Values are illustrative; this is not a fresh live result.

{
  "name": "Boston Hop-On Hop-Off Trolley Tour",
  "productCode": "5892HOHO",
  "url": "https://www.viator.com/tours/Boston/Old-Town-Trolley-Tour/d678-5892HOHO",
  "image": "https://media.viator.com/sample-image-1.jpg",
  "locationName": "Boston",
  "addressLocality": "Boston",
  "addressCountryName": "United States",
  "offerPrice": 42.5,
  "offerCurrency": "USD",
  "availability": "InStock",
  "priceValidUntil": "2027-01-01",
  "ratingValue": 4.6,
  "exactRating": 4.6,
  "bestRating": 5,
  "worstRating": 1,
  "reviewCount": 1280,
  "description": "Hop on and off a narrated trolley at stops around Boston's historic sites.",
  "images": [
    "https://media.viator.com/sample-image-1.jpg",
    "https://media.viator.com/sample-image-2.jpg"
  ],
  "reviews": [
    {
      "author": "Sample Traveler",
      "rating": 5,
      "date": "2025-06-01",
      "text": "Great way to see the city.",
      "language": "en",
      "source": "VIATOR"
    }
  ],
  "itineraryStopCount": 3,
  "itineraryStops": [
    "Faneuil Hall",
    "Boston Common",
    "North End"
  ],
  "position": 3,
  "sourceUrl": "https://www.viator.com/Boston-tours/Bus-and-Minivan-Tours/d678-g12-c98",
  "sourcePage": 1,
  "sourceName": "Boston Bus and Minivan Tours",
  "sourceDescription": "Bus and minivan tours in Boston.",
  "breadcrumbs": [
    "Home",
    "Things to do in United States",
    "Boston",
    "Bus and Minivan Tours"
  ],
  "detailStatus": "enriched",
  "scrapedAt": "2026-09-28T12:00:00.000000+00:00"
}

Ways to use this data

  • Travel research and itinerary planning: compare tours and activities in a destination by price, rating and availability before booking.
  • Price and catalog monitoring: track how listed prices, availability and review counts for a set of products change over time.
  • Market research for tour operators: see how bus tours, walking tours, day trips and attractions in a destination are priced and reviewed.
  • Content and affiliate sites: pull activity names, images, descriptions and ratings to build destination guides or comparison pages.
  • Outreach and lead lists: collect tour and operator names with source context for a destination or category to prioritize outreach.

Before you run

Start with a small input and check the resulting records against your expected fields. Source content and actor options can change; the current Apify listing is the reference for availability and pricing.

Questions about this actor

What data does Viator Scraper return?

The documented output for Viator Scraper includes name, product code, url, price, currency, rating, reviews and location. Availability of each field depends on the source page and the selected mode.

How much does Viator Scraper cost?

It costs $2.60 per 1,000 results on the Apify Free plan and from $1.50 on paid plans, with smaller per-run or optional feature charges listed on Apify. The Apify listing shows the current rate for every plan.

Do the filters and sort also apply when I paste a URL?

Yes. Keyword, price range, currency, minimum rating, minimum reviews, availability and sort order all apply to search mode and to a pasted URL's results alike. Only Destination, Destination (type a name) and Category are search-mode settings; they pick the listing page that search mode walks and are ignored in URL mode, where the pasted URL is the source instead.

Why did my run return 0 rows instead of an error?

URL mode needs at least one URL: if Mode is url and no URL is provided, the run completes with an empty dataset. A destination and category combination, or a keyword and filter set, with no matching live listings can also legitimately return 0 rows.

What happens if my typed destination is not found?

The name is looked up on Viator. If it does not resolve to a destination page with a matching name, the run stops with the message "No Viator destination matches ..." and saves nothing, instead of scraping a different place. Check the spelling or pick a destination from the list.

Does URL mode work with a single product page link?

Yes. A product page URL (a Viator tour link ending in the product code, such as d678-358782P2) returns one row for exactly that product, matched on its product code. Like every other row, it carries the listing-level fields only (detailStatus is not_requested) unless Fetch details is on, in which case it also carries the description, images, reviews and itinerary, and the detail event is billed once for that row after it is saved. A page that does not carry that product is skipped with a warning and never replaced by a different tour.

Ready to collect with Viator Scraper?

Run it on Apify with your own input and export the results as JSON, CSV or Excel.