Piotr VassevPiotr Vassev

How to Scrape Viator Tours for a Destination Comparison

A Viator category page gives you a starting list of tours, but a displayed offer price does not settle what a particular date, party size, or ticket option will cost. The first useful step is to build a comparison list with source links.

The Viator Scraper extracts tour names, product codes, locations, offer prices, and rating fields from supplied Viator pages. I maintain it. This guide uses Boston bus and minivan tours to create a shortlist for further checking.

How to Scrape Viator Tours for a Destination Comparison

Supply a focused page

You need an Apify account and a relevant Viator URL. An Actor is a tool that runs on Apify; this one's input is a list of URLs rather than a keyword-and-location form.

Open Input, switch to JSON, and use the documented category example:

{
  "searchUrls": [
    "https://www.viator.com/Boston-tours/Bus-and-Minivan-Tours/d678-g12-c98"
  ]
}

The deployed schema exposes only searchUrls. There is no maxItems, date selector, party-size input, or explicit pagination control. Start with one narrow page rather than adding invented limit fields. Do not assume one category URL returns every tour in the destination.

Click Start, wait for completion, and inspect the dataset. Check that the returned locationName and tour names belong to your intended destination and category. The number of rows depends on what the supplied page exposes.

Read the offer and rating together

The README provides this historical example:

{
  "name": "Boston Hop-On Hop-Off Trolley Tour with 13 Stops",
  "productCode": "5046BOS_OTT",
  "locationName": "Boston, Massachusetts",
  "offerPrice": 51.45,
  "offerCurrency": "USD",
  "ratingValue": 4.5,
  "exactRating": 4.3,
  "reviewCount": 5724
}

The trolley title describes a particular tour format. A private guided minivan trip may be in the same broad category but is not interchangeable with a hop-on/hop-off ticket.

The two rating fields also differ in this example. Keep ratingValue and exactRating under their original names; do not choose one silently or average them. Check the source page before using a rating cutoff that would include a tour at 4.5 but exclude it at 4.3.

Viator activity dataset with offers and ratings

Historical Viator output shows the offer and rating fields used to screen tours.

Turn the export into a tour comparison

Export CSV with productCode, name, url, locationName, addressLocality, offerPrice, offerCurrency, both rating fields, and reviewCount. Add your own collection date because the documented sample has no returned scrape timestamp.

Deduplicate by productCode. Divide the tours into comparable formats, such as shared city tours, private tours, and hop-on/hop-off tickets. Open each candidate's url and add the duration, inclusions, pickup arrangements, cancellation terms, and accessibility details you actually verify. Those facts are not supplied by the documented record fields.

For a meaningful price comparison, use the same travel date, party composition, and ticket option on each source page. Record those assumptions beside the checked price. A listing offer can be a useful screening value, but it is not a final booking quote for your group.

Sort within a matching format and currency. Retain review count next to the rating so the confidence you place in a small review sample is visible. Mark missing prices as “check source” and exclude them from numerical ranking.

Costs and repeated observations

Pricing as of September 6, 2026: $0.001 per returned activity. An illustrative twenty-row result costs $0.02 in activity fees, but this input has no twenty-row cap. The active event configuration contains no separate Actor-start charge. Check current pricing before adding more URLs.

If a run is empty, confirm that the source URL opens a public Viator page and inspect the log for failed requests. If it returns only a subset, do not infer that other tours disappeared; collection scope and page content may explain the difference.

Save the input as a task only after the sample is useful. Join later observations by product code and retain collection dates. A change in offerPrice is a change in the displayed offer, which still needs a same-date, same-party check before you describe it as a change in booking cost.

The Node.js example shows how to run this Actor from code and retrieve its dataset.

Earlier video walkthrough

The video shows the earlier interface. Use the input names and pricing in this guide.

Frequently asked questions

Can I set maxItems or a travel date in this Actor?

No. The deployed input schema exposes searchUrls only. Start with one focused URL and verify travel dates, party size, and ticket options separately on Viator.

Which rating should I use if ratingValue and exactRating differ?

Preserve both fields and check the source page. The documented sample has different values, so neither should silently overwrite the other in a comparison.

Piotr Vassev

Piotr Vassev

Founder of FalconScrape. Building production-grade web scraping systems and data automation pipelines for businesses worldwide.

Connect on LinkedIn