Airbnb Rental Scraper
Pricing
from $4.00 / 1,000 results
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
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
11 days ago
Last modified
Categories
Share
Airbnb Rental Scraper
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
Why this Actor?
| Feature | What you get |
|---|---|
| Search terms | Scrape one or more locations per run (up to 10 terms) |
| Price per night | Normalized number, derived from the total stay cost |
| capturedAt | Built-in timestamp — run nightly, join on url to build a price timeline |
| Status + httpStatus | Every run row tells you SUCCESS vs BLOCKED vs ERROR — no silent gaps |
| Next pagination token | Reports the next offset when a run legitimately halts — so you can resume deep searches on a re-run |
| Detail fields | Beds, bedrooms, baths, rating, review count from the same page (no extra requests) |
| Amenities | The full "What this place offers" list, on by default, one extra request per listing (toggle off to save) |
| Google Maps link | A ready-to-open mapsUrl pin link built from each listing's lat/lng — no extra requests |
| Currency + country pinning | Fixed price baseline across re-runs (e.g. IDR on airbnb.co.id) |
| CSV / JSON / Excel | Analytics-ready flat rows with built-in dataset views |
Quick start
- Open the Actor on Apify Console and click Start.
- Set your search terms (e.g.
Bali). - 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
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
searchTerms | string[] | Yes | — | Location search terms (e.g. Bali, Paris, Tokyo). Up to 10. |
maxResults | integer | No | 500 | Max listings per run, 1–1000. |
maxPagesPerSearch | integer | No | 3 | Result pages per term (≤5, each ~18 listings). |
country | select | No | us | Airbnb site to query (id → airbnb.co.id). |
currency | select | No | USD | Price currency (USD, EUR, IDR, GBP, JPY). |
checkin | date | No | 2026-12-01 | Check-in date. |
checkout | date | No | 2026-12-07 | Check-out date (after check-in, ≤30 days). |
adults | integer | No | 2 | Adult guests (1–16). |
includeAmenities | boolean | No | true | Fetch each listing's room page for the "What this place offers" amenities list. Adds ~1 request per listing (off = cheaper). |
proxy | proxy | No | — | 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}
| Field | Type | Description |
|---|---|---|
title / name | string / null | Listing title (name). Null on completion rows. |
url | string / null | Canonical listing URL. |
lat / lng | number / null | Coordinates. |
mapsUrl | string / null | Ready-to-open Google Maps link built from lat/lng. |
pricePerNight | number / null | Price per night in the chosen currency. |
rating / reviewCount | number / null | Guest rating and review count. |
location | string / null | Human-readable region (e.g. "Vila di Mengwi"). |
propertyType | string / null | Property type parsed from title prefix. |
beds / bedrooms / baths | number / null | Room counts when present. |
amenities | string[] / null | Available amenities ("What this place offers"), null when not requested. |
capturedAt | string | ISO timestamp — the price-tracking signal. |
status | enum | SUCCESS | POST_FILTER | BLOCKED | ERROR. |
httpStatus | number / null | HTTP status of the search request. |
searchTerm | string | Search term this row belongs to. |
checkin / checkout | date / null | Stay dates used. |
currency | string / null | Currency code. |
country | string / null | Country TLD used (e.g. co.id). |
nextPagination | string / null | Offset 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
includeAmenitieson, 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
| Symptom | Cause | Fix |
|---|---|---|
All rows status: BLOCKED | Airbnb rejected the request (403/429) | Wait, then re-run; attach a residential proxy for heavy use |
Row has status: ERROR | Page structure changed / parse failed | Re-run; check for an Airbnb layout update |
status: POST_FILTER only | Search returned no eligible listings | Verify the term spelling and dates |
rating: null | New listing with no reviews yet | Expected — rating only exists after reviews |
| Duplicate URLs | Overlapping pagination offsets | Built-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.
