# Property24 South Africa Scraper (`dhrumil/property24-south-africa-scraper`)

Effortlessly extract real estate data from Property24, South Africa's leading property portal. This powerful scraper collects comprehensive property details including prices, locations, descriptions, property types, images, agent contact info, and more.

- **URL**: https://beta-securitybyobscurity.apify.com/dhrumil/property24-south-africa-scraper.md
- **Developed by:** [Dhrumil Bhankhar](https://beta-securitybyobscurity.apify.com/dhrumil) (community)
- **Categories:** Real estate, Automation, Integrations
- **Stats:** 18 total users, 10 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

$35.00/month + usage

To use this Actor, you pay a monthly rental fee to the developer. The rent is subtracted from your prepaid usage every month after the free trial period.
You also pay for the Apify platform usage, which gets cheaper the higher Apify subscription plan you have.

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

# README

### 🏡 What is Property24 Real Estate Properties Scraper?

This Property24 properties Scraper will enable you to scrape any sale/rent listing from [property24.com](https://www.property24.com/), South Africa's leading property portal.

You can simply take your listing URL from browser and enter it into this actor. This actor will crawl through all pages of particular listing and generate dataset for you.

Listing URL is something you get when you perform the search on Property24 site. Example listing URLs:

- https://www.property24.com/for-sale/val-de-vie-estate/paarl/western-cape/11726?sp=bd%3d5
- https://www.property24.com/to-rent/cape-town/western-cape/509
- https://www.property24.com/for-sale/johannesburg/gauteng/103

### 🚪 What can this Property24 Scraper do?

📈 Extract Property24 market data listings in South Africa

👀 This actor is not just a scraper but also has monitoring capability. You can turn on monitoring mode and it will give you only newly added properties compared to your previous scrapes.

📩 This actor also helps you to identify which properties are not listed anymore. Please refer to [Identifying delisted properties](#identifying-delisted-properties)

⬇️ Download Property24 real estate data in Excel, CSV, JSON, and other formats

### 📚 How do I start scraping with this scraper?

1. Register for your free Apify account [here](https://apify.com/pricing)
2. You don't need to provide your credit card details for free account. Just click on "Get Started" button on above link and complete the registration only.
3. Free account comes with reasonable credits to try out this actor. This actor also comes with free trial of 3 days without any commitment/upfront charge.
4. Run this actor and verify the scraped data. Apify has huge integration possibilities. You can download the data or push the data into any 3rd party platform directly.

### 🌳 What Property24 data can I extract using this tool?

|       📝         |             📝            |
|------------------|----------------------------|
| Listing Title    | Property ID                |
| Listing URL      | Property Type              |
| Price            | Bedrooms                   |
| Bathrooms        | Parking Spaces             |
| ERF Size         | Floor Size                 |
| Location         | Listing Date               |
| Garages          | Zoning                     |
| Pets Allowed     | Points Of Interest         |
| Description      | Images                     |
| Features         | Rooms Details              |

### ⬇️ Input

For simple usecase, you just need to provide browser URL of Property24 search result page & that's all. You can leave other fields as they are to be sensible defaults.

#### Input example

```json
{
    "listUrls": [
        {
            "url": "https://www.property24.com/for-sale/val-de-vie-estate/paarl/western-cape/11726?sp=bd%3d5"
        }
    ],
    "fullPropertyDetails": true,
    "monitoringMode": false,
    "enableDelistingTracker" : false,
    "maxProperties": 10,
    "proxy": {
        "useApifyProxy": true
    }
}
```

Understanding the input options:

- `listUrls`: Array of Property24 search result URLs you want to scrape
- `fullPropertyDetails`: By default it will scrape every single property page to get full details of property. If you don't need full details but basic details is enough for you, it's **highly encouraged** to turn off this setting. It will run the scraping a lot faster and save cost and resources.
- `monitoringMode`: This option when turned on will only scrape newly added property listings compared to previously scraped properties by this actor.
- `enableDelistingTracker` : This option when turned on will start tracking date against each property under Apify Key Value store. This KV store can be queried later to find out which properties are delisted.
- `maxProperties`: Maximum number of properties to scrape (default: 5)
- `proxy`: Proxy configuration for bypassing rate limits and geo-restrictions

### ⬆️ Output

The scraped data is stored in the dataset of each run. The data can be viewed or downloaded in many popular formats, such as *JSON, CSV, Excel, XML, RSS, and HTML*.

#### Output example

The result for scraping a single property like this:

```json
{
  "id": "111446108",
  "price": "R 39 000 000",
  "url": "https://www.property24.com/for-sale/val-de-vie-estate/paarl/western-cape/11726/111446108",
  "title": "5 Bedroom House for Sale in Val De Vie Estate",
  "bedrooms": "5",
  "bathrooms": "5",
  "parkings": "4",
  "description": "Double Storey",
  "images": [
    "https://images.prop24.com/287289515/Ensure1280x720",
    "https://images.prop24.com/359071910/Ensure1280x720"
  ],
  "garages": "2",
  "parking": "2",
  "listingNumber": "111446108",
  "typeOfProperty": "House",
  "listingDate": "12 June 2025",
  "erfSize": "1 714 m²",
  "floorSize": "870 m²",
  "petsAllowed": "Yes",
  "zoning": "General Residential",
  "rooms": {
    "bedrooms": "5",
    "bathrooms": "5, Guest Toilet, En suite",
    "kitchen": "1",
    "office": "1",
    "diningRoom": "1",
    "lounge": "1"
  },
  "features": [
    "Air Conditioning",
    "Alarm System",
    "Balcony",
    "Braai Room",
    "Built In Cupboards"
  ],
  "pointOfInterest": [
    {
      "category": "Schools",
      "name": "Val de Vie Primary School",
      "distance": "2.5 km"
    },
    {
      "category": "Shopping",
      "name": "Boland Centre",
      "distance": "15 km"
    }
  ]
}
```

### ❓Limitations

Since Property24 may have rate limiting and anti-bot measures, it's recommended to use residential proxies with South African IPs to get results smoothly. The scraper includes proxy rotation and session management to handle these challenges.

This actor has ability to bypass basic anti-bot measures. However, please run this actor with residential proxy with country South Africa to get results smoothly.

### 🔎 Identifying delisted properties

This actor provides you monitoring mode configuration using which you can get only incremental updates about newly added properties. In case, you also want to identify which properties are delisted from platform, you can use any of the following techniques with the help of this actor.

1. Running Always in full scraper mode :
   Run this actor always in full scrape mode and cross check the new incoming batch of data with your existing database. If any property that exists in yoru database but not in newly scraped data batch, that means it's not listed anymore

2. Use Key Value Store generated by scraper :
   If your are monitoring very large batch of data and you don't want to scrape everything all the time, this method involves bit of technicality but achieves the goal efectively. Apify has storage feature called [Key-value store](https://docs.apify.com/api/v2/#/reference/key-value-stores/key-collection/get-list-of-keys). When you run this scrape, this scraper stores every single property in key value store along with timestamp in `property24-properties` store. Inside this store, key is property id itself and value is timestamp like this

   ```
   { lastSeen : '2023-11-02T05:59:25.763Z'}
   ```

   Whenever you run this scraper, it will update the timestamp against particular id if it finds property on the platform. e.g. if we have 2 proprties with id `prop1` and `prop2` and we scraped them both on November 1, key value storage would look like this :

   ```
   prop1 -> { lastSeen : '2023-11-01T05:59:25.763Z'}
   prop2 -> { lastSeen : '2023-11-01T05:59:25.763Z'}
   ```

   Now if you run this scraper again on December 1 and prop1 is not on the platform anymore but prop2 is still there, key value storage would change like this :

   ```
   prop1 -> { lastSeen : '2023-11-01T05:59:25.763Z'}
   prop2 -> { lastSeen : '2023-12-01T05:59:25.763Z'}
   ```

   That means if any property has `lastSeen` less than latest batch you loaded, that property is delisted now. You can directly iterate through whole Key value storage using Apify key value storage API to identify this. Please refer to [this](https://docs.apify.com/api/v2/#/reference/key-value-stores/key-collection/get-list-of-keys) API documentation to do the same. Please remember store name generated by this scrape will be `property24-properties`.

   Alternatively, you can iterate through your existing database active properties and use [this](https://docs.apify.com/api/v2/#/reference/key-value-stores/record/get-record) API to identify listing status.

   For this approach to work, it's important that you enable this feature via `enableDelistingTracker` (Enable Delisting tracker) input.

### 🙋‍♀️ For custom solutions

In case you need some custom solution, you can contact me : <dhrumil@techvasu.com>

Or learn more about me on github : <https://github.com/dhrumil4u360>

This scraper is specifically designed for Property24.com (South Africa) and includes features like:

- Proxy rotation and session management
- Anti-bot detection handling
- Comprehensive property data extraction
- Monitoring mode for tracking new listings

# Actor input Schema

## `listUrls` (type: `array`):

Any rightmove sale or rent property listing url which has list of properties

## `propertyUrls` (type: `array`):

Any rightmove sale or rent property url to scrape

## `monitoringMode` (type: `boolean`):

If checked, it will only scrape newly listed properties compared to what has been scraped in previous runs. Please turn off full scrape setting above in case you are tunring this on.

## `fullPropertyDetails` (type: `boolean`):

If checked, it will scrape each individual property to get more details about property. If you need only limited information, turning off this option would scrape a lot more faster.

## `includePointsOfInterest` (type: `boolean`):

If checked, it will include points of interest in the scraped data. If you don't need this, turning off this option would scrape faster.

## `maxProperties` (type: `integer`):

How many listings to extract.

## `addEmptyTrackerRecord` (type: `boolean`):

If checked, it will add tracker ID record in incremental mode so that you can identify delisted properties if you have custom loader

## `enableDelistingTracker` (type: `boolean`):

If checked, it will track every single property with date so that you can find out which property is delisted. ( Enabling this has impact on billing )

## `proxy` (type: `object`):

Select proxies to be used by your crawler.

## Actor input object example

```json
{
  "listUrls": [
    {
      "url": "https://www.property24.com/for-sale/val-de-vie-estate/paarl/western-cape/11726?sp=pt%3d15000000%26bd%3d4"
    }
  ],
  "propertyUrls": [],
  "monitoringMode": false,
  "fullPropertyDetails": true,
  "includePointsOfInterest": false,
  "addEmptyTrackerRecord": false,
  "enableDelistingTracker": false,
  "proxy": {
    "useApifyProxy": 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 = {
    "listUrls": [
        {
            "url": "https://www.property24.com/for-sale/val-de-vie-estate/paarl/western-cape/11726?sp=pt%3d15000000%26bd%3d4"
        }
    ],
    "propertyUrls": [],
    "proxy": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("dhrumil/property24-south-africa-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 = {
    "listUrls": [{ "url": "https://www.property24.com/for-sale/val-de-vie-estate/paarl/western-cape/11726?sp=pt%3d15000000%26bd%3d4" }],
    "propertyUrls": [],
    "proxy": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("dhrumil/property24-south-africa-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 '{
  "listUrls": [
    {
      "url": "https://www.property24.com/for-sale/val-de-vie-estate/paarl/western-cape/11726?sp=pt%3d15000000%26bd%3d4"
    }
  ],
  "propertyUrls": [],
  "proxy": {
    "useApifyProxy": true
  }
}' |
apify call dhrumil/property24-south-africa-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Property24 South Africa Scraper",
        "description": "Effortlessly extract real estate data from Property24, South Africa's leading property portal. This powerful scraper collects comprehensive property details including prices, locations, descriptions, property types, images, agent contact info, and more.",
        "version": "0.0",
        "x-build-id": "HFR5efdTo4DPpxnRX"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/dhrumil~property24-south-africa-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-dhrumil-property24-south-africa-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/dhrumil~property24-south-africa-scraper/runs": {
            "post": {
                "operationId": "runs-sync-dhrumil-property24-south-africa-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/dhrumil~property24-south-africa-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-dhrumil-property24-south-africa-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": {
                    "listUrls": {
                        "title": "List URLs",
                        "type": "array",
                        "description": "Any rightmove sale or rent property listing url which has list of properties",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "propertyUrls": {
                        "title": "Property URLs",
                        "type": "array",
                        "description": "Any rightmove sale or rent property url to scrape",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "monitoringMode": {
                        "title": "Run in monitoring mode where only newly listed properties compared to previous runs will be scraped",
                        "type": "boolean",
                        "description": "If checked, it will only scrape newly listed properties compared to what has been scraped in previous runs. Please turn off full scrape setting above in case you are tunring this on.",
                        "default": false
                    },
                    "fullPropertyDetails": {
                        "title": "Include Full Property Details (Turn it on only if basic details are not enough)",
                        "type": "boolean",
                        "description": "If checked, it will scrape each individual property to get more details about property. If you need only limited information, turning off this option would scrape a lot more faster.",
                        "default": true
                    },
                    "includePointsOfInterest": {
                        "title": "Include Points of Interest",
                        "type": "boolean",
                        "description": "If checked, it will include points of interest in the scraped data. If you don't need this, turning off this option would scrape faster.",
                        "default": false
                    },
                    "maxProperties": {
                        "title": "Max properties to Scraper",
                        "minimum": 1,
                        "maximum": 99999,
                        "type": "integer",
                        "description": "How many listings to extract."
                    },
                    "addEmptyTrackerRecord": {
                        "title": "Add tracker ID record in incremental mode (Additional Usage*)",
                        "type": "boolean",
                        "description": "If checked, it will add tracker ID record in incremental mode so that you can identify delisted properties if you have custom loader",
                        "default": false
                    },
                    "enableDelistingTracker": {
                        "title": "Enable Delisting tracker with KV Store",
                        "type": "boolean",
                        "description": "If checked, it will track every single property with date so that you can find out which property is delisted. ( Enabling this has impact on billing )",
                        "default": false
                    },
                    "proxy": {
                        "title": "Proxy Configuration",
                        "type": "object",
                        "description": "Select proxies to be used by your crawler.",
                        "default": {
                            "useApifyProxy": 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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
