# Mubawab Scraper — Morocco, Tunisia & Algeria Property (`logiover/mubawab-scraper`) Actor

Scrape Mubawab, the leading property portal in Morocco, Tunisia and Algeria: price in dirhams or dinars, surface in m², rooms, bedrooms, bathrooms, amenity list, description and photos. Sale and rent, any city. Keyless. JSON, CSV or Excel.

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

## Pricing

from $2.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/platform/actors/running/actors-in-store#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

## Mubawab Scraper — Morocco, Tunisia & Algeria Property

Export property listings from **Mubawab**, the leading real-estate portal in the Maghreb — price, surface, rooms, amenities and description — to JSON, CSV or Excel. Keyless, no login.

### What does Mubawab Scraper do?

Mubawab covers Morocco, Tunisia and Algeria, and renders its result cards server-side, so this Actor reads them without a browser and stays cheap at volume.

The part that needs care is the specification row. Surface, total rooms, bedrooms and bathrooms sit in four identically-classed cells, and each cell only appears when the advertiser filled it in. Reading them in order breaks the moment a listing omits the bathroom count — every later value shifts one column left. Here each value is matched to its own icon, so bedrooms are always bedrooms.

Prices are written with non-breaking separators and a currency suffix — "1 620 000 DH" — and rentals print exactly the same way with no period marker. Rather than guess, the Actor records whether you asked for sale or rental listings and writes that into a `transactionType` column, so a monthly rent is never mistaken for an asking price.

The amenity list is exported in full: terrace, garage, lift, concierge, air conditioning, Moroccan lounge, security, double glazing and the rest. In this market those amenities drive price more than raw surface does.

### Who is it for?

- **Estate agencies** in Casablanca, Rabat, Marrakech, Tangier or Tunis tracking competitor stock.
- **Investors** comparing price per m² between neighbourhoods and cities.
- **Diaspora buyers** monitoring a specific city from abroad.
- **Analysts** measuring supply and asking prices across the Maghreb.
- **Portal builders** who need a structured Moroccan, Tunisian or Algerian feed.

### Use cases

- Pull every apartment for sale in Casablanca with surface, rooms and amenities.
- Compare price per m² between Rabat and Marrakech.
- Model rental yield by running sale and rent over the same city.
- Find listings with a specific amenity — garage, lift, terrace — at scale.
- Track new supply weekly on a schedule.

### Why use this Actor?

- **Three countries** from one dropdown: Morocco, Tunisia, Algeria.
- **Icon-matched specifications** — surface, rooms, bedrooms and bathrooms never shift.
- **Full amenity list** as its own column.
- **Sale and rent** clearly labelled, not inferred.
- **Description included**, so you can filter on text without opening each page.
- **Keyless and browserless** — no login, no headless Chrome, low cost per row.

### What data can you extract?

Every row carries the listing ID, title and URL, location, price as label and number with currency, surface in m², total rooms, bedrooms and bathrooms, the amenity list, the description snippet, transaction type, premium flag, image count and cover image.

### How to use it

1. Choose the **country** — Morocco, Tunisia or Algeria.
2. Enter a **city slug** from a Mubawab search URL: `casablanca`, `rabat`, `marrakech`, `tanger`, `tunis`.
3. Pick sale or rent, and optionally a price band.
4. Set **Maximum results** and run, then export JSON, CSV or Excel.

### Input example

```json
{
  "country": "ma",
  "city": "marrakech",
  "transaction": "immobilier-a-vendre",
  "minPrice": 500000,
  "maxPrice": 2500000,
  "maxResults": 1000
}
```

### Notes and limits

- Prices are asking prices in local currency — MAD for Morocco, TND for Tunisia, DZD for Algeria.
- Some listings publish "prix sur demande" instead of a figure; those rows keep the label and leave the numeric price empty rather than inventing a zero.
- Advertiser contact details sit behind a click-to-reveal popup on Mubawab and are deliberately not scraped; the listing URL is exported so you can open the advert.
- The description is the card summary, not the full advert text.
- Bathroom counts are the sparsest field here because many advertisers leave them blank.

### FAQ

**Do I need a Mubawab account?**
No. Search results are public and the Actor needs nothing from you.

**Where do I find the city slug?**
Run a search on Mubawab and copy the segment after `/ct/` in the URL.

**Does it cover Tunisia and Algeria?**
Yes — switch the country. The same card layout is used across all three sites.

**Are rentals supported?**
Yes. Choose "For rent"; the `transactionType` column then reads `rent`.

**How am I charged?**
Pay per result — you pay for the listings delivered.

# Actor input Schema

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

Which Mubawab country site to scrape.

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

Mubawab city slug from the search URL, e.g. casablanca, rabat, marrakech, tanger, tunis, alger.

## `transaction` (type: `string`):

Properties for sale or for rent.

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

In local currency (MAD, TND, DZD). 0 disables the filter.

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

In local currency (MAD, TND, DZD). 0 disables the filter.

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

Stop after this many listings. Mubawab renders about 30 per page and the Actor walks pages until the target is met.

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

Mubawab renders its cards server-side; the default datacenter proxy is enough.

## Actor input object example

```json
{
  "country": "ma",
  "city": "casablanca",
  "transaction": "immobilier-a-vendre",
  "minPrice": 0,
  "maxPrice": 0,
  "maxResults": 500,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `listingId` (type: `string`):

No description

## `title` (type: `string`):

No description

## `listingUrl` (type: `string`):

No description

## `location` (type: `string`):

No description

## `priceLabel` (type: `string`):

No description

## `priceAmount` (type: `string`):

No description

## `currency` (type: `string`):

No description

## `areaSqm` (type: `string`):

No description

## `rooms` (type: `string`):

No description

## `bedrooms` (type: `string`):

No description

## `bathrooms` (type: `string`):

No description

## `features` (type: `string`):

No description

## `description` (type: `string`):

No description

## `transactionType` (type: `string`):

No description

## `isPremium` (type: `string`):

No description

## `imageCount` (type: `string`):

No description

## `imageUrl` (type: `string`):

No description

## `source` (type: `string`):

No description

## `scrapedAt` (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 = {
    "country": "ma",
    "city": "casablanca",
    "transaction": "immobilier-a-vendre",
    "minPrice": 0,
    "maxPrice": 0,
    "maxResults": 500,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("logiover/mubawab-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 = {
    "country": "ma",
    "city": "casablanca",
    "transaction": "immobilier-a-vendre",
    "minPrice": 0,
    "maxPrice": 0,
    "maxResults": 500,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("logiover/mubawab-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 '{
  "country": "ma",
  "city": "casablanca",
  "transaction": "immobilier-a-vendre",
  "minPrice": 0,
  "maxPrice": 0,
  "maxResults": 500,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call logiover/mubawab-scraper --silent --output-dataset

```

## MCP server setup

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