Booking.com Scraper avatar

Booking.com Scraper

Pricing

from $0.97 / 1,000 scraped results

Go to Apify Store
Booking.com Scraper

Booking.com Scraper

Scrape hotels from Booking.com search results by destination or URL with check-in and check-out dates. Extract nightly prices, review scores, location, and amenities, with optional hotel details, availability pricing calendars, and guest reviews.

Pricing

from $0.97 / 1,000 scraped results

Rating

0.0

(0)

Developer

Farhan Ali

Farhan Ali

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Categories

Share

Booking.com Scraper creates a structured dataset of hotel listings collected from Booking.com. Each dataset item represents one hotel and can include nightly price, review score, location, and amenities, with optional hotel details, a year-round availability pricing calendar, and guest reviews. Query the source by destination name or Booking.com URL, set check-in and check-out dates, control the result limit with maxItems, and retrieve records through the Apify Dataset API or export them as JSON, CSV, Excel, or other supported formats.

Dataset at a glance

PropertyValue
Sourcebooking.com (public hotel search and property pages)
Record unitOne hotel, with nested optional details, availability, and reviews
Input methodsDestination name (searchQueries) or Booking.com URLs (startUrls)
Main identifiershotelId, hotel page url
DeliveryApify Dataset and API
Export formatsJSON, CSV, Excel, XML, HTML (Apify dataset exports)
Update modelFresh records per Actor run
Pricing$1 per 1,000 hotels; +$1 per 1,000 for details; +$0.10 per 1,000 for availability; +$1 per 1,000 for reviews

Coverage and available records

The Actor collects hotels from public Booking.com pages using one of two entry points:

  • Query-based: Pass plain destination names (for example "Berlin, Germany") in searchQueries. The Actor resolves the Booking.com destination ID automatically.
  • URL-based: Pass ready-made search-results or hotel page URLs in startUrls when you already know the exact dest_id or property page.

Record types and limits:

  • Listing-level records are always collected: name, hotel ID, URL, city, address, coordinates, nightly price, review score, review count, and image URL.
  • Hotel detail fields are conditional: facilities, house rules, surroundings, and description are returned only when hotelDetails is enabled.
  • Availability records are conditional: a year-round daily availability and pricing calendar is returned only when scrapeAvailability is enabled.
  • Guest review records are conditional: a nested guestReviews array is returned only when scrapeReviews is enabled, capped by maxReviews.
  • Result cap: maxItems limits the number of hotels collected (0 means unlimited; the default is 10).

Known exclusions: content Booking.com only shows behind a booking flow is not collected; each run captures page state at run time (no historical snapshots); availability and reviews are not collected unless their toggles are enabled.

Data dictionary

Field names below match dataset record JSON properties exactly. Fields marked conditional appear only when the corresponding input toggle is enabled.

Hotel-level fields

FieldTypeNullableDescriptionExample
hotelIdnumberNoBooking.com hotel identifier; best stable deduplication key177530
namestringNoHotel nameIndustriepalast Berlin
urlstringNoHotel page URLhttps://www.booking.com/hotel/de/industriepalast-berlin.html
pageNamestringNoURL slug for the hotelindustriepalast-berlin
countryCodestringYesCountry codede
citystringYesCity as shown on the listingBerlin
addressstringYesStreet addressWarschauer Straße 43
latitudenumberYesHotel latitude52.5040844271257
longitudenumberYesHotel longitude13.4472857415676
reviewScorenumberYesAverage guest review score8.0
reviewCountnumberYesNumber of guest reviews5803
reviewScoreTextstringYesReview score labelVery Good
pricestringYesNightly price as renderedS$ 102.85
priceRoundedstringYesRounded nightly priceS$ 103
currencystringYesCurrency codeSGD
imageUrlstringYesMain hotel image URLhttps://cf.bstatic.com/...
sourceQuerystringYesDestination query that produced the recordBerlin
searchCheckInstringYesCheck-in date used for the search2026-09-25
searchCheckOutstringYesCheck-out date used for the search2026-09-27

Hotel detail fields (conditional — hotelDetails)

FieldTypeNullableDescriptionExample
houseRules.checkInFromstringYesEarliest check-in time3:00 PM
houseRules.checkInUntilstringYesLatest check-in time11:30 PM
houseRules.checkOutUntilstringYesCheck-out deadline10:00 AM
houseRules.minCheckInAgenumberYesMinimum check-in age18
facilities.relevantForYourTripstring[]YesHighlighted facilities["Free Wifi", "Parking", ...]
facilities.spokenLanguagesstring[]YesLanguages spoken at the property["ar", "de", "en", ...]

Availability fields (conditional — scrapeAvailability)

FieldTypeNullableDescriptionExample
availability[].datestringNoCalendar date2026-09-25
availability[].availablebooleanNoWhether the hotel is available that datetrue
availability[].pricestringYesDaily price (string)56
availability[].minLengthOfStaynumberYesMinimum length of stay2

Guest review fields (conditional — scrapeReviews)

FieldTypeNullableDescriptionExample
guestReviews.summary.totalReviewCountnumberYesTotal review count in summary5802
guestReviews.reviews[].reviewScorenumberYesReviewer score9.0
guestReviews.reviews[].guestNamestringYesReviewer nameHéloïse
guestReviews.reviews[].guestCountrystringYesReviewer countryFrance
guestReviews.reviews[].guestTypestringYesTraveler typeSolo traveler
guestReviews.reviews[].roomTypestringYesRoom type reviewedSingle Bed in Female Dormitory Room
guestReviews.reviews[].positiveTextstringYesPositive review textEverything went great...
guestReviews.reviews[].negativeTextstringYesNegative review textThe rooms didn't have air con...

Example dataset record

Real record produced with a destination query (searchQueries: ["Berlin"]), dates 2026-09-25 to 2026-09-27, with details, availability, and reviews enabled. The availability and reviews arrays are truncated for readability.

{
"hotelId": 177530,
"name": "Industriepalast Berlin",
"url": "https://www.booking.com/hotel/de/industriepalast-berlin.html",
"pageName": "industriepalast-berlin",
"countryCode": "de",
"city": "Berlin",
"address": "Warschauer Straße 43",
"latitude": 52.5040844271257,
"longitude": 13.4472857415676,
"reviewScore": 8.0,
"reviewCount": 5803,
"reviewScoreText": "Very Good",
"price": "S$ 102.85",
"priceRounded": "S$ 103",
"currency": "SGD",
"imageUrl": "https://cf.bstatic.com/xdata/images/hotel/square600/488699632.webp",
"sourceQuery": "Berlin",
"searchCheckIn": "2026-09-25",
"searchCheckOut": "2026-09-27",
"houseRules": {
"checkInFrom": "3:00 PM",
"checkInUntil": "11:30 PM",
"checkOutUntil": "10:00 AM",
"minCheckInAge": 18
},
"facilities": {
"relevantForYourTrip": ["Free Wifi", "Parking", "Pet friendly", "Non-smoking rooms", "Family rooms"],
"spokenLanguages": ["ar", "de", "en", "es", "it"]
},
"availability": [
{ "date": "2026-09-25", "available": true, "price": "56", "minLengthOfStay": 2 },
{ "date": "2026-09-26", "available": false, "price": "0", "minLengthOfStay": 1 }
],
"guestReviews": {
"summary": { "totalReviewCount": 5802 },
"reviews": [
{
"reviewScore": 9.0,
"guestName": "Héloïse",
"guestCountry": "France",
"guestType": "Solo traveler",
"roomType": "Single Bed in Female Dormitory Room",
"positiveText": "Everything went great, the location is perfect...",
"negativeText": "The rooms didn't have air con..."
}
]
}
}

The record above was produced with this input:

{
"searchQueries": ["Berlin"],
"checkIn": "2026-09-25",
"checkOut": "2026-09-27",
"maxItems": 10,
"hotelDetails": true,
"scrapeAvailability": true,
"scrapeReviews": true,
"maxReviews": 10,
"proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}

Query and input reference

InputTypeRequiredDefaultAccepted valuesDescription
searchQueriesarray (JSON)No*["Berlin, Germany"]Destination names (e.g. "Paris", "Berlin, Germany")Query-based entry point; destination IDs are resolved automatically
startUrlsarray (requestListSources)No*[]Booking.com search-results or hotel URLsURL-based entry point; overrides queries when set
checkInstringNo2026-09-25YYYY-MM-DDCheck-in date
checkOutstringNo2026-09-27YYYY-MM-DDCheck-out date
adultsintegerNo11 or moreAdults per room
roomsintegerNo11 or moreNumber of rooms
childrenintegerNo00 or moreNumber of children
childrenAgesarrayNo[]One integer per childAges of children
maxItemsintegerNo100 (unlimited) or positive integerMaximum hotels to collect
hotelDetailsbooleanNofalsetrue / falseCollect detail fields per hotel (charged as hotel details)
scrapeAvailabilitybooleanNofalsetrue / falseCollect the year-round availability calendar (charged as availability)
scrapeReviewsbooleanNofalsetrue / falseCollect guest reviews (charged as reviews)
maxReviewsintegerNo100 (unlimited) or positive integerMaximum reviews per hotel
langstringNoen-usen-us, en-gb, de, fr, es, it, nl, pt-ptBooking.com language code
currencystringNoEURISO currency code (e.g. EUR, USD)Preferred currency for prices
proxyConfigurationobjectNoApify proxy, RESIDENTIAL groupApify proxy groups or custom proxiesResidential proxies are recommended; datacenter IPs are frequently rate-limited

* Provide either searchQueries or startUrls — at least one source is required.

Minimal request:

{ "searchQueries": ["Berlin, Germany"], "checkIn": "2026-09-25", "checkOut": "2026-09-27" }

Advanced request (destination query with enrichment):

{
"searchQueries": ["Paris"],
"checkIn": "2026-09-25",
"checkOut": "2026-09-27",
"adults": 2,
"rooms": 1,
"maxItems": 1000,
"hotelDetails": true,
"scrapeAvailability": true,
"scrapeReviews": true,
"maxReviews": 20,
"lang": "fr",
"currency": "EUR",
"proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}

Retrieve the data through the API

The Actor runs on the Apify platform, so there is no server to host and no crawling infrastructure to maintain.

  1. Start the Actor with a JSON input (console or API).
  2. Wait for the run to finish, or use a synchronous endpoint if you want the response inline.
  3. Retrieve items from the run's default dataset.
  4. Paginate or export the dataset.

Python example:

from apify_client import ApifyClient
client = ApifyClient("YOUR-APIFY-TOKEN")
run_input = {
"searchQueries": ["Berlin, Germany"],
"checkIn": "2026-09-25",
"checkOut": "2026-09-27",
"maxItems": 10,
}
run = client.actor("datascrapers/booking-com-scraper").call(run_input=run_input)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item["hotelId"], item["name"], item["price"], item["reviewScore"])

Apify generates ready-to-run Python, JavaScript, and cURL examples on the Actor's API tab. Do not put a real API token in shared code or URLs.

Data quality and record handling

  • Conditional fields: detail, availability, and review fields are present only when their input toggle is enabled. Listing-only runs return a leaner record.
  • Source changes: Booking.com page structure and values can change; unreadable fields are returned as null rather than fabricated.
  • Deduplication: each run appends fresh records; the Actor does not deduplicate hotels across runs. Use hotelId as the stable key and filter repeated runs against previously stored IDs.
  • Rate limits and geo-behavior: Booking.com can serve region- or currency-specific pages. Keep the default residential proxy enabled and match the destination's country in your proxy settings for consistent coverage.
  • Normalization: price and availability values are read from the page and kept as strings; dates use YYYY-MM-DD format. Review scores are normalized to numbers.

Export and pipeline examples

DestinationRecommended methodTypical use
PostgreSQL / SupabaseDataset API poll or webhook consumerStore hotel inventory alongside price history
Google SheetsApify Google Sheets integrationShare destination shortlists with teams
BI tools (Looker, Tableau)Scheduled export via Apify schedulerRate benchmarking and market snapshots
S3 / cloud storageScheduled export + integrationArchival of daily price and availability snapshots

Pricing and cost examples

The Actor uses pay-per-event pricing with four chargeable events:

EventTriggerRate
Scraped resultEvery hotel record pushed to the dataset$1 per 1,000 hotels
Hotel detailshotelDetails enabled, profile visited$1 per 1,000 hotels
Availability calendarscrapeAvailability enabled, calendar fetched$0.10 per 1,000 hotels
ReviewsscrapeReviews enabled, reviews fetched$1 per 1,000 hotels

Example costs:

RecordsConfigurationEstimated base cost
1,000Listing only$1.00
10,000Listing only$10.00
1,000Listing + details$2.00
1,000Listing + details + availability$2.10
1,000Listing + details + availability + reviews$3.10

Apify paid plans reduce the per-1,000 rate. Compute units consumed by the run are billed by your Apify plan. Estimates depend on the verified pricing model and the options selected for the run.

Limitations and responsible data use

  • The Actor collects publicly accessible data from Booking.com pages only.
  • Field availability depends on what Booking.com renders at run time; some values can be null or missing, and site changes can alter fields.
  • Availability and reviews are only collected when their toggles are enabled.
  • The Actor does not provide historical snapshots unless you store them yourself.
  • Large runs require residential proxies; without them, coverage may degrade due to rate limiting.
  • You are responsible for compliance with Booking.com's terms of service, applicable privacy law, and any contractual obligations before using the data.

Dataset questions

What does one dataset item represent?

One hotel from Booking.com. Availability and guest reviews are nested inside the hotel record as availability and guestReviews arrays, so a hotel with hundreds of reviews still produces a single dataset item.

Which field should I use as a unique identifier?

hotelId is the stable Booking.com identifier and is the recommended deduplication key. The url (hotel page URL) is a reasonable secondary key.

Are fields nullable or conditional?

Yes. Detail fields (house rules, facilities) exist only when hotelDetails is enabled; availability exists only when scrapeAvailability is enabled; guestReviews exists only when scrapeReviews is enabled. Within available records, fields that Booking.com does not render are returned as null.

Can I retrieve the records as CSV or JSON?

Yes. The dataset can be exported as JSON, CSV, Excel, XML, or HTML from the Apify Console, and queried through the Dataset API.

Does the Actor return historical data?

No. Each run captures the state of the pages at run time. To track price changes over time, schedule repeated runs and store the outputs yourself; each record includes searchCheckIn and searchCheckOut to distinguish snapshots.

What counts as a billable result?

Four pay-per-event charges apply: a scraped-result charge for every hotel record ($1 per 1,000), a hotel-details charge for each enriched profile ($1 per 1,000), an availability-calendar charge for each calendar fetched ($0.10 per 1,000), and a reviews charge for each hotel whose reviews are fetched ($1 per 1,000). A listing-only run incurs only the scraped-result charge.

Why am I getting empty results?

This usually means Booking.com blocked the request or served a region/currency page you do not expect. Keep the default residential proxy enabled, match the destination's country in your proxy settings, and confirm your checkIn / checkOut dates are valid and in YYYY-MM-DD format.

  • Tripadvisor Reviews Scraper — Guest review records that can be joined with hotels by name or location for reputation analysis.
  • Yelp Scraper — Local business and hospitality listings useful alongside hotel supply research.
  • Apartments Scraper — Rental listings for comparative lodging market analysis.

Data Scrapers support

Need an additional field, record type, or export workflow? Contact Data Scrapers at stardustspotlight@gmail.com. Include a sample source URL, required fields, expected record volume, and preferred delivery format.