Booking.com is the largest accommodation marketplace on the web, which makes it the reference source for hotel pricing, availability and guest sentiment. It is also heavily defended, and it has one property that catches most people out: the price you see depends on where you appear to be browsing from. That single fact changes how you have to build the scraper.
Set Expectations First
This is not a requests.get() target. Expect:
- Bot protection that blocks datacenter IP ranges quickly.
- Client-side rendering — prices and availability populate after JavaScript runs.
- Geo and currency variation — the same room on the same dates can be presented differently to visitors in different countries.
- Session and cookie state that affects what you are shown.
- Obfuscated, rotating markup, so hard-coded selectors decay fast.
Booking.com also runs an official Partner / Affiliate API for approved partners. If your use case fits it, it is far more stable and lower risk than scraping. Check that first.
What a Listing Exposes
- Property name, star rating, and property type.
- Nightly price for the searched dates, plus taxes and fees where shown.
- Availability — whether rooms remain, and scarcity messaging.
- Review score and review count, plus individual guest reviews.
- Location, distance from a landmark or centre.
- Amenities, cancellation policy, and room configuration.
Guest reviews carry reviewer names and nationalities — that is personal data, and it changes your obligations. More on that below.
The Part Most Guides Miss: Price Varies by Visitor Country
Travel platforms routinely localise pricing presentation — currency, tax display, regional promotions and available rate plans can all differ depending on where the visitor appears to be. Scraping Booking.com from a single datacenter IP in one country therefore gives you one market's view, not the market.
If you are doing rate-parity checks, competitive pricing, or building a fare aggregator, you need to collect the same property and dates from multiple countries. That means residential proxies with country targeting — not as an anti-blocking measure, but because the country is a variable in your dataset. It is the same requirement behind travel fare aggregation.
The Setup That Works
A real browser plus country-matched residential exits:
from playwright.sync_api import sync_playwright
ENDPOINT = "geo.spyderproxy.com:12321"
def fetch(url, country="gb", locale="en-GB"):
proxy = {"server": f"http://{ENDPOINT}",
"username": f"USERNAME-country-{country}", "password": "PASSWORD"}
with sync_playwright() as p:
browser = p.chromium.launch(headless=True, proxy=proxy)
ctx = browser.new_context(locale=locale)
page = ctx.new_page()
page.goto(url, wait_until="networkidle", timeout=60000)
page.wait_for_timeout(2500) # let prices settle
html = page.content()
browser.close()
return html
Set the country in your proxy username (your dashboard shows the exact format) and keep the browser locale consistent with it — a UK IP paired with a US locale is an obvious mismatch. Then crawl in two phases: collect property URLs from paginated search results, then visit each property. That is the list crawling pattern.
One deliberate omission: no CSS selectors here. Booking.com's class names are generated and rotate; anything printed today would be wrong within weeks. Inspect the live page and anchor on stable attributes or text landmarks. Where the page embeds JSON-LD, parse that instead of the DOM — it is far more durable.
Collecting at Scale Without Getting Blocked
- Rotate residential IPs and match the country to the market you are measuring.
- Constrain the search space — specific cities, date windows and property types beat crawling everything.
- Remember dates multiply your work: every check-in/check-out combination is a separate request. Prioritise the windows that matter commercially.
- Throttle and randomise. Prices move daily, not by the second.
- Retry on a fresh IP after a challenge instead of hammering the blocked one.
- Cache and resume so an interrupted run does not restart — see advanced web scraping in Python.
Store results as JSON to keep the nested room/rate structure, or flatten for analysis (JSON vs CSV).
Terms, Copyright and Personal Data
- Collect only public search and listing pages. Never log in to scrape.
- Booking.com is an EU-headquartered business and its Terms restrict automated access — read them before scaling.
- Guest reviews are personal data under the GDPR, and they are copyrighted by their authors. Prefer aggregate review scores over storing individual review text and reviewer identities.
- Take price and availability for analysis; do not republish listing content wholesale.
Educational, not legal advice — see is web scraping legal, and get proper advice for a commercial build. The general rules in web scraping best practices apply throughout.
What Teams Build With It
- Rate parity monitoring — hotels checking their rates across channels and markets.
- Competitive pricing — revenue managers tracking a comp set by date.
- Market analysis — average daily rate and occupancy proxies by city and season.
- Fare aggregation — comparison products that need multi-market pricing.
Frequently Asked Questions
Can you scrape Booking.com?
Technically yes, but not with simple HTTP requests. Booking.com uses bot protection and renders prices client-side, so a reliable scraper needs a headless browser such as Playwright routed through rotating residential proxies. Check whether their official Partner or Affiliate API covers your use case first, as it is more stable and lower risk.
Why do Booking.com prices change depending on the proxy country?
Travel platforms localise pricing presentation — currency, tax display, regional promotions and available rate plans can differ by the visitor's apparent location. If you scrape from one country you capture one market's view. For rate parity or competitive pricing you need country-targeted residential IPs so the market becomes a controlled variable in your dataset.
Is scraping Booking.com legal?
Collecting public data is broadly permitted in many jurisdictions, but Booking.com's Terms of Service restrict automated access, and guest reviews contain personal data governed by the GDPR as well as being copyrighted by their authors. Stay on public pages, never log in, prefer aggregate review scores over storing individual reviews, and take legal advice for commercial use.
What data can you extract from Booking.com?
Public listings typically expose the property name, star rating and type, nightly price for the searched dates plus taxes and fees, availability and scarcity messaging, review score and count, location and distance from the centre, amenities, cancellation policy and room configuration.
Conclusion
Scraping Booking.com is an advanced job with one twist that defines the architecture: price depends on where you appear to browse from. Use a headless browser for the rendering, country-targeted residential IPs so geography becomes a deliberate variable rather than an accident, stable-attribute parsing that survives redesigns, tight date and city scoping, and a careful line on reviews and personal data.
Collect hotel pricing from any market: SpyderProxy residential proxies from $2.75/GB — country and city targeting across 195+ countries.