Krisha.kz Real Estate Scraper | Kazakhstan Property avatar

Krisha.kz Real Estate Scraper | Kazakhstan Property

Pricing

from $0.87 / 1,000 listings

Go to Apify Store
Krisha.kz Real Estate Scraper | Kazakhstan Property

Krisha.kz Real Estate Scraper | Kazakhstan Property

Collect property listings from Krisha.kz (Kazakhstan): title, rooms, area, floor, price, currency, city, address, photo and listing link. No login, walk any search or category page.

Pricing

from $0.87 / 1,000 listings

Rating

0.0

(0)

Developer

Vitalii Bondarev

Vitalii Bondarev

Maintained by Community

Actor stats

0

Bookmarked

12

Total users

3

Monthly active users

16 days ago

Last modified

Features

Limited permissions

Share

Krisha.kz Real Estate Scraper

This Actor collects public property listings from Krisha.kz search and category pages in Kazakhstan and returns structured rows with titles, property types, rooms, areas, floors, prices, locations, images, and listing URLs. It needs no Krisha.kz login or API key; billing is $0.0009 per listing-result event and $0.00005 per apify-actor-start event on the Free tier, the default 2048 MB run uses two start events, and each Free-plan run returns at most 25 listings.

What you get

A dataset row is produced for each unique listing returned from the requested result pages. A source-derived field is null when the source does not provide its value; isNegotiable, scrapedAt, and parse_confidence are always present.

FieldTypeMeaningNull or empty behavior
listingIdstringKrisha.kz listing identifiernull when no listing ID is found in the card or URL
uuidstringCard or photo UUIDnull when the card does not provide it
titlestringListing titlenull when the card does not provide a title
propertyTypestringNormalized property typeapartment, house, land, or null for other card types
roomsintegerRoom count parsed from the titlenull unless the title contains an N-комнат value; it depends on the card type
areaM2numberArea in square metresnull when the card does not provide an area; decimal values are supported
landSotkanumberLand size in сотокnull unless the title contains land-size text such as соток; decimal values are supported
floorintegerProperty floornull when the card does not provide a floor value; it depends on the card type
totalFloorsintegerTotal building floorsnull when the card does not provide a total-floor value
priceintegerParsed numeric price. Some cards show a starting price (priceText begins with от); then price is that starting amount and nothing else marks it.null for the bare text Договорная or price text without digits
currencystringPrice currency codenull when no numeric price is available; defaults to KZT when digits appear without a recognized currency symbol
priceTextstringOriginal price text from the cardnull when the card does not provide price text
isNegotiablebooleanWhether the card marks the price as negotiableAlways true or false; never null
addressstringAddress from the listing cardnull when the card does not provide an address
citystringCity from the card statistics linenull when the card does not provide a city
postedTextstringPosting-date text shown on the cardnull when unavailable; source text has no year
descriptionstringDescription field from the list-page resultnull for every result from list pages; the key is still present in every dataset row and export
imageUrlstringListing image URLnull when the card does not provide an image
urlstringListing detail URLnull when the card does not provide a detail URL
querystringStart URL that produced the rowNot empty for emitted rows
scrapedAtISO 8601 stringUTC timestamp created during the runAlways present
parse_confidencenumberShare from 0 to 1 of the five core fields listingId, title, url, price, and city that are presentAlways present and rounded to two decimals

propertyType is limited to apartment, house, land, or null. The output has no field that marks a listing as sale or rent. Supported price symbols are converted to codes such as KZT, USD, EUR, and RUB.

For the bare price text Договорная, price and currency are null and isNegotiable is true. Non-digit characters are removed when the integer price is parsed; for example, a price text such as 1,5 млн ₸ would become 15, so check priceText for unusual cards. Text fields keep the language of the Krisha.kz page you request; the sample and recipes use the Russian pages. propertyType, rooms, floor, totalFloors and landSotka are read from Russian words in the card title (комнат, квартир, дом, коттедж, участок, этаж, сот), so a title that lacks those words gives null for them.

Sample output

The following two records are taken from a successful dataset sample produced from https://krisha.kz/prodazha/kvartiry/ with pagesToFetch: 3 and maxItems: 5.

[
{
"listingId": "1016119428",
"uuid": "5b56fada-3c12-43d6-adf0-70af982a1e10",
"title": "2-комнатная квартира · 41 м² · 4/5 этаж",
"propertyType": "apartment",
"rooms": 2,
"areaM2": 41,
"landSotka": null,
"floor": 4,
"totalFloors": 5,
"price": 35000000,
"currency": "KZT",
"priceText": "35 000 000 ₸",
"isNegotiable": false,
"address": "Алмалинский р-н, Нурмакова 75 — Карасай Батыра",
"city": "Алматы",
"postedText": "5 окт.",
"description": null,
"imageUrl": "https://krisha-photos.kcdn.online/webp/5b/5b56fada-3c12-43d6-adf0-70af982a1e10/21-full.jpg",
"url": "https://krisha.kz/a/show/1016119428",
"query": "https://krisha.kz/prodazha/kvartiry/",
"scrapedAt": "2026-10-05T13:32:00Z",
"parse_confidence": 1
},
{
"listingId": "1012969209",
"uuid": "bc0bff17-2887-4133-8b4a-2464cbe2b4dd",
"title": "2-комнатная квартира · 70 м² · 6/10 этаж",
"propertyType": "apartment",
"rooms": 2,
"areaM2": 70,
"landSotka": null,
"floor": 6,
"totalFloors": 10,
"price": 32900000,
"currency": "KZT",
"priceText": "32 900 000 ₸",
"isNegotiable": false,
"address": "Сарыарка р-н, Сейфуллина 5",
"city": "Астана",
"postedText": "5 окт.",
"description": null,
"imageUrl": "https://krisha-photos.kcdn.online/webp/bc/bc0bff17-2887-4133-8b4a-2464cbe2b4dd/35-full.jpg",
"url": "https://krisha.kz/a/show/1012969209",
"query": "https://krisha.kz/prodazha/kvartiry/",
"scrapedAt": "2026-10-05T13:32:00Z",
"parse_confidence": 1
}
]

Pricing

This Actor uses live pay-per-event billing. A listing-result event is charged once per listing returned, and an apify-actor-start event is charged once per GB of run memory, with a minimum of one event.

Live event rates

Prices below are per event in USD. The applicable rate depends on the Apify pricing tier.

Apify tierapify-actor-startlisting-result
Free$0.000050$0.000900
Bronze$0.0000495$0.000891
Silver$0.000049$0.000882
Gold$0.0000485$0.000873
Platinum$0.000048$0.000864
Diamond$0.0000475$0.000855

You pay only for the events listed below. This Actor does not use the Pay per event + usage option, so the platform usage of your runs (compute, proxy traffic and storage) is not billed to you separately.

Worked calculations

The Actor's default run memory is 2048 MB, so the default run is charged 2 apify-actor-start events. Changing the memory changes the number of apify-actor-start events.

A full Free-plan run of 25 listings costs:

25 × $0.000900 + 2 × $0.000050 = $0.0226

The Free-plan cap means that 1,000 or 10,000 listings are not returned by one Free run. At the Bronze tier rate, using the default 2048 MB memory:

  • 1,000 listings: 1,000 × $0.000891 + 2 × $0.0000495 = $0.891099
  • 10,000 listings: 10,000 × $0.000891 + 2 × $0.0000495 = $8.910099

These are totals for the Bronze tier at the stated listing counts, not the result of one Free-plan run.

The Apify Free plan includes $5 of platform credit each month. At the Free-plan rate, the $5 monthly credit covers 221 full runs (5,525 listings).

How it works

  1. The Actor accepts one or more Krisha.kz listing, category, or filtered-search URLs.
  2. It fetches each result page independently, adding ?page= for pages after the first.
  3. It parses server-rendered a-card listing blocks from the result-page HTML.
  4. It normalizes title, price, location, property facts, media, source URL, query URL, scrape time, and parse confidence into a fixed row structure.
  5. It removes duplicates across the run using the listing ID when available. When no ID is available, it uses the title and address combination as a fallback key.
  6. It pushes parsed rows to the Apify dataset during the run and charges one listing-result event per listing returned.
  7. It writes an OUTPUT record containing totalListings, urlsRun, and pagesPerUrl.

Rows reach the dataset after the corresponding result page has been parsed, in batches as needed. Rows already pushed before an abort, timeout, or failure remain in the dataset; rows not yet pushed are absent.

The source pages are reached without a Krisha.kz login or API key. The default proxy configuration uses Apify's RESIDENTIAL proxy group with country KZ.

Input parameters

InputTypeDefaultDetails
startUrlsArray of stringshttps://krisha.kz/prodazha/kvartiry/ if emptyKrisha.kz listing, category, or search URLs only; other sites are not supported and are expected to return no rows. Each URL is paginated independently.
pagesToFetchinteger3Number of result pages to walk per URL. Accepted range: 1 to 1000.
maxItemsinteger100Maximum listings returned across URLs and pages. 0 removes the cap, subject to the Free-plan preview cap and available pages. Minimum: 0. URLs are walked in the order given, so earlier URLs use the cap first.
proxyConfigurationobjectApify RESIDENTIAL, country KZProxy configuration used to reach the public Krisha.kz pages.
disableUsageStatsbooleanfalseSet to true to turn off the run summary described in Usage statistics.

The default proxyConfiguration is:

{
"useApifyProxy": true,
"apifyProxyGroups": [
"RESIDENTIAL"
],
"apifyProxyCountry": "KZ"
}

Example inputs

Apartment sale listings

{
"startUrls": [
"https://krisha.kz/prodazha/kvartiry/"
],
"pagesToFetch": 3,
"maxItems": 100,
"proxyConfiguration": {
"useApifyProxy": true,
"apifyProxyGroups": [
"RESIDENTIAL"
],
"apifyProxyCountry": "KZ"
}
}

Apartment rentals in Almaty

{
"startUrls": [
"https://krisha.kz/arenda/kvartiry/almaty/"
],
"pagesToFetch": 10,
"maxItems": 250,
"proxyConfiguration": {
"useApifyProxy": true,
"apifyProxyGroups": [
"RESIDENTIAL"
],
"apifyProxyCountry": "KZ"
}
}

Walk several result pages of one URL

{
"startUrls": [
"https://krisha.kz/prodazha/kvartiry/"
],
"pagesToFetch": 20,
"maxItems": 0,
"proxyConfiguration": {
"useApifyProxy": true,
"apifyProxyGroups": [
"RESIDENTIAL"
],
"apifyProxyCountry": "KZ"
}
}

Combine sale and rental searches

{
"startUrls": [
"https://krisha.kz/prodazha/kvartiry/",
"https://krisha.kz/arenda/kvartiry/almaty/"
],
"pagesToFetch": 5,
"maxItems": 300,
"proxyConfiguration": {
"useApifyProxy": true,
"apifyProxyGroups": [
"RESIDENTIAL"
],
"apifyProxyCountry": "KZ"
}
}

The output has no sale/rent flag or price-period field. Use the query field to tell the two searches apart, and do not average price across them. If a listing appears in both searches, de-duplication keeps the first query value.

maxItems is a ceiling. The number of rows is also bounded by pagesToFetch times the cards on each result page (the apartment-sale results page used to test this Actor held 23 cards), so raise pagesToFetch when you need more rows. On the Free plan every recipe returns at most 25 listings.

How to use

  1. Open this Actor in your Apify account and create a new run.
  2. Add one or more Krisha.kz URLs to startUrls, using the recipes above as a starting point.
  3. Set pagesToFetch and maxItems according to the pages and listings you want.
  4. Keep the default proxy configuration unless your run requires another supported Apify proxy setup.
  5. Start the run and use the resulting Apify dataset for the listing rows.

Limits and edge cases

  • On the Apify Free plan, each run returns at most 25 listings across URLs and pages. This is a preview cap; paid Apify plans have no such cap.
  • maxItems accepts values from 0 upward. 0 removes the configured cap, but it does not remove the Free-plan cap of 25 listings per run.
  • pagesToFetch accepts values from 1 through 1000 for each start URL.
  • Any page parameter in a start URL is ignored. Each URL is walked from page 1, and later pages use the page query parameter.
  • Each start URL is walked independently. Earlier URLs can use the shared maxItems cap before later URLs are reached.
  • Duplicate listings are removed across the run using listingId, with a title-and-address fallback when no ID is available.
  • A page that fetches successfully but parses no records ends that URL normally; the run log shows parsed 0 record(s) for that page.
  • A page fetch uses a 45-second timeout. The Actor makes up to three attempts for a page when a transport error or detected page-access issue occurs.
  • HTTP statuses 401, 403, 429, and 503, a response body shorter than 3,000 characters, or a response that contains neither a-card nor data-id are treated as page-access failures.
  • A results page with no listing cards still carries the data-id markers of the site menu, so it is not treated as a blocked page: it ends that URL normally, without retries. Only a response that matches the previous point is retried three times and then treated as a blocked page; that stop reason is written to the run log only.
  • A blocked page ends the run as Succeeded, possibly with 0 rows or a short dataset. The Actor skips the remaining pages of that URL and moves to the next URL. OUTPUT in the run's default key-value store records totalListings, urlsRun, and pagesPerUrl, but not the block or fetch-error reason.
  • A proxy connection error while fetching a page is retried up to three times and then handled like a blocked page (run Succeeded, possibly with 0 rows). An error raised outside the page fetch, for example while creating the proxy configuration or reading the input, ends the run as Failed. Rows pushed before a timeout, abort, or failure remain in the dataset; later rows are not added.
  • The parser tolerates missing card cells and returns null values for fields that are not available. A malformed page can produce an empty result for that page.
  • The Actor reads listing cards from result pages only; it does not open each listing's detail page, so fields that exist only on the detail page are not included.
  • postedText is retained as source text, while scrapedAt is generated as a UTC timestamp for the Actor run.
  • Results depend on what Krisha.kz returns for the requested URL, pagination, and page-access conditions.
  • For rental searches, price is the amount shown on the card, but no price period is captured. For the bare text Договорная, price and currency are null and isNegotiable is true. If the price text also contains digits, price holds them, and isNegotiable is still true when the word договорная appears.
  • A priceText that begins with от is a starting price; price holds that amount without a flag.
  • If a price contains digits but no recognized currency symbol, currency defaults to KZT. Non-digit characters are removed when price is converted to an integer.
  • parse_confidence is the fraction of the five core fields listingId, title, url, price, and city that are present, rounded to two decimals. A negotiable-price listing can therefore have a maximum value of 0.8 when price is missing.
  • description is null for every result from list pages. The key is still present in every dataset row and in exports, but the Console overview table does not show it.

Integrations

Apify dataset

Listing rows are pushed to the Actor's Apify dataset during the run. The dataset contains the normalized fields described in What you get and can be exported as JSON, CSV, or Excel from the Apify Console or API.

Apify run output

The Actor writes an OUTPUT record to the run's default key-value store:

{
"totalListings": 0,
"urlsRun": 0,
"pagesPerUrl": 0
}

totalListings is the number of rows pushed. The record is written after the last start URL has been processed; a run that fails, times out or is aborted before that has no OUTPUT record. urlsRun is the number of non-empty start URLs in the input (1 when the default URL is applied), including URLs skipped because maxItems was already reached. pagesPerUrl is the requested pagesToFetch value, not necessarily the number of pages actually fetched.

ActorWhat it does
Idealista ScraperCollects Spain real estate listings, prices, and square-metre information.
OnTheMarket ScraperCollects UK property data, prices, and days listed.
Zoopla ScraperCollects UK property listings, prices, and agent information.

FAQ

Does the Actor require a Krisha.kz login or API key?

No. The Actor reads public Krisha.kz result pages and needs no Krisha.kz login or API key. You only configure the run in your Apify account.

Which Krisha.kz URLs can I use?

Use Krisha.kz listing, category, or filtered-search URLs copied from the site. Example URLs from the input schema include https://krisha.kz/prodazha/kvartiry/ and https://krisha.kz/arenda/kvartiry/almaty/; other sites are not supported and are expected to return no rows.

How does pagination work?

pagesToFetch controls the number of result pages per URL, from 1 to 1000. Any page parameter in a start URL is ignored, so each URL begins at page 1; later pages use the page query parameter.

Why did the Actor return fewer listings than expected?

Possible causes include a low pagesToFetch (rows are bounded by pagesToFetch times the cards on each result page, so maxItems is only a ceiling), maxItems, duplicate listings, a result page with no parsed cards, a card with neither a listing ID nor a title (skipped), or a page that remains unavailable after three attempts. On the Free plan, each run also has a preview cap of 25 listings, even when maxItems is higher or set to 0.

Why is description null?

description is null for every result from list pages. The key is still present in every dataset row and in exports, but the Console overview table does not show it.

What happens when a source field is missing?

The parser keeps the row and sets the unavailable field to null where applicable. Missing card cells can therefore reduce field coverage without stopping the whole run. A card with neither a listing ID nor a title is skipped. Missing card cells can therefore reduce field coverage without stopping the whole run.

Does propertyType show whether a listing is for sale or rent?

No. propertyType can be apartment, house, land, or null, but the output has no sale/rent field. For mixed searches, use query to identify the start URL that produced the row.

Does maxItems: 0 remove the configured cap?

It removes the configured maxItems cap and allows the Actor to walk the requested pages. It does not remove the Free-plan cap of 25 listings per run, and the Actor also stops when there are no more parsed records or when a page cannot be processed.

Can I use the returned listing URLs to open individual properties?

Yes. The output includes a url field for each listing. The Actor reads result pages and extracts those links; it does not fetch the individual detail pages.

The default input uses Apify's RESIDENTIAL proxy group with country KZ. You can provide another supported proxyConfiguration value when needed.

Does using this public data comply with applicable law?

The Actor collects public data from Krisha.kz result pages. Whether a particular use is permitted depends on the source's terms and applicable law for your use case, so review them before using the data. This Actor does not provide a legal guarantee.

Usage statistics

At the end of each run this Actor creates a short summary of how the run went and sends it over HTTPS to a server run by the Actor's developer. It is used to monitor reliability and improve this Actor. A copy is saved as USAGE_STATS in your own Apify key-value store, so you can see the exact record created for your run.

Set disableUsageStats to true in the input to opt out. Nothing is sent then; your USAGE_STATS record only says that statistics were disabled.

The summary contains at most these items (an item this Actor does not track is left out):

  • schema version, Actor name and build number;
  • UTC start and finish hour (not a precise timestamp);
  • run duration, number of results and time to the first result, each as a coarse range;
  • whether the result was empty, the end status, and an error type from a fixed list;
  • memory setting and counts of charged events;
  • names of the input fields you set, and the selected option for fields that offer a fixed list of choices (for example a country or a sort order);
  • the size range of list inputs, the requested result count as a range, how much of it was delivered, whether it was reached, and the average number of results per input entry as a range;
  • coarse shares of filled fields, failed rows and duplicate rows, and the range of distinct field names in the output;
  • how the run was started (for example API, Console or schedule), whether it was aborted, timed out or stopped at your charge limit, and how many times it was restarted;
  • the range of input targets that succeeded or failed, and the most common failure reason from a fixed list;
  • your Apify user ID, whether Apify marks your account as paying, and one category from a fixed Actor list;
  • two 8-character fingerprints (short hashes): one of the input field names you set, and one of your input values without the proxy settings. The same input always gives the same fingerprint, which lets us count repeated runs of one input.

Apart from those fingerprints, the summary holds no input text, search terms, URLs, domains, email addresses, names, proxy credentials, tokens, scraped records, output items, raw error messages or stack traces. It is used only for aggregated reliability and repeat-use statistics. We do not sell or share this data, and we do not try to identify people from it.