# Fotocasa Scraper - Spain Property Data (`benthepythondev/fotocasa-scraper`) Actor

Scrape Fotocasa (Spain's #2 property portal), for sale or to rent: price, rooms, bathrooms, area (m2), floor, full address, coordinates, agency name and phone, image and listing URL. Search by city or paste a URL.

- **URL**: https://apify.com/benthepythondev/fotocasa-scraper.md
- **Developed by:** [ben](https://apify.com/benthepythondev) (community)
- **Categories:** Real estate, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## 🏠 Fotocasa Scraper - Spain Property & Agent Data

Extract real-estate listings from **Fotocasa.es**, Spain's #2 property portal, in clean structured form. Give it a city or a Fotocasa search URL and get back every listing with **price, surface (m²), rooms, bathrooms, floor, full address, GPS coordinates, the listing agency and — when Fotocasa shows it — the advertiser's phone number**, plus photos and the direct listing URL. Perfect for property research, market analysis, price tracking and real-estate lead generation across Spain. Export to JSON/CSV/Excel, run on a schedule, call via API, or connect to Make, Zapier or n8n.

### 🔎 What is the Fotocasa Scraper?

Fotocasa lists hundreds of thousands of homes for sale and to rent across Spain — Madrid, Barcelona, Valencia, Sevilla, Málaga, Bilbao and every province. This Actor reads Fotocasa's own search results and turns each property card into a tidy row you can drop straight into a spreadsheet, database or CRM, with no copy-pasting and no browser babysitting.

You can search two ways:

- **By location** — pass one or more city / province-capital names (e.g. `madrid`, `barcelona`, `valencia`) and choose *for sale* or *to rent*.
- **By Search URL** — paste a Fotocasa results URL straight from your browser to keep every filter you set on the site (price range, number of rooms, zone, property type, new construction, etc.).

The Actor paginates automatically until it reaches your `maxResults`.

#### What data does it extract?

For every listing it returns flat, ready-to-use fields, including:

- **Price** — clean numeric price plus the original formatted string, currency, and rent period.
- **Property details** — rooms, bathrooms, surface area in m², floor, property type/subtype, new-construction flag, and a list of amenities (elevator, air conditioning, terrace, parking, pool, storage room…).
- **Location** — street/area, neighborhood, district, city, municipality, province, postcode, and exact **latitude/longitude**.
- **Agency & contact (lead-gen)** — the listing agency name, agency type (professional/private), agency profile URL, and the advertiser **phone number** whenever Fotocasa exposes it.
- **Media** — main image URL, image count, and video / virtual-tour flags.
- **Meta** — listing id, ad id, direct listing URL, how many days ago it was published, and the publish timestamp.

### ⬇️ Input

| Field | Type | Description |
| --- | --- | --- |
| `location` | array | Spanish city / province-capital names to search, e.g. `["madrid","barcelona"]`. Each becomes a Fotocasa search. |
| `searchUrls` | array | Fotocasa search-results URLs to scrape exactly (keeps all your filters). Used in addition to `location`. |
| `operation` | string | `sale` (comprar) or `rent` (alquiler). Applies to location searches. |
| `maxResults` | integer | Max listings to return per location or URL (default 50). |
| `useResidentialProxy` | boolean | Route through Apify residential (ES) proxies. Off by default; enable only for very large jobs. |

#### Example input

```json
{
  "location": ["madrid", "valencia"],
  "operation": "sale",
  "maxResults": 50
}
````

Or scrape an exact filtered search:

```json
{
  "searchUrls": [
    "https://www.fotocasa.es/es/comprar/viviendas/barcelona-capital/todas-las-zonas/l"
  ],
  "maxResults": 100
}
```

### ⬆️ Output

Each item looks like this (fields shown are the real ones the Actor emits):

```json
{
  "id": 189678845,
  "ad_id": "fa743746-c596-4013-bb8d-6dded76175ad",
  "url": "https://www.fotocasa.es/es/comprar/vivienda/madrid-capital/aire-acondicionado-calefaccion-amueblado/189678845/d",
  "operation": "sale",
  "transaction_type_id": 1,
  "property_type": "Flat",
  "property_subtype": "Flat",
  "is_new_construction": false,
  "price": 269000,
  "price_raw": "269.000 €",
  "currency": "EUR",
  "price_period": null,
  "reduced_price": "9.000 €",
  "rooms": 3,
  "bathrooms": 1,
  "area_sqm": 65,
  "floor": 7,
  "amenities": ["air_conditioner", "armored_door", "equiped_kitchen", "furnished", "heating"],
  "title": "Calle de Berastegui, Pueblo Nuevo",
  "description": "Luminosa vivienda reformada de 65 m²…",
  "address": "Pueblo Nuevo",
  "neighborhood": "Pueblo Nuevo",
  "district": "Ciudad Lineal",
  "city": "Madrid",
  "province": "Madrid",
  "postcode": "28017",
  "country": "España",
  "latitude": 40.4266138,
  "longitude": -3.6400208,
  "agency": "TENGOTUCASA",
  "agency_type": "professional",
  "agency_url": "https://www.fotocasa.es/es/inmobiliaria-tengotucasa/...",
  "phone": "+34913046530",
  "image": "https://static.fotocasa.es/images/ads/5cb8ec6d-...?rule=original",
  "num_images": 38,
  "has_video": false,
  "has_virtual_tour": false,
  "published_days_ago": 46,
  "published_timestamp": 1778760098190,
  "query": "madrid"
}
```

### 💡 Use cases

- 🏠 **Real-estate lead generation** — build prospect lists of agencies and advertisers (name, profile, phone) actively listing in a city or zone.
- 📊 **Market & price analysis** — track €/m², asking prices and inventory by neighborhood or province over time.
- 🧭 **Property sourcing & alerts** — monitor new listings that match your buy/rent criteria and feed them into your pipeline.
- 🗺️ **Geospatial datasets** — every listing ships with latitude/longitude for mapping, heatmaps and proximity analysis.

### ❓ FAQ

**Which locations are supported?** Anywhere on Fotocasa — pass a city/province-capital name, or paste any Fotocasa search URL to target an exact area or filter set.

**Sale and rent?** Yes. Set `operation` to `sale` or `rent` for location searches; for URLs the operation is detected from the link.

**How many listings can I get?** As many as the search returns — the Actor paginates automatically up to your `maxResults`. A single Fotocasa search can hold thousands of listings.

**Does it return the agent's phone number?** When Fotocasa publishes a phone for the listing, yes — it's in the `phone` field, along with the agency name and profile URL.

**Do I need a proxy?** The Actor uses Apify residential (ES) proxies by default, because Fotocasa blocks cloud/datacenter IP ranges. This is handled automatically — you don't need to configure anything. It uses only a small amount of residential traffic per run.

**What formats can I export?** JSON, CSV, Excel, HTML table or XML from the dataset, or pull results via the Apify API and integrations (Make, Zapier, n8n).

**Will it break when the site changes?** The Actor reads Fotocasa's structured page data and is built defensively; if the layout changes it's updated to keep working.

**Is it legal?** The Actor collects only publicly available listing information that Fotocasa shows to any visitor. You are responsible for using the data lawfully — in particular, handle any personal data (such as advertiser phone numbers) in line with **GDPR** and Spanish data-protection law, and respect Fotocasa's terms. Do not use scraped contact details for unsolicited spam.

### 🔗 You might also like

- **Idealista Scraper** — Spain's #1 property portal.
- **Immobiliare.it Scraper** — Italy's leading real-estate site.
- **Rightmove Scraper** — the UK's #1 property portal.
- **Funda Scraper** — the Netherlands' top real-estate portal.
- **Real Estate Agent Lead Scraper** — build agent contact lists across portals.

### ⚙️ How it works

The Actor requests Fotocasa's search-results pages exactly like a browser (using realistic TLS/headers), reads the structured listing data Fotocasa embeds in each page, normalizes it into the flat fields above, and pushes one record per property to your dataset. It de-duplicates by listing id and walks through result pages until it has collected your requested number of listings.

**Keywords:** fotocasa scraper, fotocasa api, scrape fotocasa, fotocasa.es, spain real estate scraper, spanish property data, idealista alternative, property listings spain, real estate lead generation spain, piso en venta, alquiler madrid, barcelona property scraper, real estate market data, property price scraper, agency phone scraper, apify real estate, casas en venta, viviendas españa, property dataset, rental listings spain

# Actor input Schema

## `location` (type: `array`):

Spanish city / province-capital names to search, e.g. 'madrid', 'barcelona', 'valencia', 'sevilla'. Each is turned into a Fotocasa search. For an exact area, zone or filtered search, use Search URLs instead.

## `searchUrls` (type: `array`):

Fotocasa search-results URLs to scrape exactly (paste from your browser to keep every filter: price, rooms, zone, property type). Used in addition to any locations.

## `operation` (type: `string`):

Whether to scrape properties for sale (comprar) or to rent (alquiler). Applies to location searches.

## `maxResults` (type: `integer`):

Maximum number of listings to return per location or search URL. Fotocasa returns about 30 listings per page and the actor paginates automatically.

## `useResidentialProxy` (type: `boolean`):

Route requests through Apify residential proxies in Spain. On by default — Fotocasa blocks cloud/datacenter IPs, so this is required for runs on the Apify platform. Uses a small amount of residential proxy traffic.

## Actor input object example

```json
{
  "location": [
    "madrid"
  ],
  "searchUrls": [
    "https://www.fotocasa.es/es/comprar/viviendas/madrid-capital/todas-las-zonas/l"
  ],
  "operation": "sale",
  "maxResults": 10,
  "useResidentialProxy": true
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "location": [
        "madrid"
    ],
    "searchUrls": [
        "https://www.fotocasa.es/es/comprar/viviendas/madrid-capital/todas-las-zonas/l"
    ],
    "operation": "sale",
    "maxResults": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("benthepythondev/fotocasa-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "location": ["madrid"],
    "searchUrls": ["https://www.fotocasa.es/es/comprar/viviendas/madrid-capital/todas-las-zonas/l"],
    "operation": "sale",
    "maxResults": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("benthepythondev/fotocasa-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "location": [
    "madrid"
  ],
  "searchUrls": [
    "https://www.fotocasa.es/es/comprar/viviendas/madrid-capital/todas-las-zonas/l"
  ],
  "operation": "sale",
  "maxResults": 10
}' |
apify call benthepythondev/fotocasa-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=benthepythondev/fotocasa-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Fotocasa Scraper - Spain Property Data",
        "description": "Scrape Fotocasa (Spain's #2 property portal), for sale or to rent: price, rooms, bathrooms, area (m2), floor, full address, coordinates, agency name and phone, image and listing URL. Search by city or paste a URL.",
        "version": "1.0",
        "x-build-id": "gyE9BddrBN4H1lug7"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/benthepythondev~fotocasa-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-benthepythondev-fotocasa-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/benthepythondev~fotocasa-scraper/runs": {
            "post": {
                "operationId": "runs-sync-benthepythondev-fotocasa-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/benthepythondev~fotocasa-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-benthepythondev-fotocasa-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "location": {
                        "title": "Locations",
                        "type": "array",
                        "description": "Spanish city / province-capital names to search, e.g. 'madrid', 'barcelona', 'valencia', 'sevilla'. Each is turned into a Fotocasa search. For an exact area, zone or filtered search, use Search URLs instead.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "searchUrls": {
                        "title": "Search URLs",
                        "type": "array",
                        "description": "Fotocasa search-results URLs to scrape exactly (paste from your browser to keep every filter: price, rooms, zone, property type). Used in addition to any locations.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "operation": {
                        "title": "For sale or to rent",
                        "enum": [
                            "sale",
                            "rent"
                        ],
                        "type": "string",
                        "description": "Whether to scrape properties for sale (comprar) or to rent (alquiler). Applies to location searches.",
                        "default": "sale"
                    },
                    "maxResults": {
                        "title": "Max results per search",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Maximum number of listings to return per location or search URL. Fotocasa returns about 30 listings per page and the actor paginates automatically.",
                        "default": 50
                    },
                    "useResidentialProxy": {
                        "title": "Use residential proxy (ES)",
                        "type": "boolean",
                        "description": "Route requests through Apify residential proxies in Spain. On by default — Fotocasa blocks cloud/datacenter IPs, so this is required for runs on the Apify platform. Uses a small amount of residential proxy traffic.",
                        "default": true
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
