# Magicbricks Property Search Scraper (`codingfrontend/magicbricks-property-search-scraper`) Actor

Scrape property listings from Magicbricks.com. Supports filtering by city, property type, BHK, budget, posted by, and more.

- **URL**: https://apify.com/codingfrontend/magicbricks-property-search-scraper.md
- **Developed by:** [Coding Frontned](https://apify.com/codingfrontend) (community)
- **Categories:** Real estate, Automation, Developer tools
- **Features:** Limited permissions
- **Stats:** 37 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.99 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## MagicBricks Property Search Scraper

Scrapes publicly rendered Magicbricks property-search result pages with a bounded Crawlee HTML workflow. The Actor uses the page's public HTML; it does not solve CAPTCHAs, bypass login, call private APIs, spoof fingerprints, or inject stealth scripts.

### Inputs

`searchUrls` is the preferred input. It accepts up to 20 HTTPS Magicbricks search URLs, including URLs with filters already applied.

| Field | Type | Default | Description |
|---|---|---:|---|
| `searchUrls` | array | — | Public search URLs. |
| `startUrls`, `sourceUrls`, `urls`, `url` | array/string | — | Backward-compatible aliases for `searchUrls`; provide only one alias. |
| `maxPropertiesPerSearch` | integer | `100` | Maximum normal property records per search URL. `maxItems` and `maxProducts` are accepted aliases. |
| `maxPages` | integer | `5` | Maximum bounded scroll/pagination cycles per URL. |
| `includeDiagnostics` | boolean | `false` | Emit minimal `{url,error,errorCode,scrapedAt}` rows for empty/failed pages. |
| `requestDelayMs` | integer | `250` | Delay before each public HTML request, from 0 to 5000 ms. |
| `requestTimeoutSecs` | integer | `120` | Public HTML request timeout, from 10 to 180 seconds. |
| `maxRequestRetries` | integer | `2` | Bounded crawler retries, from 0 to 3. |
| `maxConcurrency` | integer | `1` | Public-request concurrency, from 1 to 3. |
| `fixtureHtml` / `fixtureFile` | string | — | Local QA mode; parses fixture HTML instead of making a network request. Use only one. |
| `fixtureSourceUrl` | string | — | Optional Magicbricks source context for fixture records. |
| `proxyConfiguration` | object | disabled | Optional standard Apify Proxy configuration. |
| `proxy` | object | — | Backward-compatible alias for `proxyConfiguration`. |

Example input:

```json
{
  "searchUrls": [
    "https://www.magicbricks.com/property-for-sale/residential-real-estate?proptype=Multistorey-Apartment&cityName=Mumbai&language=en"
  ],
  "maxPropertiesPerSearch": 25,
  "maxPages": 3,
  "includeDiagnostics": true
}
```

### Dataset output

Each normal row keeps the Actor's existing rich property fields and adds stable/provenance fields:

- `recordType`: `magicbricksProperty`
- `recordId`: same source property identifier as `propertyId`
- `sourceDomain`, `sourceUrl`, `searchUrl`, `pageUrl`
- `pageNumber`, `position`, and ISO `scrapedAt`
- existing price, area, location, project, seller, amenity, media, status, and date fields

Image fields contain only absolute HTTP(S) image URLs from Magicbricks image hosts and common image extensions; logo/icon/sprite-like assets are excluded. Missing optional values are omitted rather than replaced with fabricated commercial facts.

Diagnostic rows are opt-in and deliberately minimal:

```json
{
  "url": "https://www.magicbricks.com/...",
  "error": "No public Magicbricks listing records were found on the page.",
  "errorCode": "NO_RESULTS",
  "scrapedAt": "2026-09-09T00:00:00.000Z"
}
```

The `OUTPUT_SUMMARY` key-value record reports run status, normal/diagnostic counts, failed requests, limits, proxy usage, and elapsed time. `OUTPUT` remains available as the compatibility summary key.

### Local development

```powershell
npm ci --ignore-scripts --no-audit --no-fund
npm test
npm run lint
npm run check
npm run validate
```

The `lint` script is a bounded JavaScript syntax check for this legacy Actor; it does not scan the repository root.
`npm run validate` checks existing local dataset files. Use an isolated `APIFY_LOCAL_STORAGE_DIR` for a clean QA run so older shared storage is not overwritten or silently migrated.

### Code structure

- `src/actor.js` owns Apify lifecycle and error handling.
- `src/runner.js` validates input, fetches public HTML with bounded retries, extracts result cards, and writes summaries.
- `src/pagination.js` contains the bounded scroll behavior used to request additional public result batches.
- `src/property.js` normalizes and validates rich listing records, filters media, and adds provenance.
- `test/property.test.js` covers the normalization/output contract.
- `validate-datasets.js` checks local rows for required identity/provenance fields and forbidden transport/debug metadata.

### Limitations

Magicbricks may vary result-card markup, return no rows, or require a normal user interaction before results are rendered. The Actor records an opt-in diagnostic for these cases and does not attempt CAPTCHA or access-control bypass. Pagination is best-effort and bounded by `maxPages`.

# Changelog

This Actor's version history is a separate document: https://apify.com/codingfrontend/magicbricks-property-search-scraper/changelog.md

# Actor input Schema

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

Magicbricks search URLs copied from the public site. Compatibility aliases: startUrls, sourceUrls, urls, or url.

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

Compatibility alias for searchUrls using request-list objects.

## `sourceUrls` (type: `array`):

Compatibility alias for searchUrls.

## `urls` (type: `array`):

Compatibility alias for searchUrls.

## `url` (type: `string`):

Compatibility alias for one public Magicbricks search URL.

## `maxPropertiesPerSearch` (type: `integer`):

Maximum normal property records per search URL.

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

Compatibility alias for maxPropertiesPerSearch.

## `maxProducts` (type: `integer`):

Compatibility alias for maxPropertiesPerSearch.

## `maxPages` (type: `integer`):

Maximum bounded scroll/pagination cycles per search URL.

## `deduplicate` (type: `boolean`):

The Actor always deduplicates by source property ID; this compatibility field is accepted for integrations.

## `includeDiagnostics` (type: `boolean`):

Emit minimal diagnostic rows for failed or empty pages; diagnostics do not count as properties.

## `requestDelayMs` (type: `integer`):

Delay before each public search page request.

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

Maximum time for one public HTML request.

## `maxRequestRetries` (type: `integer`):

Bounded retries for transient public requests.

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

Bounded public-request concurrency; 1 is recommended for ordered source traversal.

## `fixtureHtml` (type: `string`):

Optional local QA HTML. When provided, the Actor parses this fixture instead of making a network request.

## `fixtureFile` (type: `string`):

Optional local QA fixture path relative to the Actor directory. Use either fixtureFile or fixtureHtml.

## `fixtureSourceUrl` (type: `string`):

Optional HTTPS Magicbricks URL used as source context for fixture records.

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

Backward-compatible alias for proxyConfiguration.

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

Standard Apify Proxy configuration passed to the public HTML crawler when enabled. It is not a CAPTCHA or fingerprint bypass.

## Actor input object example

```json
{
  "searchUrls": [
    "https://www.magicbricks.com/property-for-sale/residential-real-estate?proptype=Multistorey-Apartment&cityName=Mumbai&language=en"
  ],
  "maxPropertiesPerSearch": 100,
  "maxPages": 5,
  "deduplicate": true,
  "includeDiagnostics": false,
  "requestDelayMs": 250,
  "requestTimeoutSecs": 120,
  "maxRequestRetries": 2,
  "maxConcurrency": 1,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "IN"
  }
}
```

# Actor output Schema

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

No description

## `keyValueStore` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

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

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchUrls": [
        "https://www.magicbricks.com/property-for-sale/residential-real-estate?proptype=Multistorey-Apartment&cityName=Mumbai&language=en"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("codingfrontend/magicbricks-property-search-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "searchUrls": ["https://www.magicbricks.com/property-for-sale/residential-real-estate?proptype=Multistorey-Apartment&cityName=Mumbai&language=en"] }

# Run the Actor and wait for it to finish
run = client.actor("codingfrontend/magicbricks-property-search-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 '{
  "searchUrls": [
    "https://www.magicbricks.com/property-for-sale/residential-real-estate?proptype=Multistorey-Apartment&cityName=Mumbai&language=en"
  ]
}' |
apify call codingfrontend/magicbricks-property-search-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,codingfrontend/magicbricks-property-search-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/ICyqKftvJpSjtrL4z/builds/SDYK3zkrWCmVxNyEo/openapi.json
