Booking.com Hotels Scraper
Pricing
from $2.70 / 1,000 hotel scrapeds
Booking.com Hotels Scraper
Scrape Booking.com hotels by destination and dates: name, price per night, review score, stars, address, type and link. Fast, low cost.
Scrape Booking.com hotel search results by destination/dates/guests, and/or individual hotel pages by URL. Returns name, price, review score & count, address, amenities and more per hotel β using a real headless browser (Playwright) behind Apify residential proxy to actually pass Booking.com's AWS WAF anti-bot challenge, on both search results and hotel detail pages.
Why it's useful
Booking.com is one of the most valuable β and most protected β travel data sources. Track hotel prices for a destination and date range, monitor a specific property's rate/review score over time, or build a dataset of hotels for a city.
Input
{"destination": "Lisbon","checkIn": "2026-11-10","checkOut": "2026-11-12","adults": 2,"maxItems": 30,"currency": "USD"}
or, for specific properties:
{ "hotelUrls": ["https://www.booking.com/hotel/pt/altis-avenida.html"] }
destinationβ place name (e.g. "Lisbon", "Paris, France"). Optional ifhotelUrlsis set.checkIn/checkOutβYYYY-MM-DD. Optional; Booking.com uses its own default dates if omitted. When set, the dates are also appended to each hotel URL so live room prices render for exactly those dates.adultsβ guest count (default 2).childrenβ number of children (default 0).roomsβ number of rooms to price (default 1).hotelUrlsβ specific hotel page URLs to scrape directly. Optional ifdestinationis set. At least one ofdestination/hotelUrlsis required.maxItemsβ cap on hotels returned from the destination search (paginated 25 at a time).currencyβ 3-letter code Booking.com should price in.languageβ Booking.com interface language (e.g.en-us,pt-br,es). Controls review words and amenity labels.proxyConfigurationβ Apify Proxy settings. Residential proxies strongly recommended (see Notes).
Output
One item per hotel, source: "search" or source: "url":
{"source": "search","name": "Altis Avenida Hotel","url": "https://www.booking.com/hotel/pt/altis-avenida.html","stars": 5,"price": 187,"currency": "USD","price_for_nights_text": "US$374 for 2 nights","taxes_and_charges": "+US$25 taxes and charges","free_cancellation": true,"review_score": 8.9,"review_word": "Fabulous","reviews_count": 3421,"address": "Lisbon, Portugal","distance": "0.3 km from centre","latitude": 38.7169,"longitude": -9.1399,"image": "https://cf.bstatic.com/...","images": ["https://cf.bstatic.com/...", "..."],"badges": ["Breakfast included"],"room_config": "1 double bed"}
Fields returned
Every search-result item carries: name, url, stars (1β5), price, currency, raw_price_text, price_for_nights_text, taxes_and_charges, free_cancellation, review_score, review_word, reviews_count, address, distance, latitude, longitude, image, images[], badges[], room_config, plus the echoed destination/checkIn/checkOut/adults.
Every hotel-page item (source: "url") carries all of the above-relevant fields plus:
starsβ official star classification (from JSON-LDstarRatingwhen present).address_detailsβ structured{ street, city, region, postal_code, country }.review_subscoresβ per-category guest scores:{ cleanliness, comfort, location, facilities, staff, value_for_money, free_wifi, breakfast }(only the categories Booking shows).room_types[]β{ name, price, currency, raw_price }for each listed room (best-effort; price isnullif not shown for the selected dates).price_range,price_for_nights_text,taxes_and_chargesβ pricing context.free_cancellation/cancellation_textβ cancellation policy.nearby[]β nearby landmarks / points of interest as{ name, distance }.reviews_sample[]β sample guest reviews ({ rating, author, title, text, date }) from JSON-LD when present.amenities[]β facilities (merged from JSON-LDamenityFeature+ the on-page facilities list).telephone,email,map_urlβ contact/map links from JSON-LD.description,images[],latitude/longitude.parsed_withβ which extraction tier supplied the fields (json-ld+meta/dom,meta+dom, ordom), so you can judge confidence.
All enrichment fields default to null / [] / {} when Booking.com doesn't expose them for a given property β never fabricated.
Honesty on blocking
Every page load runs in a real headless browser behind a residential proxy session. If Booking.com's AWS WAF still serves a challenge/CAPTCHA page, the actor marks that proxy session bad and retries with a fresh session and a new residential IP (up to maxRequestRetries: 4). Only if every retry is still blocked does it emit { ..., error: "BLOCKED_OR_FAILED ..." } for that item β never fabricated hotel data. If a page loads cleanly but no results can be parsed (no matches, or Booking.com changed its markup), it says so explicitly instead of returning nothing silently.
Notes / limitations
- Booking.com fronts most pages with an AWS WAF managed challenge β a small JS page that must actually run in a browser to pass. This actor uses Playwright (a real headless Chromium) for exactly that reason, unlike a plain-HTTP approach which can spoof headers/TLS but can't execute the challenge JS β that's why a prior HTTP-only version of this actor could load search results (lighter-weight anti-bot) but got hotel detail pages blocked outright.
- Search parsing targets the
data-testidattributes Booking.com's React app renders on result cards (title,price-and-discounted-price,review-score,address,distance). Hotel-page parsing prefers JSON-LD (schema.orgHotel) when present, then Open Graph/meta tags, then the same DOM markers β all reliably-present fields are extracted, nothing is guessed. - A sign-in popup and/or cookie-consent banner are dismissed automatically if Booking.com shows one, before scraping.
β Enjoying this Actor?
A quick rating/review helps others find it. Hotel-page items now include amenities, room types & prices, per-category review subscores, cancellation policy, nearby landmarks and sample reviews. Want multi-page hotel-review scraping or another field added? Open a ticket on the Issues tab.