Use Idealista Search Listings Price & Feature Scraper with Python
Pull real estate search-result listings from Idealista for Spain, Italy, and Portugal: price, size, rooms, address, thumbnail, feature flags, and agency name for homes, offices, land, and more.
1. Choose the data you need
Review the published README for supported collection modes, examples, and limits. The recipe below uses the current published input definition.
2. Prepare a source-based input
This JSON contains published prefills and required-field defaults. Review every value for your task before running it; it is not a promise of successful collection.
{
"bathrooms": "any",
"condition": "any",
"country": "it",
"fetchDetails": false,
"hasAirConditioning": false,
"hasBalcony": false,
"hasGarage": false,
"hasGarden": false,
"hasLift": false,
"hasPool": false,
"hasSeaViews": false,
"hasStorageRoom": false,
"hasTerrace": false,
"isAccessible": false,
"isAuction": false,
"isBankOwned": false,
"isLuxury": false,
"isNewDevelopment": false,
"location": "roma-roma",
"maxDetails": 3,
"maxItems": 3,
"mode": "search",
"onlyPriceDrops": false,
"onlyPrivateOwners": false,
"operation": "sale",
"partitionLargeSearches": false,
"propertySubtype": "any",
"propertyType": "homes",
"rooms": "any",
"sortBy": "relevance"
}
Download input.example.json and save your reviewed copy as input.json.
| Field | Type | Required | Description |
|---|---|---|---|
mode | string | optional | What to scrape: a location search, your own search URLs, or individual property URLs/IDs. Inferred from the supplied URLs when omitted. |
location | string | optional | City or area slug from an Idealista URL (e.g. madrid-madrid, barcelona-barcelona, lisboa, roma-roma). You can also paste a full Idealista search URL. Used in Search by location mode. |
operation | string | optional | Properties for sale or for rent. |
propertyType | string | optional | Type of property to search for. |
country | string | optional | Idealista market: Spain, Portugal, or Italy. Auto-detected when you use URLs. |
startUrls | array | optional | Idealista search-result URLs to scrape (filters and map-area URLs are kept as-is). Used in Search URLs mode. |
propertyUrls | array | optional | Individual Idealista property URLs or numeric property IDs. Used in Property URLs / IDs mode. |
propertySubtype | string | optional | Narrow homes to a subtype (flat, penthouse, duplex, villa, etc.). |
priceMin | integer | optional | Drop listings cheaper than this price. Rounded to Idealista's nearest price bucket. |
priceMax | integer | optional | Drop listings more expensive than this price. Rounded to Idealista's nearest price bucket. |
sizeMin | integer | optional | Drop listings smaller than this size. Rounded to Idealista's nearest size bucket. |
sizeMax | integer | optional | Drop listings larger than this size. Rounded to Idealista's nearest size bucket. |
rooms | string | optional | Number of rooms. |
bathrooms | string | optional | Number of bathrooms. |
condition | string | optional | Property condition. |
hasLift | boolean | optional | Only listings with a lift. |
hasTerrace | boolean | optional | Only listings with a terrace. |
hasPool | boolean | optional | Only listings with a swimming pool. |
hasGarden | boolean | optional | Only listings with a garden. |
hasGarage | boolean | optional | Only listings with a garage or parking space. |
hasStorageRoom | boolean | optional | Only listings with a storage room. |
hasAirConditioning | boolean | optional | Only listings with air conditioning. |
hasBalcony | boolean | optional | Only listings with a balcony. |
isNewDevelopment | boolean | optional | Only new-development listings. |
isBankOwned | boolean | optional | Only bank-owned listings where the source marks them. |
isAuction | boolean | optional | Only auction listings where the source marks them. |
isLuxury | boolean | optional | Only luxury listings. |
hasSeaViews | boolean | optional | Only listings advertised with sea views. |
isAccessible | boolean | optional | Only accessible homes. |
sortBy | string | optional | Result order. |
onlyPriceDrops | boolean | optional | Keep only listings whose price was reduced. |
minPriceDropPercent | integer | optional | Keep only listings reduced by at least this percentage. Implies price-drop filtering. |
onlyPrivateOwners | boolean | optional | Keep only private-seller listings. |
fetchDetails | boolean | optional | Visit each listing's page to add bathrooms, energy rating, year built, condition, full description, gallery and agency phone. Slower and uses more requests. |
maxDetails | integer | optional | Maximum number of listing pages to enrich when Fetch Details is on. |
maxItems | integer | optional | Maximum number of listings to save. |
partitionLargeSearches | boolean | optional | When a search has more than 1,800 results and you ask for more, split it by price buckets so the 1,800-per-search cap is bypassed. |
3. Start an Actor run
Set APIFY_TOKEN in your environment. Python 3.10 or newer is sufficient; this recipe uses no third-party packages.
Execution may incur charges. Review current pricing on Apify. The request asks for a 120-second timeout and a charge limit; these settings are subject to Apify’s pricing and do not guarantee an all-inclusive spending cap.
import json
import os
import urllib.request
# Save the schema-derived example as input.json; review and edit it first.
with open("input.json", encoding="utf-8") as stream:
actor_input = json.load(stream)
token = os.environ["APIFY_TOKEN"]
request = urllib.request.Request(
"https://api.apify.com/v2/acts/NyUqiKhjLo7WaoLJ3/runs?timeout=120&maxTotalChargeUsd=0.50",
data=json.dumps(actor_input).encode("utf-8"),
headers={"Authorization": "Bearer " + token, "Content-Type": "application/json"},
method="POST",
)
# This starts a potentially billable run. Do not automatically retry this POST.
with urllib.request.urlopen(request, timeout=40) as response:
run = json.load(response)["data"]
print("Run ID:", run["id"])
print("Status:", run["status"])
# Inspect and download results in Apify Console once the run succeeds.
4. Inspect the actual results
Open the run in Apify Console and wait for a successful completion. Use the published output schema to locate results and the dataset schema to understand declared views. Missing or optional record fields must not be treated as guaranteed values.
Dataset of Idealista property listings for Spain, Italy and Portugal: price, price history signals, size, rooms, bathrooms, location and coordinates, features, energy certificate, agency contact, images and description.
Questions before you run
Which inputs are required?
No top-level fields are marked required in the published schema. Conditional requirements can still apply; check the README.
What does this guide verify?
The fields, prefills, and schema links are rendered from the published build. This is a usage recipe, not a paid live extraction test. Source availability and collection results can vary.
What if the run request times out?
Check Apify Console before retrying. The first request may already have created a run. Do not automatically repeat a run-creation POST.
Generated from source build NmaO0OGZLbpxwqbDg and its README and schemas. Source changes regenerate this guide; no third-party editorial claims are inferred.