# Zoopla Search Scraper (`kawsar/zoopla-search-scraper`) Actor

Collect UK property listings from any Zoopla search. Enter search URLs or location keywords, the actor scrapes prices, addresses, postcodes, bedrooms, bathrooms, agent details, GPS coordinates, and images. Run multiple searches per run with automatic pagination. For-sale and to-rent both supported.

- **URL**: https://apify.com/kawsar/zoopla-search-scraper.md
- **Developed by:** [Kawsar](https://apify.com/kawsar) (community)
- **Categories:** Real estate, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.99 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Zoopla Search Scraper

Extract structured property listing data from [Zoopla](https://www.zoopla.co.uk) — the UK's largest property portal. Whether you're tracking the London rental market, researching prices in a specific postcode, or building a dataset across multiple UK cities, this actor handles the heavy lifting. Paste in a search URL, type a location keyword, or combine both — it pages through results automatically and delivers clean, analysis-ready data.

---

### What you can do with it

- **Market research** — Compare asking prices, property types, and stock levels across multiple UK locations in a single run.
- **Investment analysis** — Filter by price range, bedroom count, and property type to identify yield opportunities.
- **Price tracking** — Run the actor on a schedule to monitor how prices in a target area change over time.
- **Lead generation** — Collect estate and letting agent names and phone numbers from active listings in any market.
- **Portfolio monitoring** — Keep tabs on under-offer status, price reductions, and new listings for properties you're watching.
- **Academic and journalism** — Build datasets for housing affordability research, regional price studies, or investigative reporting.

---

### What it collects

Each property listing returns up to 25 structured fields:

| Field | Description |
|---|---|
| `listingId` | Unique Zoopla listing identifier |
| `url` | Full URL to the property detail page |
| `propertyTitle` | Listing headline, e.g. "3 bed semi-detached house for sale" |
| `price` | Asking price or monthly rent with currency symbol |
| `priceNumeric` | Price as a plain integer, ready for sorting and calculations |
| `priceCurrency` | ISO currency code — always GBP for UK listings |
| `address` | Full property address |
| `postcode` | UK postcode extracted from the address |
| `bedrooms` | Number of bedrooms |
| `bathrooms` | Number of bathrooms |
| `propertyType` | Detached, semi-detached, terraced, flat, bungalow, etc. |
| `sizeSqft` | Floor area in square feet (where Zoopla publishes it) |
| `listingDescription` | Short marketing summary from the listing |
| `images` | Array of full-size property image URLs |
| `agentName` | Estate or letting agent name |
| `agentPhone` | Agent phone number |
| `addedOn` | ISO 8601 date the listing was first published |
| `listingStatus` | Status flag such as "Just added" or "Reduced" |
| `underOffer` | `true` if the property is currently under offer |
| `isPremium` | `true` if this is a premium featured listing |
| `listingType` | `for-sale` or `to-rent` |
| `latitude` | GPS latitude coordinate |
| `longitude` | GPS longitude coordinate |
| `scrapedAt` | ISO 8601 timestamp of when the record was collected |
| `searchSource` | The URL or keyword that produced this listing |

Fields such as `sizeSqft`, `bathrooms`, `latitude`, and `longitude` return `null` when Zoopla does not publish that data for a given listing.

---

### How to use it

There are two ways to tell the actor what to scrape — use one, the other, or both at the same time.

#### Option 1 — Paste a Zoopla search URL

1. Go to [zoopla.co.uk](https://www.zoopla.co.uk) and run a property search.
2. Apply any filters you want — location, price range, bedrooms, property type.
3. Copy the full URL from your browser's address bar.
4. Paste it into the **Search URLs** field.

This is the most precise method. The URL carries all your filter settings, so the actor scrapes exactly what you searched for.

#### Option 2 — Type a location keyword

Enter a place name such as `London`, `Manchester`, or `Long Ditton` into the **Search queries** field. The actor resolves it to the correct Zoopla area page automatically — no URL needed. Select whether you want for-sale or to-rent results using the **Listing type for queries** dropdown.

You can mix both methods in a single run. Each URL and each keyword is treated as a separate search, with its own listing and page limits.

---

### Input parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| `searchUrls` | array | — | One or more full Zoopla search URLs |
| `queries` | array | — | Location keywords to search, e.g. `London`, `Bristol` |
| `queryListingType` | string | `for-sale` | Listing type for keyword searches: `for-sale` or `to-rent` |
| `maxListingsPerInput` | integer | 100 | Maximum listings to collect per URL or keyword (up to 1,000) |
| `maxPagesPerInput` | integer | 10 | Maximum pages to paginate per URL or keyword (up to 50) |
| `requestTimeoutSecs` | integer | 30 | Per-request timeout in seconds. Raise this if you see timeout errors. |

At least one `searchUrls` entry or one `queries` entry is required.

---

### Example inputs

#### Scrape a single for-sale search

```json
{
    "searchUrls": [
        "https://www.zoopla.co.uk/for-sale/property/wales/newport/?q=Newport"
    ],
    "maxListingsPerInput": 200,
    "maxPagesPerInput": 10
}
````

#### Scrape multiple cities using keywords

```json
{
    "queries": ["London", "Manchester", "Birmingham", "Leeds"],
    "queryListingType": "to-rent",
    "maxListingsPerInput": 100,
    "maxPagesPerInput": 5
}
```

#### Mix URLs and keywords in one run

```json
{
    "searchUrls": [
        "https://www.zoopla.co.uk/for-sale/property/london/?q=London&price_max=500000&beds_min=2"
    ],
    "queries": ["Bristol", "Cardiff"],
    "queryListingType": "for-sale",
    "maxListingsPerInput": 150,
    "maxPagesPerInput": 6
}
```

***

### Example output

```json
{
    "listingId": "73070889",
    "url": "https://www.zoopla.co.uk/for-sale/details/73070889/",
    "propertyTitle": "4 bed terraced house for sale",
    "price": "£225,000",
    "priceNumeric": 225000,
    "priceCurrency": "GBP",
    "address": "Court Crescent, Bassaleg NP10",
    "postcode": "NP10",
    "bedrooms": 4,
    "bathrooms": 1,
    "propertyType": "terraced",
    "sizeSqft": null,
    "listingDescription": "An extended four-bedroom terraced house in Bassaleg, offered with no onward chain.",
    "images": [
        "https://lid.zoocdn.com/800/600/a1b2c3d4e5f6.jpg",
        "https://lid.zoocdn.com/800/600/b2c3d4e5f6a1.jpg"
    ],
    "agentName": "Crook and Blight",
    "agentPhone": "01633 244333",
    "addedOn": "2026-04-28T10:22:00",
    "listingStatus": "Just added",
    "underOffer": false,
    "isPremium": false,
    "listingType": "for-sale",
    "latitude": 51.573388,
    "longitude": -3.043725,
    "scrapedAt": "2026-05-03T09:14:22.841Z",
    "searchSource": "https://www.zoopla.co.uk/for-sale/property/wales/newport/?q=Newport"
}
```

***

### Tips

**Getting the most from search URLs**
Apply all your filters on Zoopla before copying the URL — price range, minimum bedrooms, property type, sort order. The actor scrapes exactly what that URL shows, so the more specific your search, the cleaner your dataset.

**Using keywords for quick multi-city scrapes**
Keywords work well for broad searches across named towns and cities. For precise area control (specific postcodes, custom price bands), a direct URL is more reliable.

**Pagination and limits**
Each Zoopla search page returns up to 25 listings. Setting `maxPagesPerInput` to 10 gives you up to 250 results per search. Raise `maxListingsPerInput` and `maxPagesPerInput` together if you need more — the actor stops at whichever limit it hits first.

**Scheduling**
You can run this actor on a schedule in Apify to build a time-series dataset of prices and stock levels. The `scrapedAt` field makes it straightforward to track what changed between runs.

**Sort order**
Zoopla defaults to sorting by relevance. If you want newest listings first, add `&sort_field=listing_date&sort_direction=descending` to your search URL before pasting it in.

***

### Notes

- The actor collects both regular and premium (extended) listings from each page.
- Listings that appear on multiple pages are deduplicated at the Zoopla level — each listing ID appears only once per search.
- When using keyword queries, the actor automatically resolves the location to Zoopla's correct area URL. If a keyword returns no results, try a more specific place name or switch to a direct search URL.
- This actor is built for research and data collection. Always respect Zoopla's terms of service and applicable data protection laws when using scraped data.

# Actor input Schema

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

One or more full Zoopla search URLs. Copy each URL from your browser after running a search on zoopla.co.uk. Each URL is scraped independently.

## `queries` (type: `array`):

Location or keyword queries (e.g. 'London', 'Manchester'). Each query is run as a separate Zoopla search using the listing type below.

## `queryListingType` (type: `string`):

Whether query-based searches target for-sale or to-rent listings. Has no effect on Search URLs (their listing type is detected from the URL).

## `maxListingsPerInput` (type: `integer`):

Maximum number of property listings to collect per URL or query. One page returns roughly 25 listings.

## `maxPagesPerInput` (type: `integer`):

Maximum number of search result pages to paginate through per URL or query. Each page contains up to 25 listings.

## `requestTimeoutSecs` (type: `integer`):

Per-request timeout in seconds. Increase if you see timeout errors on slow connections.

## Actor input object example

```json
{
  "searchUrls": [
    "https://www.zoopla.co.uk/for-sale/property/london/?q=London",
    "https://www.zoopla.co.uk/to-rent/property/manchester/?q=Manchester"
  ],
  "queries": [
    "London",
    "Manchester",
    "Birmingham"
  ],
  "queryListingType": "for-sale",
  "maxListingsPerInput": 100,
  "maxPagesPerInput": 10,
  "requestTimeoutSecs": 30
}
```

# 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 = {
    "searchUrls": [
        "https://www.zoopla.co.uk/for-sale/property/wales/newport/?q=Newport"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("kawsar/zoopla-search-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 = { "searchUrls": ["https://www.zoopla.co.uk/for-sale/property/wales/newport/?q=Newport"] }

# Run the Actor and wait for it to finish
run = client.actor("kawsar/zoopla-search-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 '{
  "searchUrls": [
    "https://www.zoopla.co.uk/for-sale/property/wales/newport/?q=Newport"
  ]
}' |
apify call kawsar/zoopla-search-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Zoopla Search Scraper",
        "description": "Collect UK property listings from any Zoopla search. Enter search URLs or location keywords, the actor scrapes prices, addresses, postcodes, bedrooms, bathrooms, agent details, GPS coordinates, and images. Run multiple searches per run with automatic pagination. For-sale and to-rent both supported.",
        "version": "0.0",
        "x-build-id": "ei4KhIQ5KecSLwW1Y"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/kawsar~zoopla-search-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-kawsar-zoopla-search-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/kawsar~zoopla-search-scraper/runs": {
            "post": {
                "operationId": "runs-sync-kawsar-zoopla-search-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/kawsar~zoopla-search-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-kawsar-zoopla-search-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": {
                    "searchUrls": {
                        "title": "Search URLs",
                        "type": "array",
                        "description": "One or more full Zoopla search URLs. Copy each URL from your browser after running a search on zoopla.co.uk. Each URL is scraped independently.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "queries": {
                        "title": "Search queries",
                        "type": "array",
                        "description": "Location or keyword queries (e.g. 'London', 'Manchester'). Each query is run as a separate Zoopla search using the listing type below.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "queryListingType": {
                        "title": "Listing type for queries",
                        "enum": [
                            "for-sale",
                            "to-rent"
                        ],
                        "type": "string",
                        "description": "Whether query-based searches target for-sale or to-rent listings. Has no effect on Search URLs (their listing type is detected from the URL).",
                        "default": "for-sale"
                    },
                    "maxListingsPerInput": {
                        "title": "Max listings per URL / query",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Maximum number of property listings to collect per URL or query. One page returns roughly 25 listings.",
                        "default": 100
                    },
                    "maxPagesPerInput": {
                        "title": "Max pages per URL / query",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Maximum number of search result pages to paginate through per URL or query. Each page contains up to 25 listings.",
                        "default": 10
                    },
                    "requestTimeoutSecs": {
                        "title": "Request timeout (seconds)",
                        "minimum": 5,
                        "maximum": 120,
                        "type": "integer",
                        "description": "Per-request timeout in seconds. Increase if you see timeout errors on slow connections.",
                        "default": 30
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
