Airbnb Reviews Scraper avatar

Airbnb Reviews Scraper

Pricing

from $2.99 / 1,000 reviews

Go to Apify Store
Airbnb Reviews Scraper

Airbnb Reviews Scraper

Scrape public Airbnb listing reviews with pagination, category ratings, star distribution, host responses, and fail-closed access diagnostics.

Pricing

from $2.99 / 1,000 reviews

Rating

0.0

(0)

Developer

w3crawler

w3crawler

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Categories

Share

What does Airbnb Reviews Scraper do?

Airbnb Reviews Scraper extracts rich, public review records from one or more Airbnb listing pages. It is an Airbnb reviews API alternative for collecting listing context, ratings, reviewer details, review text, host responses, topic mentions, and pagination provenance in a normalized dataset.

The Actor opens Airbnb's public reviews surface in a real browser, activates the public sort/search controls when available, follows incremental review loading, and extracts hydrated review cards from the DOM. A bounded JSON-LD/HTML fallback keeps a run explainable when a browser cannot launch or a listing cannot be opened. The Actor does not log in, solve CAPTCHAs, cross paywalls, or bypass access controls.

Why use Airbnb Reviews Scraper?

Use it for accommodation research, guest-sentiment analysis, host-response monitoring, listing quality comparisons, travel-market reports, and review datasets for downstream analytics.

Main capabilities:

  • Rich review rows with listing, host, reviewer, review, response, image, rating, category-rating, and public topic-mention fields.
  • Multiple listing URLs in one run, URL normalization, global maxItems enforcement, and optional global review deduplication.
  • Incremental DOM pagination for Airbnb's scrollable review dialog, with a bounded maxPages control and stable reviewIndex, pagesScraped, and reviewsLoaded context.
  • Airbnb sort and search controls plus local deterministic filtering and sorting by rating/date.
  • Rating, reviewer-location, stay-text, language, date, keyword, and host-response filters.
  • Fail-closed diagnostics for blocked, empty, malformed, timed-out, and unavailable public pages. Diagnostics use pageType: "run_diagnostic" and are never presented as fake review rows.
  • A named OUTPUT_SUMMARY key-value record with counts, pagination, filter, fallback, and browser status information.
  • Apify scheduling, API access, integrations, run history, and monitoring.

What data can Airbnb Reviews Scraper extract?

Fields are omitted when Airbnb does not expose a public value. Arrays and nested objects are bounded so a single row remains practical to download.

GroupFields
Record and request provenancerecordId, recordType, url, listingId, listingUrl, requestedUrl, finalUrl, sourceDomain, ok, dataAvailable, accessStatus, targetKind, source, pageType, found, runStatus, extractionMethod, fallbackMode, scrapedAt
Listing contextlistingTitle, listingType, location, guestCapacity, bedroomCount, bedCount, bathroomCount, listingDescription, coverImageUrl, listingImages, amenities, amenitiesSnippet, amenityCount, isGuestFavourite
Listing ratings and review topicsoverallRating, totalReviewCount, starDistribution, categoryRatings, reviewTopics
Host contexthostName, hostProfileUrl, hostIsSuperhost, hostReviewCount, hostRating, hostYearsHosting, hostResponseRate, hostResponseTime
Review and pagination contextreviewIndex, reviewPage, pagesScraped, scrollsPerformed, reviewsLoaded, reviewId, rating, date, dateIso, stayType, stayDate, stayDateIso, reviewText, reviewLanguage, isTranslated, helpfulCount, reviewImages
Reviewer contextauthorName, authorInfo, reviewerLocation, reviewerYearsOnAirbnb, reviewerId, reviewerUrl, authorAvatar
Host response contexthasHostResponse, hostResponse, hostResponseAuthor, hostResponseAuthorId, hostResponseAuthorUrl, hostResponseDate, hostResponseDateIso
Diagnostic-only fieldsstatus, error, errorCode

reviewTopics is an array such as { "name": "Location", "count": 40 }. starDistribution contains percentage buckets such as 5_star; categoryRatings contains public sub-ratings such as cleanliness, accuracy, checkIn, communication, location, and value.

How to scrape Airbnb reviews

  1. Open the Actor's Input tab.
  2. Add one or more public Airbnb /rooms/<id> URLs to productUrls.
  3. Choose review limits, pagination, filters, sort order, and output fields.
  4. Start the Actor and open the Dataset tab when the run completes.
  5. Download the dataset or use the Actor's API tab to integrate it into an application, workflow, or scheduled job.

How much will it cost to scrape Airbnb reviews?

The Actor is compute-based. A one-listing, low-limit run normally uses less compute than a multi-listing run that loads many review pages. The main cost controls are maxItems, maxReviewsPerListing, maxPages, requestDelayMs, maxConcurrency, maxRequestRetries, and requestTimeoutSecs. The browser path is more complete but more expensive than the bounded HTTP fallback.

maxPages: 0 can load all publicly exposed review batches, so a listing with hundreds of reviews can use more browser time. Airbnb may require several physical scroll windows to request one additional batch; scrollsPerformed exposes that actual browser work. Filters are applied after the visible review cards are hydrated; a restrictive filter may still require pagination to find matches. Current run cost and platform pricing are shown in the Apify Console for your account.

Input

All input values are validated and normalized by the same runtime validator used by the test fixtures. URL rules are also checked in code because they are more specific than a generic JSON Schema pattern.

Input sources

FieldTypeDefaultDescription
productUrlsarray of stringsrequiredHTTPS Airbnb listing URLs such as https://www.airbnb.com/rooms/123456789. Region domains are accepted and normalized to www.airbnb.com. Duplicate listing IDs are removed.

Pagination and limits

FieldTypeDefaultDescription
maxItemsinteger0Preferred global maximum number of review rows across all listings. 0 means no global cap.
maxTotalReviewsinteger0Legacy alias for maxItems. If both are greater than zero, maxTotalReviews takes precedence.
maxReviewsPerListinginteger0Maximum rows emitted for each listing. 0 means no per-listing cap.
maxPagesinteger0Maximum bounded review pagination scan windows per listing. Airbnb may require several physical scroll events per window; 0 continues until the source is exhausted or stable loading stops.
deduplicatebooleantrueRemove repeated review IDs globally. If no ID exists, use normalized listing/author/date/text as a fallback key.

The browser path prefers the real scrollable review container and stops when the requested review target is reached, Airbnb exposes no more cards, the configured maxPages is reached, or loading remains stable for a bounded number of rounds. The HTTP fallback can expose only the bounded review sample present in public JSON-LD; it does not pretend that static HTML pagination is complete.

Review filters and sorting

FieldTypeDefaultDescription
reviewSearchstring""Case-insensitive phrase matched against review text, reviewer details, stay text, and host response text. The Actor also attempts Airbnb's public Search all reviews control.
minRatingnumber 05not setKeep reviews at or above this rating.
maxRatingnumber 05not setKeep reviews at or below this rating.
reviewerLocationstring""Case-insensitive substring filter for the public reviewer location line.
stayTypeFilterstring""Case-insensitive substring filter for displayed stay text, such as night or business.
reviewLanguagestring""Optional language code such as en or fr. Reviews without an exposed language attribute do not pass when this filter is set.
minReviewDateYYYY-MM-DD string""Inclusive minimum date. Month/year and relative Airbnb dates are normalized best-effort.
maxReviewDateYYYY-MM-DD string""Inclusive maximum date. Must be on or after minReviewDate.
hasHostResponseOnlybooleanfalseKeep only reviews with a detected public host response.
reviewSortenumBEST_QUALITYBEST_QUALITY, MOST_RECENT, HIGHEST_RATED, or LOWEST_RATED. Ties retain source order and missing values sort last.

The selected Airbnb sort is requested before scrolling, then the normalized rows are sorted locally as a deterministic safety net. Filters do not fabricate missing values: a minimum/date/language filter requires the corresponding public value.

Output options

FieldTypeDefaultDescription
includeListingMetadatabooleantrueInclude public listing, rating, amenities, and gallery fields.
includeReviewerDetailsbooleantrueInclude public reviewer profile, location/tenure, avatar, and profile URL fields.
includeHostResponsesbooleantrueInclude public host response text and response-author fields. hasHostResponse remains available for filtering/context.
includeReviewMediabooleantrueInclude public image URLs attached to review cards.
includeReviewTopicsbooleantrueInclude the public review-topic chips and counts shown by Airbnb.

Developer options

These controls are grouped under Developer Options in the input schema and are always bounded.

FieldTypeDefaultValid rangeDescription
requestDelayMsinteger1500015000Delay before listing/review requests and fallback fetches.
maxConcurrencyinteger215Maximum concurrent browser listing pages.
maxRequestRetriesinteger2010Crawlee retries for failed browser requests. HTTP fallback retries are separately bounded.
requestTimeoutSecsinteger9030300Navigation and fallback HTTP timeout per listing request.
saveDebugHtmlbooleantrueSave bounded debug-<listingId>.html artifacts when browser extraction fails.
saveDebugScreenshotbooleanfalseSave bounded debug-<listingId>.jpg artifacts alongside debug HTML.
proxyConfigurationobjectnot setCompatibility field. It is intentionally ignored; this Actor uses direct transparent requests without IP rotation.

Proxy credentials are never logged. Proxy settings are not a CAPTCHA, login, fingerprint, or access-control bypass, and the Actor does not claim that a proxy was used.

Input examples

1. Quick rich smoke test

This is a small browser test that should produce several rich records without loading every review.

{
"productUrls": [
"https://www.airbnb.com/rooms/1104883308160967951"
],
"maxItems": 3,
"maxReviewsPerListing": 3,
"maxPages": 2,
"reviewSort": "MOST_RECENT",
"requestDelayMs": 0,
"maxConcurrency": 1,
"requestTimeoutSecs": 60,
"saveDebugHtml": false
}

2. Multiple listings with a global cap

The global limit applies across all URLs, while the per-listing limit prevents one listing from consuming the complete result set.

{
"productUrls": [
"https://www.airbnb.com/rooms/1104883308160967951",
"https://www.airbnb.com/rooms/38637542"
],
"maxItems": 4,
"maxReviewsPerListing": 2,
"maxPages": 2,
"deduplicate": true,
"includeHostResponses": true,
"includeReviewerDetails": true,
"requestDelayMs": 0,
"maxConcurrency": 1,
"maxRequestRetries": 0,
"requestTimeoutSecs": 60,
"saveDebugHtml": false
}

3. Filtered sentiment sample

Filters are allow-listed and validated; no arbitrary code or sort expression is accepted.

{
"productUrls": [
"https://www.airbnb.com/rooms/1104883308160967951"
],
"reviewSearch": "comfortable",
"minRating": 5,
"reviewerLocation": "Virginia",
"hasHostResponseOnly": true,
"minReviewDate": "2026-01-01",
"reviewSort": "HIGHEST_RATED",
"maxItems": 5,
"maxPages": 5,
"requestDelayMs": 0,
"maxConcurrency": 1,
"maxRequestRetries": 0,
"requestTimeoutSecs": 60,
"saveDebugHtml": false
}

4. Review-only output with media/topics disabled

This is useful when downstream storage should contain the core text and response fields only.

{
"productUrls": [
"https://www.airbnb.com/rooms/1104883308160967951"
],
"maxItems": 10,
"includeListingMetadata": false,
"includeReviewerDetails": false,
"includeReviewMedia": false,
"includeReviewTopics": false,
"includeHostResponses": false,
"requestDelayMs": 0,
"maxConcurrency": 1,
"maxRequestRetries": 0,
"requestTimeoutSecs": 60,
"saveDebugHtml": false
}

5. Developer-controlled conservative run

{
"productUrls": [
"https://www.airbnb.com/rooms/1104883308160967951"
],
"maxItems": 5,
"maxPages": 1,
"requestDelayMs": 3000,
"maxConcurrency": 1,
"maxRequestRetries": 1,
"requestTimeoutSecs": 60,
"saveDebugHtml": false,
"saveDebugScreenshot": false
}

Output

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

The default dataset contains one normalized review record per emitted review. Rows with pageType: "run_diagnostic" are transparent diagnostics for blocked, empty, or failed listings and should be separated from normal review rows in downstream processing.

Representative rich review item

The following is a shortened, anonymized example. Array lengths vary with the public page and input limits.

{
"recordId": "123456789#review-987654321",
"recordType": "review",
"url": "https://www.airbnb.com/rooms/123456789",
"listingId": "123456789",
"listingUrl": "https://www.airbnb.com/rooms/123456789",
"requestedUrl": "https://www.airbnb.com/rooms/123456789",
"finalUrl": "https://www.airbnb.co.in/rooms/123456789?locale=en",
"sourceDomain": "www.airbnb.co.in",
"ok": true,
"dataAvailable": true,
"accessStatus": "ok",
"targetKind": "listing",
"source": "Airbnb listing reviews",
"pageType": "review",
"found": true,
"extractionMethod": "playwright_dom",
"fallbackMode": "browser",
"listingTitle": "Example central apartment",
"listingType": "Entire apartment",
"location": "Example City, Example Region",
"guestCapacity": 2,
"bedroomCount": 1,
"bedCount": 1,
"bathroomCount": 1,
"listingImages": ["https://a0.muscache.com/im/pictures/example-cover.jpg"],
"amenities": ["Wifi", "Kitchen", "Air conditioning"],
"amenityCount": 24,
"isGuestFavourite": true,
"overallRating": 4.9,
"totalReviewCount": 128,
"starDistribution": { "5_star": 96, "4_star": 4 },
"categoryRatings": { "cleanliness": 4.9, "accuracy": 4.8, "communication": 5, "location": 4.9 },
"reviewTopics": [{ "name": "Location", "count": 40 }, { "name": "Cleanliness", "count": 30 }],
"hostName": "Example host",
"hostIsSuperhost": true,
"reviewIndex": 1,
"pagesScraped": 2,
"scrollsPerformed": 12,
"reviewsLoaded": 18,
"reviewId": "987654321",
"authorName": "Example guest",
"authorInfo": "Example region",
"reviewerLocation": "Example region",
"reviewerUrl": "https://www.airbnb.com/users/profile/111222333",
"rating": 5,
"date": "March 2026",
"dateIso": "2026-03-01T00:00:00.000Z",
"stayType": "Stayed a few nights",
"reviewText": "A clean and comfortable stay near public transport.",
"reviewLanguage": "en",
"isTranslated": false,
"hasHostResponse": true,
"hostResponse": "Thank you for staying with us.",
"hostResponseAuthor": "Example host",
"hostResponseDate": "April 2026",
"scrapedAt": "2026-09-05T12:00:00.000Z"
}

Diagnostic item

{
"recordId": "123456789#diagnostic-blocked",
"recordType": "diagnostic",
"url": "https://www.airbnb.com/rooms/123456789",
"listingId": "123456789",
"requestedUrl": "https://www.airbnb.com/rooms/123456789",
"finalUrl": "https://www.airbnb.com/rooms/123456789",
"sourceDomain": "www.airbnb.com",
"status": 403,
"ok": false,
"dataAvailable": false,
"accessStatus": "blocked",
"targetKind": "listing",
"source": "Airbnb listing reviews",
"pageType": "run_diagnostic",
"found": false,
"runStatus": "BLOCKED_FAIL_CLOSED",
"error": "Airbnb public page returned a CAPTCHA, access-denied, or rate-limit page.",
"errorCode": "BLOCKED",
"extractionMethod": "http_html",
"fallbackMode": "http",
"scrapedAt": "2026-09-05T12:00:00.000Z"
}

OUTPUT_SUMMARY key-value record

{
"status": "SUCCEEDED",
"itemCount": 25,
"successfulCount": 25,
"diagnosticCount": 0,
"blockedCount": 0,
"startUrlCount": 2,
"pagesProcessed": 8,
"scrollsProcessed": 24,
"filteredOutCount": 12,
"dataAvailable": true,
"fallbackUsed": false,
"browserBlocked": false,
"browserInfraFailure": false,
"source": "airbnb_public_reviews",
"completedAt": "2026-09-05T12:00:00.000Z"
}

Pagination, multiple listings, and fallback behavior

Airbnb currently presents reviews in a scrollable dialog rather than a stable numbered URL sequence. The Actor tracks the initial/incremental scan windows in pagesScraped and the physical DOM scroll work in scrollsPerformed. maxPages bounds those scan windows per listing; maxItems is global across all normalized listing URLs; maxReviewsPerListing is applied per listing; and deduplication is global across the run.

When the browser path fails for one listing, the Actor tries a direct public JSON-LD/HTML fallback for that listing only. A fallback success is marked with extractionMethod: "http_ssr_jsonld" and fallbackMode: "http"; fallback output may contain fewer reviews because static JSON-LD is not the full modal feed. If both paths fail, one diagnostic row is emitted for that listing. No synthetic review is created.

Troubleshooting

  • No review rows: Check OUTPUT_SUMMARY, then inspect diagnostic rows and any debug-<listingId>.html or .jpg artifacts. A restrictive filter can intentionally produce NO_MATCHING_REVIEWS.
  • Blocked or CAPTCHA page: The Actor stops that source with BLOCKED_FAIL_CLOSED. Increase pacing, lower concurrency, respect Airbnb's policies, and try again later. The Actor does not solve the challenge.
  • Only a few reviews: Confirm maxPages and maxReviewsPerListing. Static HTTP fallback is intentionally bounded; the browser path is required for deeper public review loading.
  • Search did not appear: Airbnb may change its public UI. The Actor still applies the same keyword locally to hydrated text and reports the extraction path in each row.
  • API/integration output: Use the Dataset and API tabs in the Apify Console. The named OUTPUT_SUMMARY key is in the default key-value store.

Use this Actor only for public information and in accordance with Airbnb's Terms of Service, robots guidance, applicable privacy/data-protection laws, and your own authorization. Do not use it to collect private data, evade access controls, harass reviewers or hosts, or make decisions about people. Airbnb is a trademark of its respective owner; this Actor is an independent tool and is not affiliated with or endorsed by Airbnb.