What the Rosreestr scraper collects
Queries Rosreestr's online reference service (lk.rosreestr.ru) for real-estate objects: full records by cadastral number, with each record's image captcha solved through 2Captcha, or every object at an address through the free address search. Output is JSON or CSV with a sidecar recording the solves and their cost.
Cadastral number lookup
Input: One or more cadastral numbers (--cad-number) or a file of them (--input)One full record per object: cadastral value in RUB, object kind, area, status, registration and valuation dates, floor, purpose, permitted use, and the registered rights and encumbrances. One image captcha per record.
Address search
Input: A Russian address (--address), optionally --list-kind and --detailsEvery object the site lists at an address — number, address, kind, current or not — with no captcha; --details fetches full records for them.
Code dictionaries
Input: No inputThe site's own code dictionaries: the nine object kinds, land categories, permitted uses and purposes.
From zero to Rosreestr data in 3 steps
Install
Clone the repository and install one browser engine. Python 3.9+.
$ git clone https://github.com/2scraper/rosreestr-scraper.git && cd rosreestr-scraper $ python3 -m venv venv && . venv/bin/activate $ pip install --require-hashes -r requirements-playwright.lock $ python -m playwright install chromium $ cp .env.example .env $ python3 env_config.py
Run a scraper
Pick what you need and run it. Every flag is documented in the README.
$ python3 playwright_scraper.py --cad-number 77:01:0001044:3030 --cad-number 77:01:0001044:2981$ python3 playwright_scraper.py --mode address --address "Москва, ул. Тверская, д. 13"$ python3 playwright_scraper.py --mode dictionaries --out codesGet structured data
Rows land in JSON or CSV (
--format), with a.meta.jsonsidecar recording status, pages fetched and why the run stopped.
Rosreestr data fields
41 columns per row in a predictable schema. The most useful ones:
| Field | What it holds |
|---|---|
sku | Cadastral number |
title | Address as the site renders it |
price | Cadastral value; null when the site states none |
currency | RUB, as the site labels the value |
category | Object kind in the site's words, e.g. Помещение |
status | actual or cancelled (list lines: actual / not_actual) |
area | Area, with its unit in area_unit |
cad_quarter | Cadastral quarter |
reg_date | Registration date (ISO) |
cad_cost_determination_date | Date the cadastral value was determined |
purpose | Purpose, decoded through the site's dictionaries |
permitted_use | Permitted use (land parcels) |
level_floor | Floor the object is on |
rights | Registered rights as [{number, date, type}] — never the holder |
encumbrances | Registered encumbrances as [{number, date, type}] |
detail_level | full (a record) or list (an address-search line) |
[
{
"source": "lk.rosreestr.ru",
"scraped_at": "2026-09-29T09:29:54.048253+00:00",
"url": "https://lk.rosreestr.ru/eservices/real-estate-objects-online?cadNumber=77%3A01%3A000104…",
"sku": "77:01:0001044:3030",
"title": "Москва, Тверской, ул. Тверская, д. 13, пом. III",
"price": 123431740.67,
"currency": "RUB",
"category": "Помещение",
"page": 1,
"position": 1,
"query": "77:01:0001044:3030",
"detail_level": "full",
"object_type_code": "002001003000",
"status": "actual",
"cad_quarter": "77:01:0001044",
"area": 479.8,
"area_unit": "кв.м",
"main_characteristics": [
{
"type": "Площадь",
"value": 479.8,
"unit": "кв.м"
}
],
"region": "Москва",
"reg_date": "2013-03-22",
"cancel_date": null,
"cad_cost_determination_date": "2025-01-01",
"cad_cost_registration_date": "2025-12-13",
"info_update_date": "2025-12-13",
"land_category": null,
"permitted_use": null,
"purpose": "Нежилое",
"floors": null,
"underground_floors": null,
"level_floor": "5",
"wall_material": null,
"year_built": null,
"year_commissioned": null,
"ownership_type": null,
"parent_cad_number": null,
"child_cad_numbers": null,
"old_numbers": [
{
"type": "Инвентарный номер",
"number": "III"
}
],
"rights": null,
"encumbrances": null,
"list_kind": null
},
{
"source": "lk.rosreestr.ru",
"scraped_at": "2026-09-29T09:29:31.818858+00:00",
"url": "https://lk.rosreestr.ru/eservices/real-estate-objects-online?cadNumber=77%3A01%3A000104…",
"sku": "77:01:0001044:2981",
"title": "Москва, Тверской район, ул. Тверская, д. 13",
"price": null,
"currency": null,
"category": null,
"page": 1,
"position": 1,
"query": "Москва, ул. Тверская, д. 13",
"detail_level": "list",
"object_type_code": null,
"status": "actual",
"cad_quarter": null,
"area": null,
"area_unit": null,
"main_characteristics": null,
"region": null,
"reg_date": null,
"cancel_date": null,
"cad_cost_determination_date": null,
"cad_cost_registration_date": null,
"info_update_date": null,
"land_category": null,
"permitted_use": null,
"purpose": null,
"floors": null,
"underground_floors": null,
"level_floor": null,
"wall_material": null,
"year_built": null,
"year_commissioned": null,
"ownership_type": null,
"parent_cad_number": null,
"child_cad_numbers": null,
"old_numbers": null,
"rights": null,
"encumbrances": null,
"list_kind": "OKS"
}
]First 2 of 5 rows from a real run — sample_output.json. Long values shortened here.
Handles what breaks naive Rosreestr scrapers
Every captcha answer checked by the site
Each record's image captcha is solved with ImageToTextTask in the Cyrillic language pool, then verified against the site's own check. A refused answer is reported and a fresh image solved, up to --captcha-attempts and never past --max-solves.
The bill in the sidecar
Each run records captcha_solves, captcha_cost (summed from 2Captcha's own reported cost), captcha_rejected and autosolved, so the price of a run is measured, not estimated.
The free half needs no captcha
The address search and the code dictionaries cost no captcha at all, and run even without a local browser through the Scraper API.
Personal data deliberately left out
The service returns the cadastral engineer's name, phone and certificate number with every record. They identify a private person and are never written.
Scraping infrastructure included
The same tested core runs every 2scraper repository, so the hard parts work the same way on every site.
CAPTCHA handling
Detects the challenge a page really serves and, with a 2Captcha key, solves it only when it blocks the data — a capped number of solves per page.
Proxy rotation
Single proxy or a pool from a file, rotated on blocks with a fresh browser per exit. Credentials stay out of argv and logs.
Fingerprints
Optional complete device identity from the 2Captcha Fingerprint API — user agent, client hints, locale and timezone that agree with each other.
Scraping Browser API
Point --cdp-endpoint at a managed Chromium with its own exit country — no browser infrastructure to run yourself.
Honest run metadata
Every run writes a .meta.json sidecar and distinct exit codes: complete, blocked, empty and partial are never confused, and a failed run never overwrites good data.
Diff two runs
diff_runs.py compares two complete Rosreestr snapshots by id — new, removed and changed rows for monitoring.
What teams do with Rosreestr data
Cadastral value monitoring
Re-run a watchlist and use diff_runs.py to catch re-valuations, deregistrations and rights or encumbrances registered or lifted.
Property due diligence
Pull area, status, purpose, dates and encumbrances for objects before a transaction.
Building inventories
List every object at an address with the free search, then fetch full records for the ones you need.
Real-estate data enrichment
Attach official cadastral values and object kinds to your own property datasets by cadastral number.
Free to run. Pay only for what the site requires.
Needs a residential exit or the Scraping Browser API
The service answers only Russian addresses — from a non-Russian exit every host timed out, measured Sep 2026 — so you need a Scraping Browser API profile with country-ru or a 2Captcha proxy with a -region-ru login. Every full record costs one image captcha, which 2Captcha's image solver answers ($0.001 a record as measured). The address search and dictionaries need no captcha, and no Gosuslugi account is needed or used.
Optional 2Captcha services — captcha solving, the Scraping Browser API, residential proxies and fingerprints — work behind one key.
Good to know
- The address search returns at most 100 lines and ignores the object kind; --list-kind filters after the site's choice.
- Rights and encumbrances never include who holds them: the public service does not show it.
- This repo does not implement the page's three other search types (by restriction-of-right, previously assigned or right number).
2scraper vs. hosted scraper APIs
| 2scraper | Typical hosted API | |
|---|---|---|
| Code | Open source, MIT — read and patch it | Closed |
| Cost | Free; optional services billed only when used | Subscription or per request / per result |
| Runs on | Your machine, server or CI | The vendor's infrastructure |
| Output | JSON/CSV files + run metadata | API responses |
| When the site changes | Fix it yourself or open an issue / PR | Wait for the vendor |
Rosreestr scraper FAQ
Do I need a Russian IP?
Yes. From a Belgian exit on 2026-09-29 every Rosreestr host timed out at the TCP connect. Use a Scraping Browser API profile with country-ru or a residential proxy with a -region-ru login.
How much does a lookup cost?
A full record costs one image captcha, measured at $0.001 each. The address search and the dictionaries are free.
Do I need a Gosuslugi account?
No. No ESIA login is needed or used.
Why does an address search stop at 100 objects?
The site returns at most 100 lines per address, and not always the same 100. Capped queries are listed in address_capped; narrow the address to house, building or room.
Which engines work against the site?
Playwright and Puppeteer, through the Scraping Browser API or an authenticated proxy. Selenium needs an IP-allowlisted Russian exit because it cannot authenticate either.
Is it legal?
It reads a public government reference service the way its own page does. Follow the service's terms, keep volumes reasonable and respect data-protection law where you are.