HeadHunter Jobs Scraper avatar

HeadHunter Jobs Scraper

Pricing

Pay per event

Go to Apify Store
HeadHunter Jobs Scraper

HeadHunter Jobs Scraper

Scrape public hh.ru vacancies by keyword or search URL. Extract employers, locations, salary text, parsed salary ranges, and descriptions.

Pricing

Pay per event

Rating

0.0

(0)

Developer

Stas Persiianenko

Stas Persiianenko

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Scrape public hh.ru vacancy search results and detail pages. Get clean vacancy titles, employers, salary text, parsed salary ranges, locations, experience, employment, schedules, descriptions, source URLs, and timestamps from HeadHunter / hh.ru.

What does HeadHunter Jobs Scraper do?

HeadHunter Jobs Scraper extracts public job vacancy data from hh.ru search pages.

It is built for public vacancy pages that are visible without logging in.

The actor starts from either:

  • a search keyword plus hh.ru area id, or
  • a complete hh.ru search URL copied from the browser.

It then paginates result pages, normalizes vacancy URLs, optionally visits vacancy detail pages, and saves structured records to the default dataset.

Who is it for?

Recruiting teams use it to monitor public openings by skill, city, or employer.

Sourcing agencies use it to build lead lists for outreach and market mapping.

Job-board analysts use it to track job demand, salary language, and hiring trends.

Labor-market researchers use it to collect comparable public vacancy data.

Sales teams use it to identify companies currently hiring for specific roles.

Why use this actor?

  • ✅ Scrapes public hh.ru HTML without relying on the blocked JSON API
  • ✅ Supports keyword and direct search URL workflows
  • ✅ Extracts both search-card data and optional vacancy detail fields
  • ✅ Normalizes vacancy IDs and vacancy URLs where possible
  • ✅ Adds salary range parsing when the salary text is parseable
  • ✅ Keeps provenance fields for reproducible analysis
  • ✅ Uses HTTP + Cheerio for low compute cost

Data you can extract

FieldDescription
titleVacancy title
vacancyIdhh.ru vacancy id when detected
urlNormalized vacancy URL
employerEmployer name
employerUrlEmployer profile URL
locationLocation or address text
salaryTextRaw public salary text
salaryFromParsed lower salary bound
salaryToParsed upper salary bound
salaryCurrencyParsed currency code
experienceExperience requirement
scheduleSchedule text from the detail page
employmentEmployment type text from the detail page
publishedAtTextPublic publication/update text when available
snippetSearch-result snippet when available
descriptionVacancy description from the detail page
sourceSearchUrlSearch page that produced the record
scrapedAtISO timestamp when the record was saved

How much does it cost to scrape hh.ru jobs?

The actor uses pay-per-event pricing.

There is a small run-start charge and a per-vacancy charge for each saved result.

Formula-based cloud validation set the BRONZE per-vacancy price at about $0.082 per 1,000 saved vacancy records, plus a $0.005 run-start event.

Always keep first test runs small.

Recommended first run:

  • searchQuery: python
  • area: 1
  • maxItems: 25
  • maxPages: 3
  • includeDetails: true

Input options

Search query

Use searchQuery when you want the actor to build the hh.ru search URL for you.

Example:

"python"

Area / region ID

Use area for the hh.ru region id.

Common examples:

  • 1 — Moscow
  • 2 — Saint Petersburg
  • 113 — Russia

Search URL

Use searchUrl when you already configured filters in hh.ru and copied the browser URL.

When searchUrl is set, it overrides searchQuery and area.

Example:

"https://hh.ru/search/vacancy?text=python&area=1"

Maximum vacancies

Use maxItems to stop after a specific number of vacancy records.

Maximum pages

Use maxPages to limit pagination.

Each hh.ru search page usually contains about 20 vacancies.

Include vacancy details

Set includeDetails to true to visit each vacancy detail page and enrich the output.

Set it to false for faster search-list-only scraping.

Request delay

Use requestDelayMs to slow down requests.

A polite default delay is included.

Example input

{
"searchQuery": "python",
"area": "1",
"maxItems": 25,
"maxPages": 3,
"includeDetails": true,
"requestDelayMs": 750
}

Example with a copied search URL

{
"searchUrl": "https://hh.ru/search/vacancy?text=data%20analyst&area=1",
"maxItems": 50,
"maxPages": 5,
"includeDetails": true
}

Output example

{
"title": "Python Developer",
"vacancyId": "123456789",
"url": "https://hh.ru/vacancy/123456789",
"employer": "Example Company",
"employerUrl": "https://hh.ru/employer/12345",
"location": "Москва",
"salaryText": "от 150 000 ₽ за месяц",
"salaryFrom": 150000,
"salaryTo": null,
"salaryCurrency": "RUB",
"experience": "1–3 года",
"schedule": "График: 5/2",
"employment": "Полная занятость",
"publishedAtText": "",
"snippet": null,
"description": "Public vacancy description text...",
"sourceSearchUrl": "https://hh.ru/search/vacancy?text=python&area=1&page=0",
"scrapedAt": "2026-06-02T00:00:00.000Z"
}

How to run

  1. Open the actor on Apify.
  2. Enter a search keyword or paste a hh.ru search URL.
  3. Choose the area id and maximum vacancies.
  4. Keep includeDetails enabled if you need descriptions.
  5. Start the run.
  6. Export the dataset as JSON, CSV, Excel, or via API.

Tips for best results

  • Start with 25–50 vacancies to validate your filters.
  • Use copied hh.ru URLs for advanced filters.
  • Increase requestDelayMs if responses slow down.
  • Disable includeDetails when you only need result-list fields.
  • Use sourceSearchUrl to audit which search page produced each record.

Integrations

Use this actor in recruiting dashboards, lead scoring systems, BI pipelines, and market intelligence workflows.

Typical workflows:

  • Send dataset items to Google Sheets for recruiter review.
  • Load CSV exports into Airtable or Notion.
  • Use the Apify API to refresh labor-market dashboards daily.
  • Combine vacancy records with company enrichment actors.
  • Trigger alerts when new jobs match a keyword and city.

API usage with Node.js

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/headhunter-jobs-scraper').call({
searchQuery: 'python',
area: '1',
maxItems: 25,
includeDetails: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

API usage with Python

from apify_client import ApifyClient
client = ApifyClient('YOUR_APIFY_TOKEN')
run = client.actor('automation-lab/headhunter-jobs-scraper').call(run_input={
'searchQuery': 'python',
'area': '1',
'maxItems': 25,
'includeDetails': True,
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)

API usage with cURL

curl -X POST "https://api.apify.com/v2/acts/automation-lab~headhunter-jobs-scraper/runs?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"searchQuery":"python","area":"1","maxItems":25,"includeDetails":true}'

MCP usage

Use the actor through Apify MCP in Claude Code or Claude Desktop.

MCP URL:

https://mcp.apify.com/?tools=automation-lab/headhunter-jobs-scraper

Add it in Claude Code:

$claude mcp add apify-headhunter-jobs "https://mcp.apify.com/?tools=automation-lab/headhunter-jobs-scraper"

Claude Desktop JSON config example:

{
"mcpServers": {
"apify-headhunter-jobs": {
"url": "https://mcp.apify.com/?tools=automation-lab/headhunter-jobs-scraper"
}
}
}

Example prompts:

  • "Run the HeadHunter Jobs Scraper for Python jobs in Moscow and summarize salary ranges."
  • "Find 50 public hh.ru data analyst vacancies and group them by employer."
  • "Scrape this hh.ru search URL and export the dataset as CSV."

Reliability notes

This actor intentionally uses the public HTML pages.

The hh.ru JSON API returned 403 in feasibility checks, so the actor does not depend on it.

Selectors may change when hh.ru redesigns its frontend.

If a page returns no public vacancy cards, the actor stops gracefully.

Limits

The actor only scrapes public data visible without an account.

It does not apply for jobs, contact candidates, log in, or bypass access controls.

Some advertised or redirect result links may be normalized from the vacancy id detected in the card.

Salary parsing is best-effort because salary formats vary by employer and country.

Legality

This actor extracts publicly available job vacancy information.

Make sure your use complies with applicable laws, hh.ru terms, and privacy requirements.

Do not scrape personal data unnecessarily.

Do not use the output for spam or prohibited employment decisions.

FAQ

Does this actor require a HeadHunter account?

No. It is designed for vacancy data visible without logging in.

Why did my run return fewer items than requested?

The search may have fewer public results, hh.ru may return duplicate vacancies across pages, or your maxPages limit may be too low.

Why is salary sometimes empty?

Many employers do not publish salary information. The actor saves salary fields only when public salary text is present.

Should I use searchQuery or searchUrl?

Use searchQuery for simple searches. Use searchUrl for advanced hh.ru filters copied from the browser.

Explore other Automation Lab actors for job boards, company enrichment, search results, and lead generation:

Support

If the actor stops returning expected results, provide the input JSON, run URL, and a public hh.ru sample URL.

We can then compare the current HTML structure with the extractor selectors.