You want to know what a two-bedroom apartment rents for in Lisbon in November, how entire homes compare with private rooms, and whether "Guest favorite" listings charge more. Airbnb shows you all of this, eighteen cards at a time, with a ranking that changes every time you reload. Reading it by hand does not scale past the first page. Here is how I do it with the Airbnb Listings Scraper, an Apify Actor that turns a search into one flat row per listing, without collecting anything about hosts or guests.
The question before the tool
A market study is only as good as its question. Three examples that work well with search data:
- Benchmark for a host or property manager: what do comparable listings (same area, same size, same dates) charge per night, and where does my listing sit in that distribution?
- Investor screening: how many entire homes are listed in a neighbourhood, at what price and with what review volume?
- Seasonal pricing: how does the median nightly price for a fixed stay move when you run the same search every week?
All three need the same thing: a fixed stay (dates and guests), a fixed currency, and enough listings to compute a distribution rather than a handful of anecdotes.
Step 1: run the search
The input below is the one behind the public task "Entire homes on Airbnb in Lisbon". It asks for entire homes only, in euros, for two adults, and stops at 50 listings. Without dates, Airbnb proposes a one-week stay per listing, which is fine for a first look.
{
"location": "Lisbon, Portugal",
"adults": 2,
"roomTypes": ["entire_home"],
"currency": "EUR",
"maxResults": 50
}
The fields not shown keep the Actor's defaults. For a real benchmark, add checkIn and checkOut so that every row describes the same stay, and raise maxResults to 300 or more. The Actor keeps one browsing session per search for a consistent ranking, removes duplicate listings, and stops exactly at the number you ask for, so the cost of a run is known before you start.
The Actor is pay-per-event: you pay a fixed price per listing saved, nothing else. A few hundred listings take a couple of minutes.
Step 2: look at one row
Every row has every column, in the same order, run after run. Here is a real row from a Lisbon search on airbnb.com (USD, 20 to 23 November 2026, two adults), shortened to the columns that matter for the study:
{
"platformListingId": "29990558",
"title": "Tram 28 - Marvelous Balcony & Tagus River Views 3D",
"propertyType": "Apartment",
"roomType": "entire_place",
"city": "Lisbon",
"latitude": 38.71785,
"longitude": -9.12793,
"checkIn": "2026-11-20",
"checkOut": "2026-11-23",
"nights": 3,
"guests": 2,
"currency": "USD",
"pricePerNight": 135.45,
"priceTotal": 407,
"priceBeforeDiscount": null,
"rating": 4.92,
"reviewCount": 726,
"bedrooms": 1,
"beds": 2,
"bathrooms": 1,
"badges": ["Guest favorite"],
"isSuperhost": false,
"cancellationPolicy": "free_cancellation",
"searchRank": 1
}
Two columns deserve a note. pricePerNight is the base nightly rate from Airbnb's price breakdown, before discounts, fees and taxes. priceTotal is what the guest pays for the stay. For an "effective nightly price" that includes everything, divide priceTotal by nights; that is the number a traveller actually compares.
Step 3: the analysis in a spreadsheet
Export the dataset as CSV or Excel from the run's Output tab (or pull it from the Apify API). With the columns above, a few pivot tables answer most questions:
| Question | Columns to use |
|---|---|
| Price distribution for the stay |
priceTotal / nights, grouped by bedrooms
|
| Entire homes vs private rooms |
roomType against the median effective nightly price |
| Does the badge pay? |
badges contains "Guest favorite" vs the others, same bedrooms
|
| Where are the listings? |
latitude, longitude on a map, coloured by price |
| How established is the supply? | histogram of reviewCount; isNew for fresh listings |
| How many run promotions? | rows where priceBeforeDiscount is not null |
A concrete reading from a Lisbon run: sort by effective nightly price and look at the 25th, 50th and 75th percentiles per bedroom count. That gives a host three reference points ("cheap", "median", "premium") that are far more useful than the average, because Airbnb search results always contain a few outliers at the top.
Step 4: make it repeat
A market study made once is a snapshot. Schedule the Actor on Apify (weekly is enough for a seasonal view, daily for revenue management), keep the same input, and append each run's rows to the same sheet with the scrapedAt column. Compare runs by platformListingId, checkIn and checkOut: a listing that appears in both runs with a different priceTotal has changed its price; a listing that disappears is either booked or delisted.
For a whole city rather than one search, the Actor splits the map area into quadrants when a search is saturated, so a maxResults of 1,000 is realistic for Lisbon. It just takes more requests.
Honest limits
- 270 listings per search. Airbnb serves at most 15 pages of 18 listings for one search. The area splitting works around it, but whole cities take many more requests than a neighbourhood. Narrow searches (a district, a map area pasted as a search URL) are cheaper and more precise.
-
Rankings move. Airbnb recomputes its ranking per session.
searchRankis what one session saw, not a stable popularity score. Do not build a "top 10" on it; build distributions instead. - Search cards show a subset. Amenities, maximum guests, instant booking and detailed fees are not on search cards and come back empty. Bedrooms, beds and bathrooms are shown for searches with dates only.
-
Prices depend on the site. European Airbnb sites (airbnb.fr, airbnb.de) display a regulated total that includes taxes and fees, itemised in
taxesAndFees; airbnb.com shows a total that may exclude taxes. Always compare rows obtained with the samedomain,currencyand dates. - No personal data, by design. Nothing about hosts or guests is collected: no names, no profile photos, no identifiers, no review texts. You get the listing facts, the average rating, the number of reviews and the badges. If your study needs host-level information, this is not the tool.
- A run that finds nothing fails on purpose, with an explicit message (misspelt location, filters too strict), so that a scheduled study never silently produces an empty sheet.
Use the data for analysis, respect the platform's terms and local law, and do not republish listings.
Where to go next
Once the search export exists, the url column is the entry point for a second pass: the Airbnb Listing Details Scraper reads each listing page for amenities, house rules, category ratings and an availability calendar, and both Actors share their first columns so that the rows join on platformListingId. That is the subject of another article.
Disclosure: I build these Actors and may earn a commission if you sign up to Apify through these links.













