Yandex Search Scraper - Web, Images, Videos & SEO Rankings avatar

Yandex Search Scraper - Web, Images, Videos & SEO Rankings

Pricing

from $1.00 / 1,000 serp results

Go to Apify Store
Yandex Search Scraper - Web, Images, Videos & SEO Rankings

Yandex Search Scraper - Web, Images, Videos & SEO Rankings

Scrape Yandex web, image and video search results with URLs, snippets and organic rankings for SEO and competitor analysis. Парсер Яндекс Поиска, картинок и видео: ссылки, сниппеты и позиции для SEO, мониторинга выдачи и анализа конкурентов.

Pricing

from $1.00 / 1,000 serp results

Rating

0.0

(0)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

2

Bookmarked

2

Total users

2

Monthly active users

9 days ago

Last modified

Categories

Share

Yandex Search SERP Scraper

Scrape organic Yandex Search results for any list of queries, across web, image, and video search. Every result comes back as clean, structured JSON with its title, URL, domain, and a continuous position across the whole query walk, ready for rank tracking, SEO monitoring, and competitor research. Ads and vertical inserts (news, image, and video carousels shown on a web SERP) are filtered out, so every emitted position reflects the true organic rank. Export the dataset as JSON, CSV, or Excel, or pull it straight into your app through the API.

Why This Scraper?

  • Organic results only. Ads and vertical inserts are filtered out of web search, so every emitted position is a genuine organic rank.
  • Continuous position tracking. Every result carries its query, 1-based SERP page, and a running 1-based position across the whole query walk, not just the current page.
  • Three verticals from one input. Pick web, images, or videos with searchType. Media rows add their own thumbnail, duration, view count, and embed fields.
  • Pagination that knows when to stop. The walk keeps requesting pages until maxPages is reached or a page returns no new organic results.
  • A hard run-wide cap. maxItems bounds total emitted results across every query, so run size and cost stay predictable.
  • Built for monitoring. Incremental mode returns only new and changed results on repeated runs, and resumeFromRunId skips results an earlier run already collected (see the resume notes below for its limits).
  • Loud failures, not silent gaps. A search that is fully refused fails the run with a clear message instead of quietly returning an empty dataset.

Use Cases

  • SEO and rank tracking: monitor organic positions for target keywords over time, using incremental mode to see only what moved.
  • Competitor and SERP research: see which domains and pages currently rank for a query, with breadcrumbs and snippets included.
  • Content and media discovery: pull the current top videos or images for a topic, with thumbnails, durations, and view counts.
  • Brand monitoring: track how a brand or product name surfaces in Yandex search results.
  • Data science and NLP datasets: build structured, position-tagged corpora of titles and snippets for downstream analysis.

Data You Get

Sample shape: values are illustrative placeholders, not from a live SERP.

FieldExample
query"wireless noise cancelling headphones"
page1
position1
title"Sample Audio Shop - Noise Cancelling Headphones"
url"https://www.example-audio-shop.com/noise-cancelling-headphones"
domain"example-audio-shop.com"
breadcrumb"example-audio-shop.com › headphones › noise-cancelling" (null when the SERP served none)
snippet"Compare top noise cancelling headphones in stock at Sample Audio Shop..." (null when the SERP served none)
changeType"NEW" (incremental mode only: NEW, UPDATED, UNCHANGED, or EXPIRED; absent when incremental mode is off)
changedFields["content"] (incremental mode only, populated on UPDATED rows)
firstSeenAt"2026-01-01T00:00:00.000Z" (incremental mode only)
lastSeenAt"2026-03-01T00:00:00.000Z" (incremental mode only)
kindabsent for web rows, "video" or "image" for media rows
thumbnailUrl"https://example-cdn.com/thumb.jpg" (media rows)
imageUrl"https://example-cdn.com/original.jpg" (image rows)
sourceHost"example-video-host.com" (video rows)
embedUrl"https://example-video-host.com/embed/sample123" (video rows)
durationSeconds245 (video rows)
durationText"4:05" (video rows, as displayed)
views"12K" (video rows, as displayed)
publishedDate"3 months ago" (video rows, as displayed)

Image and video rows share the same shape as web rows (query, page, position, title, url, domain) plus their own media fields; the web-only breadcrumb and snippet fields are not populated for media rows. EXPIRED rows (incremental mode with emitExpired) are slim tombstones carrying only recordId, url, changeType, and lastSeenAt, where lastSeenAt is the time of the run that marked them expired.

How to Use

  1. Enter one or more search queries.
  2. Pick a search type, web, images, or videos, and set Max pages per query if you need more than the first page.
  3. Set Max results to cap run size and cost, and adjust Connection if you need a different proxy.
  4. Start the run, then read the dataset's organic-results view as JSON, CSV, or Excel, or through the API.

Search two queries on the web vertical, two pages each:

{
"queries": ["wireless noise cancelling headphones", "portable espresso maker"],
"maxPages": 2,
"maxItems": 100
}

Image search:

{
"searchType": "images",
"queries": ["minimalist desk setup"],
"maxItems": 50
}

Video search with a region code:

{
"searchType": "videos",
"queries": ["home workout routine"],
"lr": 213,
"maxPages": 2
}

Recurring monitoring of one query:

{
"queries": ["wireless noise cancelling headphones"],
"incrementalMode": true,
"emitExpired": true,
"stateKey": "headphones-watch"
}

Run it from your code

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/yandex-serp-scraper").call(run_input={"queries": ["wireless noise cancelling headphones"], "maxPages": 2})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item["position"], item["title"], item["url"])

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/yandex-serp-scraper').call({ queries: ['wireless noise cancelling headphones'], maxPages: 2 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Or connect it to Make, Zapier, n8n, Google Sheets, or webhooks from the Integrations tab.

How Max results interacts with pagination and incremental mode

maxItems (Max results) is a hard cap on rows emitted across the whole run, counted by rows actually pushed to the dataset, not by results merely scanned. On web and video search, each query's own walk stops early once a page returns no new organic results, even before maxPages or maxItems is reached; image search keeps paging past a page of repeats and stops on an empty page.

In incremental mode, a page's share of the remaining cap is taken before unchanged rows are suppressed, so on a capped run some new results further down that page can be skipped even though the cap was not filled. They are not lost: they are returned as NEW on a later run.

Known limitation: when incremental mode's emitExpired is on, maxItems only governs the newly collected NEW / UPDATED / UNCHANGED rows. The EXPIRED batch (previously tracked results this run's queries no longer found) is pushed as a separate step that is not counted against maxItems. If your tracked scope holds far more previously-seen results than this run's queries still match, a tightly capped run can still emit, and be billed for, far more rows than maxItems once the EXPIRED batch is added. Leave emitExpired off on tightly capped runs, or budget for it separately from maxItems.

Resume and recurring updates

  • Resume (resumeFromRunId): paste a previous run ID or dataset ID to continue an interrupted pull. Every query is searched again from page 1, and results whose URL was already collected there are skipped, never re-emitted. Cannot be combined with incremental mode.
  • Incremental mode (incrementalMode): for daily or recurring monitoring of the same search. The first run returns everything as NEW; later runs return only NEW and UPDATED rows, with changeType, changedFields, firstSeenAt, and lastSeenAt on every returned result row. A pure rank move alone is not a content change (position and page are excluded from the fingerprint), so a result that only shifted rank classifies UNCHANGED. UNCHANGED rows are suppressed unless emitUnchanged is on. EXPIRED rows are only produced after a run that fully scanned every query and page in scope, and only when emitExpired is on. State is keyed per search scope, or per your own stateKey, in a named key-value store.

Known limitation: resumeFromRunId's dedup set is built from every URL in the resumed dataset, without regard to which query originally returned it. If two different queries in your list can legitimately return the same URL (common for closely related terms), and that URL was already collected under one query in the resumed run, this run silently skips it under every query, including a query that never actually returned it before.

Known limitation: on web and video search, a page where every result was already collected ends that query's walk, just like a page with no new results. So a resume does not reach later pages of a query whose first page was fully collected before the interruption: a maxPages: 3 query interrupted after page 1 returns nothing new on resume. The same applies across queries: if a query's first page consists only of URLs another query already collected, its later pages are never requested. Positions on resumed rows are numbered from 1 over the newly returned results only, so they do not continue the earlier run's numbering. If you need complete, correctly ranked results for a query, run it again fresh (without resumeFromRunId), one query at a time if queries overlap.

Input Parameters

ParameterTypeDefaultDescription
searchTypestringwebWhich Yandex vertical to search: web, images, or videos. Images and videos return media fields like thumbnails and durations.
queriesarraysample queryOne SERP walk per query. Each query gets a fresh proxy session. Required.
maxPagesinteger1SERP pages per query (page 1 is &p=0). Stops early if a page returns no new organic results.
lrinteger(none)Yandex region code for the SERP locale, for example 213 (Moscow), 2 (Saint Petersburg), 21265 (San Francisco). Leave empty for auto-detection.
maxItemsinteger(none)Hard cap on emitted dataset items across the whole run. Leave empty for no cap (very large runs need a long run timeout, each query holds one browser session).
proxySettingsobjectApify residentialProxy configuration. Residential is the default and returns the fullest result pages.
resumeFromRunIdstring(none)Paste a previous run ID or dataset ID to continue an interrupted pull without returning results already collected there. Cannot be combined with incremental mode.
incrementalModebooleanfalseTurn this on for daily or recurring monitoring. The first run returns every matching result as NEW. Later runs normally return only NEW and UPDATED results. A pure rank move alone is not a content change. Cannot be combined with resumeFromRunId.
stateKeystring(none)Optional. Name this monitoring campaign to keep its state stable, or deliberately share state across differently configured runs. Leave empty to derive a key automatically from the search settings.
emitUnchangedbooleanfalseOff by default. Turn on to also return records that have not changed since the last run, marked UNCHANGED. This returns, and bills, extra rows you already have.
emitExpiredbooleanfalseOff by default. Turn on to also return records that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search.

Output Example

Sample shape: values are illustrative placeholders, not from a live SERP.

{
"query": "wireless noise cancelling headphones",
"page": 1,
"position": 1,
"title": "Sample Audio Shop - Noise Cancelling Headphones",
"url": "https://www.example-audio-shop.com/noise-cancelling-headphones",
"domain": "example-audio-shop.com",
"breadcrumb": "example-audio-shop.com › headphones › noise-cancelling",
"snippet": "Compare top noise cancelling headphones in stock at Sample Audio Shop..."
}

Plan Requirement

The default connection (Apify residential proxy) works out of the box. This actor charges per event: a fixed run-start charge plus one charge per organic result returned to the dataset. The Pricing tab shows current rates. Occasional automated verification checks are resolved by the actor itself and are never billed to you as a separate Apify event; see the FAQ below for how that affects a run that fails instead of returning results.

FAQ

How much does it cost?

You pay a run-start charge plus one charge per result returned to the dataset. The Pricing tab shows the current rates. Use Max results to cap the cost of any run.

This actor collects only publicly available search result data. You are responsible for how you use it: follow Yandex's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Search snippets and thumbnails may reflect third-party content and rights.

Can I get only new or changed results on a schedule?

Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new and updated results, and unchanged ones are not billed unless you also turn on Emit unchanged.

Why did my run fail instead of returning an empty dataset?

If a search is refused on every attempt, the run stops with a clear message so "no results for this query" is never confused with "nothing could be read." Run it again in a few minutes. A run can also stop if the cost of resolving automated verification checks would exceed a fixed ceiling relative to the run's size, a sign that the connection is being refused unusually hard; retrying, often with a different proxy country, usually clears it.

Why does an incremental run with Emit expired sometimes return far more rows than Max results?

emitExpired pushes every previously tracked result your queries no longer found, and that batch is not capped by maxItems. On a scope with a large tracked history, this can push and bill well beyond your maxItems setting in a single run. Leave emitExpired off for tightly capped runs, or expect it to add rows outside that cap.

Why is a shared result missing from one of my queries after a resume?

resumeFromRunId skips any URL already present anywhere in the resumed dataset, regardless of which query returned it. If two queries can legitimately share a result, the second query's copy is silently skipped when it was already collected under the first, and if that query's whole first page was already collected, its later pages are not requested at all. Resume is most useful for queries the interrupted run never reached, and even those can lose results shared with other queries; for a query's complete, correctly ranked result set, run it fresh without resumeFromRunId.

Can I use it with AI agents or automation tools?

Yes. Call it from any Apify integration, the API, or an MCP-compatible client, and route the results into your own pipeline or app.

🔗 Want more Yandex data?

Pair this actor with these related scrapers from the same team:

🧩 Yandex Maps Scraper / Парсер Яндекс Карт
Scrape businesses and places from Yandex Maps by search term or URL for research, leads...
🤖 AI Search Tool
Give your AI agents real-world knowledge. This Actor provides high-quality web, news...
📇 Yellow Pages AU
From $1/1K. Scrape business listings from Yellow Pages Australia by type and location...
📇 Herold.at Scraper
From $0.80/1K. Scrape Herold.at business listings across Austria into clean JSON. Extract...
⚽ Globo Esporte Scraper
Scrape public sports content from ge.globo.com, including news, videos, matches and feed...
🤖 Web Scraper For Llms
Stealth web scraping engine built for LLMs. Converts any web page to clean markdown or...

👉 Browse all abotapi scrapers

💬 Support & custom scrapers

  • 🐞 Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
  • 🛠️ Need another site, extra fields or a private build? Email contact@abotapi.com or message Telegram @abotapi.
  • ⭐ Enjoying it? A quick review on the actor page helps other users find it.