Airbnb Listings Scraper - Prices, Ratings & Geo
Pricing
from $1.26 / 1,000 results
Airbnb Listings Scraper - Prices, Ratings & Geo
Scrapes Airbnb stay listings from the search page's own embedded data: price, rating, coordinates, photos and room type. Deduplicates the listings Airbnb repeats within a page, decodes the real listing id, and reports the currency the page actually rendered.
Pricing
from $1.26 / 1,000 results
Rating
0.0
(0)
Developer
Ibnu Adzim
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
11 days ago
Last modified
Categories
Share
Airbnb Listings Scraper — Prices, Ratings & Geo
Reads Airbnb stay listings from the search page's own embedded data — the
data-deferred-state blob the site server-renders. No API key, no GraphQL
call, no account.
What you get
recordType | One per | Carries |
|---|---|---|
LISTING | stay | real listing id and /rooms/ URL, name, room type and area, latitude/longitude, rating (numeric and as Airbnb labelled it), badges, photos, and the price with the window it actually covers |
SEARCH_SUMMARY | destination | listings returned vs raw result objects, duplicates removed within and across pages, the currency requested vs the one rendered, and the stay lengths the prices cover |
ERROR | failed input | a named reason |
Four things the payload will mislead you about
1. One page reports 48 results that are 30 listings. The deferred state
carries the set across overlapping sections — 18 ids appear exactly twice, same
title, same price, nothing malformed. Counting result objects overstates by
60%. This actor deduplicates within a page as well as across pages, and
reports rawResultObjects beside listingsReturned so the gap stays visible.
2. The currency follows the exit IP. Same listing, same session, seconds apart:
(no currency parameter) -> Rp 17,326,505 <- Rupiah, from the addresscurrency=USD -> $3,246currency=EUR -> EUR 2,785
Nothing asked for Rupiah. So a local run and a cloud run through a US proxy
silently produce different numbers for the same listing. An unknown code isn't
refused either — it's sticky, keeping whatever was in effect. This actor
always sends the currency explicitly, validates it, and reports
currenciesReturned read from the rendered price symbol so a mismatch is
visible rather than assumed away.
3. The headline price is a stay total, not a nightly rate. With no dates, Airbnb invents its own window:
no dates "$3,246" qualifier "for 5 nights"checkin/checkout supplied "$795" qualifier "for 3 nights"
Reading that as a per-night price is wrong by whatever the window happened to
be — and the window changes with the search. Every row carries
priceQualifier, priceNights and priceIsStayTotal, and
pricePerNightApprox is derived only when the night count is actually
known.
4. The listing id is base64 and isn't the one in the URL.
RGVtYW5kU3RheUxpc3Rpbmc6MTY3NTM4… decodes to
DemandStayListing:1675389828808490095. The opaque form joins to nothing —
including Airbnb's own /rooms/<id> URLs. Decoded here, with the raw form kept
beside it.
Smaller things
- Rating is a localized string. A listing with no reviews comes back as the
word "New", not
0ornull. Both survive:ratingValue(numeric, null for New),ratingLabel(Airbnb's own text) and anisNewListingflag — so a new listing never gets averaged in as a zero. - Pagination cursors are constructed, not scraped. They're base64 of
{"section_offset":0,"items_offset":N,"version":1}stepping by 18, and the server accepts ones this actor builds — so there's no cursor bookkeeping and no dependence on the page exposing them. titleis the room type and area ("Apartment in Paris"); the human name of the place is a separate field.
Notes
airbnb.com/robots.txtscopes its Claude rules to specific paths and leaves/s/and/rooms/allowed.- DataDome runs on this origin. It did not challenge during development,
but a datacenter exit is far more likely to be challenged than a residential
one. A challenge is reported as a named
challengederror rather than silently returning nothing. - The proxy setting changes the data here, not just the routing — see the currency point above. Residential is recommended for anything large.
- Pages are ~930 KB each, so pacing defaults to 3 seconds.
