Airbnb Search Scraper — Prices, Ratings & Discounts by Location
Pricing
from $2.00 / 1,000 results
Airbnb Search Scraper — Prices, Ratings & Discounts by Location
Scrape Airbnb search results for any location - title, price with discount breakdown, rating, review count, coordinates, images. No login, no API key.
Airbnb Search Scraper
Scrapes Airbnb search results for any location — title, price with discount breakdown, rating, review count, coordinates, images. No login, no API key.
Useful for market research on short-term rental pricing, competitor listing tracking, and building a location-price dataset across many cities.
What makes this different
An unrecognized location doesn't quietly return the wrong thing. Search a place name Airbnb can't resolve, and it doesn't error — it silently substitutes a global "explore" feed full of real-looking listings from random cities worldwide. There's exactly one tell in the response that distinguishes a genuine match from that fallback, and this Actor checks it before returning anything, so a typo'd location fails loudly instead of quietly shipping listings from the wrong place entirely.
Duplicate listings across pages are caught and compensated for, not just counted. Airbnb repeats certain listings — apparently boosted or promoted ones — across multiple pages of the same search; the very first listing on page 1 can reappear verbatim on page 2. A scraper that doesn't dedupe would report "60 results" that are actually 40-some unique listings padded with repeats. This Actor deduplicates by listing ID within a run and pages further to make up the difference, so the count you ask for is the count of distinct listings you get.
The full discount picture, not just a single price. price_display and price_original_display are both kept, along with has_discount, so a promotional price is visible as exactly that — not indistinguishable from a listing's normal rate.
Input
| Field | Type | Notes |
|---|---|---|
locations | array | City, region, or "City, Country" — same as Airbnb's own search box. |
currency | string | 3-letter code, e.g. USD, EUR, IDR. |
priceMin / priceMax | integer | Optional nightly price range, in the chosen currency. |
maxItems | integer | Per location, deduplicated. 0 walks every page available. |
incremental | boolean | Only listings not seen in previous runs. |
proxyConfiguration | object | Not normally needed. |
Output
{"listing_id": "airbnb.com:672988127335230371","title": "Room in Paris","subtitle": "Room with terrace & art exhibition","rating": 4.88,"review_count": 151,"price_display": "$558","price_original_display": "$617","has_discount": true,"badges": ["Guest favorite"],"latitude": 48.82888,"longitude": 2.32166,"url": "https://www.airbnb.com/rooms/672988127335230371"}
A location Airbnb doesn't recognize fails that location's run with a clear message rather than returning listings from somewhere else entirely. Each run also writes a RUN_COVERAGE record to the key-value store with what was requested, what came back, and any per-location failures.
Local development
pip install -r requirements.txtpython test_local.py Paris --max 40 --out sample_output.jsonpython test_local.py "Bali, Indonesia" --currency USD --price-min 20 --price-max 100
sample_output.json is real output from a live 40-listing run, deduplicated across pages.