Idealista Scraper - Spain, Italy & Portugal Listings
Pricing
from $2.20 / 1,000 listings
Idealista Scraper - Spain, Italy & Portugal Listings
Collect Idealista property listings in Spain, Italy and Portugal by location or URL. Get prices, rooms, floor area, agency names and photos. Pay per delivered listing row plus a start fee.
Pricing
from $2.20 / 1,000 listings
Rating
0.0
(0)
Developer
kane liu
Maintained by CommunityActor stats
1
Bookmarked
3
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Security
Limited permissionsShare
Idealista Scraper
Get Idealista property listings from Spain, Italy and Portugal as structured rows you can export to a spreadsheet or read through an API.
- Search homes for sale or rent by location or use your own Idealista URLs.
- Collect prices, rooms, floor area, descriptions, agency names and image links where available.
- Choose homes, new developments, rooms, garages, storage, offices, commercial property, land or buildings.
- Enrich search results with listing details, or keep search-card data only.
- Pay for the rows you receive: $3.00 per 1,000 rows on the Free plan, plus a small start fee.
What does Idealista Scraper do?
Idealista Scraper collects property listings from idealista.com, idealista.it and idealista.pt. It returns one property listing per row, with rowType set to listing. Use the rows for price comparisons, inventory monitoring or property research. Choose one country per run.
- Location search: fill
location, then choosecountry,channelandpropertyType. - Search URLs: fill
startUrlswith Idealista search pages. The URLs take priority over the location and select the market. - Listing URLs: provide individual property URLs in
startUrlsto collect those listings directly. - Detail enrichment:
scrapeDetailsis on by default. It adds available detail fields to the same listing row, not a separately billed row.
Business transfers are supported in all three markets. Holiday categories are supported in Spain and Italy, not Portugal. There are no separately billed optional row types.
What data can you extract from Idealista?
The fields below belong to listing rows. Availability depends on the page and whether details were collected; examples illustrate the format, not a live listing.
| Field | Description | Example |
|---|---|---|
rowType | Row category | listing |
id | Listing identifier, stored as text | 123456789 |
url | Listing page | https://www.idealista.com/inmueble/123456789/ |
country | Market code | ES |
channel | Sale or rental | BUY |
propertyType | Local category name | viviendas |
title | Listing title | Example apartment in Madrid |
priceAmount | Numeric advertised price | 350000 |
priceFormatted | Price text shown on the page | 350.000 € |
rooms | Room count interpreted from the listing | 3 |
livingSpace | Advertised floor area in square metres | 85 |
floor | Floor description, when shown | 2ª planta |
description | Available property description | Example listing description |
address | Structured address: street, locality, district, neighborhood, region (exact details may be absent) | {"street":"Calle de Santa Brígida","locality":"Madrid","district":"Centro","neighborhood":"Chueca-Justicia","region":"Madrid"} |
geo | Coordinates when available on the detail page | null |
agencyName | Advertiser or agency label | Example Agency |
org | Agency name and identifier when available | {"name":"Example Agency","id":null} |
images | Available image URLs | [] |
plansCount | Floor-plan count from detail data | 0 |
videosCount | Video count from detail data | 0 |
phones | Phone numbers the site exposes on the listing; empty when the ad hides them | [{"value":"+34910000000","type":"mobile","e164":"+34910000000"}] |
emails | Email addresses are not collected | [] |
sourceLayer | Search, detail or combined data | srp+ldp |
leadSource | Source of contact-related fields (search = listing row, detail = listing page) | detail |
leadReveal | How contact data was obtained: inline in the row, click, absent | inline |
leadAbsences | Reasons contact-related fields are missing (未验证 not verified / 本站无 structurally absent, always proven in quality / 未采集 not read this run / 闸门锁 behind form gate) | Missing or unverified field reasons |
quality | missingFields + evidence: why a field is empty and what was actually looked at | {"missingFields":{"emails":"not_present"},"evidence":{"emails":"…"}} |
scrapedAt | Collection timestamp | 2026-10-24T08:00:00+00:00 |
Search-card agency names can populate org without detail enrichment. Exact addresses and coordinates are not guaranteed. The Actor does not supply individual contact names, emails or social profiles; it does fill the agency's own website and real in-stock count from the agency's idealista profile.
How to scrape Idealista
- Open Idealista Scraper in Apify Console. A free Apify account is enough to try it.
- Fill
startUrls, or clear its sample URL and filllocationfor your chosen country. - Set
maxResultsto5for your first run. - Click Start and wait for the run to finish.
- Open the dataset and download JSON, CSV or Excel, or read the rows through the API.
An empty input starts a Madrid homes-for-sale example capped at 10 rows; the form's row-count sample is 3. This example uses normal pricing, not a separate free service. If only country is changed, the example location becomes roma-roma for Italy or lisboa for Portugal. Filling a target field selects the matching search automatically; there is no mode field to set.
Search by location
Leave startUrls empty. Enter a location path such as madrid-madrid, roma-roma or lisboa, or a plain place name such as Madrid. For a less ambiguous search, copy a search URL from Idealista instead.
Search by URL
Paste search pages from one market into startUrls. Their country, category and search selection take priority over the corresponding location-based options. Do not leave the Madrid sample URL in place when you want a different location.
Collect individual listings
Use property URLs with paths such as /inmueble/, /immobile/ or /imovel/. Spanish new-development detail URLs using /obra-nueva/ are also recognized. This selects the supplied listings rather than searching a city.
What to fill in
| Field | What to enter | Default |
|---|---|---|
startUrls | Idealista search or listing URLs from one country | Empty; form has a Madrid sample |
location | Place name or Idealista location path; used without URLs | Empty; example uses the market's default city |
country | ES, IT or PT; URLs select it when supplied | ES |
channel | BUY for sale, RENT for rental | BUY |
propertyType | A category alias or local category path | homes |
maxResults | Maximum rows per URL or location, from 1 to 300 | 70; form sample 3 |
maxPages | Search-page setting, from 1 to 25; not a strict page cap in current row-limited runs | 1 |
scrapeDetails | Add available details to search rows | true |
includeRawPayloads | Keep additional page text and map-related data; increases row size | false |
requestDelayMillis | Requested delay between page visits, in milliseconds | 3000 |
cursor | Copy nextCursor from the previous run summary, if present | Empty |
Category aliases are homes, new_homes, rooms, garages, storage, offices, commercial, land, buildings and business_transfer. Use holiday only for Spain or Italy. Rooms are rent-only: the search uses RENT even if BUY was selected. Business-transfer paths use /traspasos/, /cessione-attivita/ or /trespasse/, without a sale/rent prefix.
Location search, for Lisbon rentals:
{"country": "PT","location": "lisboa","channel": "RENT","propertyType": "homes","maxResults": 5}
Search URL, for Rome listings without detail enrichment:
{"startUrls": [{"url": "https://www.idealista.it/vendita-case/roma-roma/"}],"maxResults": 5,"scrapeDetails": false}
Individual listing; replace the illustrative ID with a current listing:
{"startUrls": [{"url": "https://www.idealista.com/inmueble/123456789/"}],"maxResults": 1}
maxItemsandlimitare aliases formaxResults. The canonical field takes precedence.- Unknown fields alone do not fail the run: close misspellings are corrected; other fields are ignored with a note. Corrected values still need to be valid.
- Invalid input stops before any row is charged. For example:
INVALID_INPUT: maxPages must be a whole number from 1 to 25. The start fee is separate. - The
INPUT_REPORTrecord in the run's key-value store lists fields filled, corrected or ignored. - For continuation, keep the same search and copy
nextCursorfromOUTPUTorRUN_SUMMARYintocursor. UsemaxResults, notmaxPages, to control delivered rows.
Output example
This illustrative row shows a search result; omitted fields may also appear in actual output.
{"rowType": "listing","id": "123456789","url": "https://www.idealista.com/inmueble/123456789/","source": "idealista","country": "ES","sourceLayer": "srp","channel": "BUY","propertyType": "viviendas","title": "Example apartment in Madrid","priceAmount": 350000,"priceFormatted": "350.000 €","rooms": 3,"livingSpace": 85,"agencyName": "Example Agency","images": [],"phones": [],"emails": [],"geo": null,"scrapedAt": "2026-10-24T08:00:00+00:00"}
You can export the dataset as JSON, CSV, Excel, XML, RSS or an HTML table. The separate OUTPUT record contains the run summary, warnings and any continuation token.
Why use this Idealista scraper?
- Pay per delivered row. A listing is billed when written to the dataset, not for each page attempted.
- Keep partial output. Available partial rows are delivered when collection ends early. Rows already written remain in the dataset; a forced stop before delivery may leave it empty.
- Understand missing fields. Missing values stay empty, and
leadAbsencesexplains gaps in contact-related data. - Use several URLs. Collect multiple searches or listings from the same country in one run.
- No proxy setup. You do not need to set up proxies, provide cookies or supply an Idealista account.
How much does it cost to scrape Idealista?
The Actor uses pay-per-event pricing: $0.005 per start event plus a price per delivered listing row. The start event is charged once per GB of Actor memory, with a minimum of one event. At the default 512 MB, the start fee is $0.005.
| Apify plan | Price per row | Price per 1,000 rows |
|---|---|---|
| Free | $0.003 | $3.00 |
| Starter | $0.003 | $3.00 |
| Scale | $0.0026 | $2.60 |
| Business | $0.0022 | $2.20 |
maxResultsapplies to each input URL, or to the location search. Its default is70, with larger requests collected in parts of 70, up to the input maximum of300.- Free-plan runs are capped at 200 rows across the run and 10 runs of this Actor. These are developer-set limits. A paid Apify plan removes the 10-run restriction, not input limits.
- Set Maximum cost per run in the run options (
maxTotalChargeUsdin the API) to cap the run's event charges. This is not an input field.
Example: three search URLs delivering 50 rows each produce 150 rows. On the Free plan, at default memory and one start event, the event charges are 150 × $0.003 + $0.005 = $0.455. Fewer delivered rows mean fewer row charges.
What happens when the run timeout is too short
When automatic resumption is used, a run awaiting results can pause instead of failing. Its status message reads "Queued on the collection backend; this run will resume automatically when results are ready (about N s)." It temporarily shows ABORTED.
When results are ready, the same run resumes, reports "Resumed: delivering N rows.", writes to the same dataset and finishes as SUCCEEDED if delivery succeeds. Rows already delivered are skipped, so they are not charged again. No manual restart is needed for this queued pause. A collection failure can still fail the run; resumption is not an unlimited retry mechanism.
Keep the default timeout of 3600 seconds to reduce pauses. Synchronous API endpoints (run-sync and run-sync-get-dataset-items) wait at most 300 seconds and can return an empty dataset while the run is paused. For longer searches, start asynchronously and read the dataset after SUCCEEDED, or use a webhook for ACTOR.RUN.SUCCEEDED.
Use with AI agents and the API
Apify MCP server (Claude, ChatGPT, Cursor, VS Code)
Add this remote MCP server in a compatible client:
https://mcp.apify.com?tools=lentic_clockss/idealista-scraper
Sign in with Apify through OAuth when prompted, or send Authorization: Bearer <YOUR_APIFY_TOKEN>. The tool starts a run and returns its run and dataset IDs; the agent can then read rows with get-dataset-items.
Clients without remote MCP support can use npx @apify/actors-mcp-server --tools lentic_clockss/idealista-scraper with APIFY_TOKEN set.
Example prompt: "Collect five Lisbon rental listings from Idealista Portugal and show their prices, floor areas and listing URLs."
Apify API
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("lentic_clockss/idealista-scraper").call(run_input={"location": "madrid-madrid", "maxResults": 5})if run["status"] == "SUCCEEDED":for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item)
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('lentic_clockss/idealista-scraper').call({location: 'madrid-madrid', maxResults: 5,});if (run.status === 'SUCCEEDED') {const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);}
For asynchronous HTTP, send the input JSON to POST https://api.apify.com/v2/acts/lentic_clockss~idealista-scraper/runs with an Authorization: Bearer <YOUR_APIFY_TOKEN> header. After completion, read GET https://api.apify.com/v2/datasets/<datasetId>/items?format=json. Do not treat a queued ABORTED pause as final completion.
Standby HTTP endpoint
Base URL: https://lentic-clockss--idealista-scraper.apify.actor.
| Method | Route | Returns |
|---|---|---|
GET | / | Service information |
GET | /health | Service health |
GET | /input-example | Small example input for a normal Actor run |
GET | /openapi.json | OpenAPI document |
These are information routes, not scraping routes. Start collection through the normal Actor API above; there is no collection POST route in this Actor's published OpenAPI document.
Integrations
Use the Actor's Integrations tab to connect results to Google Sheets, Make, Zapier, n8n, Slack, Airtable or a webhook. Use Apify Schedules for repeated runs.
En español
Este Actor recoge anuncios de Idealista en España, Italia y Portugal y entrega una fila por inmueble. Puedes consultar viviendas en venta o alquiler, además de otras categorías disponibles en cada país. Para empezar, introduce una localidad en location y elige country; si tienes un enlace de búsqueda, pégalo en startUrls y borra los enlaces de ejemplo que no necesites. Prueba con maxResults igual a 5. Con scrapeDetails activado se añaden los detalles disponibles del anuncio. No se garantizan teléfonos, direcciones exactas ni coordenadas. Puedes descargar los resultados en Excel, CSV o JSON. Se cobra por cada fila entregada, más el cargo de inicio. Utiliza una sola combinación de país y dominio por ejecución.
FAQ
Is it legal to scrape Idealista?
Use only data you may lawfully collect and process. You are responsible for Idealista's terms and applicable data-protection law. Public availability does not remove privacy obligations; personal data requires a lawful basis. The Actor does not grant permission to reuse data.
Why did my run end as ABORTED?
If the status message says the run is queued and will resume automatically, this is a temporary pause. Wait for the same run to resume. Other aborts, including manual stops, do not necessarily mean automatic resumption.
How many results can I get?
Set maxResults from 1 to 300 per input. Available listings, the run's cost limit and free-plan limits can reduce delivery. The number requested is a ceiling, not a guarantee.
Why are some fields empty?
A listing may omit an attribute or hide its exact address. Search-only rows contain fewer fields than enriched rows. Contact-related fields have specific gaps; check leadAbsences. Empty values are not replaced with invented data.
Can I combine Spain, Italy and Portugal in one run?
Use a separate run for each country. For location searches, choose ES, IT or PT; for URL searches, use links from the matching Idealista domain.
Is this the official Idealista API?
No. This is an independent Actor that collects listing-page data and makes its results available through the Apify API. It is not Idealista's own API.
What does scrapeDetails change?
For search results, false keeps search-card data; true adds available descriptions, advertiser information and media details. It can take longer, but enrichment does not create an extra listing row charge. Direct listing URLs still select detail pages.
Why did my free-plan run stop after 10 runs?
The developer allows 10 runs of this Actor for free-plan users, with up to 200 rows per run. A paid Apify plan removes this run-count restriction. The run summary and status message explain when a free-plan limit is reached.
Limitations
- Only the Spanish, Italian and Portuguese Idealista markets are supported. External holiday sites, including Rentalia, are outside scope.
- Phone numbers appear when the listing itself publishes them; ads that hide the number return an empty
phoneslist. The agency's own website is filled from its idealista profile when it publishes one (web.website,org.agencyWebUrl); email addresses, individual contact names and social profiles are not supplied —quality.evidencerecords what was checked for each of them. - Detail enrichment may be incomplete. Room counts and floor areas can be absent or inapplicable to garages, storage or land.
maxPagesis not a strict stop condition in current row-limited runs; usemaxResultsand the cost cap.- A successful search can return no matching listings. Check the run summary rather than assuming every empty dataset is an error.
Related scrapers
More real estate and property data scrapers from the same publisher:
- Zumper Scraper
- Booli Scraper
- Craigslist Scraper
- PropertyGuru Scraper
- OpenSooq Scraper
- Apartments.com Rental Scraper
- Dot Property Scraper
- FINN.no Scraper
Browse all of our scrapers at apify.com/lentic_clockss.
Support
Found a problem or need another field? Open an issue in the Issues tab of this Actor's page and include the run ID and the input you used.