Booking.com Hotel Listings & Reviews Scraper avatar

Booking.com Hotel Listings & Reviews Scraper

Pricing

Pay per event

Go to Apify Store
Booking.com Hotel Listings & Reviews Scraper

Booking.com Hotel Listings & Reviews Scraper

Scrape Booking.com hotel search results and detail pages by destination or direct URL: name, address, coordinates, star rating, review score, price, room type, and optional guest reviews. Camoufox-powered to clear the AWS WAF challenge. Pay only per hotel scraped.

Pricing

Pay per event

Rating

0.0

(0)

Developer

DevilScrapes

DevilScrapes

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share


🎯 What this scrapes

For each run, this Actor works in one of two modes:

  1. Search mode — pass a destination (plus check-in/check-out dates), and it opens Booking.com's search results for that window, capped at your maxHotelsPerSearch.
  2. Direct-URL mode — pass a list of hotelUrls, and it visits each hotel's own detail page directly, independent of a destination search.

For every hotel it visits, the Actor emits one dataset row with name, address, city, country, coordinates, star rating, review score, review count, price, currency, room type, and thumbnail. When scrapeReviews is enabled, it also attaches up to maxReviewsPerHotel best-effort guest reviews per hotel.

🔥 Features

  • We clear the JS-execution gate Booking.com puts in front of raw HTTP requests — a hardened browser layer renders the page like a real visitor instead of bouncing off an automated bot-control challenge screen.
  • We rotate proxy sessions on every block — a fresh exit IP and session id whenever a challenge or mismatch is detected.
  • We verify the currency and locale actually match what you asked for before trusting a price — a wrong-geo page never gets emitted as if it were correct.
  • We back off when the target pushes back. Partial successes surface with a clear status message — we never silently return an empty dataset.
  • Per-hotel fault isolation — one dead page, timeout, or parse error skips that hotel with a logged warning; it never fails the whole run.
  • Pydantic v2 input + output validation — every row is a typed, schema-enforced record; nullable fields are always null, never silently dropped.
  • Pay-Per-Event pricing — you're charged per hotel row written to your dataset, plus a small per-review charge only when you opt into reviews.

💡 Use cases

  • OTA price intelligence — track how a set of hotels prices a given date range across markets.
  • Revenue-management benchmarking — hotel revenue managers pull comparable listings to sanity-check their own pricing and positioning.
  • Review-signal analysis — pull guest review scores and text at scale for sentiment or competitive analysis.
  • Travel-agtech and itinerary tools — bulk-source structured hotel data (name, coordinates, star rating, price) to power a booking or comparison product.

⚙️ How to use it

  1. Click Try for free at the top of the page.
  2. Enter a destination with checkin/checkout dates (search mode), or paste one or more hotelUrls (direct-URL mode) — or both.
  3. Optionally enable scrapeReviews to pull guest reviews alongside each hotel.
  4. Click Start. Output streams into the run's dataset.
  5. Export from Storage → Dataset as JSON, CSV, or Excel — or fetch via the API.

📥 Input

FieldTypeRequiredDefaultNotes
destinationstringno*Free-text destination for search mode, e.g. "Paris, France".
checkinstringrequired if destination setCheck-in date (YYYY-MM-DD).
checkoutstringrequired if destination setCheck-out date (YYYY-MM-DD), must be after checkin.
adultsintegerno21-30 adults per room.
roomsintegerno11-10 rooms.
maxHotelsPerSearchintegerno201-200 hotels returned per search.
hotelUrlsarrayno*[]Direct hotel-detail URLs; alongside or instead of destination.
scrapeReviewsbooleannofalseAlso fetch guest reviews per hotel.
maxReviewsPerHotelintegerno201-200 reviews per hotel when scrapeReviews is on.
countryCodestringno"US"2-letter ISO country code — proxy geo pin.
currencystringno"USD"3-letter ISO 4217 currency code.
sortOrderstringnoOptional search sort: popularity, price, review_score, class.
proxyConfigurationobjectnounsetApify Proxy editor; not required to be RESIDENTIAL.

* At least one of destination or hotelUrls must be set.

Example input

{
"destination": "Paris, France",
"checkin": "2026-09-10",
"checkout": "2026-09-12",
"adults": 2,
"rooms": 1,
"maxHotelsPerSearch": 20,
"scrapeReviews": false,
"countryCode": "US",
"currency": "USD"
}

📤 Output

Every row is one dataset item — one Booking.com hotel.

FieldTypeNotes
hotel_namestringHotel name.
booking_urlstringCanonical hotel detail URL.
addressstring | nullStreet address.
citystring | nullCity.
countrystring | nullCountry.
latitudefloat | nullLatitude, when available.
longitudefloat | nullLongitude, when available.
star_ratingfloat | nullOfficial star rating.
review_scorefloat | nullBooking.com's own review score (0-10 scale).
review_countinteger | nullNumber of reviews behind the score.
pricefloat | nullPrice in the requested currency, numeric.
currencystringEchoes the requested currency.
room_typestring | nullRoom type.
thumbnail_urlstring | nullThumbnail image URL.
checkin / checkoutstring | nullEchoes the requested dates.
reviewsarray | nullGuest reviews, only when scrapeReviews=true; best-effort.

Example output

{
"hotel_name": "Hôtel Eiffel Trocadéro",
"booking_url": "https://www.booking.com/hotel/fr/eiffel-trocadero.html",
"address": "35 Rue Benjamin Franklin, 75116 Paris",
"city": "Paris",
"country": "France",
"latitude": 48.8635,
"longitude": 2.287,
"star_rating": 4.0,
"review_score": 8.6,
"review_count": 1204,
"price": 189.0,
"currency": "USD",
"room_type": "Superior Double Room",
"thumbnail_url": "https://cf.bstatic.com/xdata/images/hotel/square200/....jpg",
"checkin": "2026-09-10",
"checkout": "2026-09-12",
"reviews": null
}

💰 Pricing

Pay-Per-Event — you pay only when these events fire:

EventUSDWhat it is
actor-start$0.02One-off warm-up charge per run.
hotel-scraped$0.0020Per hotel row written to your dataset.
reviews-scraped$0.0005Per review item emitted, only when scrapeReviews=true.

Example: 1 000 hotel rows at the rates above ≈ $2.00. No subscription, no minimum, no card to start — Apify gives every new account $5 of free credit.

🚧 Limitations

Scaffold-stage build — hotels-only (no Booking.com Attractions, car rentals, or flights), one-shot scrape per run (no price-trend history), and read-only extraction (no booking/reservation actions). Review pagination shape may evolve as recon continues; reviews stay best-effort and never block a hotel's core row.

❓ FAQ

Is this legal?

We only fetch content Booking.com makes publicly available on its search and hotel pages. Respect Booking.com's terms of service before using output commercially.

Why is a field null?

Detail-page fields are null when Booking.com doesn't expose that field publicly for a given hotel, or when a currency/locale mismatch caused the Actor to skip trusting that page's price.

Do I need my own proxy?

No — a proxy is wired in by default; proxyConfiguration is optional if you want to bring your own.

Why did I get fewer rows than maxHotelsPerSearch?

Any hotel that hits a dead page, a challenge that doesn't clear, or a currency/locale mismatch is skipped rather than failing the run — check the run's status message for a breakdown.

💬 Your feedback

Spotted a bug, hit a weird edge case, or need a new field? Open an issue on the Actor's Issues tab on Apify Console — we ship fixes weekly and we read every report.