# Zameen.com Scraper | Pakistan Property Data & Price Trends (`taiw/zameen-scraper`) Actor

Collect detailed property listings from Pakistan's biggest real estate portal. This fast, no-login scraper pulls houses, flats, plots and commercial properties for sale or rent, with price per marla, price-drop tracking and CSV, JSON or API export.

- **URL**: https://apify.com/taiw/zameen-scraper.md
- **Developed by:** [ThinkAIWorks](https://apify.com/taiw) (community)
- **Features:** Limited permissions
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $1.00 / 1,000 listing saveds

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

## Zameen.com Scraper | Pakistan Property Data & Price Trends

### What does Zameen.com Scraper do?

It turns public Zameen.com search results into clean, structured property data for Pakistan. Pick a city (or several) and an optional area or society, or paste your own Zameen search or listing links. Every record comes back with the price in PKR, price per marla, size, bedrooms, bathrooms, location, agency, photos, description, features and the link to the original listing.

Teams use it for market research, real estate lead generation, investment screening, price comparison, tracking property inventory, monitoring agencies, price-drop alerts and scheduled data collection. It handles houses, flats, plots, commercial properties and farmhouses, for sale or for rent, as well as single property pages. Contact name and phone number, as published on each listing, are included by default and can be switched off.

Download the results as CSV, Excel or JSON, or connect them to Google Sheets, n8n, Make, Zapier or the API.

### Why use this Zameen scraper

- **Ready for analysis:** prices as whole PKR numbers (lakh/crore converted), area in marla, kanal, sq ft and m², and **price per marla** for every listing.
- **Search the way you think:** city (or several cities at once), buy or rent, house/flat/plot/commercial/farmhouse, area or society (e.g. "DHA Phase 6"), price, size, bedrooms and posting date.
- **Price trends mode:** median price and median price per marla per society, compared with your earlier runs (week over week).
- **New listings and price drops:** schedule it daily and receive only listings you haven't seen, or only listings whose price went down.
- **Contact details on or off:** the contact name and phone number shown on each listing are included by default (useful for agents and lead preparation), and one switch removes them.
- **Pay only for results:** no charge for skipped or duplicate listings, and it stops cleanly at your maximum cost.

### Key features

- Searches Zameen.com by **city (one or several), buy/rent, property type, area/society, price, size, bedrooms and posting date**, or scrapes any Zameen search URL you paste (English or Urdu `/ur/` pages).
- Returns **one row per listing** with numbers as numbers, missing values as `null`, prices converted to whole PKR, and area converted to marla.
- Can open each listing for the **full description, all features/amenities and all image URLs**.
- **Price trends mode** turns the listings into one row per area and property type: median price, median price per marla, min/max, listing count, and change versus earlier runs.
- **Only new listings** mode skips listings you already received in earlier runs, which suits daily or weekly schedules.

It reads the public search and listing pages only. It does not log in, and it never collects email addresses. Contact name and phone number are only what Zameen.com shows publicly on the listing, and you can switch them off with **Include contact details**.

### Who it's for

- **Real estate investors**: compare price per marla across societies, and spot newly listed properties.
- **Agents and agencies**: monitor competing listings and asking prices in your area, and build real estate lead lists of listing agents and agencies with their contact name and phone number.
- **Lead generation and sales teams**: collect leads from fresh listings (property owners' agents, builders, developers) by city, society and price range, and refresh the list on a schedule with only new listings.
- **Researchers and analysts**: build datasets of asking prices and sizes by city and area.
- **Overseas Pakistanis**: follow prices in a specific society without checking the site every day.

### Real estate lead generation from Zameen.com

Every listing includes the agency name, agency logo, contact name and phone number shown on Zameen.com (on by default, switch off with **Include contact details**). That makes the Actor a ready source of real estate leads:

1. Choose a city and society, a property type and a price range for the segment you sell to.
2. Turn on **Only new listings** and schedule the run daily, so each day you receive leads from newly posted properties only.
3. Send the results to Google Sheets, your CRM or a webhook with the Apify integrations.

Use contact details lawfully. They can be personal data, so follow Zameen.com's terms of use and the data-protection, telemarketing and anti-spam rules that apply to you before you contact anyone. See the legal note below.

### How to scrape Zameen.com (quick start)

1. Click **Try for free**. The default input (Islamabad, houses for sale, 20 listings) works as is.
2. Change the **City**, **Purpose**, **Property type** and optionally **Area / society** and price or size filters, then click **Start**.
3. Open the **Output** tab to view the table, or export it as CSV, Excel or JSON.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `listings` | `listings` (one row per property) or `priceTrends` (one row per area + property type). |
| `city` | string | `Islamabad` | One of Islamabad, Lahore, Karachi, Rawalpindi, Faisalabad, Peshawar, Multan, Gujranwala, Sialkot, Hyderabad, Quetta, Bahawalpur, Abbottabad, Sargodha, Sahiwal, Murree, Attock (17 cities). Any other city works through Start URLs. |
| `cities` | array | none | Several of the cities above in one run. Replaces `city`, and `maxItems` is split evenly between them. |
| `purpose` | string | `buy` | `buy` (for sale) or `rent`. |
| `propertyType` | string | `house` | `house`, `flat`, `plot`, `commercial`, `farmhouse`. |
| `locationKeyword` | string | none | Area or society inside the city, e.g. `DHA Phase 2`, `Bahria Town`, `G-13`. Matched to Zameen's own location list. If nothing matches, a keyword text search is used and a warning is logged. |
| `minPrice` / `maxPrice` | integer | none | Price range in PKR, e.g. `10000000` = 1 crore. For rentals this is the monthly rent. |
| `minAreaMarla` / `maxAreaMarla` | number | none | Size range in marla (1 kanal = 20 marla). |
| `bedrooms` | integer | none | Exact number of bedrooms (1–10). |
| `sortBy` | string | `newest` | `newest`, `price_low_high`, `price_high_low`. |
| `postedWithinDays` | integer | none | Only listings added or refreshed in the last N days. |
| `startUrls` | array | none | Zameen search URLs (or single `/Property/` listing URLs, English or Urdu `/ur/`) to scrape instead of the fields above. Filters in the URL are kept, and the city, purpose, type, location, price, area, bedroom and sort fields are ignored. With several search URLs, `maxItems` is split evenly between them. |
| `maxItems` | integer | `50` | Maximum listings to save (1–10,000). In price-trends mode, how many listings to analyse. This also caps your cost. |
| `includeContacts` | boolean | `true` | Include `contact_name` and `phone_number` as published on each listing. Turn off to leave them out (and to have phone numbers and emails removed from description text). |
| `includeDetailPages` | boolean | `false` | Open each listing for the full description, features and all images. Slower and uses more data. |
| `onlyNew` | boolean | `false` | Skip listing IDs saved by your earlier runs of this Actor. |
| `onlyPriceDrops` | boolean | `false` | Return only listings whose price went down since an earlier run, with the old price, the new price and the change in percent. The first run builds the baseline. Can be combined with `onlyNew` (keeps new listings and price drops). |
| `maxPagesPerSearch` | integer | none | Limit on result pages per city or start URL (25 listings per page). Defaults to 40 when `onlyPriceDrops` is on. |
| `proxyConfiguration` | object | Apify Proxy on | Proxy settings. Switch to the RESIDENTIAL group if you see blocked requests. |
| `maxConcurrency` | integer | `8` | Parallel requests (advanced). Raise it for large runs, lower it if the log shows many refused requests. |

#### Example input

```json
{
    "mode": "listings",
    "city": "Lahore",
    "purpose": "buy",
    "propertyType": "house",
    "locationKeyword": "DHA Phase 6",
    "minPrice": 30000000,
    "maxPrice": 80000000,
    "minAreaMarla": 10,
    "maxAreaMarla": 20,
    "sortBy": "newest",
    "postedWithinDays": 14,
    "maxItems": 200,
    "includeDetailPages": false,
    "onlyNew": false,
    "proxyConfiguration": { "useApifyProxy": true }
}
```

#### More examples

| Goal | Input |
|---|---|
| Flats for rent in Karachi | `{"city":"Karachi","purpose":"rent","propertyType":"flat","maxItems":200}` |
| Houses in Lahore and Islamabad, 100 each | `{"cities":["Lahore","Islamabad"],"maxItems":200}` |
| New plots in Bahria Town, last 7 days | `{"city":"Rawalpindi","propertyType":"plot","locationKeyword":"Bahria Town","postedWithinDays":7,"maxItems":500}` |
| Weekly price index for DHA Lahore | `{"mode":"priceTrends","city":"Lahore","locationKeyword":"DHA Defence","maxItems":1000}` |
| One exact Zameen search | `{"startUrls":[{"url":"https://www.zameen.com/Homes/Lahore-1-1.html?price_max=50000000"}],"maxItems":100}` |
| Full details of one listing | `{"startUrls":[{"url":"https://www.zameen.com/Property/<listing>.html"}],"includeDetailPages":true}` |

#### Supported URLs

- Search pages: `https://www.zameen.com/<Category>/<City_or_Area>-<id>-<page>.html`, e.g. `/Homes/`, `/Plots/`, `/Commercial/`, `/Flats_Apartments/`, `/Rentals/`, `/Rentals_Plots/`, `/Rentals_Commercial/`, with any filters in the query string.
- Single listings: `https://www.zameen.com/Property/...html`.
- Urdu versions of both (`https://www.zameen.com/ur/...`). Data is returned in English.

### Output

#### Example listing (SAMPLE DATA)

> This is a sample record from a test run on 2026-11-11 (search pages only, so detail-page fields are empty). The agency name, logo, contact name and phone number are replaced with placeholders. Your results will reflect live listings.

```json
{
    "id": "54974518",
    "url": "https://www.zameen.com/Property/dha_11_rahbar_sector_2_dha_11_rahbar_sector_2_-_block_f_5-marla_top_premiun_house_avalible_in_f_block_corner_house_with_excess_land_near_to_park_and_main_road-54974518-3722-1.html",
    "title": "5-MARLA TOP PREMIUN HOUSE AVALIBLE IN F BLOCK. CORNER HOUSE WITH EXCESS LAND. NEAR TO PARK AND MAIN ROAD.",
    "purpose": "buy",
    "property_type": "house",
    "price_pkr": 33000000,
    "price_text": "PKR 3.3 Crore",
    "currency": "PKR",
    "rent_frequency": null,
    "area_value": 5,
    "area_unit": "marla",
    "area_marla": 5,
    "area_sqft": 1125,
    "area_sqm": 104.52,
    "price_per_marla": 6600000,
    "previous_price_pkr": null,
    "previous_price_seen_at": null,
    "price_change_pkr": null,
    "price_change_pct": null,
    "bedrooms": 3,
    "bathrooms": 4,
    "city": "Lahore",
    "location": "DHA 11 Rahbar Sector 2 - Block F, DHA 11 Rahbar Sector 2, DHA 11 Rahbar, Lahore",
    "society": "DHA 11 Rahbar",
    "sub_location": "DHA 11 Rahbar Sector 2 - Block F",
    "latitude": 31.386761,
    "longitude": 74.271777,
    "agency": "Sample Realty",
    "agency_logo": "https://media.zameen.com/thumbnails/<logo-id>-120x90.jpeg",
    "contact_name": "Sample Agent",
    "phone_number": "+92 300 0000000",
    "is_verified": false,
    "promotion_tier": "hot",
    "completion_status": null,
    "furnishing_status": null,
    "posted_date": "2026-11-11T11:22:27.000Z",
    "updated_date": "2026-11-11T11:22:27.000Z",
    "reactivated_date": null,
    "photo_count": 0,
    "video_count": 0,
    "panorama_count": null,
    "thumbnail_url": null,
    "image_urls": [],
    "description": "5 MARLA BEAUTIFULL HOUSE AVAILBLE IN F BLOCK. NEAR TO PARK AND MAIN ROAD",
    "features": [],
    "detail_scraped": false,
    "scraped_at": "2026-11-11T11:24:04.461Z",
    "price": 33000000,
    "area": 5,
    "added_date": "2026-11-11T11:22:27.000Z",
    "agency_name": "Sample Realty",
    "amenities": [],
    "external_id": "54974518",
    "photos": []
}
```

#### Field dictionary

| Field | Description |
|---|---|
| `id` | Zameen listing ID. |
| `url` | Link to the listing page. |
| `title` | Listing title. |
| `purpose` | `buy` or `rent`. |
| `property_type` | `house`, `flat`, `upper_portion`, `lower_portion`, `farmhouse`, `penthouse`, `room`, `residential_plot`, `commercial_plot`, `plot_file`, `agricultural_land`, `office`, `shop`, `building`, etc. |
| `price_pkr` | Price as a whole number of rupees (lakh/crore/arab converted). `null` if the price is hidden. |
| `price_text` | The price written the way Zameen shows it, e.g. `PKR 3.2 Crore`. |
| `currency` | Always `PKR`. |
| `rent_frequency` | For rentals (usually `monthly`), `null` for sales. |
| `area_value`, `area_unit` | Size the way Zameen displays it: marla, or kanal from 20 marla upward. |
| `area_marla` | Size in marla (Zameen convention: 1 marla = 225 sq ft; 1 kanal = 20 marla). |
| `area_sqft`, `area_sqm` | Size in square feet and square metres (Zameen stores area in square metres). |
| `price_per_marla` | `price_pkr / area_marla`, rounded. `null` if either value is missing. |
| `previous_price_pkr`, `previous_price_seen_at`, `price_change_pkr`, `price_change_pct` | Only present when **Only price drops** is on. The earlier price, when it was seen, and the change in rupees and percent. Negative = price drop. |
| `bedrooms`, `bathrooms` | Counts. `null` when not given (common for plots and commercial units). |
| `city`, `society`, `sub_location`, `location` | Location hierarchy. `society` is the main area/society (e.g. "DHA Defence", "Bahria Town", "G-13"), `sub_location` is the most specific level (phase/block), and `location` is the full path. |
| `latitude`, `longitude` | Map position as published on the listing. |
| `agency`, `agency_name` | Name of the real estate agency that posted the listing. `null` for private sellers. |
| `agency_logo` | Link to the agency logo, `null` if none. |
| `contact_name`, `phone_number` | Contact name and phone number as published on the listing, when `includeContacts` is on (default). `null` if not shown or if switched off. Email addresses are never collected. |
| `is_verified` | Zameen's "verified" badge. |
| `promotion_tier` | Zameen ad tier: `superhot` / `hot` are paid promotions shown first; `premium` and others are regular listings. |
| `completion_status`, `furnishing_status` | E.g. `completed`, `under-construction`; `furnished`, `unfurnished`. Only with `includeDetailPages`; `null` if the seller did not specify. |
| `posted_date`, `updated_date` | ISO 8601 timestamps (UTC). |
| `reactivated_date` | When an expired listing was re-activated (only with `includeDetailPages`). |
| `photo_count`, `video_count` | Number of photos and videos on the listing. |
| `panorama_count` | Number of 360° panoramas (only with `includeDetailPages`). |
| `thumbnail_url` | Cover image URL (single link), `null` if the listing has no photos. |
| `image_urls` | Cover image only, or all images when `includeDetailPages` is on. |
| `description` | Short preview from search results (about 100 characters), or the full text when `includeDetailPages` is on. With `includeContacts` off, phone numbers and emails typed into the text are replaced with `[contact removed]`. |
| `features` | Amenities such as `Parking Spaces: 2` or `Drawing Room` (only with `includeDetailPages`). |
| `detail_scraped` | `true` if the listing page was opened for extra fields. |
| `price`, `area`, `added_date`, `external_id`, `amenities`, `photos` | The same values as `price_pkr`, `area_value`, `posted_date`, `id`, `features` and `image_urls`, under the names other Zameen scrapers use, so you can switch tools without changing your pipeline. |
| `scraped_at` | When the record was collected. |

### Pakistan property price data: a real example

The table below comes from one real run of this Actor on **2026-11-10**: Price trends mode, Lahore, houses for sale, the 500 newest listings (`{"mode":"priceTrends","city":"Lahore","propertyType":"house","maxItems":500}`). It took one run and produced 52 rows; the 6 largest are shown. These are **asking prices**, not sale prices, and the sample is the newest 500 listings, so treat small groups with care.

| Society / area | Listings | Median price (PKR) | Median PKR per marla | Cheapest | Most expensive |
|---|---|---|---|---|---|
| DHA Defence | 210 | 80,750,000 | 5,540,000 | 8,500,000 | 1,250,000,000 |
| Raiwind Road | 40 | 15,000,000 | 4,716,667 | 8,700,000 | 110,000,000 |
| GT Road | 38 | 22,500,000 | 4,800,000 | 7,500,000 | 55,000,000 |
| Valencia Housing Society | 22 | 85,000,000 | 3,612,500 | 24,000,000 | 230,000,000 |
| Bahria Town | 18 | 27,600,000 | 4,375,000 | 14,800,000 | 185,000,000 |
| Park View City | 16 | 21,250,000 | 4,200,000 | 10,000,000 | 44,000,000 |

Run it weekly and the `week_over_week_change` column starts filling in, which gives you a price-per-marla history per society.

### Price drop alerts for Zameen listings

Turn on **Only price drops** (`onlyPriceDrops`) and schedule the Actor daily. The first run stores each listing's price as a baseline. Later runs return only the listings whose price went down, with the old price, the new price and the percentage change:

```json
{ "id": "…", "price_pkr": 55000000, "previous_price_pkr": 60500000, "price_change_pkr": -5500000, "price_change_pct": -9.09 }
```

Tips:

- Use the same search every run (same city, filters and sort), so the same listings are checked each time.
- Combine with **Only new listings** to get a daily feed of "new today" plus "price dropped".
- Prices are stored in your own account (key-value store `zameen-scraper-price-history`) and contain only listing IDs, prices and dates.
- Drops are only detected for listings the Actor has already seen. `maxPagesPerSearch` (default 40 pages = 1,000 listings) limits how far each run scans.

### Price trends mode

Set `mode` to `priceTrends`. The Actor scrapes up to `maxItems` listings with your filters, then saves one row per **city + society + property type + purpose**:

| Field | Description |
|---|---|
| `listing_count`, `priced_listing_count` | Listings in the group, and how many of them had a visible price. |
| `median_price_pkr`, `median_price_per_marla` | Medians of the asking prices. |
| `min_price`, `max_price` | Lowest and highest asking price. |
| `change_vs_previous_snapshot` | % change in median price per marla (or median price if area is missing) versus the last run with the **same search**. |
| `week_over_week_change` | The same % change, compared with a snapshot taken 6–8 days earlier. `null` until such a snapshot exists. Schedule the run weekly or daily to fill this. |
| `previous_snapshot_at`, `snapshot_at`, `search` | When the comparison snapshot and this one were taken, and which search they belong to. |

Example trend row (SAMPLE DATA from a test run on 2026-11-09):

```json
{
    "city": "Lahore",
    "society": "DHA Defence",
    "property_type": "house",
    "purpose": "buy",
    "listing_count": 107,
    "priced_listing_count": 107,
    "median_price_pkr": 115000000,
    "median_price_per_marla": 5800000,
    "min_price": 24500000,
    "max_price": 600000000,
    "week_over_week_change": null,
    "change_vs_previous_snapshot": 0,
    "previous_snapshot_at": "2026-11-09T13:22:31.911Z",
    "snapshot_at": "2026-11-09T13:23:01.542Z",
    "search": "Lahore | buy | house | ?sort=date_desc"
}
```

Notes:

- These figures are **asking prices** from active listings, not sale transactions.
- Groups with only a few listings are noisy. Use `listing_count` to judge reliability, and raise `maxItems` (e.g. 500–2,000) for city-wide trends.
- Snapshots are stored in your account in the key-value store `zameen-scraper-price-trends`, keyed by the search. Keep the same input between runs so the comparisons line up.

### Pricing

This Actor uses **pay-per-event** pricing. You pay only for what is saved:

| Event | When it is charged | Price |
|---|---|---|
| `listing` | One listing saved from search results (default) | $0.001 per listing ($1.00 per 1,000) |
| `result-detailed` | One listing saved with full details (`includeDetailPages` on) | $0.003 per listing ($3.00 per 1,000) |
| `price-trend` | One trend row saved (price-trends mode) | $0.02 per row |

Each listing is charged **once**, at one of the two prices. Examples: **1,000 listings = $1.00**; **1,000 listings with full details = $3.00**. If a detail page cannot be loaded, the listing is saved with search-page data and charged as a normal `listing`. Duplicates and skipped listings are not charged. In price-trends mode, only the trend rows are charged, not the listings analysed.

Apify may also charge its standard small fee for starting the Actor. There are no other charges from this Actor. Set **Maximum cost per run** in the run options to cap spending: the Actor stops cleanly when the limit is reached and keeps everything saved so far.

### Zameen.com API alternative

Zameen.com does not offer a public API for listings. This Actor gives you the same public data as an API you can call from any language: start a run, then read the results as JSON, CSV, Excel or XML from the dataset. Prices, areas, locations and dates are already normalised (whole PKR, marla, ISO 8601), so you can load the output straight into a spreadsheet, database or BI tool. Python, Node.js and cURL examples are below.

### Scheduling and integrations

- **Schedules**: In Apify Console, go to **Schedules** and run daily or weekly. Combine with `onlyNew: true` to get only fresh listings, or with `priceTrends` to build a weekly price history.
- **Daily "new listings + price drops" to Google Sheets (recipe):** create a Schedule with this input: `{"cities":["Lahore","Islamabad"],"onlyNew":true,"onlyPriceDrops":true,"maxItems":300}`, then add the **Google Sheets** integration (Integrations tab of the Actor or the Schedule) to append each run's results to a sheet. For instant alerts, add a **webhook** on "run succeeded" that calls your own URL, Slack, n8n or Make.
- **Google Sheets, Make, n8n, Zapier**: Use the Apify integrations (or the Apify app/node in Make, n8n and Zapier) to send each run's dataset to a sheet, CRM or Slack.
- **API**: Run the Actor and get the results in one call:

```bash
curl -X POST "https://api.apify.com/v2/acts/taiw~zameen-scraper/run-sync-get-dataset-items?token=<YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"city":"Karachi","purpose":"rent","propertyType":"flat","maxItems":100}'
```

Python (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("taiw/zameen-scraper").call(run_input={
    "cities": ["Lahore", "Islamabad"],
    "propertyType": "house",
    "maxItems": 200,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["title"], item["price_pkr"], item["price_per_marla"])
```

Node.js (`npm install apify-client`):

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

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('taiw/zameen-scraper').call({
    city: 'Lahore',
    locationKeyword: 'DHA Phase 6',
    maxItems: 100,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length, items[0]);
```

Replace `<YOUR_API_TOKEN>` with your token from **Settings > Integrations**. Keep your token private.

### Use Zameen data with AI agents (MCP)

Apify runs an MCP server, so AI assistants that support MCP (such as Claude Desktop or Cursor) can call this Actor directly. Add the Apify MCP server to your assistant (see the Apify MCP documentation for the current setup and sign-in steps), enable this Actor (`taiw/zameen-scraper`), and then ask in plain language, for example:

- "Find 4-bedroom houses for sale in Bahria Town Rawalpindi under 5 crore and rank them by price per marla."
- "Which Lahore societies have the lowest median price per marla for 10 marla houses this week?"
- "Show me Islamabad flats whose price dropped since last week."

The assistant fills in this Actor's input fields for you. Each run is charged like any other run, and you can set a maximum cost per run.

### Tips

- **Start small** (20–50 listings) to check your filters, then scale up.
- Use **Area / society** for a precise location. If you need an exact page, run the search on zameen.com and paste the URL into **Start URLs**.
- `sortBy: newest` + `postedWithinDays` is the most efficient way to get recent listings, because the Actor stops paging once listings get too old.
- Leave `includeDetailPages` off unless you need full descriptions, features or all images. In our tests it made runs roughly 6 times slower and used about 20 times more data.
- **Avoiding blocks**: lower `maxConcurrency` if blocks continue. If the log shows blocked requests, switch the proxy group to **RESIDENTIAL**.

### Frequently asked questions

#### What can I scrape?

##### Which cities are supported?

Seventeen cities are built in: Islamabad, Lahore, Karachi, Rawalpindi, Faisalabad, Peshawar, Multan, Gujranwala, Sialkot, Hyderabad, Quetta, Bahawalpur, Abbottabad, Sargodha, Sahiwal, Murree and Attock. For any other place, open a search for it on zameen.com and paste the address into **Start URLs**.

##### Can I scrape several cities in one run?

Yes. Pick them in **Several cities**. `maxItems` is split evenly between the cities, so 300 listings across 3 cities gives up to 100 each.

##### Which property types are supported?

Houses, flats, plots, commercial properties and farmhouses, for sale or for rent. The `property_type` field gives the exact kind, for example `house`, `flat`, `residential_plot`, `commercial_plot`, `office`, `shop` or `farmhouse`.

##### Can I collect rental listings?

Yes. Set **Purpose** to `rent`. Area/society search and the price, size and bedroom filters all work for rentals. For rentals, `price_pkr` is the monthly rent.

##### How do I search one area or society?

Type it into **Area / society**, for example `DHA Phase 6`, `Bahria Town` or `G-13`. The Actor matches it to Zameen's own location list and logs what it picked (look for `Location "..." resolved to ...` in the run log). If the wrong area is picked, use a more specific name or paste the exact search URL.

##### Can I use my own Zameen search link or an Urdu link?

Yes. Paste any Zameen search address, or a single listing address, into **Start URLs**. Filters in the link are kept. Urdu pages (addresses starting with `/ur/`) work too, and the output is always in English.

##### Can I scrape one specific listing?

Yes. Paste its address (starting with `https://www.zameen.com/Property/`) into **Start URLs**. You get the full details for it.

#### Output and data

##### What data do I get for each listing?

Price in PKR, price per marla, area in marla, kanal, sq ft and m², bedrooms, bathrooms, city, society, full location, map coordinates, agency, posting and update dates, photo count, description, features and the link to the original listing. The full list is in the field dictionary above.

##### Why is the area given in marla?

Marla makes listings comparable across cities. Zameen's own convention is used: 1 marla = 225 sq ft and 1 kanal = 20 marla. The original size is kept in `area_value` and `area_unit`, and `area_sqft` and `area_sqm` are included too.

##### Why is `price_pkr` empty for some listings?

The seller chose to hide the price ("Call for price"). `price_text` and `price_per_marla` are empty for those listings too.

##### Why are `bedrooms` and `bathrooms` empty for some listings?

Plots and many commercial listings have no rooms, and some sellers leave them blank. Missing values are always `null`, never an empty string.

##### Why are `description`, `features` and the extra images missing?

Search results only carry a short description and the cover image. Turn on **Open each listing for full details** to get the full description, all features, every image and the status fields (completion, furnishing).

##### Are the prices real sale prices?

No. They are the asking prices shown on listings at the time of the run, not confirmed sale prices.

##### How fresh is the data?

It is read live from Zameen.com when the run starts, so it is as current as the site itself.

##### Does it return phone numbers or agent contact details?

Yes, by default. Each listing includes `contact_name` and `phone_number` as Zameen.com shows them publicly on that listing, plus the agency name and logo. Email addresses are never collected, and the Actor does not log in. Turn off **Include contact details** to leave the name and phone number out. If a listing does not show a phone number without logging in, the field is `null`.

##### Can I use the contact details for marketing or outreach?

That is your responsibility. Phone numbers and names can be personal data. Check Zameen.com's terms of use and the data-protection, telemarketing and anti-spam rules that apply to you before contacting anyone. See the legal note below.

#### Price drops, new listings and trends

##### How do I get only new listings or price drops?

Turn on **Only new listings** and/or **Only price drops** and run the Actor on a schedule. The first run builds a baseline. Later runs return only what is new or cheaper. See "Price drop alerts for Zameen listings" above.

##### Why did my first price-drop run return nothing?

Price drops are measured against what the Actor saw in earlier runs, so the first run only stores a baseline. From the second run on, listings whose price went down are returned with the old price, the new price and the change in percent. Use the same search each time.

##### What does price trends mode return?

One row per society and property type with the number of listings, median price, median price per marla, lowest and highest price, and the change since earlier runs. See "Price trends mode" above.

##### Why is the week-over-week change empty?

It needs an earlier snapshot taken 6 to 8 days before, with the same input. Schedule the run weekly and keep the input the same, and the column fills in from the second week.

#### Pricing and speed

##### How much does it cost?

You pay per result: $1.00 per 1,000 listings, or $3.00 per 1,000 with full details. Price-trend rows cost $0.02 each. Skipped and duplicate listings are free. Set a maximum cost per run to cap spending. See Pricing above.

##### How many listings can I get in one run?

Up to 10,000 (`maxItems`). For more, split the work by city, area or price range across several runs.

##### How fast is it?

In our tests, 1,000 listings from search pages took about a minute and a half. Opening every listing for full details is roughly six times slower. Speed depends on Zameen.com and the proxy.

##### Why do I get fewer listings than the number shown on Zameen.com?

The number on Zameen.com keeps changing as listings are added and removed. The Actor removes duplicates by listing ID, applies your filters (such as **Posted within**), and stops at your `maxItems` or when the results end.

#### Setup and reliability

##### Do I need a proxy?

Apify Proxy is on by default. If Zameen.com starts refusing the standard (datacenter) IPs, the Actor switches to residential proxies by itself for the rest of the run, at no extra charge to you. You can also choose the RESIDENTIAL group yourself under **Proxy configuration**, and consider lowering **Max concurrency**.

##### What happens if Zameen blocks a request?

The Actor waits a little longer after each failed attempt and retries with a new session, up to 6 times per page. If blocks continue it switches to residential proxies. If Zameen still refuses everything, the run fails with a clear message and nothing is charged. Anything already saved is kept.

##### Is there a Zameen.com API?

Zameen does not offer a public API for listings. This Actor gives you the same public data through the Apify API: start a run, then read the results as JSON, CSV, Excel or XML. See Scheduling and integrations above for code examples.

##### Can I schedule it or connect it to other tools?

Yes. Use Apify Schedules for daily or weekly runs, and the integrations for Google Sheets, n8n, Make, Zapier or webhooks. AI assistants can call it through Apify's MCP server (see above).

##### Is it legal to scrape Zameen.com?

The Actor only reads public pages and never logs in. You are responsible for following Zameen.com's terms of use and the laws that apply to you, especially for contact details. See the legal note below.

### Roadmap

Planned or under consideration (no dates promised): more cities as built-in options, new-project and developer listings, and a ready-made Google Sheets template. Tell us what you need in the **Issues** tab: requests there shape what comes next.

### Legal note

This Actor collects only data that is publicly visible on Zameen.com without logging in, and it never logs in. Contact names and phone numbers are included only as shown publicly on each listing, and can be switched off. You are responsible for making sure your use of the data complies with Zameen.com's terms of use and with applicable laws, including data protection, telemarketing and copyright laws in Pakistan and your own country. Do not use contact details in ways those laws or the site's terms do not allow. This Actor is not affiliated with or endorsed by Zameen.com.

### Support

Found a bug, a wrong value or a missing field? Open an issue in the **Issues** tab of this Actor's page. Please include the run ID and, if possible, the listing URL. Feature requests are welcome there too.

# Actor input Schema

## `mode` (type: `string`):

"Listings" returns one row per property. "Price trends" scrapes the same listings and returns one summary row per area and property type (median price, median price per marla, count, min/max, and change versus earlier runs).

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

City to search. Ignored when Start URLs are provided.

## `cities` (type: `array`):

Search several cities in one run. When you pick cities here, the single City field above is ignored, and Maximum listings is split evenly between the cities (e.g. 300 for 3 cities = up to 100 each).

## `purpose` (type: `string`):

Properties for sale or for rent. Ignored when Start URLs are provided.

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

Type of property. "Flat" covers apartments; "Plot" covers residential, commercial and other plots; "Commercial" covers shops, offices, buildings and similar. Ignored when Start URLs are provided.

## `locationKeyword` (type: `string`):

Narrow the search to an area or housing society inside the chosen city, e.g. "DHA Phase 2", "Bahria Town", "G-13". The Actor matches it to Zameen's own location list. If no location matches, it falls back to a keyword text search and logs a warning.

## `minPrice` (type: `integer`):

Lowest price in Pakistani rupees, e.g. 10000000 for 1 crore. For rentals this is the monthly rent.

## `maxPrice` (type: `integer`):

Highest price in Pakistani rupees, e.g. 50000000 for 5 crore.

## `minAreaMarla` (type: `number`):

Smallest plot/covered area in marla (1 kanal = 20 marla; Zameen uses 1 marla = 225 sq ft).

## `maxAreaMarla` (type: `number`):

Largest area in marla.

## `bedrooms` (type: `integer`):

Exact number of bedrooms (1-10). Leave empty for any.

## `sortBy` (type: `string`):

Order of results. "Newest" works best with "Posted within" and "Only new listings".

## `postedWithinDays` (type: `integer`):

Only keep listings added or refreshed in the last N days. Leave empty for any age.

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

Zameen search result URLs to scrape instead of the city/filter fields above, e.g. https://www.zameen.com/Homes/Lahore_DHA_Defence-9-1.html?price_max=50000000. Run a search on zameen.com and copy the address bar. Single listing URLs (https://www.zameen.com/Property/...) are also accepted. When provided, City, Purpose, Property type, Area/society, price, area, bedroom and sort fields are ignored.

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

Stop after this many listings (in Price trends mode: how many listings to analyse). You are charged per listing saved, so this also caps your cost.

## `includeDetailPages` (type: `boolean`):

When on, the Actor also opens every listing page to collect the full description, all features/amenities, all image URLs and status fields. Slower (one extra page per listing) and priced as a detailed result ($0.003 instead of $0.001 per listing). When off, description is the short preview from search results and only the cover image is returned. Ignored in Price trends mode.

## `includeContacts` (type: `boolean`):

When on (default), each listing includes the contact name and phone number published on Zameen.com for that listing, plus the agency name and logo. Turn it off to leave out contact_name and phone_number. You are responsible for using contact data lawfully (see the legal note in the README).

## `onlyNew` (type: `boolean`):

When on, skips listing IDs already saved by earlier runs of this Actor in your account (remembered in a named key-value store "zameen-scraper-seen-ids"). Useful for scheduled runs.

## `onlyPriceDrops` (type: `boolean`):

Return only listings whose price went down since an earlier run, with the old price, the new price and the change in percent. The first run builds the baseline, so price drops appear from the second run. Prices are kept in your account in the key-value store "zameen-scraper-price-history". Combine with "Only new listings" for a daily feed of new listings plus price drops. Scans up to 40 search pages per search unless you set "Max pages per search".

## `maxPagesPerSearch` (type: `integer`):

Optional limit on search result pages per city or start URL (25 listings per page). Leave empty for no limit (40 when "Only price drops" is on).

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

Apify Proxy is on by default. If Zameen.com starts refusing datacenter IPs, the Actor automatically switches to residential proxies for the rest of the run, so you normally do not need to change anything. You can also pick the RESIDENTIAL group yourself.

## `maxConcurrency` (type: `integer`):

Maximum parallel requests. The default (8) suits most runs. Raise it up to 20 to speed up large runs; lower it if you see many refused requests in the log.

## Actor input object example

```json
{
  "mode": "listings",
  "city": "Islamabad",
  "purpose": "buy",
  "propertyType": "house",
  "sortBy": "newest",
  "maxItems": 20,
  "includeDetailPages": false,
  "includeContacts": true,
  "onlyNew": false,
  "onlyPriceDrops": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "maxConcurrency": 8
}
```

# Actor output Schema

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

Scraped listings (listings mode).

## `trends` (type: `string`):

Trend rows (priceTrends mode).

## `summary` (type: `string`):

Counts of saved, skipped and failed items for this run.

# 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 = {
    "mode": "listings",
    "city": "Islamabad",
    "purpose": "buy",
    "propertyType": "house",
    "sortBy": "newest",
    "maxItems": 20,
    "includeDetailPages": false,
    "includeContacts": true,
    "onlyNew": false,
    "proxyConfiguration": {
        "useApifyProxy": true
    },
    "maxConcurrency": 8
};

// Run the Actor and wait for it to finish
const run = await client.actor("taiw/zameen-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 = {
    "mode": "listings",
    "city": "Islamabad",
    "purpose": "buy",
    "propertyType": "house",
    "sortBy": "newest",
    "maxItems": 20,
    "includeDetailPages": False,
    "includeContacts": True,
    "onlyNew": False,
    "proxyConfiguration": { "useApifyProxy": True },
    "maxConcurrency": 8,
}

# Run the Actor and wait for it to finish
run = client.actor("taiw/zameen-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 '{
  "mode": "listings",
  "city": "Islamabad",
  "purpose": "buy",
  "propertyType": "house",
  "sortBy": "newest",
  "maxItems": 20,
  "includeDetailPages": false,
  "includeContacts": true,
  "onlyNew": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "maxConcurrency": 8
}' |
apify call taiw/zameen-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,taiw/zameen-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/MiYcNN07jd2a4MmnI/builds/to766KasWtsKKcMUr/openapi.json
