Airbnb Rental Scraper avatar

Airbnb Rental Scraper

Pricing

from $4.00 / 1,000 results

Go to Apify Store
Airbnb Rental Scraper

Airbnb Rental Scraper

Search Airbnb rental listings and get clean, price-tracking-ready data — no browser, no login.

Pricing

from $4.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

11 days ago

Last modified

Categories

Share

Airbnb Rental Scraper

Airbnb Rental Scraper banner

Search Airbnb rental listings and get clean, price-tracking-ready data — no browser, no login.

HTTP-only search summaries · price per night · capturedAt signal · pay per result

Quick Start Apify Node.js

Why this Actor?

FeatureWhat you get
Search termsScrape one or more locations per run (up to 10 terms)
Price per nightNormalized number, derived from the total stay cost
capturedAtBuilt-in timestamp — run nightly, join on url to build a price timeline
Status + httpStatusEvery run row tells you SUCCESS vs BLOCKED vs ERROR — no silent gaps
Next pagination tokenReports the next offset when a run legitimately halts — so you can resume deep searches on a re-run
Detail fieldsBeds, bedrooms, baths, rating, review count from the same page (no extra requests)
AmenitiesThe full "What this place offers" list, on by default, one extra request per listing (toggle off to save)
Google Maps linkA ready-to-open mapsUrl pin link built from each listing's lat/lng — no extra requests
Currency + country pinningFixed price baseline across re-runs (e.g. IDR on airbnb.co.id)
CSV / JSON / ExcelAnalytics-ready flat rows with built-in dataset views

Quick start

  1. Open the Actor on Apify Console and click Start.
  2. Set your search terms (e.g. Bali).
  3. Download the dataset as JSON, CSV, or Excel.
{
"searchTerms": ["Bali"],
"maxResults": 100,
"country": "id",
"currency": "IDR",
"checkin": "2026-12-01",
"checkout": "2026-12-07",
"adults": 2
}

How it works

Public Airbnb search pages → structured listing rows + completion row → dataset

For each search term, the Actor requests public search pages with itemsOffset pagination, parses the embedded JSON, dedupes listings, and emits one flat row per listing plus a terminal status row per term (POST_FILTER). No browser, no login — the detail fields come from the same page. When includeAmenities is on, it makes one extra request per listing to the room page for the "What this place offers" list (best-effort; failures stay null).

Input

FieldTypeRequiredDefaultDescription
searchTermsstring[]Yes—Location search terms (e.g. Bali, Paris, Tokyo). Up to 10.
maxResultsintegerNo500Max listings per run, 1–1000.
maxPagesPerSearchintegerNo3Result pages per term (≤5, each ~18 listings).
countryselectNousAirbnb site to query (id → airbnb.co.id).
currencyselectNoUSDPrice currency (USD, EUR, IDR, GBP, JPY).
checkindateNo2026-12-01Check-in date.
checkoutdateNo2026-12-07Check-out date (after check-in, ≤30 days).
adultsintegerNo2Adult guests (1–16).
includeAmenitiesbooleanNotrueFetch each listing's room page for the "What this place offers" amenities list. Adds ~1 request per listing (off = cheaper).
proxyproxyNo—Optional residential proxy for heavy use.

Output

One row per listing (plus one completion row per search term):

{
"title": "Vila 3KT Canggu Oasis | Penginapan dengan Kolam Renang Tropis",
"url": "https://www.airbnb.com/rooms/1775283437968243475",
"lat": -8.6321,
"lng": 115.1525,
"mapsUrl": "https://www.google.com/maps?q=-8.6321,115.1525",
"pricePerNight": 1245750,
"rating": null,
"reviewCount": null,
"location": "Rumah di Kuta Utara",
"propertyType": null,
"beds": 3,
"bedrooms": 3,
"baths": 3,
"amenities": null,
"capturedAt": "2026-10-11T16:56:42.730Z",
"status": "SUCCESS",
"httpStatus": null,
"searchTerm": "Bali",
"checkin": "2026-12-01",
"checkout": "2026-12-07",
"currency": "IDR",
"country": "co.id",
"nextPagination": null
}
FieldTypeDescription
title / namestring / nullListing title (name). Null on completion rows.
urlstring / nullCanonical listing URL.
lat / lngnumber / nullCoordinates.
mapsUrlstring / nullReady-to-open Google Maps link built from lat/lng.
pricePerNightnumber / nullPrice per night in the chosen currency.
rating / reviewCountnumber / nullGuest rating and review count.
locationstring / nullHuman-readable region (e.g. "Vila di Mengwi").
propertyTypestring / nullProperty type parsed from title prefix.
beds / bedrooms / bathsnumber / nullRoom counts when present.
amenitiesstring[] / nullAvailable amenities ("What this place offers"), null when not requested.
capturedAtstringISO timestamp — the price-tracking signal.
statusenumSUCCESS | POST_FILTER | BLOCKED | ERROR.
httpStatusnumber / nullHTTP status of the search request.
searchTermstringSearch term this row belongs to.
checkin / checkoutdate / nullStay dates used.
currencystring / nullCurrency code.
countrystring / nullCountry TLD used (e.g. co.id).
nextPaginationstring / nullOffset to resume on a re-run.

Export as JSON, CSV, or Excel from the dataset — built-in views flatten all fields for spreadsheet use.

Cost, limits, proxy

  • Memory: 256 MB profile (sufficient; Node + got-scraping baseline).
  • Concurrency: 1 (sequential per term) — HTTP-only, deliberately low for anti-bot friendliness.
  • Proxy: none by default. Attach a residential proxy for heavy or long-running searches.
  • Pricing: $0.0007 per listing (≈$0.70 / 1,000 rows). Error/blocked rows are free.
  • Expected runtime: a single-term run (3 pages, ~30–50 listings) completes in seconds; a 10-term run in a few minutes. With includeAmenities on, expect roughly double the runtime (one extra request per listing).
  • Scale note: Airbnb serves a limited unique result set per query region (a Bali run converges to ~30 unique listings across offsets); pagination stops on dedupe. For deep coverage, split into multiple specific search terms.

Recipes

Nightly price watch (Bali, IDR)

{
"searchTerms": ["Bali"],
"maxResults": 100,
"country": "id",
"currency": "IDR",
"checkin": "2026-12-01",
"checkout": "2026-12-07"
}

Run nightly, join prior runs on url, and chart pricePerNight over capturedAt.

Multi-market compare (US + EU, USD)

{
"searchTerms": ["New York", "Lisbon", "Barcelona"],
"maxResults": 90,
"country": "com",
"currency": "USD"
}

Lead-gen export (high-rated villa leads)

{
"searchTerms": ["Canggu", "Seminyak", "Ubud"],
"maxResults": 300,
"country": "id",
"currency": "IDR"
}

Export CSV, filter rating >= 4.5, load into your CRM.

Troubleshooting

SymptomCauseFix
All rows status: BLOCKEDAirbnb rejected the request (403/429)Wait, then re-run; attach a residential proxy for heavy use
Row has status: ERRORPage structure changed / parse failedRe-run; check for an Airbnb layout update
status: POST_FILTER onlySearch returned no eligible listingsVerify the term spelling and dates
rating: nullNew listing with no reviews yetExpected — rating only exists after reviews
Duplicate URLsOverlapping pagination offsetsBuilt-in dedupe keeps the first occurrence

FAQ

Q: Does this use a browser (Playwright)? A: No. It is HTTP-only (Node + got-scraping) — faster and far cheaper than browser-based scrapers.

Q: How fast is it? A: A single search (3 pages) completes in seconds. Ten search terms complete in a few minutes on the 256 MB profile.

Q: Can I scrape full listing pages / reviews / calendars? A: Not in v1. This Actor ships clean search summaries (price, rating, rooms, location, coords). Detail-page depth is a future direction and would cost more.

Q: How does price tracking work? A: Each row carries capturedAt. Run the Actor on a schedule with fixed dates and currency, then join runs on url.

Q: What if I type a region name that doesn't exist (typo, wrong spelling)? A: Airbnb silently falls back to a global/default search, so an unrecognized slug can return listings from anywhere (e.g. a typo of "Bali" may surface "Cartagena" rentals). Always use a real, working Airbnb location slug, and spot-check the location / searchTerm columns in the output. This Actor echoes your exact searchTerm on every row so mismatches are easy to spot.

Q: How does the amenities ("What this place offers") list work? A: Amenities live only on each listing's room detail page, not the search page. Each listing costs one extra HTTP request (~2x requests). It's on by default; set includeAmenities: false to halve requests for cheaper runs.

Q: What about legal / ToS? A: The Actor only reads public pages. You are responsible for complying with Airbnb's ToS and applicable law in your jurisdiction.

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 it as your own.

Limitations

  • Public data only. No login, cookies, or auth-gated content.
  • Airbnb caps the unique search result set per region; heavy pagination returns repeats (handled by dedupe).
  • Anti-bot blocks can occur under aggressive re-runs; low concurrency and optional residential proxy mitigate this.

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.