# Changelog of 2GIS Places Scraper (`devilscrapes/2gis-places-scraper`) Actor

- **URL**: https://apify.com/devilscrapes/2gis-places-scraper/changelog.md
- **Full Actor documentation**: https://apify.com/devilscrapes/2gis-places-scraper.md

## Changelog

### 0.0.1 — Unreleased

- First implementation: 2GIS search over the server-rendered result pages
  (`/<city>/search/<query>[/page/<n>]`), reading the embedded
  `var initialState = JSON.parse('…')` blob (`data.entity.profile`).
- The page only renders for current browser fingerprints; chrome131 / firefox133
  get a ~12 KB "update your browser" redirect to `/museum`. The client detects it,
  logs a wrong-profile warning, rotates to a current profile and never reports it
  as zero results.
- 2GIS serves pages 1-5 only; page 6+ silently returns page 1 again. The loop
  checks the server-reported `currentPage` and stops with `pager_cap`, so no
  duplicate rows are emitted. Depth comes from more cities and queries.
- `includeContacts` (off by default) opens each place page for phones, website
  and e-mail — the search blob carries no contacts.
- `src/models.py` (`ActorInput`, `ResultRow`), `src/client.py` (curl-cffi,
  profile rotation, retry/backoff), `src/parser.py` (JS-string unescape, state
  and row parsing), `src/scraper.py` (city x query x page loop, fault isolation,
  run-wide dedupe), `src/main.py` (SDK wiring, PPE).
- Fixtures are trimmed real captures (`scripts/capture_fixtures.py`).
