# Bazoš Czech Classifieds Scraper (`automation-lab/bazos-czech-classifieds-scraper`) Actor

Search Czech Bazoš classifieds and export detailed public listings for inventory research and repeatable price-change monitoring.

- **URL**: https://apify.com/automation-lab/bazos-czech-classifieds-scraper.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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

## Bazoš Czech Classifieds Scraper

Search public Czech **Bazoš** classifieds and export complete, stable listing records for inventory research and price-change monitoring. The Actor follows every search result to its public detail page, so each dataset row contains the listing ID, URL, title, description, price, location, date, category, and full-size image links.

Use it for one-time market research or schedule the same input repeatedly and compare records by `listingId`. It only reads anonymous public pages on `bazos.cz`; it does not reveal phone numbers, message sellers, post ads, or use account workflows.

### What does this Bazoš scraper do?

1. Builds a Czech Bazoš search from a keyword and optional category, location, radius, or price filters.
2. Paginates the server-rendered result pages up to `maxItems`.
3. Follows each unique public listing URL.
4. Extracts complete listing details and full-size image URLs.
5. Saves typed JSON records to the run's default dataset.

You can also supply public Bazoš search, category, or individual `/inzerat/` URLs. This makes the Actor useful both for discovery and for refreshing a known set of listing IDs.

### Who is it for?

- **Marketplace analysts** comparing supply and asking prices across Czech categories.
- **Dealers and resellers** tracking public competing inventory.
- **Researchers** building reproducible snapshots of public classifieds.
- **Data teams** feeding Bazoš listing records into spreadsheets, warehouses, or dashboards.
- **Automation builders** monitoring whether known listings are still available or have changed price.

The Actor is intentionally narrow: Czech `bazos.cz` public listings only. It does not claim coverage of Bazoš Slovakia, Poland, or Austria.

### Why use this Actor?

- **Stable identity:** every row includes the numeric Bazoš `listingId` for joins and change detection.
- **Detail-page data:** descriptions and full-size image links come from each public listing, not only search snippets.
- **Useful filters:** keyword, Bazoš category, location/radius, and CZK price range.
- **Two input routes:** discover listings with search or refresh exact public URLs.
- **Source-friendly execution:** bounded concurrency, result limits, and transient-only retries.
- **Integration ready:** typed records in the default Apify dataset.

### What Bazoš data can I extract?

| Field | Type | Meaning |
| --- | --- | --- |
| `listingId` | string | Stable numeric Bazoš listing ID |
| `url` | string | Canonical public listing URL |
| `title` | string | Public listing title |
| `description` | string | Full public listing description |
| `price` | number or null | Numeric price when shown |
| `priceText` | string or null | Price exactly as displayed |
| `currency` | `CZK` or null | Currency for a Czech-koruna price |
| `location` | string or null | Public locality |
| `postalCode` | string or null | Public Czech postal code |
| `postedDate` | string or null | Displayed date in day.month.year format |
| `category` | string | Category subdomain such as `auto` or `mobil` |
| `images` | string\[] | Full-size public listing image URLs |
| `scrapedAt` | string | ISO 8601 extraction timestamp |

No phone reveal endpoint is called. Seller account actions and private data are outside the Actor's scope.

### How to get started

1. Open the Actor in Apify Console.
2. Enter a `searchQuery`, such as `iphone` or `skoda`.
3. Optionally choose a category and add location or price filters.
4. Set `maxItems` to the maximum detailed listings you need.
5. Click **Start**.
6. Open the **Dataset** tab to preview, download, or integrate the records.
7. To monitor changes, schedule the same input and compare rows by `listingId`.

The prefilled input searches the current mobile-phone category and is suitable for a first run.

### Input parameters

| Input | Type | Default | Description |
| --- | --- | --- | --- |
| `searchQuery` | string | `iphone` prefill | Keyword used by Bazoš search |
| `category` | string | `all` | One supported Czech category or all categories |
| `location` | string | empty | Czech place or postal code accepted by Bazoš |
| `radiusKm` | integer | `0` | Radius around the supplied location, up to 100 km |
| `minPrice` | integer | empty | Minimum price in CZK |
| `maxPrice` | integer | empty | Maximum price in CZK |
| `startUrls` | URL array | empty | Public Czech Bazoš search/category/listing URLs |
| `maxItems` | integer | `20` | Maximum detailed records, from 1 to 1,000 |
| `maxConcurrency` | integer | `5` | Parallel detail requests, from 1 to 10 |

Provide either `searchQuery` or at least one `startUrls` entry. When both are supplied, results from both routes are deduplicated by URL before the limit is applied.

#### Example search input

```json
{
  "searchQuery": "skoda",
  "category": "auto",
  "minPrice": 50000,
  "maxPrice": 500000,
  "maxItems": 50
}
```

#### Example explicit URL input

```json
{
  "startUrls": [
    { "url": "https://mobil.bazos.cz/inzerat/221875490/iphone-17-pro-max-256gb-novy-se-s-plnou-zarukou-zarukou.php" }
  ],
  "maxItems": 1
}
```

Only `https://bazos.cz` and `https://*.bazos.cz` URLs are accepted.

### Output example

A current detail-page record has this shape:

```json
{
  "listingId": "221875490",
  "url": "https://mobil.bazos.cz/inzerat/221875490/iphone-17-pro-max-256gb-novy-se-s-plnou-zarukou-zarukou.php",
  "title": "iPhone 17 Pro MAX 256GB - Nový s plnou zárukou zárukou",
  "description": "Dobrý den, nabízím k prodeji iPhone 17 Pro MAX 256GB...",
  "price": 31800,
  "priceText": "31 800 Kč",
  "currency": "CZK",
  "location": "Praha 10",
  "postalCode": "100 00",
  "postedDate": "31.7. 2026",
  "category": "mobil",
  "images": [
    "https://www.bazos.cz/img/1/490/221875490.jpg?t=1785249322"
  ],
  "scrapedAt": "2026-07-31T04:40:00.000Z"
}
```

Listings change and disappear, so values above are illustrative of real output shape rather than a promise that this ad remains available.

### How much does it cost to extract Bazoš listings?

This Actor uses pay-per-event pricing: one small `start` charge per run plus an `item` charge only for each valid listing saved. The per-item price decreases through Apify's usage tiers. Failed, duplicate, or rejected records are not item-charged.

The start fee is **$0.005**. At the BRONZE tier, each saved listing is **$0.002668**; higher plans receive progressively lower item prices. Example BRONZE totals are about **$0.0077 for 1 listing**, **$0.0317 for 10**, and **$0.2718 for 100**. The active tier price is always shown in Apify Console before a run.

Batching more records into one run reduces the relative effect of the one-time start charge. Runtime and platform usage are covered by the pay-per-event price.

### Monitor inventory and price changes

Apify schedules can run the same input hourly, daily, or weekly. For each snapshot:

1. Use `listingId` as the durable listing key.
2. Compare `price`, `priceText`, `title`, and `description` with the previous snapshot.
3. Treat an absent ID as a possible removal, expiration, or changed query match.
4. Keep `scrapedAt` to identify when each value was observed.
5. Send changed rows to a webhook, database, or spreadsheet integration.

The Actor emits snapshots; it does not maintain a cross-run history table or send alerts by itself.

### Export to spreadsheets and data pipelines

From the Dataset tab, download JSON, CSV, Excel, XML, or RSS. You can also:

- connect Apify to Google Sheets through an integration;
- trigger a webhook when a run finishes;
- fetch dataset items from the Apify API;
- load records into BigQuery, Snowflake, PostgreSQL, or your own warehouse;
- use Make or Zapier to route new snapshots.

Keep `listingId` values as strings in spreadsheets so they are not reformatted.

### Run with the Apify API

Set `APIFY_TOKEN` in your shell and start a synchronous run:

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~bazos-czech-classifieds-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"searchQuery":"iphone","category":"mobil","maxItems":10}'
```

For larger jobs, use the asynchronous `/runs` endpoint and retrieve the dataset after the run succeeds.

### JavaScript integration

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/bazos-czech-classifieds-scraper').call({
  searchQuery: 'skoda',
  category: 'auto',
  maxItems: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.map(({ listingId, price }) => ({ listingId, price })));
```

### Python integration

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/bazos-czech-classifieds-scraper').call(run_input={
    'searchQuery': 'iphone',
    'category': 'mobil',
    'maxItems': 20,
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print([(item['listingId'], item['price']) for item in items])
```

### Use through Apify MCP

Add the Actor to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/bazos-czech-classifieds-scraper"
```

Desktop and editor clients can use:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/bazos-czech-classifieds-scraper"
    }
  }
}
```

Example prompts:

- “Search Czech Bazoš mobile listings for iPhone and return 20 prices with listing IDs.”

The same MCP URL works in **Claude Desktop**, **Cursor**, and **VS Code** when added as an HTTP MCP server using the JSON configuration above.

- “Extract this public Bazoš listing URL and summarize its price, location, and images.”
- “Run the Škoda inventory input and give me a CSV-ready table keyed by listing ID.”

### Legality and responsible use

- Only anonymous public Czech Bazoš pages are supported.
- Listings can be edited, removed, promoted, or expire between runs.
- Search ranking is controlled by Bazoš and may include promoted results.
- The Actor does not bypass CAPTCHA, login, phone reveal, or access controls.
- `maxItems` limits accepted detail records, not raw HTTP requests.
- Public markup can change; a recognized-shape check fails the run rather than silently returning misleading empty data.
- Keep concurrency conservative and follow Bazoš terms, robots guidance, privacy law, and your intended use's legal requirements.
- Do not republish personal data or use results for harassment, spam, or discriminatory decisions.

### Troubleshooting

#### Why did the run return no records?

The current query and filters may have no public matches. Try a broader keyword, choose `all`, remove price/location filters, or open the generated search directly on Bazoš. A legitimate zero-result search completes without fabricated rows.

#### Why did an explicit listing URL fail?

The ad may have expired, been removed, or no longer expose the expected public detail shape. Confirm that it opens anonymously and that the URL uses the Czech `.cz` domain and `/inzerat/<id>/` path.

#### Why are records in a different order?

Detail requests run concurrently for efficiency, so dataset order is not guaranteed. Sort by `listingId`, `postedDate`, `price`, or `scrapedAt` in your downstream system.

#### Does the Actor reveal seller phone numbers?

No. Phone reveal and private/account workflows are deliberately excluded.

### Frequently asked questions

#### Can I scrape Bazoš Auto?

Yes. Set `category` to `auto` and add a keyword such as `skoda`. The output schema is the same across categories.

#### Can I monitor a fixed set of listings?

Yes. Put their public detail URLs in `startUrls`, schedule the Task, and compare returned rows by `listingId`. Removed listings fail explicitly rather than being represented as current inventory.

#### Does it support Bazoš Slovakia or Poland?

No. This Actor is scoped to Czech `bazos.cz`. URLs from other Bazoš country domains are rejected.

#### Can I search without a category?

Yes. Keep `category` as `all` to use the Czech all-category search surface.

#### Is the dataset suitable for price comparison?

Yes. `price` is numeric when Bazoš displays a CZK amount, while `priceText` preserves the source representation. Some ads legitimately have no numeric price.

### Related scrapers

There is currently no other automation-lab scraper dedicated to Czech Bazoš classifieds. Browse [automation-lab on Apify](https://apify.com/automation-lab) for other public-data tools; third-party competitors are intentionally not presented as related products.

### Support

If a reproducible input stops working, open an issue from the Actor's Apify page and include the run URL and non-sensitive input. Do not paste API tokens or private data. Source pages change, and a concrete failed URL helps us distinguish an expired listing from a parser regression.

# Actor input Schema

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

Keyword to search across Bazoš, for example iphone, skoda, or dental chair.

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

Limit discovery to one Bazoš Czech category, or search all categories.

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

Optional Czech place name or postal code accepted by the Bazoš search form.

## `radiusKm` (type: `integer`):

Radius around the supplied location. Ignored when location is empty.

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

Optional minimum listing price in Czech koruna.

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

Optional maximum listing price in Czech koruna.

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

Optional public bazos.cz search/category URLs or individual /inzerat/ listing URLs. Filters encoded in search URLs are preserved.

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

Maximum number of detailed listing records saved to the dataset.

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

Maximum parallel listing-detail requests. Keep the default for source-friendly operation.

## Actor input object example

```json
{
  "searchQuery": "iphone",
  "category": "all",
  "radiusKm": 0,
  "startUrls": [],
  "maxItems": 20,
  "maxConcurrency": 5
}
```

# Actor output Schema

## `overview` (type: `string`):

Open the typed overview view of scraped Bazoš 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 = {
    "searchQuery": "iphone",
    "category": "all",
    "startUrls": [],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/bazos-czech-classifieds-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 = {
    "searchQuery": "iphone",
    "category": "all",
    "startUrls": [],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/bazos-czech-classifieds-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 '{
  "searchQuery": "iphone",
  "category": "all",
  "startUrls": [],
  "maxItems": 20
}' |
apify call automation-lab/bazos-czech-classifieds-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/bazos-czech-classifieds-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/k7Ivef8HvvcSaWhZg/builds/YhIcynDVcS85QBUM4/openapi.json
