Hh.ru Jobs Scraper
Pricing
from $0.88 / 1,000 item extracteds
Hh.ru Jobs Scraper
Search public hh.ru jobs by keyword, location, filters, or URL. Export normalized vacancy, employer, salary, experience, schedule, skills, and canonical URL records.
Pricing
from $0.88 / 1,000 item extracteds
Rating
0.0
(0)
Developer
Stas Persiianenko
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
Collect public hh.ru jobs by keyword, location, and source URL. The Actor exports one normalized vacancy record per result, including title, employer, location, experience, compensation context, publication context, and a canonical URL.
Use lightweight search extraction for recurring labor-market snapshots, or enable detail enrichment to add full descriptions, employment terms, schedules, and key skills.
What can Hh.ru Jobs Scraper do?
- Search hh.ru by keyword and one or more area IDs.
- Process an existing filtered hh.ru search URL.
- Extract a known public hh.ru vacancy URL.
- Filter by experience, employment form, schedule, publication period, and sort order.
- Deduplicate vacancies across areas and search URLs by stable vacancy ID.
- Normalize displayed salary bounds, currency, and gross/net context.
- Optionally enrich every result from its detail page.
- Stop predictably at
maxItemsandmaxPageslimits.
The Actor reads server-rendered public pages without a browser. This keeps ordinary runs fast and economical while retaining the source's displayed context.
Who is it for?
Recruiting intelligence teams
Build repeatable snapshots of active vacancies by role and region. Compare dataset exports from scheduled runs to see changes in hiring demand.
Labor-market analysts
Aggregate titles, employers, locations, experience requirements, and displayed compensation into a spreadsheet, warehouse, or BI workflow.
Recruiters and sourcing teams
Research employer activity and role requirements before designing a sourcing campaign. Enable details when full descriptions and key skills matter.
Developers and data teams
Feed typed vacancy records into an internal pipeline through the Apify API, webhooks, integrations, or MCP.
What hh.ru job data is extracted?
| Field | Meaning |
|---|---|
vacancyId | Stable hh.ru vacancy identifier |
title | Public vacancy title |
url | Canonical https://hh.ru/vacancy/{id} URL |
employer | Employer name, when displayed |
employerUrl | Public hh.ru employer page |
location | City or address displayed by hh.ru |
salary | Object with from, to, currency, gross, and original text |
experience | Displayed experience requirement |
employment | Employment form from the detail page, or null |
schedule | Work schedule from the detail page, or null |
publishedAt | Source timestamp when exposed, or null |
snippet | Search-card requirements and responsibilities |
description | Full text when includeDetails is enabled |
keySkills | Skills from the vacancy detail page |
sourceSearchUrl | Filtered search page that produced the row |
scrapedAt | UTC collection timestamp |
Optional fields are null when hh.ru does not display them or detail enrichment is disabled.
How to search hh.ru jobs
- Open the Actor input page.
- Enter a
query, such asPython developer. - Set one or more
areaIds;1is Moscow,2is Saint Petersburg, and113is Russia. - Choose filters and a sort order.
- Keep
includeDetailsoff for a quick listing feed, or enable it for full vacancy content. - Set
maxItemsandmaxPagesto control scope. - Start the run and download the default dataset as JSON, CSV, Excel, XML, or another supported format.
A query or at least one start URL is required.
Input parameters
| Input | Type | Default | Description |
|---|---|---|---|
query | string | — | Search words. Also narrows explicit vacancy URLs. |
areaIds | string array | ['1'] | hh.ru location IDs; one search is run per area. |
startUrls | URL array | — | Public hh.ru search or vacancy URLs; overrides generated searches. |
experience | string array | — | hh.ru experience IDs such as between1And3. |
employment | string array | — | Employment-form values supported by hh.ru search. |
schedule | string array | — | Schedule values such as remote or fullDay. |
periodDays | integer | — | Include vacancies from the past 1–30 days. |
orderBy | string | publication_time | Relevance, publication time, or salary order. |
includeDetails | boolean | false | Add descriptions, employment, schedule, and skills. |
maxItems | integer | 50 | Maximum unique records across all searches. |
maxPages | integer | 5 | Maximum result pages per search or area. |
Filters are appended to supplied search URLs, so explicit and generated searches follow the same requested scope. For a supplied individual vacancy URL, query is applied to its title, employer, and full description.
Example input: Moscow Python vacancies
{"query": "Python developer","areaIds": ["1"],"orderBy": "publication_time","includeDetails": false,"maxItems": 20,"maxPages": 2}
Example enriched output
This shortened record reflects current Actor output; values change as hh.ru vacancies change.
{"vacancyId": "134772804","title": "Специалист обработки электронных баз данных (ул. Союзная)","url": "https://hh.ru/vacancy/134772804","employer": "METRO.Торговые центры","location": "Ижевск, Союзная улица, 6","salary": {"from": null,"to": 55200,"currency": "RUB","gross": true,"text": "55 200 ₽ за месяц до вычета налогов"},"experience": "не требуется","employment": "Полная занятость","schedule": "График: 5/2","description": "Full public vacancy description…","keySkills": ["Внимательность", "Ответственность"],"sourceSearchUrl": "https://hh.ru/search/vacancy?text=Data+analyst&area=113&page=0","scrapedAt": "2026-09-06T06:44:00.000Z"}
Listing mode or detail enrichment?
Use includeDetails: false for frequent market snapshots where title, employer, location, salary, experience, snippet, and URL are sufficient. It performs one request per result page.
Use includeDetails: true when the workflow needs descriptions, key skills, schedules, detailed addresses, or employment terms. It performs an additional public page request per vacancy and therefore runs longer.
Both modes emit the same stable record shape. Detail-only fields remain nullable in listing mode.
How much does it cost to extract hh.ru vacancies?
The Actor uses pay-per-event pricing:
- a one-time Start event for each run;
- one Item processed event for each vacancy saved to the dataset.
The current initial curve starts at $0.02 per run and $0.001468 per vacancy on the BRONZE tier. Final billed prices depend on your Apify plan tier. For example, at BRONZE, a run returning 25 vacancies costs about $0.0567 in Actor charges: $0.02 + 25 × $0.001468. A 100-vacancy run costs about $0.1668.
Failed, rejected, duplicate, or filtered-out vacancy records do not generate an item event. Apify displays the applicable event rates before you start a paid run.
Recurring recruiting-intelligence workflow
- Configure a narrow role, region, and
periodDayswindow. - Sort by
publication_time. - Save the task and add a schedule in Apify Console.
- Export each run's dataset to Google Sheets, a webhook, or cloud storage.
- Compare rows by
vacancyIdto identify additions, removals, and changed public content.
The Actor does not maintain cross-run state or label changes itself. Stable IDs and timestamps make that comparison straightforward in your destination system.
Integrations and exports
Use Apify integrations to send the default dataset to:
- Google Sheets for recruiter review;
- webhooks for downstream automation;
- Make, Zapier, or n8n workflows;
- Amazon S3, Google Cloud Storage, or Azure storage;
- a database or warehouse through your own API client.
CSV is convenient for analysts. JSON preserves nested salary data and skill arrays for applications and data pipelines.
Run through the Apify API with cURL
curl -X POST \"https://api.apify.com/v2/acts/automation-lab~hh-ru-job-listings-scraper/runs?token=$APIFY_TOKEN" \-H 'Content-Type: application/json' \-d '{"query":"Data analyst","areaIds":["113"],"periodDays":7,"maxItems":25}'
Do not commit API tokens to source control. Use an environment variable or secret manager.
Run with JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('automation-lab/hh-ru-job-listings-scraper').call({query: 'Python developer',areaIds: ['1'],maxItems: 50,includeDetails: false,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
Run with Python
import osfrom apify_client import ApifyClientclient = ApifyClient(os.environ['APIFY_TOKEN'])run = client.actor('automation-lab/hh-ru-job-listings-scraper').call(run_input={'query': 'Data analyst','areaIds': ['113'],'periodDays': 7,'includeDetails': True,'maxItems': 10,})items = client.dataset(run['defaultDatasetId']).list_items().itemsprint(items)
Use with MCP and AI assistants
Add the Actor to Claude Code:
claude mcp add --transport http apify \"https://mcp.apify.com?tools=automation-lab/hh-ru-job-listings-scraper"
Claude Desktop, Cursor, and VS Code setup
Claude Desktop, Cursor, and VS Code can use this equivalent MCP configuration:
{"mcpServers": {"apify": {"url": "https://mcp.apify.com?tools=automation-lab/hh-ru-job-listings-scraper"}}}
Example prompts:
- “Find the newest 20 Python developer vacancies in Moscow on hh.ru and summarize salary ranges.”
- “Extract this hh.ru vacancy URL with details and list the required skills.”
- “Collect Russian data analyst vacancies posted in the last seven days for my weekly market report.”
Reliability, limits, and responsible usage
hh.ru controls page availability and markup. The Actor retries transient network, rate-limit, and server errors up to three times. Stable 4xx responses, unsupported URLs, and unrecognized pages fail clearly rather than returning a misleading empty dataset.
Search results can change during a paginated run. Very broad queries may be capped by hh.ru's own search behavior. maxPages is a per-search safety limit; maxItems is the global dataset limit.
The Actor uses direct public pages and has no automatic residential-proxy fallback. If source access changes, review run logs instead of blindly repeating runs.
Legal and ethical use
This Actor extracts information that hh.ru displays publicly. You are responsible for ensuring your use complies with hh.ru's terms, applicable database and copyright rules, privacy law, and employment regulations.
Collect only fields needed for a legitimate purpose. Do not use vacancy or employer data for spam, harassment, discrimination, or decisions that require human review. Respect deletion requests and set appropriate retention periods in downstream systems.
This Actor is not affiliated with or endorsed by HeadHunter or hh.ru.
Troubleshooting
Why did the run reject my URL?
Only public hh.ru/search/vacancy... and hh.ru/vacancy/{numeric-id} URLs are supported. Profile, résumé, login, employer-admin, and other pages are intentionally rejected.
Why are detail fields null?
Enable includeDetails. Some vacancies still omit salary, key skills, schedule, or other optional fields at the source.
Why did I receive fewer records than maxItems?
The filtered source may have fewer vacancies, duplicate IDs may occur across searches, a supplied query may not match an explicit vacancy, or maxPages may stop pagination first.
Why did the Actor fail instead of returning zero records?
A valid no-result search exits successfully with zero rows. A challenge page, unsupported response, or deterministic source error fails so an automation does not mistake a source outage for “no vacancies.”
Related Automation Lab Actors
- IrishJobs.ie Job Listings & Salaries Scraper for Irish vacancy intelligence.
- GCC Job Listings Aggregator for normalized Gulf-region hiring feeds.
- Built In Job Listings Scraper for technology-company vacancy research.
Choose this Actor when the required source is hh.ru and the workflow needs stable vacancy IDs, normalized salary context, or optional detail enrichment.
FAQ
Does it require an hh.ru account?
No. It processes public search and vacancy pages only.
Can it search multiple locations?
Yes. Add multiple hh.ru IDs to areaIds. Results are deduplicated across generated searches.
Can I provide a fully filtered search URL?
Yes. Put it in startUrls. Input filters are then applied to that URL before pagination.
Does it scrape résumés or personal candidate profiles?
No. The product scope is public job vacancies and displayed employer context.
Does it detect newly added or changed jobs?
It emits stable vacancyId and scrapedAt values. Schedule tasks and compare run datasets in your own spreadsheet or pipeline; the Actor does not persist a monitoring database.
Can I increase maxItems?
Yes, up to 10,000. Increase maxPages as needed, and prefer listing mode unless details are required.