Airbnb Scraper
Under maintenancePricing
from $2.99 / 1,000 listings
Airbnb Scraper
Under maintenanceScrape rich public Airbnb listing search and detail data with explicit access-boundary diagnostics when the site is unavailable or challenged.
Pricing
from $2.99 / 1,000 listings
Rating
0.0
(0)
Developer
w3crawler
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
Airbnb Scraper
Scrape rich public Airbnb search-result cards or specific public listing pages. The Actor returns normalized listing rows with pricing, stay parameters, ratings, review counts, property details, host information, badges, amenities, images, policies, availability text, coordinates, category ratings, and bounded review samples when Airbnb exposes them to the public page.
The Actor supports Airbnb search pagination, multiple search sources, global deduplication, post-collection sorting, optional detail-page enrichment, an HTTP structured-data fallback, and explicit diagnostic rows when the public page is blocked or does not expose usable data.
You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.
Start here
- Choose
searchmode for a city or one or more public/s/...URLs. - Choose
productUrlmode for a bounded list of public/rooms/<id>URLs. - Set
maxItemsto the number of dataset rows you want. - Keep
deepScrapeenabled when host, amenities, policies, coordinates, or reviews are needed. Disable it for a fast card-only export. - Use
maxPagesto bound search pagination.0follows observed Airbnb next-page links until the source ends or the result budget is satisfied.
Target URL: Airbnb
What this Actor extracts
Search-card data
- Listing ID, canonical listing URL, title, marketing description, property type, room type, location, position, and source search page.
- Visible stay price, original price, currency, number of nights, check-in/check-out dates, and calculated price per night.
- Average rating, review count, Guest favourite/Superhost badges, free-cancellation label, and public thumbnail/image URLs.
Detail-page data
- Full public description, guest capacity, bedrooms, beds, bathrooms, sleeping arrangements, and public location/address text.
- Amenities and amenity count, images and image count, public coordinates when exposed, availability/calendar text, cancellation policy, house rules, checkout time, and listing highlights.
- Host name, profile URL, Superhost status, tenure, public biography, host rating, host review count, response rate, and response-time label when exposed.
- Rating-category values and a bounded sample of public review cards with author, author location, reviewer profile/avatar URL, rating, date, stay type, and text.
Provenance and diagnostics
Dataset rows are intentionally listing-focused. Listing rows contain the public listing facts, source/search context, detailEnriched, and scrapedAt; internal Actor state such as record IDs, access flags, extraction method, retry state, and quality/debug metrics is not written to the dataset. If detail enrichment fails after a usable search card was found, the listing row is retained with detailEnriched: false. If no listing data is available, the Actor writes one minimal diagnostic row containing only url, error, and errorCode.
Input examples
Fast search-card export
{"mode": "search","location": "Paris","maxItems": 10,"maxPages": 1,"deepScrape": false,"includeReviews": false,"includeAmenities": false,"includeImages": true,"sortBy": "recommended"}
Filtered and globally sorted search
{"mode": "search","location": "Paris","keyword": "apartment","minRating": 4.5,"minReviewCount": 10,"guestFavouriteOnly": true,"sortBy": "rating_desc","maxItems": 25,"maxPages": 3,"deepScrape": true,"maxDetailItems": 10,"includeReviews": true,"maxReviews": 5}
Multiple search sources
Each source receives its own maxPages budget. Results are merged, deduplicated by Airbnb listing ID, sorted once, and capped by the global maxItems value.
{"mode": "search","startUrls": [{"url": "https://www.airbnb.com/s/Paris/homes"},{"url": "https://www.airbnb.com/s/London/homes"}],"maxItems": 50,"maxPages": 2,"deepScrape": false,"sortBy": "price_asc"}
Specific listing details
{"mode": "productUrl","productUrls": ["https://www.airbnb.com/rooms/38637542","https://www.airbnb.com/rooms/54337133"],"maxItems": 2,"deepScrape": true,"includeDescription": true,"includeAmenities": true,"includeImages": true,"includeReviews": true,"maxReviews": 10}
Developer controls
{"mode": "search","location": "Paris","maxItems": 5,"maxPages": 1,"requestDelayMs": 500,"maxConcurrency": 1,"maxRequestRetries": 2,"requestTimeoutSecs": 120,"requestHandlerTimeoutSecs": 300,"includeDiagnostics": true}
requestTimeoutSecs is the preferred timeout name. navigationTimeoutSecs remains as a backward-compatible alias; when both are present, requestTimeoutSecs takes precedence. requestDelayMs, maxConcurrency, and maxRequestRetries are bounded by the Actor input validator.
Input reference
Input sources
| Field | Type | Default | Description |
|---|---|---|---|
mode | string | search | search or productUrl. |
location | string | Paris | City, region, or neighbourhood used to build a search URL. |
searchUrl | string | — | One approved HTTPS Airbnb /s/... URL. |
startUrls | array | [] | Additional approved search URLs; each may be a string or { "url": "..." }. |
productUrls | array | [] | Approved HTTPS /rooms/<id> URLs for productUrl mode. Maximum 500. |
Stay parameters
| Field | Type | Default | Description |
|---|---|---|---|
checkIn | string | — | YYYY-MM-DD; must be provided with checkOut. |
checkOut | string | — | YYYY-MM-DD; must be after checkIn. |
guests | integer | 2 | Adult guest count, 1–16. |
currency | enum | USD | USD, EUR, GBP, CAD, AUD, INR, JPY, or SGD. |
locale | string | en-US | Airbnb language or language-region code. |
Search filters and ordering
| Field | Type | Default | Description |
|---|---|---|---|
propertyType | enum | any | Query filter: any, entire_home, private_room, or shared_room. |
priceMin | number | — | Minimum visible price per night in the requested currency. |
priceMax | number | — | Maximum visible price per night. |
keyword | string | — | Case-insensitive match across title, description, property, location, neighbourhood, and amenities. |
minRating / maxRating | number | — | Average rating bounds from 0 to 5. |
minReviewCount | integer | — | Minimum public review count. |
guestFavouriteOnly | boolean | false | Keep Guest favourite listings. |
superhostOnly | boolean | false | Keep Superhost listings. |
freeCancellationOnly | boolean | false | Keep listings visibly offering free cancellation. |
sortBy | enum | recommended | recommended, price_asc, price_desc, rating_desc, review_count_desc, or title_asc. Sorting is global across collected pages/sources. |
deduplicate | boolean | true | Deduplicate by listing ID across sources and cursor pages. |
Limits and detail enrichment
| Field | Type | Default | Description |
|---|---|---|---|
maxItems | integer | 50 | Global maximum dataset rows, 1–500. |
maxPages | integer | 0 | Search pages per source, 0–50; 0 follows observed next links. |
deepScrape | boolean | true | Visit selected detail pages. |
maxDetailItems | integer | 0 | Detail-page cap; 0 means every selected listing. |
includeDescription | boolean | true | Include public descriptions. |
includeAmenities | boolean | true | Collect visible/expanded amenities. |
includeImages | boolean | true | Include public image URLs and counts. |
includeReviews | boolean | true | Include bounded first-page public review cards. |
maxReviews | integer | 10 | Review cards per listing, 0–50. |
includeDiagnostics | boolean | true | Emit diagnostics when no listing data is available. |
Developer options and access
| Field | Type | Default | Description |
|---|---|---|---|
requestDelayMs | integer | 0 | Delay before extraction, 0–15,000 ms. |
maxConcurrency | integer | 1 | Concurrent browser requests, 1–5. |
maxRequestRetries | integer | 3 | Crawlee retries, 0–10. |
requestTimeoutSecs | integer | 120 | Browser/HTTP request timeout, 30–300 s. |
navigationTimeoutSecs | integer | — | Legacy alias for requestTimeoutSecs; the preferred field takes precedence when both are supplied. |
requestHandlerTimeoutSecs | integer | 300 | Per-page extraction timeout, 60–900 s. |
proxyConfiguration | object | — | Optional Apify proxy configuration passed to browser requests. Credentials are never logged. |
Pagination, deduplication, and sorting behavior
The browser extractor follows an actual Airbnb pagination link (Next, Next page, rel="next", or the next numbered link) and preserves the cursor and query parameters returned by Airbnb. It does not invent a cursor when the page does not expose a next link. Repeated URLs are skipped. maxPages is applied independently to every searchUrl/startUrls source.
When a non-default sortBy or a filter is used, the Actor collects eligible candidates across the allowed pages before selecting the global maxItems set. This prevents page-local sorting from returning the wrong records. Detail requests are created only for that final selected set.
With deduplicate: true, the first candidate for an Airbnb listing ID wins. A listing detail failure does not create a second row: the selected search row is retained with detailEnriched: false.
Output dataset
The dataset contains listing records and, only when public data is unavailable, minimal diagnostic records. Fields are optional because Airbnb can omit price, address, coordinates, review text, or other information depending on locale, dates, availability, and access state. Listing rows have url, listingId, title, and scrapedAt; diagnostic rows have exactly url, error, and errorCode.
Listing record field inventory
| Group | Fields |
|---|---|
| Identity and provenance | url, listingId, listingUrl, source, sourceDomain, sourceUrl, locale, scrapedAt |
| Search context | searchUrl, searchLocation, searchPage, pageNum, position |
| Listing | url, listingId, listingUrl, title, description, propertyType, roomType, guests, bedrooms, beds, bathrooms |
| Pricing and stay | price, priceTotal, pricePerNight, cleaningFee, serviceFee, currency, priceFormatted, originalPriceTotal, originalPriceFormatted, nights, checkIn, checkOut |
| Ratings and location | rating, reviewCount, ratingBreakdown, location, address, latitude, longitude, neighborhood |
| Host | hostName, hostProfile, isSuperhost, hostJoined, hostYearsHosting, hostMonthsHosting, hostAbout, hostReviewCount, hostRating, hostResponseRate, hostResponseTime |
| Amenities and media | isGuestFavourite, amenities, amenityCount, images, imageCount, thumbnail, badges |
| Stay policies | availability, houseRules, cancellationPolicy, freeCancellation, sleepingArrangement, checkoutTime |
| Reviews and detail status | reviews, detailEnriched, scrapedAt |
Each review object may contain reviewId, author, authorLocation, reviewerProfile, reviewerAvatar, rating, date, stayType, text, and isTranslated.
Example listing output
{"url": "https://www.airbnb.co.in/rooms/38637542","listingId": "38637542","listingUrl": "https://www.airbnb.co.in/rooms/38637542","source": "Airbnb public listings","sourceDomain": "www.airbnb.co.in","locale": "en-US","searchLocation": "Paris","title": "Private bedroom & bathroom 15 min away from Paris","propertyType": "Room","roomType": "Private room","guests": 2,"beds": 1,"bathrooms": 1,"priceTotal": 480,"pricePerNight": 96,"currency": "USD","nights": 5,"rating": 4.96,"reviewCount": 141,"ratingBreakdown": {"cleanliness": 4.9, "accuracy": 4.9, "checkIn": 4.9, "communication": 4.9, "location": 4.9, "value": 4.9},"location": "Asnières-sur-Seine, Île-de-France, France","hostName": "Valentina","hostProfile": "https://www.airbnb.co.in/users/show/123456","isSuperhost": true,"hostJoined": "10 years hosting","hostReviewCount": 144,"hostRating": 4.97,"hostResponseRate": 100,"hostResponseTime": "within an hour","isGuestFavourite": true,"amenities": ["Kitchen", "Wifi", "Dedicated workspace", "Pets allowed", "TV"],"amenityCount": 18,"imageCount": 20,"badges": ["Guest favourite", "Top 10% of homes"],"freeCancellation": true,"detailEnriched": true,"reviews": [{"reviewId": "review-1", "author": "Example Guest", "rating": 5, "date": "July 2026", "text": "A comfortable stay."}],"scrapedAt": "2026-09-05T12:00:00.000Z"}
Example diagnostic output
{"url": "https://www.airbnb.com/s/Paris/homes","error": "Airbnb public page presented a block or challenge","errorCode": "BLOCKED_SOURCE"}
Run summary and debug artifacts
The Actor writes OUTPUT_SUMMARY to the key-value store with status, itemCount, successfulCount, diagnosticCount, blockedCount, searchPagesProcessed, filteredOutCount, detailRequested, detailSucceeded, detailFailed, startUrlCount, dataAvailable, fallbackUsed, browser status flags, source, and completedAt. When a browser challenge is detected, a bounded debug-blocked.html artifact may be saved for troubleshooting.
Data availability and fallback behavior
The Actor uses public browser-rendered DOM evidence first, including stable Airbnb data-section and card attributes. It also reads public JSON-LD and deferred server-rendered state when the browser is unavailable. It does not bypass login, CAPTCHA, robots controls, or anti-bot challenges. If the browser returns no listing rows, the HTTP fallback is attempted; if that also fails, diagnostics explain the access boundary instead of inventing listing data.
Airbnb may intentionally generalize an address, hide coordinates, omit prices without dates, or vary content by locale and availability. Empty optional fields mean the public response did not expose that value during this run.
Cost and performance
The Actor's cost depends on Apify compute usage and the number of browser pages requested. Search pages and detail pages are the main cost drivers. Use deepScrape: false, maxDetailItems, maxPages, maxItems, low maxConcurrency, and a modest maxReviews value for economical runs. Higher concurrency can finish sooner but may increase traffic and challenge risk.
Proxy behavior
proxyConfiguration is passed to browser requests through Apify/Crawlee when supplied. The direct HTTP fallback does not replay proxy credentials; its provenance is labeled http_ssr. Do not place secrets in README examples or dataset fields.
Troubleshooting
The dataset contains diagnostics instead of listings
Check the diagnostic row's errorCode and the OUTPUT_SUMMARY key-value record. A BLOCKED_SOURCE, REQUEST_TIMEOUT, or NO_PUBLIC_DATA result is an explicit result of the public access boundary. Retry later, reduce concurrency, increase the timeout, or use a smaller page/detail budget. The Actor will not attempt to circumvent a challenge.
Search returns fewer rows than maxItems
Airbnb may expose fewer eligible listings after filters, duplicate removal, availability constraints, or pagination. Increase maxPages, relax filters, or use a broader location. Missing optional price/rating values are not fabricated to satisfy a filter.
Detail enrichment is partial
Inspect detailEnriched. The search card remains usable when a detail page is unavailable. Set maxDetailItems to control how many listings receive detail requests.
Pagination stops early
The Actor follows only observed Airbnb next links/cursors. A page with no next link, a repeated cursor, a source limit, or a public challenge ends that source safely. Check searchPagesProcessed and debug-blocked.html when diagnostics are enabled.
Support and legal
For support, include the Actor run ID, sanitized input, OUTPUT_SUMMARY, and representative errorCode values. Do not share credentials, cookies, private messages, or proxy secrets.
Use this Actor only for public data and in accordance with Airbnb's Terms of Service, robots rules, applicable law, and your contractual rights. Respect rate limits and personal-data obligations. This project is not affiliated with, endorsed by, or sponsored by Airbnb.