Use Yandex Maps Business Search, Details & Reviews Scraper with Python
Search Yandex Maps by keyword, fetch full business details, or collect customer reviews - with address, phone, rating, working hours, photos, coordinates, and review text across six regional domains.
1. Choose the data you need
Review the published README for supported collection modes, examples, and limits. The recipe below uses the current published input definition.
2. Prepare a source-based input
This JSON contains published prefills and required-field defaults. Review every value for your task before running it; it is not a promise of successful collection.
{
"city": "Moscow",
"goodPlace": false,
"maxItems": 3,
"mode": "searchPlaces",
"openNow": false,
"priceCategories": [],
"requirePhone": false,
"requireWebsite": false,
"reviewRequireOwnerReply": false,
"searchQueries": [
"coffee"
],
"yandexDomain": "yandex.com"
}
Download input.example.json and save your reviewed copy as input.json.
| Field | Type | Required | Description |
|---|---|---|---|
mode | string | required | What to collect. searchPlaces finds businesses by keyword. getDetails returns full business cards for IDs or URLs. getReviews collects customer reviews for IDs, URLs or a search. |
searchQueries | array | optional | One query per line, for example 'coffee' or 'dentist'. Used by searchPlaces, and by getReviews when no business IDs or URLs are supplied. |
city | string | optional | City name in any language, for example 'Moscow', 'Kazan' or 'Istanbul'. Yandex Maps resolves the city centre and passes it to the search. |
coordinates | string | optional | Optional point for a local search, for example '55.7558,37.6173'. When set, it overrides the city centre. Combine with Radius to search around the point. |
radiusKm | integer | optional | Keep only places within this distance of the centre point or city centre. Results are measured by straight-line distance and filtered strictly. |
bbox | string | optional | Optional rectangular area, for example '37.45,55.65,37.85,55.85'. Results outside the rectangle are dropped. |
businessIds | array | optional | Yandex Maps organization IDs, one per line. Use for getDetails or getReviews. |
startUrls | array | optional | Yandex Maps organization URLs, short links or search URLs, one per line. Business and search URLs work in both getDetails and getReviews. |
maxItems | integer | optional | Run-wide cap. In searchPlaces and getDetails it counts places; in getReviews it counts reviews across all businesses. |
maxReviewsPerPlace | integer | optional | Review cap for each business. Yandex exposes up to 600 reviews per sort order; the actor combines four orders to reach up to 2,400 unique reviews per business. |
reviewSort | string | optional | Primary review order. When you ask for more than 600 reviews per place, the actor also walks the other three orders and merges them, removing duplicates. |
reviewMinRating | integer | optional | Keep only reviews with at least this many stars (1-5). |
reviewMaxRating | integer | optional | Keep only reviews with at most this many stars (1-5). |
reviewDateFrom | string | optional | Keep reviews published on or after this date (YYYY-MM-DD). |
reviewDateTo | string | optional | Keep reviews published on or before this date (YYYY-MM-DD). |
reviewTextContains | array | optional | One phrase per line. A review is kept when its text contains any of these phrases, ignoring case. |
reviewRequireOwnerReply | boolean | optional | Keep only reviews where the business wrote a reply. |
minRating | string | optional | Drop businesses below this rating. Businesses without a rating are dropped when a threshold is set. Applies to place records. |
minReviewCount | integer | optional | Drop businesses with fewer text reviews. 0 disables the filter. Applies to place records. |
requirePhone | boolean | optional | Drop businesses without a phone number. Applies to searchPlaces and getDetails. |
requireWebsite | boolean | optional | Drop businesses without a website. Applies to searchPlaces and getDetails. |
openNow | boolean | optional | Keep only businesses that Yandex reports as open at collection time. Applies to place records. |
goodPlace | boolean | optional | Yandex Good Place quality filter. Used as a server-side search filter and verified client-side on place records. |
priceCategories | array | optional | Keep businesses in any of these price bands. Leave empty for all prices. Server-side in searchPlaces, verified client-side elsewhere. |
categoryIds | array | optional | Optional Yandex category IDs, one per line. The category ID appears in each place's categoryDetails. Used server-side in searchPlaces and verified client-side. |
maxPagesPerQuery | integer | optional | Yandex returns 25 businesses per page. More pages find more places but take longer. |
maxConcurrency | integer | optional | How many business pages or review batches to process at once. Higher is faster but more likely to trigger rate limiting. |
yandexDomain | string | optional | Regional Yandex domain. yandex.com works worldwide; regional domains return local metadata. |
language | string | optional | Interface and metadata language. Review text stays in the reviewer's language and translations are returned separately. |
proxyConfiguration | object | optional | Optional. The actor works without a proxy and negotiates access automatically. Supply a proxy only if you want to pin a specific country or provider. |
3. Start an Actor run
Set APIFY_TOKEN in your environment. Python 3.10 or newer is sufficient; this recipe uses no third-party packages.
Execution may incur charges. Review current pricing on Apify. The request asks for a 120-second timeout and a charge limit; these settings are subject to Apify’s pricing and do not guarantee an all-inclusive spending cap.
import json
import os
import urllib.request
# Save the schema-derived example as input.json; review and edit it first.
with open("input.json", encoding="utf-8") as stream:
actor_input = json.load(stream)
token = os.environ["APIFY_TOKEN"]
request = urllib.request.Request(
"https://api.apify.com/v2/acts/YYnETyuUyTTy4DeLE/runs?timeout=120&maxTotalChargeUsd=0.50",
data=json.dumps(actor_input).encode("utf-8"),
headers={"Authorization": "Bearer " + token, "Content-Type": "application/json"},
method="POST",
)
# This starts a potentially billable run. Do not automatically retry this POST.
with urllib.request.urlopen(request, timeout=40) as response:
run = json.load(response)["data"]
print("Run ID:", run["id"])
print("Status:", run["status"])
# Inspect and download results in Apify Console once the run succeeds.
4. Inspect the actual results
Open the run in Apify Console and wait for a successful completion. Use the published output schema to locate results and the dataset schema to understand declared views. Missing or optional record fields must not be treated as guaranteed values.
One dataset containing Yandex Maps place records (recordType=place) and review records (recordType=review). Empty fields are omitted.
Questions before you run
Which inputs are required?
The published required fields are mode
What does this guide verify?
The fields, prefills, and schema links are rendered from the published build. This is a usage recipe, not a paid live extraction test. Source availability and collection results can vary.
What if the run request times out?
Check Apify Console before retrying. The first request may already have created a run. Do not automatically repeat a run-creation POST.
Generated from source build D8zEadOFOCSTloS2r and its README and schemas. Source changes regenerate this guide; no third-party editorial claims are inferred.