Bazos.cz Classifieds Scraper avatar

Bazos.cz Classifieds Scraper

Pricing

from $1.05 / 1,000 results

Go to Apify Store
Bazos.cz Classifieds Scraper

Bazos.cz Classifieds Scraper

Czech classifieds from Bazos.cz across all 20 categories: title, price in CZK, city, postcode, view count, seller identity and the paid TOP badge. Reports how much of the catalogue is actually reachable instead of implying a full crawl.

Pricing

from $1.05 / 1,000 results

Rating

0.0

(0)

Developer

Ibnu Adzim

Ibnu Adzim

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Categories

Share

Bazos.cz Classifieds Scraper (Czech Republic)

Listings from Bazos.cz, the dominant Czech classifieds site, across all 20 categories — cars, property, animals, electronics, jobs, tickets and the rest — as structured rows: title, price in CZK, city, postcode, view count, seller identity and the paid TOP badge.


Two things this Actor tells you that the site does not

1. The result count is not the reachable count

auto.bazos.cz prints "Zobrazeno 1-20 inzerátů z 410 334". It will hand over 20 000, and then answer 404:

/19980/ -> 200, 20 listings <- last reachable page
/20000/ -> 404

A round 20 000 is a cap, not the end of the data. It was pinned by binary search, and checked to be global rather than per-category: prace holds 6 402 listings and ends honestly at its own size (/6400/ → 2 listings, /6420/ → 404).

What 20 000 rows actually buys you is narrower still. The feed is date-descending, and the far end of the window is yesterday:

offset 0 -> 6.9. 2026
offset 19980 -> 5.9. 2026

So this is a newest-first feed covering roughly two days, not a catalogue dump. Every summary row carries upstreamTotal (what the site claims), reachableCeiling and reachableCeilingHit, so a run never implies a completeness it did not achieve.

2. "TOP" is paid advertising, and it saturates the top of the feed

<span title="TOP 21x Platí do 17.10. 2026" class="ztop">TOP</span>

Bazos sells topování, which re-dates an ad to now. Measured on auto:

OffsetTOP rows
0 – 9 00020 / 20
12 5002 / 20
19 9801 / 20

A shallow scrape of this site returns nothing but advertising. That is not a defect to hide — it is the most commercially interesting thing on the page, so each row carries isPromoted, topPurchases (how many bumps were bought) and topExpiresOn. Filter with promotedOnly to measure dealer ad spend, or skipPromoted to reach organic stock — the latter needs depth to return much.

Because a bump rewrites the date, the date field is named bumpedDate rather than postedDate. Calling it a posting date would be a quiet lie on the majority of early rows.


What you get

One SEARCH_SUMMARY row per category, then one LISTING row per ad.

GroupFields
IdentitylistingId, listingUrl, title, description
Priceprice, priceKind, priceRaw, currency
Locationcity, postcode
EngagementviewCount
PromotionisPromoted, topPurchases, topExpiresOn, bumpedDate
SellersellerId, sellerRef, sellerName
MediaimageUrl
Provenance_input, _source, _scrapedAt, pageFound, offsetFound, category, subcategory

viewCount is unusual. Most classifieds keep view counts private; Bazos prints them on the results page. Combined with bumpedDate it gives a direct read on how fast stock moves.

Seller identity comes free. Each row's sellerId is stable across that seller's ads — measured on one page: 20 ads, 9 distinct sellers, one dealer appearing three times. Dealer-versus-private analysis needs no detail fetch.

Price is a word more often than a number

Sampled across 140 rows: 96 numeric, and then V textu (17), Dohodou (16), Nabídněte (10), Zdarma (1). Coercing those to 0 would invent 44 free cars, so price stays null and priceKind says why — amount, inText, negotiable, makeOffer or free. Only Zdarma yields 0.


Example input

{
"categories": [
"auto",
"https://reality.bazos.cz/",
"https://auto.bazos.cz/audi/"
],
"maxPages": 10
}

A category can be a plain name (auto), a host (auto.bazos.cz) or a pasted category or subcategory URL.

Categories: auto, reality, zvirata, elektro, pc, mobil, sport, deti, dum, foto, hudba, knihy, motorky, nabytek, obleceni, ostatni, prace, sluzby, stroje, vstupenky.


Limits and behaviours

A URL with a query string is refused before any request. Every Bazos subdomain's robots.txt disallows the query search surface (hledat=, order=, cenaod=, hlokalita= …), so this Actor navigates by path only and says so rather than quietly stripping your filter.

The run stops when a category runs out. Bazos answers an honest 404 past the last page rather than re-serving it, so no ceiling has to be guessed per category. stoppedReason distinguishes exhausted from reachableCeiling, maxItems and pageBudget.

maxPages above 1 000 is refused rather than silently truncated — beyond that the site returns nothing.

Every block must yield a listing id. If a layout change ever produced a row this parser could not identify, the run stops instead of dropping it silently.


How it works

HTTP-only. No browser, no login, no API key.

robots.txt is defined per origin, and Bazos serves 21 of them — one per category subdomain. All 21 were fetched and checked individually rather than assuming the apex file speaks for the subdomains; they are not identical files. Each allows the listing paths, disallows the query search surface and the write endpoints, names no AI crawler and sets no crawl delay.

The pages are plain server-rendered HTML in UTF-8 with no JSON-LD, no __NEXT_DATA__ and no framework payload — the HTML is the data layer here. Each result is a <div class="inzeraty inzeratyflex"> whose fields live in sibling elements, so blocks are cut at the next block rather than at a closing tag.

Pagination is a path offset (/40/), verified by set overlap rather than by comparing first rows: /20/, /40/ and /2000/ each share zero ids with page 1.

One detail worth stating because it looks like a trap and is not: each page carries 20 listing blocks but 21 price cells. The extra one is the Cena/Lokalita table header, not a hidden promoted row. Block-based extraction excludes it by construction, and the Actor asserts that this is still the reason — so if a real 21st row ever appears, the run fails loudly instead of quietly emitting a header as a listing.