# Property24 Scraper - SA Property Listings & Agent Data (`haketa/property24-scraper`) Actor

Scrape Property24 SA real estate: for-sale, to-rent, sold properties with price, beds, baths, floor size, location, agent data. SA property data, market research and lead gen.

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

## Pricing

from $1.50 / 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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Property24 Scraper — South Africa Real Estate Listings & Property Data API

Extract comprehensive property listings from **Property24.com** — South Africa's largest real estate portal. Scrape for-sale, to-rent and recently sold properties with prices (ZAR), bedrooms, bathrooms, floor size, parking spaces, location details, agent contacts, images and more. Perfect for real estate market research, property investment analysis, lead generation, competitive intelligence and SA housing market data pipelines.

### 🎯 Key Differentiators

- **Server-rendered HTML extraction** — Property24 is an ASP.NET MVC site that renders listings server-side. No JavaScript execution needed — fast, cheap CheerioCrawler architecture
- **20+ data fields per listing** — price, beds, baths, floor size, parking, location, agent details, listing URL, and more
- **Three listing types** — For Sale, To Rent, and Sold Properties across all nine South African provinces
- **Location-based search** — search by province, city, or suburb slug (e.g., "gauteng", "cape-town", "sandton")
- **Zero anti-bot** — no Cloudflare, no DataDome, no CAPTCHA. Datacenter proxies work fine for large-scale runs
- **Auto-pagination** — handles up to 200 pages per location automatically
- **Lean & fast** — CheerioCrawler extracts listings in milliseconds per page with minimal memory footprint
- **No login required** — all data is publicly accessible on Property24

### 📊 What You Can Extract

| Field | Description | Example |
|-------|-------------|---------|
| `propertyId` | Numeric property ID | "117293126" |
| `listingNumber` | Property24 listing number | "P117293126" |
| `title` | Full listing title | "2 Bedroom Apartment / Flat to rent in Kibler Park" |
| `price` | Price in ZAR (numeric) | 7600 |
| `priceFormatted` | Price as displayed | "R 7 600" |
| `description` | Short listing description | "2 Bedroom Apartment in Kibler Park" |
| `location` | Suburb/area name | "Kibler Park" |
| `bedrooms` | Number of bedrooms | 2 |
| `bathrooms` | Number of bathrooms | 1 |
| `parkingSpaces` | Number of parking spaces | 1 |
| `floorSizeM2` | Floor/land size in m² | 51 |
| `listingUrl` | Full property detail URL | property24.com/to-rent/kibler-park/.../117293126 |
| `image` | Main listing image URL | images.prop24.com/355778626/Crop525x350 |
| `agentTitle` | Agency/agent name | "CSi Property Group" |
| `agentLogo` | Agency logo URL | images.prop24.com/214384406/Ensure450x261 |
| `availableBadge` | Availability status | "AVAILABLE: 01 JUL" |
| `availableDate` | Available date | "01 JUL" |
| `searchLocation` | Search location used | "gauteng" |
| `listingType` | Listing type | "to-rent" / "for-sale" / "sold" |
| `scrapedAt` | Extraction timestamp | ISO 8601 |

### 🚀 Use Cases

#### Real Estate Market Research

Analyze South African property markets at scale. Track pricing trends across provinces and cities, identify undervalued areas, and monitor inventory levels by property type and location.

#### Property Investment Intelligence

Screen for investment opportunities across the entire SA market. Filter by price, bedrooms, location to find rental yield opportunities, fix-and-flip candidates, or development land.

#### Competitor & Agent Analysis

Track which agencies are most active in specific areas. Monitor competitor listings, pricing strategies, and market share by suburb or city.

#### Lead Generation for Real Estate Services

Extract agent/agency data to build B2B contact lists. Identify active agents and agencies for partnership, software sales, or service offerings in the SA property sector.

#### Data Pipelines & Analytics

Feed structured SA property data into your data warehouse, BI dashboards, or ML models. Track market changes over time with scheduled scraping runs.

### 📥 Input Parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `listingType` | Enum | ✅ Yes | `"for-sale"` | `"for-sale"`, `"to-rent"`, or `"sold"` |
| `locations` | String array | ✅ Yes | — | SA provinces, cities or suburbs. Examples: `["gauteng"]`, `["western-cape", "cape-town"]`, `["sandton", "durban"]` |
| `maxItems` | Integer | No | 200 | Maximum properties to scrape across all locations |
| `includeDetails` | Boolean | No | `false` | Visit each property page for full descriptions, GPS, agent contacts |
| `proxyConfiguration` | Object | No | Datacenter | Proxy settings. Datacenter works fine. Residential for large runs. |

### 📍 Location Reference

#### Provinces (broadest coverage)

`gauteng`, `western-cape`, `kwazulu-natal`, `eastern-cape`, `free-state`, `limpopo`, `mpumalanga`, `north-west`, `northern-cape`

#### Major Cities

`cape-town`, `johannesburg`, `pretoria`, `durban`, `port-elizabeth`, `bloemfontein`, `east-london`, `polokwane`, `nelspruit`

#### Popular Suburbs

`sandton`, `alberton`, `centurion`, `midrand`, `roodepoort`, `kibler-park`, `umhlanga`, `stellenbosch`, `somerset-west`

> **Tip**: Use lowercase with hyphens for multi-word names. Check property24.com to find the exact URL slug for any location.

### 💰 Pricing & Performance

Property24 Scraper uses a **CheerioCrawler** — the lightest, fastest crawler type:

- **Speed**: ~200-500ms per page (no browser, no JavaScript)
- **Cost**: ~$0.01-0.05 per 1,000 listings (datacenter proxy)
- **Memory**: 512 MB minimum
- **Concurrency**: 8 parallel requests default
- **Pagination**: ~20 listings per page, auto-paginated

### 📋 Example Output

```json
{
  "propertyId": "117293126",
  "listingNumber": "P117293126",
  "title": "2 Bedroom Apartment / Flat to rent in Kibler Park",
  "description": "2 Bedroom Apartment in Kibler Park",
  "price": 7600,
  "priceFormatted": "R 7 600",
  "location": "Kibler Park",
  "bedrooms": 2,
  "bathrooms": 1,
  "parkingSpaces": 1,
  "floorSizeM2": 51,
  "listingUrl": "https://www.property24.com/to-rent/kibler-park/johannesburg/gauteng/5326/117293126",
  "image": "https://images.prop24.com/355778626/Crop525x350",
  "agentTitle": "Contact CSi Property Group to sell your home",
  "agentLogo": "https://images.prop24.com/214384406/Ensure450x261",
  "availableBadge": "AVAILABLE: 01 JUL",
  "availableDate": "01 JUL",
  "listingType": "to-rent",
  "searchLocation": "alberton",
  "scrapedAt": "2026-06-24T14:00:00.000Z"
}
```

### 🏗️ Technical Architecture

Built on:

- **[Crawlee](https://crawlee.dev)** — Apify's open-source scraping framework with request queuing, dedup, and proxy rotation
- **[Cheerio](https://cheerio.js.org)** — Fast jQuery-like HTML parser for server-rendered content
- **[Apify SDK](https://docs.apify.com/sdk/js)** — Cloud platform integration for storage, proxy, and deployment

Property24 serves listings via **server-rendered HTML** (ASP.NET MVC). Each search results page contains ~20 listing cards in structured HTML with clear CSS classes (`p24_tileContainer`, `p24_price`, `p24_featureDetails`, etc.). The scraper parses these cards directly — no JavaScript, no browser, no anti-bot challenges.

### 🔍 Tips for Best Results

- **Use specific locations** for targeted data. "gauteng" returns thousands of listings across the whole province. "sandton" returns focused results for one area.
- **Combine provinces and cities** in one run to build a comprehensive dataset.
- **Run regularly** (weekly/monthly) to track price changes, new developments, and market trends.
- **Set `includeDetails: true`** when you need agent phone numbers and full property descriptions — adds ~1 extra request per listing.
- **Check sold properties** for actual transaction data to calibrate price estimates and investment models.

### ⚙️ Running on Apify

1. Click "Try for free"
2. Select listing type: For Sale, To Rent, or Sold
3. Enter locations (e.g., `["western-cape", "gauteng"]`)
4. Set max items to your desired limit
5. Click "Save & Run"

Results download as JSON, CSV, Excel, or via API integration.

### 📚 Related Actors

- **Realestate.com.kh Scraper** — Cambodia property market
- **Daft.ie Scraper** — Ireland real estate data
- **Hemnet Scraper** — Sweden housing market with sold prices
- **Otodom Scraper** — Poland property listings
- **Funda Scraper** — Netherlands real estate data

### ⚠️ Legal & Responsible Use

This scraper extracts publicly available property listing data from Property24.com. It is designed for market research, investment analysis, and real estate data applications.

Users are responsible for:

- Complying with Property24's Terms of Service
- Respecting rate limits and fair use
- Not scraping personal data beyond publicly displayed listing information
- Complying with POPIA (South Africa's data protection law) and applicable regulations

***

Built for the SA real estate and property data community.

### 📅 Changelog & Maintenance

**Last updated:** 2026-07-02 — Actor verified and maintained. Data pipeline tested for quality, structure and freshness; selectors/endpoints confirmed against the live site.

# Actor input Schema

## `listingType` (type: `string`):

Choose which kind of property listings you want to collect.

## `locations` (type: `array`):

Pick one or more South African provinces, cities or suburbs to search. Leave empty to get a broad nationwide sample across the biggest metros.

## `maxItems` (type: `integer`):

Maximum number of properties to collect across all selected locations. Use 0 for no limit.

## `includeDetails` (type: `boolean`):

Reserved for future full-detail enrichment. Leave off for the fast listing scrape.

## `startUrls` (type: `array`):

Power users only: paste specific Property24 search result URLs to scrape exactly those pages. Most users can ignore this and just pick locations above.

## `proxyConfiguration` (type: `object`):

Proxy is recommended for larger runs to keep collection fast and reliable. The default Apify proxy works well.

## Actor input object example

```json
{
  "listingType": "for-sale",
  "locations": [
    "gauteng"
  ],
  "maxItems": 100,
  "includeDetails": false,
  "startUrls": [],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

Open to view, filter and export all scraped results from this run (JSON, CSV, Excel).

# 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 = {
    "listingType": "for-sale",
    "locations": [
        "gauteng"
    ],
    "maxItems": 100,
    "includeDetails": false,
    "startUrls": [],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("haketa/property24-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 = {
    "listingType": "for-sale",
    "locations": ["gauteng"],
    "maxItems": 100,
    "includeDetails": False,
    "startUrls": [],
    "proxyConfiguration": { "useApifyProxy": True },
}

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

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

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

```

## CLI example

```bash
echo '{
  "listingType": "for-sale",
  "locations": [
    "gauteng"
  ],
  "maxItems": 100,
  "includeDetails": false,
  "startUrls": [],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call haketa/property24-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,haketa/property24-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/jLOOdMZwNdanqGQvX/builds/OdAjxl9GbsfKfTX1q/openapi.json
