# Bazaraki Cyprus Classifieds Scraper (`crawlerbros/bazaraki-scraper`) Actor

Scrape Bazaraki.com - Cyprus's largest classifieds marketplace with real estate, cars, jobs, electronics and general items. Search by keyword, browse any of the 15 categories, filter by city/price/sort, or fetch specific listings by ID. Get price, seller, images, coordinates and full descriptions.

- **URL**: https://apify.com/crawlerbros/bazaraki-scraper.md
- **Developed by:** [Crawler Bros](https://apify.com/crawlerbros) (community)
- **Categories:** Real estate, E-commerce, Jobs
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 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.
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

## Bazaraki Cyprus Classifieds Scraper

Scrape [Bazaraki.com](https://www.bazaraki.com) — Cyprus's largest classifieds marketplace, covering real estate, cars & motors, jobs, electronics, and general items across all five districts of Cyprus. Search by keyword, browse all 15 top-level categories directly (no keyword required), drill into Real Estate / Motors subcategories, filter by city and price, or fetch specific listings by URL.

### What this actor does

- **Two modes:** `search` (keyword + category/subcategory/city/price/sort browsing) and `byUrls` (fetch specific listing URLs you already have)
- **15 categories, all directly browsable without a keyword:** real estate for sale/rent, motors, jobs, phones, electronics, clothing, computers/gaming, home/garden, hobbies/sports, animals, health/beauty, kids' stuff, services, business, or all
- **33 subcategories** for Real Estate for Sale/to Rent and Motors (e.g. houses, apartments, cars, motorbikes, boats) for finer-grained browsing than the top-level category
- **5 cities:** Nicosia, Limassol, Larnaca, Paphos, Famagusta, or all Cyprus
- **4 sort orders:** most relevant, newest, cheapest, most expensive
- **Price range filter:** min/max in EUR
- **Bedrooms filter (Real Estate):** studio, 1–5, or 6+
- **Condition filter:** new or used (Real Estate, Motors, Electronics, and most other categories)
- **Full detail enrichment (optional):** category breadcrumb path, full description, precise coordinates, full photo gallery
- **Empty fields are omitted** — every record only contains fields Bazaraki actually published for that listing

### Output per listing

- `id`, `title`
- `price`, `currencySymbol`, `currencyCode`
- `pricePerSquareMeter` (real estate listings, requires `includeDetails`)
- `cityName`, `areaName`, `location` — from the search page; `includeDetails` refines `location`/`cityName` from the listing's own map
- `latitude`, `longitude` (requires `includeDetails`; present when the listing has a map pin)
- `categoryPath[]`, `categoryName` (breadcrumb, requires `includeDetails`)
- `description` (full text, requires `includeDetails`)
- `features[]` — raw feature chips from the search card (e.g. bedroom count, area, condition) when Bazaraki shows them; unlabeled by the site itself, see Limitations
- `characteristics` — full labeled key/value map from the listing's own "characteristics" panel, exactly as Bazaraki labels it for that category (e.g. `{"Property area": "77 m²", "Mileage (in km)": "22826 km"}`); requires `includeDetails`
- Promoted typed fields parsed from `characteristics` when present for that listing's category, requires `includeDetails`:
  - Real estate: `bedrooms`, `bathrooms`, `propertyAreaSqm`, `condition`, `parking`, `includedAmenities[]`, `energyEfficiency`, `itemType`, `floor`, `furnishing`, `constructionYear`, `airConditioning`
  - Motors: `year`, `mileageKm`, `gearbox`, `fuelType`, `bodyType`, `driveType`, `enginePower`, `engineSize`, `seats`, `colour`, `extras[]`, `referenceNumber`
  - Other categories (phones, electronics, etc.): `condition`, `kind`, `itemType` when Bazaraki publishes them
- `imageUrl`, `imageUrls[]`, `imageCount`
- `isFeatured` — true for VIP/premium listings
- `sourceUrl` — the canonical Bazaraki.com listing page
- `recordType: "listing"`, `scrapedAt`

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | select | `search` | `search` / `byUrls` |
| `searchQuery` | string | – | Free-text keyword (mode=search) |
| `category` | select | `all` | One of 15 categories, or `all` (mode=search) |
| `subcategory` | select | – | One of 33 Real Estate / Motors subcategories (e.g. `real-estate-for-sale/houses`); overrides `category` when set (mode=search) |
| `city` | select | `all` | Nicosia / Limassol / Larnaca / Paphos / Famagusta / all (mode=search) |
| `sortBy` | select | `relevant` | `relevant` / `newest` / `cheapest` / `expensive` (mode=search) |
| `minPrice` | int | – | Drop listings priced below this (EUR) |
| `maxPrice` | int | – | Drop listings priced above this (EUR) |
| `bedrooms` | select | – | `studio` / `1`–`5` / `6` (6+), Real Estate categories (mode=search) |
| `condition` | select | – | `new` / `used` (mode=search) |
| `startUrls` | array | – | Direct Bazaraki.com listing URLs (mode=byUrls) |
| `includeDetails` | bool | `false` | Fetch each listing's detail page for extra fields (slower, more complete) |
| `maxItems` | int | `30` | Hard cap on emitted records (1–2000) |

#### Example: iPhones under €800 in Nicosia, cheapest first

```json
{
  "mode": "search",
  "searchQuery": "iphone",
  "city": "nicosia",
  "maxPrice": 800,
  "sortBy": "cheapest",
  "maxItems": 50
}
```

#### Example: mobile phones for sale in Limassol, with full details

```json
{
  "mode": "search",
  "category": "telephones",
  "city": "limassol",
  "sortBy": "newest",
  "maxItems": 100,
  "includeDetails": true
}
```

#### Example: houses for sale in Paphos, no keyword needed

```json
{
  "mode": "search",
  "subcategory": "real-estate-for-sale/houses",
  "city": "paphos",
  "sortBy": "cheapest",
  "maxItems": 50
}
```

#### Example: new 2-bedroom apartments for sale in Limassol

```json
{
  "mode": "search",
  "subcategory": "real-estate-for-sale/apartments-flats",
  "city": "limassol",
  "bedrooms": "2",
  "condition": "new",
  "maxItems": 50
}
```

#### Example: fetch specific listing URLs

```json
{
  "mode": "byUrls",
  "startUrls": ["https://www.bazaraki.com/adv/6659275_iphone/"]
}
```

### Use cases

- **Vehicle price comparison** — monitor used car / motorbike listings
- **Price tracking / arbitrage** — watch electronics, phones and general items for deals
- **Real estate market research** — track Cyprus property prices and locations (with `includeDetails`)
- **Job market analysis** — pull listings from the Jobs category
- **Data aggregation** — feed a classifieds-aggregator or price-comparison tool

### Limitations

- **Real Estate and Motors category pages use a different card layout.** `real-estate-for-sale`, `real-estate-to-rent` and `car-motorbikes-boats-and-parts` render their listings in an older card layout than other categories; the actor detects and parses both layouts automatically, so browsing these 3 categories (with or without a keyword, at the top level or via `subcategory`) returns real listings either way.
- **A bare listing ID is not enough to fetch a specific listing.** Bazaraki's URL routing requires the listing's own slug — `mode=byUrls` needs the full URL (e.g. `https://www.bazaraki.com/adv/6659275_iphone/`), not just the numeric ID.
- **`features[]` values (from the search-results card) are unlabeled.** The search page shows small icon-tagged chips (e.g. bedroom count, floor area) without machine-readable labels in the page's own HTML — the actor passes these through as raw text so you can still see them. For labeled equivalents, turn on `includeDetails`: every listing's own detail page publishes a full labeled `characteristics` map (and the common ones are promoted to typed top-level fields like `bedrooms`, `mileageKm`, `fuelType` — see "Output per listing").
- **No private contact info.** Bazaraki requires a logged-in session to reveal seller phone numbers, WhatsApp, and email; the actor only extracts publicly visible listing data.
- **`sourceUrl` is Cloudflare-protected.** Bazaraki.com sits behind Cloudflare's bot-management, so `sourceUrl` (and any other bazaraki.com page link) returns a JS-challenge page to plain `curl`/non-browser HTTP clients — it opens normally in a real web browser. Image URLs (`imageUrl`/`imageUrls[]`, served from `cdn1.bazaraki.com`) are not behind this protection and load directly.

### FAQ

**What's Bazaraki?**  Cyprus's largest online classifieds marketplace — comparable to Craigslist, OLX, or Gumtree — covering real estate, vehicles, jobs, services and general items across the whole island.

**Which currency are prices in?**  Euro (EUR) — Cyprus uses the Euro. Both the currency symbol (`€`) and ISO code (`EUR`) are included on every priced listing.

**Can I search without a keyword?**  Yes, for all 15 categories — leave `searchQuery` empty and set `category` (and/or `subcategory`, `city`) to browse unfiltered.

**Can I browse a specific property type or vehicle type?**  Yes — use `subcategory` (e.g. `real-estate-for-sale/apartments-flats`, `car-motorbikes-boats-and-parts/motorbikes`) for finer-grained browsing than the top-level `category`. It's available for the Real Estate and Motors verticals, Bazaraki's two largest categories.

**Why is `includeDetails` off by default?**  The search page already returns price, location, image and a feature summary — enough for most use cases. Turning on `includeDetails` fetches each listing's own page for the category breadcrumb, full description, precise coordinates, and the full photo gallery, at the cost of one extra request per listing.

**How many listings can I pull at once?**  Up to 2000 per run.

# Actor input Schema

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

What to fetch.

## `searchQuery` (type: `string`):

Free-text keyword search, e.g. `iphone`, `toyota`, `apartment`. Leave empty to browse a category unfiltered.

## `category` (type: `string`):

Restrict results to a top-level category.

## `subcategory` (type: `string`):

Drill down into a Real Estate or Motors subcategory (property type / vehicle type). Overrides `category` when set; leave empty to use the top-level `category` instead.

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

Restrict results to a Cyprus city/district.

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

How to order results.

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

Drop listings priced below this (EUR).

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

Drop listings priced above this (EUR).

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

Restrict Real Estate listings to this number of bedrooms. Ignored for non-Real-Estate categories.

## `condition` (type: `string`):

Restrict results to new or used items. Supported across most categories (Real Estate, Motors, Electronics, etc.); ignored where Bazaraki doesn't offer a condition attribute for that category.

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

Direct Bazaraki.com listing URLs to fetch, e.g. `https://www.bazaraki.com/adv/6659275_iphone/`. A bare numeric ID is not enough — Bazaraki's routing requires the URL's slug.

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

When on, fetches each listing's detail page for extra fields (category breadcrumb, full description, coordinates, more photos). Slower but more complete.

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

Hard cap on emitted records.

## Actor input object example

```json
{
  "mode": "search",
  "searchQuery": "iphone",
  "category": "all",
  "subcategory": "",
  "city": "all",
  "sortBy": "relevant",
  "bedrooms": "",
  "condition": "",
  "startUrls": [],
  "includeDetails": false,
  "maxItems": 30
}
```

# Actor output Schema

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

Dataset containing all scraped Bazaraki.com 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 = {
    "mode": "search",
    "searchQuery": "iphone",
    "category": "all",
    "subcategory": "",
    "city": "all",
    "sortBy": "relevant",
    "bedrooms": "",
    "condition": "",
    "startUrls": [],
    "includeDetails": false,
    "maxItems": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/bazaraki-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": "search",
    "searchQuery": "iphone",
    "category": "all",
    "subcategory": "",
    "city": "all",
    "sortBy": "relevant",
    "bedrooms": "",
    "condition": "",
    "startUrls": [],
    "includeDetails": False,
    "maxItems": 30,
}

# Run the Actor and wait for it to finish
run = client.actor("crawlerbros/bazaraki-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": "search",
  "searchQuery": "iphone",
  "category": "all",
  "subcategory": "",
  "city": "all",
  "sortBy": "relevant",
  "bedrooms": "",
  "condition": "",
  "startUrls": [],
  "includeDetails": false,
  "maxItems": 30
}' |
apify call crawlerbros/bazaraki-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,crawlerbros/bazaraki-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/pLVYbbFK5xiZIH0pH/builds/8gkiwvTiCPoz4CQ4w/openapi.json
