# Property Finder Scraper — Saudi, Qatar, Bahrain & Egypt (`clearrowdata/propertyfinder-mena-scraper`) Actor

Scrape rent and sale listings from Property Finder Saudi Arabia, Qatar, Bahrain and Egypt (propertyfinder.sa, .qa, .bh, .eg): price in SAR/QAR/BHD/EGP, size, bedrooms, location, coordinates, amenities and agency. Fast HTTP-only, no personal data, respects robots.txt.

- **URL**: https://apify.com/clearrowdata/propertyfinder-mena-scraper.md
- **Developed by:** [Clearrow Data](https://apify.com/clearrowdata) (community)
- **Categories:** Real estate, Lead generation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 listing scrapeds

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### What does Property Finder Scraper — Saudi, Qatar, Bahrain & Egypt do?

**Property Finder Scraper — Saudi, Qatar, Bahrain & Egypt** extracts **rent and sale listings** from the Property Finder country sites – [propertyfinder.sa](https://www.propertyfinder.sa), [propertyfinder.qa](https://www.propertyfinder.qa), [propertyfinder.bh](https://www.propertyfinder.bh) and [propertyfinder.eg](https://www.propertyfinder.eg) – and returns them as clean, structured data: **price in local currency (SAR, QAR, BHD, EGP), price frequency, bedrooms, bathrooms, size (sqm and sqft), furnishing, completion status, community, coordinates, amenities, agency and listing URL**. Think of it as an unofficial **Property Finder API** for Riyadh, Jeddah, Doha, Lusail, Manama, Cairo, the North Coast and more.

It is fast and lightweight (pure HTTP, no browser), polite to the website, and **collects no personal data** – no agent names, phone numbers or emails, only the agency's company name.

Looking for the UAE? Use the sibling **Property Finder UAE Listings Scraper** for propertyfinder.ae.

### Why scrape Property Finder in Saudi Arabia, Qatar, Bahrain and Egypt?

- 📈 **Market research** – track asking rents and sale prices per district, bedroom count or property type.
- 🌍 **Cross-market comparison** – one Actor, one output format for four GCC / MENA markets.
- 🏘️ **Investment analysis** – compare yields across areas, spot off-plan supply in Lusail or New Capital City, monitor new listings daily.
- 🗺️ **Geo analysis** – every listing has latitude/longitude, ready for maps and heatmaps.
- 🏢 **Competitive intelligence** – see which agencies list most in a given area.

Running on Apify gives you **scheduling** (e.g. every morning), **API access**, **integrations** (Google Sheets, Make, Zapier, webhooks) and run **monitoring** out of the box.

### Supported countries

| Country | Site | Currency | Example locations |
|---|---|---|---|
| 🇸🇦 Saudi Arabia | propertyfinder.sa | SAR | Riyadh, Makkah region (Jeddah), Eastern Province (Dammam, Khobar), Madinah, Al Qassim, Asir, Jazan |
| 🇶🇦 Qatar | propertyfinder.qa | QAR | Doha, Lusail, Al Wakra, Al Daayen, Umm Salal, Al Khor, Al Shamal |
| 🇧🇭 Bahrain | propertyfinder.bh | BHD | Capital, Muharraq, Northern, Central, Southern governorates |
| 🇪🇬 Egypt | propertyfinder.eg | EGP | Cairo, Giza, Alexandria, North Coast, Red Sea, Suez, Al Daqahlya |

Prices are returned in the currency the site shows. Any other city or community works through **category URLs** (see Input).

### What data can it extract?

| Field | Type | Description |
|---|---|---|
| `listingId` | string | Property Finder listing ID |
| `country` | string | `sa`, `qa`, `bh` or `eg` |
| `title` | string | Listing headline |
| `price` / `currency` | number / string | Asking price, e.g. `1250000` `QAR` |
| `priceFrequency` | string | `yearly`, `monthly`, `weekly`, `daily` (rent) or `sale` |
| `propertyType` | string | Apartment, Villa, Townhouse, Chalet, … |
| `bedrooms` / `bathrooms` | integer | Bedrooms (`0` = studio) and bathrooms |
| `sizeSqft` / `sizeSqm` | number | Built-up area in sq ft and m² |
| `furnished` | string | `furnished`, `unfurnished`, `partly-furnished` |
| `completionStatus` | string | `completed`, `off_plan`, `completed_primary`, `off_plan_primary` |
| `community` / `subCommunity` / `city` | string | Location hierarchy (district / area / city or governorate) |
| `latitude` / `longitude` | number | Coordinates |
| `agencyName` | string | Listing agency (company name only; `null` for individual brokers) |
| `listedDate` | string | ISO 8601 publish date |
| `verified` | boolean | Property Finder "verified" badge |
| `amenities` | array | e.g. `["Shared Pool", "Covered Parking"]` |
| `imageCount` | integer | Number of photos |
| `listingUrl` | string | Link to the listing |

### How to scrape Property Finder Saudi, Qatar, Bahrain or Egypt

1. Click **Try for free** / **Start**.
2. Pick a **Country**, then a **City / region**, **Rent or buy** and **Property type** – *or* paste one or more Property Finder **category URLs** such as `https://www.propertyfinder.eg/en/buy/cairo/villas-for-sale.html`.
3. Set **Maximum listings**.
4. Click **Start** and download your data as JSON, CSV, Excel or HTML.

### How much will it cost to scrape Property Finder?

This Actor uses **pay-per-event** pricing. You pay for two events:

| Event | Price | When it is charged |
|---|---|---|
| `actor-start` | $0.005 | Once per run |
| `listing-scraped` | $0.001 ($1 per 1,000 listings) | Once per listing saved to the dataset |

**Cost examples:**

| Listings per run | Calculation | Total |
|---|---|---|
| 100 | $0.005 + 100 × $0.001 | **$0.105** |
| 1,000 | $0.005 + 1,000 × $0.001 | **$1.005** |
| 10,000 | $0.005 + 10,000 × $0.001 | **$10.005** |

A daily run of 1,000 listings for a month costs about **$30.15**.

- **Free Apify plan:** runs are capped at **20 listings** so you can test the output.
- **Paid plans:** up to your `maxResults`. The Actor also stops automatically when your *maximum cost per run* is reached, so you never pay more than you set.

### Input

See the **Input** tab for all options. Example:

```json
{
    "country": "qa",
    "city": "lusail",
    "offeringType": "buy",
    "propertyType": "apartments",
    "maxResults": 100
}
```

or

```json
{
    "startUrls": [
        { "url": "https://www.propertyfinder.sa/en/rent/makkah-al-mukarramah/apartments-for-rent.html" },
        { "url": "https://www.propertyfinder.bh/en/buy/muharraq-governorate/villas-for-sale.html" }
    ],
    "maxResults": 200
}
```

Leave **City / region** empty to use the country's main market (Riyadh region, Doha, Capital Governorate, Cairo). The city must belong to the selected country – otherwise the run stops with a list of valid values.

**Accepted URLs:** category pages of the form `https://www.propertyfinder.{sa|qa|bh|eg}/en/{rent|buy}/{city}/{type}-for-{rent|sale}.html`, optionally with `?page=N`. Community-level category pages work too, and URLs from different countries can be mixed in one run (each row's `country` comes from its URL). Search URLs (`/en/search?…`) and filter parameters (`bedrooms=`, `price=`, `ob=`, …) are **skipped**, because Property Finder's robots.txt disallows them – see Limitations.

### Output

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel. Sample item (values anonymized):

```json
{
    "listingId": "100000001",
    "country": "qa",
    "title": "Luxury Living | 10% Down Payment | 7-Year PP",
    "price": 1591506,
    "currency": "QAR",
    "priceFrequency": "sale",
    "propertyType": "Apartment",
    "bedrooms": 2,
    "bathrooms": 3,
    "sizeSqft": 1389,
    "sizeSqm": 129,
    "furnished": "furnished",
    "completionStatus": "off_plan_primary",
    "community": "Lusail City",
    "subCommunity": "Miran",
    "city": "Lusail",
    "latitude": 25.4286,
    "longitude": 51.5074,
    "agencyName": "Example Real Estate",
    "listedDate": "2026-11-05T14:47:50Z",
    "verified": false,
    "amenities": ["Central A/C", "Balcony", "Shared Pool", "Shared Gym", "Covered Parking", "Security"],
    "imageCount": 15,
    "listingUrl": "https://www.propertyfinder.qa/en/plp/buy/apartment-for-sale-lusail-lusail-city-miran-100000001.html"
}
```

### Limitations

- **Lebanon is not supported.** Property Finder no longer operates a Lebanon site (propertyfinder.lb does not exist), so there is nothing to scrape.
- **No search / filter URLs.** Property Finder's robots.txt disallows `/en/search?…` and filter query parameters, so the Actor only crawls category pages (city × rent/buy × property type, or a community category page). Filter by bedrooms, price, etc. in the downloaded dataset instead.
- **Not every property type exists everywhere.** E.g. chalets are mostly an Egyptian category and compounds a Saudi / Qatari one. A category that doesn't exist (HTTP 404) is reported in the log and the run finishes with 0 listings – try "All properties".
- **Results come from search result pages only** (about 25 listings per page). Detail pages are not opened, so long descriptions and full floor plans are not included. New-project / developer "project" cards are skipped – only individual listings are returned.
- **Agency reference numbers are not included**, because agencies on these sites often build them from people's names.
- **Data is as entered by the lister.** Sizes and prices are not corrected – occasional outliers (e.g. a plot size entered as the apartment size) come straight from the site.
- **Hidden prices** are returned as `null`. `completionStatus` is usually empty for rentals.
- **Polite by design:** max 2 concurrent requests, 500 ms between requests to the same domain, and a descriptive User-Agent. Large scrapes therefore take a while (~1,000 listings in a few minutes).
- **No blocking bypass.** If Property Finder blocks the crawler (HTTP 403/429 or a CAPTCHA page), the Actor stops cleanly, keeps what it has already scraped, and reports the reason in the run status. It never tries to solve CAPTCHAs.
- The Actor relies on the JSON embedded in Property Finder's pages; if the site changes its structure, it may need an update.

### FAQ, disclaimers and support

**Does it collect personal data?** No. Agent names, photos, phone numbers, WhatsApp links and emails are never stored – only the agency's company name. In Saudi Arabia individual licensed brokers can list under their own name; in that case `agencyName` is `null`. Free-text descriptions and agency reference numbers are not stored either, because they often contain phone numbers or names.

> Our Actors are ethical and do not extract any private user data, such as email addresses, gender, or location. They only extract what the user has chosen to share publicly. We therefore believe that our Actors, when used for ethical purposes by Apify users, are safe. However, you should be aware that your results could contain personal data. Personal data is protected by the GDPR in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

This Actor is not affiliated with or endorsed by Property Finder. Found a bug or need a field? Open an issue in the **Issues** tab. For programmatic access, see the **API** tab.

# Actor input Schema

## `country` (type: `string`):

Which Property Finder site to scrape: propertyfinder.sa (SAR), .qa (QAR), .bh (BHD) or .eg (EGP). Prices are returned in the currency the site shows. Ignored when category URLs are given (the country is taken from each URL).

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

Category pages to scrape, e.g. https://www.propertyfinder.qa/en/rent/doha/apartments-for-rent.html or https://www.propertyfinder.eg/en/buy/cairo/villas-for-sale.html. Leave empty to use Country / City / Rent or buy / Property type. Note: /en/search?… URLs and filter query parameters (bedrooms, price, …) are disallowed by Property Finder's robots.txt and will be skipped; only ?page=N is allowed.

## `city` (type: `string`):

Location within the selected country (must belong to that country). Leave empty for the main city: Riyadh region (SA), Doha (QA), Capital Governorate (BH), Cairo (EG). Used only when no category URLs are given.

## `offeringType` (type: `string`):

Rental listings (yearly/monthly prices) or properties for sale.

## `propertyType` (type: `string`):

"All properties" includes every residential type. Not every type exists in every country (e.g. chalets are mostly in Egypt, compounds in Saudi/Qatar); a missing category is reported in the log.

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

Stop after this many listings. Users on the Apify free plan are capped at 20 listings per run.

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

Optional. The Actor works without a proxy; requests are made politely (max 2 concurrent, 500 ms apart).

## Actor input object example

```json
{
  "country": "sa",
  "startUrls": [
    {
      "url": "https://www.propertyfinder.sa/en/rent/ar-riyadh/apartments-for-rent.html"
    }
  ],
  "offeringType": "rent",
  "propertyType": "apartments",
  "maxResults": 50,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `listings` (type: `string`):

Dataset containing all scraped listings

# 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 = {
    "startUrls": [
        {
            "url": "https://www.propertyfinder.sa/en/rent/ar-riyadh/apartments-for-rent.html"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("clearrowdata/propertyfinder-mena-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 = { "startUrls": [{ "url": "https://www.propertyfinder.sa/en/rent/ar-riyadh/apartments-for-rent.html" }] }

# Run the Actor and wait for it to finish
run = client.actor("clearrowdata/propertyfinder-mena-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 '{
  "startUrls": [
    {
      "url": "https://www.propertyfinder.sa/en/rent/ar-riyadh/apartments-for-rent.html"
    }
  ]
}' |
apify call clearrowdata/propertyfinder-mena-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,clearrowdata/propertyfinder-mena-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/ZMFtev2XwIlMfFZkw/builds/odffTRI5RzyPbJfR5/openapi.json
