Booking.Com Hotel Scraper avatar

Booking.Com Hotel Scraper

Under maintenance

Pricing

from $2.00 / 1,000 results

Go to Apify Store
Booking.Com Hotel Scraper

Booking.Com Hotel Scraper

Under maintenance

Turn Booking.com searches and hotel pages into clean, structured data with price history and drop/bargain flags — no browser required.

Pricing

from $2.00 / 1,000 results

Rating

0.0

(0)

Developer

REXREUS D.O

REXREUS D.O

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

23 days ago

Last modified

Categories

Security

Limited permissions

Share

Booking.com Hotel Scraper

Clean, structured hotel data from Booking.com — HTTP-first, no browser required

Turn Booking.com searches and hotel pages into clean, structured data with price history and drop/bargain flags — no browser required.

HTTP-first · runs on Apify · datacenter proxy by default, residential opt-in · local runs without proxy may be PARTIAL

Quick Start Apify Node.js

Why this Actor?

FeatureWhat you get
HTTP-first scrapingNo browser, no heavy infrastructure. Bookings public pages are fetched directly, so runs are fast and cheap.
Search + direct hotel URLsPaste a Booking.com search results URL, a list of hotel URLs, or both — scrape the properties you actually care about.
Date-scoped pricesPrices are quoted for your specific check-in/check-out dates via searchresults.html, or labeled city_indicative when only indicative nightly rates are available.
Price history (cross-run)The Actor stores a 90-day price history per hotel and flags drops with priceDropped + priceChangePct compared with the previous snapshot.
Bargain flagOptionally flags properties priced at or below the destination cohort median — spot the best value in a market at a glance.
20 currenciesUSD, EUR, IDR, SGD, JPY, GBP, AUD, THB, MYR, CNY, INR, KRW, VND, PHP, HKD, TWD, BRL, MXN, CAD, CHF.
Detail enrichmentFetches each hotel page for JSON-LD details — address, amenities, geo, rating — as an opt-in per-result add-on.
Clean, typed datasetOne buyer-friendly row per hotel with null for absent data and a status enum that classifies every row (SUCCESS / PARTIAL / NOT_FOUND / BLOCKED / ERROR).
Export anywhereResults export natively to JSON, CSV, or Excel from the Apify Console — schedule reruns, or pipe to a webhook.
AffordableSearch + history + flags at $0.002/result; detail enrichment is a separate line item you can leave off entirely.

Note on proxy: the Actor defaults to Apify Residential proxy — Booking.com's AWS WAF blocks datacenter/AUTO traffic with 202 stubs, so Residential is required for reliable results. A local run without proxy may return PARTIAL rows.

Quick start

  1. Open the Actor in the Apify Console and click Start.
  2. Easiest input — just set Destination (e.g. Bandung) plus dates. Or paste a full Booking.com search results URL (or hotel URLs) if you prefer.
  3. Optionally customize currency, language, and flags, then click Start.
  4. When the run finishes, open the Dataset tab and download as JSON, CSV, or Excel.

Simplest input — just a destination (no URL needed):

{
"destination": "Bandung",
"checkin": "2026-11-01",
"checkout": "2026-11-02",
"selectedCurrency": "IDR",
"maxResults": 100
}

Advanced — full search URL (any variant accepted, e.g. searchresults.en-gb.html):

{
"searchUrl": "https://www.booking.com/searchresults.html?ss=Bali&checkin=2026-11-01&checkout=2026-11-02&group_adults=2&no_rooms=1&group_children=0&selected_currency=USD&lang=en-us",
"maxResults": 25,
"enableDetail": true,
"bargain": true
}

How it works

Public search URL or hotel URLs → public Booking.com pages → clean dataset rows
  1. You paste a searchresults.html search URL (or direct /hotel/{cc}/{slug}.html URLs, or both).
  2. The Actor fetches the public pages over HTTP and parses each hotel card — name, URL, price, currency, rating, reviews, stars, free-cancellation status.
  3. Optional detail pass: each hotel's own page is fetched for richer JSON-LD data (address, amenities).
  4. Price snapshot is saved to history; the row's priceDropped, priceChangePct, and bargain flags are computed against the 90-day history.
  5. Each property becomes one dataset row, classified by a status enum.

Input

Three ways in — pick whichever fits:

  1. destination (easiest) — just a place name, the Actor builds the search URL.
  2. searchUrl — a full Booking.com search URL (any searchresults[.lang].html variant).
  3. hotelUrls — a list of hotel page URLs.
{
"destination": "Bandung",
"hotelUrls": [],
"maxResults": 25,
"selectedCurrency": "IDR",
"checkin": "2026-11-01",
"checkout": "2026-11-02",
"lang": "en-us",
"enableDetail": true,
"bargain": true,
"proxy": {
"useApifyProxy": true,
"apifyProxyGroups": ["RESIDENTIAL"]
}
}
FieldTypeRequiredDefaultDescription
destinationstringNo*—City or area name, e.g. Bali, Bandung. Builds the search URL for you. Ignored when searchUrl is set.
searchUrlstringNo*—Full Booking.com search URL. Any searchresults[.lang].html variant accepted. Overrides destination if both set.
hotelUrlsarrayNo—https://www.booking.com/hotel/{cc}/{slug}.html URLs to scrape directly.
maxResultsintegerNo25Maximum number of results (1..5000).
selectedCurrencystringNoUSDCurrency for prices: USD, EUR, IDR, SGD, JPY, GBP, AUD, THB, MYR, CNY, INR, KRW, VND, PHP, HKD, TWD, BRL, MXN, CAD, CHF.
checkinstringNo—Check-in date, YYYY-MM-DD. Overrides the date in searchUrl.
checkoutstringNo—Check-out date, YYYY-MM-DD. Overrides the checkout in searchUrl.
langstringNoen-usLanguage/locale tag, e.g. en-us, id-id, de.
enableDetailbooleanNotrueFetch each hotel's /hotel/ page for JSON-LD details (address, rating, amenities). Adds a $0.006/result add-on.
bargainbooleanNofalseFlag properties priced at or below the destination cohort median (needs ≥ 3 priced results).
proxyobjectNo{useApifyProxy: true, apifyProxyGroups: ["RESIDENTIAL"]}Proxy config. Defaults to Residential — required for Booking.com's WAF.

At least one of destination, searchUrl, or hotelUrls is required. searchUrl wins over destination; dates/currency from input fields override those in the URL.

Output

One real record from a live run (Bandung search, priceBasis: date_scoped):

{
"name": "Alqueby Hotel Bandung",
"url": "https://www.booking.com/hotel/id/alqueby-bandung.html",
"hotelId": "hotel-id-alqueby-bandung",
"city": "Kiaracondong, Bandung",
"country": "Indonesia",
"price": 281250,
"priceDisplay": "Rp 281,250",
"currency": "IDR",
"pricePerNight": 281250,
"rating": 7.9,
"reviewCount": 9,
"stars": null,
"location": "Kiaracondong, Bandung",
"distance": "3.3 miles from downtown",
"address": "ALQUEBY HOTEL",
"freeCancellation": true,
"priceBasis": "date_scoped",
"priceDropped": null,
"priceChangePct": null,
"bargain": true,
"parsedScrapedAt": "2026-10-13T15:23:18.757Z",
"httpStatus": 200,
"status": "SUCCESS",
"error": null,
"amenities": [],
"images": [
"https://cf.bstatic.com/xdata/images/hotel/square600/916087802.jpg?k=8e98453d8d9d6d72515c4c91970200881cc910fc916a4495b5cdfadff1947a6e&o="
]
}

Download the dataset as JSON, CSV, or Excel directly from the Apify Console.

FieldTypeDescription
namestring | nullHotel name.
urlstring | nullBooking.com page URL.
hotelIdstring | nullStable hotel identifier.
citystring | nullCity (when available).
countrystring | nullCountry (when available).
pricenumber | nullNumeric price.
priceDisplaystring | nullDisplay-formatted price, e.g. Rp 281,250.
currencystring | nullCurrency code, e.g. IDR.
pricePerNightnumber | nullPrice divided by nights.
ratingnumber | nullGuest rating (0–10 scale).
reviewCountnumber | nullNumber of reviews.
starsnumber | nullHotel star rating.
locationstring | nullLocation string (detail pass).
distancestring | nullDistance text, e.g. 3.3 miles from downtown.
addressstring | nullStreet address (detail pass).
amenitiesarrayAmenity list (detail pass).
imagesarrayImage URLs.
freeCancellationboolean | nullWhether free cancellation is offered.
priceBasisstring | nulldate_scoped (your dates) or city_indicative (indicative nightly price).
priceDroppedboolean | nullWhether price is lower than the prior snapshot.
priceChangePctnumber | nullPercent change vs prior snapshot.
bargainboolean | nullFlagged as at/below destination median (opt-in).
parsedScrapedAtstring | nullISO timestamp of when the row was parsed.
httpStatusnumber | nullHTTP status of the page fetch.
statusstringRow classification: SUCCESS, PARTIAL, NOT_FOUND, BLOCKED, ERROR.
errorstring | nullError detail when status is not SUCCESS.

Fields are null when absent; amenities and images are always present (may be empty arrays).

Cost, limits, proxy

  • Memory: 512 MB (fixed).
  • Pricing: pay-per-result. $0.002 per hotel result (search + history + flags). $0.006 per hotel detail enrichment when enableDetail is on.
  • Proxy: defaults to Apify Residential proxy (required — Booking.com's WAF returns 202 challenge stubs to datacenter/AUTO traffic). Residential transfer is billed by Apify at plan rates (see maxMonthlyResidentialProxyGbytes on your plan). Local runs without a proxy may return PARTIAL rows.
  • Concurrency / limits: maxResults up to 5000; bargain flag needs ≥ 3 priced results in the destination cohort. Price history is kept for 90 days / last 30 runs.
  • Expected runtime: a small run (25 hotels, no detail) takes roughly a minute; a large run (e.g. 1,000+ hotels with detail enrichment over residential proxy) takes significantly longer and costs more via the detail add-on. Plan small runs first to gauge timing for your workload.

Recipes

Daily market scan with bargain flags

Track value properties in a destination and watch for drops:

{
"destination": "Bali",
"maxResults": 50,
"selectedCurrency": "USD",
"checkin": "2026-11-01",
"checkout": "2026-11-02",
"enableDetail": false,
"bargain": true
}

Scrape exactly the properties you care about. Get URLs from a prior search run's url field — don't guess slugs:

{
"hotelUrls": [
"https://www.booking.com/hotel/id/harris-tuban-bali.html",
"https://www.booking.com/hotel/id/ayana-resort-and-spa-bali.html"
],
"selectedCurrency": "IDR",
"checkin": "2026-11-01",
"checkout": "2026-11-02",
"lang": "en-us",
"enableDetail": true,
"bargain": false
}

Cross-currency planning

Scan the same destination in a different currency:

{
"destination": "Tokyo",
"checkin": "2026-12-01",
"checkout": "2026-12-05",
"selectedCurrency": "JPY",
"maxResults": 100,
"enableDetail": false,
"bargain": true
}

Troubleshooting

SymptomCauseFix
Row shows PARTIALPage returned but could not be fully parsedRerun in the Apify Console (proxy enabled). Check the destination/country is reachable.
Row shows BLOCKEDBooking.com refused the request (WAF / rate limit)Ensure proxy.apifyProxyGroups is ["RESIDENTIAL"] (the default). Datacenter/AUTO traffic is blocked by Booking.com's WAF.
Row shows NOT_FOUNDHotel page no longer exists or URL is wrongVerify the /hotel/{cc}/{slug}.html URL is live — best source is the url field of a prior search run, not a hand-typed slug.
Run fails with Invalid search URLsearchUrl is not a Booking search URLUse destination instead (e.g. "destination": "Bandung") — the Actor builds the URL for you. Any searchresults[.lang].html variant is accepted for searchUrl.
Row shows ERRORServer error or unexpected failureCheck httpStatus / error; retry after a moment.
bargain is false everywhereCohort median could not be computed (< 3 priced results)Run with a broader search or a destination with more hotels.
Prices look like landing-page rates, not your datespriceBasis is city_indicativeProvide a checkin/checkout so prices are quoted for your stay.
Local run returns partial/unreliable dataRunning without a proxyRun in the Apify Console where the Residential proxy is enabled.

FAQ

Q: How much does it cost? A: $0.002 per hotel result, plus $0.006 per hotel detail enrichment when enableDetail is on. A 25-hotel search without detail costs about $0.05 before platform usage.

Q: How fast is it? A: It's HTTP-first, so it's fast and light — a small run completes in about a minute. Large runs (thousands of hotels with detail enrichment) take longer and cost more via the detail add-on.

Q: Can I scrape private or protected content? A: No. Only public Booking.com pages. You are responsible for complying with Booking.com's terms and applicable privacy/consumer law.

Q: Is this legal? / What about the Booking.com ToS? A: You are responsible for the legality of your use in your jurisdiction and for respecting Booking.com's terms of service. This Actor only accesses public pages.

Q: Can I run it on a schedule? A: Yes — the Apify Console supports scheduled runs. This also powers the cross-run price history: each scheduled rerun compares prices against the 90-day history.

Q: Can I download the results? A: Yes — export the dataset as JSON, CSV, or Excel from the Apify Console, or pipe it to a webhook.

Q: Can I copy or republish this Actor? A: No. This Actor is proprietary. You may run it on Apify. You may not rebrand, republish, or claim authorship. See ./LICENSE.

Limitations

  • Public data only. You are responsible for ToS and privacy law.
  • Prices that cannot be quoted for your exact dates are marked priceBasis: city_indicative — indicative nightly rates, not stay quotes.
  • bargain requires ≥ 3 priced results in the same destination cohort to compute a median.
  • Booking.com's WAF can block datacenter traffic; if you hit BLOCKED rows, use the residential proxy opt-in (more expensive).
  • Detail fields (address, amenities, location, distance) come from the optional detail pass; they are null or empty when disabled or unavailable.

Run it

Open the Actor on Apify Console and click Start.

License

Proprietary. All rights reserved. Copyright (c) 2026 REXREUS.

You may run this Actor on Apify. You may not copy, rebrand, republish, or claim this Actor as your own. See ./LICENSE.