Multi-OTA Hotel Price Comparator avatar

Multi-OTA Hotel Price Comparator

Pricing

from $2.00 / 1,000 results

Go to Apify Store
Multi-OTA Hotel Price Comparator

Multi-OTA Hotel Price Comparator

Search one or more locations across multiple OTAs (Booking.com, Hotels.com, Expedia, Agoda, Vrbo, Airbnb, Google Travel...) and normalize the prices into a single, currency-comparable dataset with the best price per hotel.

Pricing

from $2.00 / 1,000 results

Rating

0.0

(0)

Developer

ossama

ossama

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

7 days ago

Last modified

Share

Compare hotel prices for one or more locations across 7+ travel platforms at once — Booking.com, Hotels.com, Expedia, Agoda, Vrbo, Airbnb and Google Travel — and get a single, currency-normalized dataset with the best price per hotel and the cross-platform savings.

What does Multi-OTA Hotel Price Comparator do?

For every location you enter (e.g. London, Manchester, Birmingham), the Actor queries each selected platform, normalizes every offer into one schema, converts all prices into your chosen currency, and groups the same hotel across platforms so you can instantly see which OTA is cheapest. You get, per offer: hotel name, room/property type, price (per-night and whole-stay), currency, converted price, rating (always on /10), review count, coordinates, images (with captions), badges and amenities. Per hotel, you get the best price, the price spread and the percentage you can save by booking on the right platform.

🧠 How it works. The big OTAs block direct scraping with commercial anti-bot systems. Instead of fighting that, this Actor subcontracts the scraping to maintained Apify Store actors (e.g. voyager/booking-scraper, 3.8M runs) via Actor.call(), and focuses on the genuinely hard part: a correct, currency-aware cross-platform comparison.

Which platforms are supported?

PlatformKeyStatus
Booking.combooking✅ Verified (real prices live)
Hotels.comhotels_com✅ Verified (real prices live)
Expediaexpedia✅ Verified (real prices live)
Agodaagoda✅ Verified (real prices live)
Vrbovrbo✅ Verified (real prices live)
Airbnbairbnb✅ Verified (rich output)
Google Travelgoogle_travel✅ Verified (real prices live)
Trip.comtrip_com⚠️ Best-effort — free Store actors don't serve hotel data
Trivagotrivago⚠️ Best-effort — very slow, no date support

Pick any subset, or leave the platform list empty to query all of them. Non-working platforms are skipped cleanly (a warning in the log, never a crash).

⚠️ Free tier note. The Airbnb scraper requests ~4 GB. On the free plan (8 GB total), run Airbnb alone or with concurrency=1 to avoid the memory cap.

How much will it cost?

You only pay Apify platform usage plus whatever the subcontracted Store actors charge per run/result (billed to whoever runs this Actor). A typical single-location, few-platform run costs only a few cents. Heavier platforms (residential proxy, more results) cost more — tune maxResultsPerPlatform and the platform list to control spend.

Input

  • locationQueries (required) — list of locations to search, e.g. ["London", "Manchester", "Birmingham"]. Each is searched and compared separately.
  • checkIn / checkOut (required)YYYY-MM-DD.
  • platforms — subset to query, or empty for all.
  • General search optionslocale, currency, priceMin, priceMax, minBeds, minBedrooms, minBathrooms, adults, children, infants, pets. (Platforms apply the options they support; e.g. beds/infants/pets are Airbnb.)
  • maxResultsPerPlatform, concurrency, debugDumpHtml.

Input example

{
"locationQueries": ["Marrakech"],
"checkIn": "2026-07-10",
"checkOut": "2026-07-12",
"platforms": ["booking", "agoda", "expedia", "google_travel"],
"adults": 2,
"currency": "EUR"
}

Output

Two outputs:

  1. Default dataset — one row per offer per platform, normalized. Each offer is enriched with price_per_night, price_total_stay, price_total_converted (in your currency), latitude/longitude, images, badges, amenities...
  2. Comparison — written to the Key-Value Store under COMPARISON (grouped by location → list of hotels) and to a dataset named comparison (one row per hotel). Each hotel group has: the offers, platforms_found, the best_price, the price_spread and max_savings_pct (how much you save by picking the right platform).

Output example (one normalized offer)

{
"source_platform": "airbnb",
"location_query": "Prague",
"hotel_name": "Lovely Apartment Heart in Old Town",
"room_type": "entire_home",
"address": "Apartment in Prague",
"latitude": 50.090172,
"longitude": 14.417268,
"check_in": "2026-07-10",
"check_out": "2026-07-12",
"adults": 2,
"price_amount": 679,
"price_currency": "USD",
"price_is_total_stay": true,
"price_qualifier": "total",
"price_per_night": 339.5,
"price_total_stay": 679,
"price_total_converted": 679,
"price_currency_converted": "USD",
"rating": 9.9,
"review_count": 663,
"badges": ["Guest favorite"],
"subtitles": ["Free cancellation"],
"amenities": [],
"images": [
{ "url": "https://a0.muscache.com/im/.../a.jpg", "captions": [] },
{ "url": "https://a0.muscache.com/im/.../b.jpg", "captions": ["4 beds", "3 bedrooms"] }
],
"url": "https://www.airbnb.com/rooms/1686130"
}

Why the comparison is correct

  • Currencies are unified. Every offer is converted into your currency before comparison (verified live: Booking in EUR + Agoda/Expedia in USD, all compared in one currency). Live FX rates with a static fallback — see src/currency.py.
  • Per-night vs whole-stay is harmonized. Each offer is reduced to both a per-night and a whole-stay price according to its platform, so the best price is apples-to-apples.

Real example from a live Marrakech run: Grand Plaza Marrakech came back 23% cheaper on Google Travel than on Agoda.

How to use the scraped data

  • Monitor prices for your locations and catch the cheapest platform per hotel.
  • Track price spreads and savings opportunities across OTAs.
  • Feed competitive pricing/revenue tools, dashboards, or Google Sheets.
  • Spot emerging destinations and price trends across cities.

Architecture

.actor/ actor.json + input_schema.json
src/
main.py orchestration: validate input, loop locations × platforms,
call Store actors, enrich + compare, push
params.py SearchParams (one location + dates + occupancy + filters)
normalize.py normalized schema + fuzzy matching + best-price comparison
currency.py FX rates (live + static fallback) and conversion
utils.py price/rating parsing + platform selection
adapters/
base.py StoreAdapter: build_input(params) + map_item(item, params)
booking / hotels_com / expedia / agoda / vrbo / airbnb / google_travel ()
trip_com / trivago (⚠️)
tests/ pytest on the pure logic (no network)

Adding/fixing a platform = a small adapter subclassing StoreAdapter (store_actor_id + build_input [+ map_item]) registered in src/adapters/__init__.py. Nothing else changes.

Tests

All the logic (parsing, conversion, fuzzy matching, platform selection, input building and output mapping) is pure Python, so it's testable offline:

pip install -r requirements-dev.txt
python -m pytest

64 tests cover parsing, currency conversion, per-night/whole-stay and multi-currency best-price selection, fuzzy matching, and verified output mappings for the 7 live platforms.

Run it on Apify

npm install -g apify-cli
apify login
apify push

Integrations & API

Like any Apify Actor, this one connects to Make, Zapier, Slack, Google Sheets, Airbyte and more via Apify integrations and webhooks, and is fully driveable through the Apify API (Node apify-client, Python apify-client).

This Actor does not scrape the sites itself — it orchestrates public Apify Store actors and normalizes/compares their output. Stay reasonable on volume and review the terms of service of the sites and of the subcontracted actors.