От первого входа до исследования
Инструкция студенту
Этот сервис позволяет получать данные о вакансиях hh.ru для учебных исследований: искать вакансии, сравнивать города, читать полные описания и анализировать результаты в коде. Подключением к hh.ru управляет преподаватель; вам нужны собственный кабинет и личный API-ключ.
Инструкция соответствует текущей реализации раздела /hh-api/ по состоянию на 23 октября 2026 года. Значения лимитов указаны для начальных настроек и могут быть изменены преподавателем.
1. Быстрый старт и полезные адреса
- Узнайте у преподавателя, под каким ФИО и в какой группе вы добавлены.
- Откройте «Первый вход», введите ФИО, выберите группу и задайте пароль.
- В кабинете откройте «Доступ и пароль», нажмите «Выпустить ключ» и сохраните его.
- Выполните
GET /vacanciesс заголовкомAuthorization: Bearer ВАШ_КЛЮЧ. - Проверьте ответ и откройте «Журнал запросов» в кабинете.
| Назначение | Адрес |
|---|---|
| Главная страница | https://milushkoff.ru/hh-api/ |
| Первый вход | https://milushkoff.ru/hh-api/login#activate |
| Обычный вход | https://milushkoff.ru/hh-api/login |
| Личный кабинет | https://milushkoff.ru/hh-api/cabinet |
| Полная инструкция студенту | https://milushkoff.ru/hh-api/guide |
| Пошаговая документация | https://milushkoff.ru/hh-api/docs |
| Подробный справочник | https://milushkoff.ru/hh-api/reference |
| OpenAPI-схема | https://milushkoff.ru/hh-api/openapi.json |
Базовый адрес API:
https://milushkoff.ru/hh-api
Полный URL получается добавлением пути метода, например:
https://milushkoff.ru/hh-api/vacancies?area=1&text=Python&per_page=1
Не добавляйте к этому адресу ещё один /hh-api или /api. Личный учебный ключ предназначен для этого сервиса, а не для прямых запросов к api.hh.ru.
2. Первый вход и обычный вход
Если вы ещё не активировали кабинет
- Откройте страницу входа и выберите вкладку «Первый вход».
- В поле «Фамилия, имя, отчество» введите данные из списка преподавателя.
- В «Учебная группа» выберите свою группу.
- Задайте «Пароль» и заполните «Повторите пароль» тем же значением.
- Нажмите «Активировать кабинет →».
После успешной активации откроется личный кабинет с вашим именем и группой.
Свободной регистрации нет: активировать можно только заранее добавленную запись. Регистр букв, лишние пробелы и различие е/ё не мешают сопоставлению. Состав ФИО должен совпадать: если в списке есть отчество, введите его; если записи нет или ФИО указано иначе, обратитесь к преподавателю.
Пароль должен содержать от 10 до 72 байт. Чтобы не путаться с байтами, используйте 10–72 латинских символа, цифры и знаки. Кириллица и эмодзи могут занимать несколько байт на символ и раньше достигать верхнего предела. Используйте отдельный пароль для учебного сервиса и сохраните его в менеджере паролей.
Если кабинет уже активирован
- Выберите «Войти».
- Введите ФИО, выберите группу и укажите свой пароль.
- Нажмите «Войти в кабинет →».
Повторно проходить «Первый вход» при каждом занятии не нужно.
Если преподаватель выдал временный пароль, также выбирайте «Войти». Если он сбросил пароль и разрешил повторную активацию, выбирайте «Первый вход» и задайте новый пароль.
Если войти не получается
| Сообщение или ситуация | Что проверить |
|---|---|
| «Пароли не совпадают» | Оба поля пароля при активации должны совпадать |
| «Запись недоступна для активации» | ФИО, группу, не активирован ли кабинет ранее; при необходимости обратитесь к преподавателю |
| «Не удалось войти» | ФИО, группу, пароль и правильность выбора между «Войти» и «Первый вход» |
| Группы нет в списке | Попросите преподавателя проверить её наличие и разрешение доступа |
| Слишком много попыток входа | Дождитесь указанного времени; не продолжайте подбирать пароль |
3. Получение и хранение личного ключа
Выпустить ключ
- Войдите в кабинет.
- Откройте вкладку «Доступ и пароль». С первой вкладки туда также ведёт кнопка «Управление ключом →».
- В блоке «Ваш API-ключ» нажмите «Выпустить ключ».
- В появившемся поле «Скопируйте и сохраните» скопируйте весь ключ кнопкой «Скопировать».
- Сохраните его до обновления или закрытия страницы.
Если кнопка копирования не сработала, выделите значение в поле и скопируйте вручную. После обновления страницы полный ключ исчезнет; останется только его начало с многоточием. Это начало не подходит для запросов.
Полный ключ показывается только при выпуске. Если вы его потеряли, открыть прежнее значение снова нельзя — нужно перевыпустить ключ.
Пароль и ключ — разные вещи
| Что вы используете | Где вводить |
|---|---|
| Пароль кабинета | Форма входа на сайте |
| Личный API-ключ | Заголовок Authorization в запросе вашей программы |
Вход в кабинет не добавляет авторизацию в ваши скрипты или запросы из адресной строки браузера. Даже при открытом кабинете каждому запросу API нужен личный ключ.
Правильный заголовок:
Authorization: Bearer ВАШ_ЛИЧНЫЙ_КЛЮЧ
Между Bearer и ключом должен быть пробел. Не передавайте ключ в URL, параметре token, теле запроса или вместо пароля кабинета. При использовании ключа в программе передавайте полное значение без многоточия и лишних пробелов.
Перевыпустить ключ
- Откройте «Доступ и пароль».
- Нажмите «Перевыпустить ключ» и подтвердите действие.
- Скопируйте и сохраните новый ключ.
- Замените старый ключ во всех своих программах, переменных окружения и API-клиентах.
Прежний ключ сразу становится недействительным. У одной записи действует один личный ключ. Не перевыпускайте его перед каждым запросом или обычным запуском программы.
Смена собственного пароля и выход из кабинета сохраняют API-ключ. Сброс пароля преподавателем, персональная блокировка и отзыв ключа аннулируют его. Если ключ попал в чужие руки или в публичный репозиторий, сразу перевыпустите его и сообщите преподавателю, если не можете войти.
Не пересылайте ключ одногруппникам и не сдавайте его вместе с кодом или скриншотами. Запросы с вашим ключом учитываются как ваши. В браузерном учебном проекте получайте ключ от пользователя и храните в памяти страницы; не вставляйте его в опубликованный JavaScript.
4. Разделы личного кабинета
Во вкладке «Моё исследование» выберите свободную тему вашей группы или отправьте собственную на согласование. Здесь видны статус и комментарии преподавателя.
| Раздел | Что в нём делать |
|---|---|
| Документация | Смотреть базовый адрес, описание методов, переходить к инструкции и скачивать OpenAPI |
| Статистика | Смотреть количество запросов, успехов, ошибок, кешированных ответов и обращения к hh.ru |
| Журнал запросов | Разбирать конкретные запросы: время, путь, параметры, статус, источник и длительность |
| Доступ и пароль | Выпускать или перевыпускать ключ, менять пароль |
В документации доступны только семь учебных GET-методов. Общая документация hh.ru может описывать больше возможностей, чем разрешено этим сервисом. Для первого запроса используйте следующий раздел; команды запускаются в терминале или API-клиенте.
5. Первый запрос к API
Подготовьте Python
Установите Python 3.10 или новее. Создайте отдельную папку исследования и скачайте first-request.py. Дополнительные библиотеки не нужны.
Откройте терминал в папке с файлом. Команды ниже вводятся в терминале, а код программы — в файле .py.
Windows:
py -3 first-request.py
macOS / Linux:
python3 first-request.py
Скопируйте личный API-ключ из кабинета. Когда программа попросит ключ, вставьте его и нажмите Enter: символы при вводе не отображаются — это нормально. Ключ остаётся в памяти программы. Если HH_STUDY_TOKEN уже задан в настройках среды запуска, программа возьмёт его оттуда.
Код первого запроса
"""Первый запрос. Python 3.10+, установка дополнительных библиотек не нужна."""
import getpass
import json
import os
from urllib.error import HTTPError, URLError
from urllib.parse import urlencode
from urllib.request import Request, urlopen
base = os.getenv('HH_STUDY_BASE', 'https://milushkoff.ru/hh-api').rstrip('/')
# Ключ вводится при запуске, а не сохраняется в файле с кодом.
token = os.getenv('HH_STUDY_TOKEN') or getpass.getpass('Личный API-ключ (ввод скрыт): ')
params = {'area': '2', 'text': 'аналитик данных', 'per_page': 1}
request = Request(base + '/vacancies?' + urlencode(params),
headers={'Authorization': 'Bearer ' + token.strip()})
try:
with urlopen(request, timeout=25) as response:
data = json.load(response)
print('HTTP:', response.status)
print('Всего найдено:', data['found'])
print('На этой странице:', len(data['items']))
if data['items']:
print('Первая вакансия:', data['items'][0]['name'])
else:
print('По этим условиям вакансий нет. Попробуйте другой запрос.')
except HTTPError as error:
print('Ошибка HTTP:', error.code)
if error.code == 429:
print('Подождите Retry-After секунд:', error.headers.get('Retry-After', 'см. ответ сервера'))
elif error.code == 401:
print('Проверьте личный ключ в кабинете.')
else:
print('Посмотрите раздел «Ошибки» в инструкции или сообщите преподавателю.')
except (URLError, TimeoutError):
print('Нет соединения с учебным API. Проверьте интернет и повторите позже.')
Что здесь происходит
area='2'задаёт Санкт-Петербург;text— поисковую фразу;per_page=1просит только одну вакансию.urlencode(params)собирает адрес и правильно кодирует пробелы и русские буквы.Authorization: Bearer …передаёт личный ключ в заголовке, а не в адресе запроса.urlopenотправляет запрос, аjson.loadпревращает JSON в словарь Python.found— число найденных вакансий;len(items)— число вакансий только на загруженной странице. Ноль результатов — корректный ответ.
Как понять ответ
Успешный запрос возвращает HTTP: 200. Например, программа может вывести Всего найдено: 125 и На этой странице: 1. Это условные числа, не результаты исследования.
Откройте в кабинете «Журнал запросов» и нажмите «Обновить ↻»: там появится ваш запрос. При 401 проверьте ключ; при 429 дождитесь времени из Retry-After. Для автоматических повторов используйте полный Python-пример из раздела 7.
6. Доступные методы и работа с данными
Все доступные пути
Каждый путь ниже добавляется к https://milushkoff.ru/hh-api. Для каждого нужен заголовок Authorization.
| Метод и путь | Назначение | Пример использования |
|---|---|---|
GET /vacancies |
Поиск вакансий | Поиск по профессии и городу, подсчёт found |
GET /vacancies/{id} |
Полная карточка вакансии | Описание, навыки и другие поля |
GET /areas |
Дерево стран, регионов и городов | Поиск ID города |
GET /areas/{id} |
Поддерево конкретного региона | Просмотр вложенных регионов |
GET /areas/countries |
Список стран | Выбор страны |
GET /dictionaries |
Справочники параметров | Допустимые значения фильтров |
GET /professional_roles |
Профессиональные роли | Поиск роли и её ID |
{id} — обозначение места для настоящего числового ID, а не текст для передачи в URL. Для описания вакансии используйте ID из собственного ответа поиска.
Пути вроде /resumes, /employers и /me не входят в учебный API. Запрос к неподдерживаемому пути с действующим ключом вернёт 404. Методы изменения данных, например POST для вакансий, не поддерживаются.
Найти город
- Выполните
GET /areas. - Найдите нужную страну, регион и город во вложенных массивах
areas. - Сохраните
idименно выбранного города. - Передайте этот ID в параметре
areaпоиска вакансий.
Москва имеет ID 1, Санкт-Петербург — 2. Для остальных населённых пунктов проверяйте справочник. Совпадающие названия могут относиться к разным регионам; одного совпадения по названию не всегда достаточно.
Для сравнения двух городов выполните два отдельных запроса:
GET /vacancies?area=1&text=Python&per_page=1
GET /vacancies?area=2&text=Python&per_page=1
Это записи метода и пути; при отправке добавьте базовый адрес и заголовок авторизации. Между последовательными запросами делайте паузу, а при 429 соблюдайте Retry-After.
Повторяющиеся параметры поддерживаются:
GET /vacancies?area=1&area=2&text=Python&per_page=1
Этот запрос даёт общую выдачу по двум регионам. Для отдельных чисел по городам он не заменяет два предыдущих запроса.
Задать фильтры поиска
Основные параметры из локальной OpenAPI-схемы:
| Параметр | Для чего нужен |
|---|---|
text |
Поисковый текст; без дополнительных ограничений это не обязательно поиск только по названию вакансии |
area |
ID региона или города |
professional_role |
ID роли из /professional_roles |
period |
Поиск за указанное количество дней |
date_from, date_to |
Диапазон дат публикации; не используется одновременно с period |
page |
Номер страницы, начиная с 0 |
per_page |
Размер страницы, не более 100 |
Точные форматы и дополнительные фильтры смотрите в справочнике учебного API. Меняйте по одному параметру и проверяйте результат: так легче найти причину 400 или неожиданной выдачи.
Получить полное описание вакансии
- Выполните поиск и убедитесь, что
itemsне пустой. - Возьмите
idодной из найденных вакансий. - Выполните
GET /vacancies/ID, подставив его вместоID. - Разберите полученный JSON.
Полезные поля:
name— название вакансии;description— описание, содержащее HTML-разметку;key_skills— навыки, которые могут отсутствовать или быть пустым списком;salary— сведения о зарплате; значение может бытьnull;url— адрес API-ресурса, переписанный на учебный домен;alternate_url— ссылка на страницу вакансии на hh.ru.
Не обращайтесь к items[0], пока не проверили наличие элементов. Перед анализом зарплаты проверяйте наличие объекта, границ суммы, валюты и признака gross. Отсутствующая зарплата не означает нулевую. Описания для текстового анализа следует очистить от HTML-разметки.
Не все ссылки на API-ресурсы внутри ответа относятся к семи разрешённым путям. Даже переписанная на учебный домен ссылка может вернуть 404, если этот ресурс не поддерживается модулем. Ссылка alternate_url предназначена для открытия страницы hh.ru в браузере.
Работать с несколькими страницами
В локальном справочнике для поиска указаны нумерация с нуля, максимум 100 элементов на странице и глубина выдачи до 2000 вакансий.
Для страниц по 100 элементов:
GET /vacancies?area=1&text=Python&per_page=100&page=0
GET /vacancies?area=1&text=Python&per_page=100&page=1
Алгоритм сбора:
- Отправьте первую страницу с
page=0. - Сохраните
itemsи прочитайтеpages. - Увеличьте
pageна один и повторите запрос после паузы. - Остановитесь, когда следующая страница достигнет
pagesили установленного вами ограничения объёма. - Учитывайте максимальную глубину: при
per_page=100номера0–19допустимы в её пределах, а20выходит за предел.
Фактических страниц может быть меньше 20. Для первого исследования достаточно одной-двух страниц. Для сравнения количества вакансий используйте один запрос с per_page=1 на каждый набор условий — скачивать всю выдачу не требуется. Если совпадений слишком много, уточняйте профессию, регион или период.
7. Запуск готовых примеров
Два файла, оба на Python
- first-request.py — один запрос, количество найденных вакансий и первая карточка.
- research.py — две выборки, страницы результатов, исходный JSON и таблицы CSV для Calc.
Требуется Python 3.10+, только стандартная библиотека. Скачайте research.py в отдельную папку, откройте в ней терминал и запустите файл.
Windows:
py -3 research.py
macOS / Linux:
python3 research.py
Введите ключ в скрытом приглашении программы. Не вставляйте его в код, таблицу или статью. HH_STUDY_TOKEN можно вместо этого задать в настройках среды запуска. Если запускаете через IDE, используйте её терминал для скрытого ввода ключа.
Параметры исследования в одном месте
В начале файла изменяйте COMMON_PARAMS и COHORTS. По умолчанию сравниваются вакансии начинающих аналитиков данных в Москве и Санкт-Петербурге: одна поисковая фраза, поиск в названии, отсутствие опыта и последние 30 дней. Это уточнение темы № 19; адаптируйте его под свою закреплённую тему.
MAX_PAGES=20 и PER_PAGE=100 ограничивают выгрузку 2000 вакансиями на один поиск. Для короткой проверки можно уменьшить MAX_PAGES. Скрипт удаляет повторные ID внутри каждой выборки и отмечает неполную выгрузку или изменение found во время сбора. Пересекающиеся выборки сравнивайте с учётом общих вакансий; не суммируйте их как независимые.
Где искать результат
Каждый запуск создаёт новую папку results/дата-время внутри текущей папки терминала. Полный путь программа выводит после завершения.
raw.json— время начала и окончания, параметры, исходные страницы и уникальные вакансии каждой выборки.vacancies.csv— строки вакансий для Calc: выборка, ID, название, город, опыт, границы зарплаты, валюта, налоги, период оплаты и прочие поля.summary.csv—found, число загруженных уникальных вакансий, дубликаты, отметка неполноты и параметры каждой выборки.
Откройте CSV в LibreOffice Calc: кодировка UTF-8, разделитель — точка с запятой. Сохраните отдельные листы с исходными данными, очищенной выборкой и расчётами в .ods. CSV — промежуточная выгрузка, а не замена итоговому файлу Calc.
Повторы и адрес сервера
Между запросами выдерживается пауза. Скрипт делает не более пяти попыток при временных ошибках 429, 502, 504 и сетевых сбоях, учитывает Retry-After и останавливается при паузе более 120 секунд. При ошибке постоянного доступа сначала исправьте её причину.
По умолчанию используется https://milushkoff.ru/hh-api. Если преподаватель выдал другой учебный сервер, задайте HH_STUDY_BASE в среде запуска. Для этого экземпляра портала базовый адрес указан выше в инструкции; основной сервер менять не нужно.
Адрес этого учебного сервера: https://milushkoff.ru/hh-api. Для настройки другого адреса в macOS/Linux: export HH_STUDY_BASE='https://milushkoff.ru/hh-api'; в Windows PowerShell: $env:HH_STUDY_BASE = 'https://milushkoff.ru/hh-api'. Это команды терминала.
8. Пример учебного исследования
Начните с задания и выбора темы
Прочитайте полную инструкцию преподавателя, скачайте оригинал ODT и откройте «Моё исследование». В группе готовую тему может закрепить только один студент. Собственная тема сначала проходит согласование; сменить закреплённую тему можно через преподавателя.
Пример по теме № 19: Москва и Санкт-Петербург
Уточнение темы: возможности начинающих аналитиков данных в двух городах.
Исследовательский вопрос: как различаются число вакансий и сопоставимые зарплатные предложения аналитикам данных без опыта в Москве и Санкт-Петербурге?
Проверяемая гипотеза: в Москве больше таких вакансий, а медиана сопоставимых зарплатных предложений выше. Это предположение для проверки, а не готовый вывод.
Соберите две выборки
- Зафиксируйте критерии до сбора:
text='аналитик данных',search_field='name',experience='noExperience',period=30. Меняйте толькоarea: Москва —1, Санкт-Петербург —2. - Запустите
research.py. Сохраните дату, параметры и исходные данные. Данные меняются даже во время одного запуска; это ограничение среза. - Сравните
foundи количество загруженных уникальных вакансий. Если выгрузка неполная, сузьте одинаковым способом обе выборки либо явно опишите ограничение. Не называйте выгруженные строки всеми найденными вакансиями. - Проверьте релевантность названий и требований, дубликаты и пропуски. Поисковая фраза в названии не охватывает все возможные названия профессии.
Подготовьте анализ в LibreOffice Calc
Создайте листы «Исходные данные», «Отбор», «Сравнение». Сохраните первоначальные строки отдельно от отфильтрованных. В листе отбора укажите причину исключения нерелевантных вакансий и правила обработки зарплаты.
Сравните не менее двух выборок по числу найденных вакансий, числу загруженных карточек, доле карточек с указанной зарплатой и медиане сопоставимых предложений. Долю считайте среди загруженных уникальных карточек; укажите её знаменатель.
Для одного воспроизводимого варианта зарплатного анализа берите предложения в рублях с месячным периодом оплаты и одинаковым признаком налогов, например gross=false. Если обе границы указаны, используйте их середину. Исключённые односторонние диапазоны, неизвестный период и пропуски посчитайте отдельно. Не заменяйте пропуски нулём. Если данных мало или их нет, честно укажите это вместо расчёта недостоверной медианы.
Составьте таблицу сравнения городов и при необходимости редактируемую чёрно-белую диаграмму. Сохраните книгу в .ods. Эти показатели описывают вакансии по выбранным условиям, а не весь рынок труда и не фактический заработок работников.
Сопоставьте результаты и напишите статью
Найдите релевантные российские и/или зарубежные исследования; сравните их данные, методы и выводы со своими. Не делайте причинных выводов по одному срезу вакансий.
- Введение: актуальность, обзор исследований, вопрос и гипотеза.
- Методы: HH API, дата и параметры сбора, критерии включения, формулы, очистка и ограничения.
- Результаты: вычисленные показатели, таблица и/или редактируемая диаграмма.
- Обсуждение: интерпретация, сравнение с литературой, ограничения и практические выводы.
Добавьте заключение и «ЛИТЕРАТУРА». Объём — 3–5 страниц вместе с аннотациями, ключевыми словами и литературой; рекомендуются не менее 10 источников. Точные поля, шрифты, аннотации и оформление приведены в задании преподавателя. Это учебная работа: журнал не принимает статьи студентов бакалавриата.
Проверьте архив перед сдачей
Сдайте один ZIP: ФамилияИнициалы_номерГруппы.zip, например ИвановИИ_2601.zip.
.py— воспроизводимый код с параметрами запросов, без ключа..ods— исходные результаты, отфильтрованные данные и расчёты..odt— статья IMRAD по требованиям преподавателя.
API-ключ или токен в любом файле — критическая ошибка. Проверьте код, таблицу, статью и остальные материалы архива. Исходные JSON/CSV используйте в работе, но три обязательных файла должны позволять проверить результат без дополнительных файлов. AI-инструменты разрешены; проверка данных, источников и защита выводов остаются ответственностью автора.
9. Статистика и журнал
В кабинете вы видите только собственные запросы. Преподаватель может просматривать запросы всех студентов.
Статистика
Откройте «Статистика»:
| Показатель | Что означает |
|---|---|
| Всего запросов | Завершённые и незавершённые авторизованные обращения |
| Успешные ответы | Ответы со статусом 200–399 |
| Ошибки и ограничения | Завершённые ответы с ошибками, включая 429 |
| Ответы из кеша | Ответы с источником HIT |
| Обращения к hh.ru | Реальные исходящие обращения, в том числе проверка актуальности кеша |
| Среднее время, мс | Средняя длительность завершённых запросов |
| В процессе / прерваны | Запрос начался, но его завершение не записано |
| Методов API | Разные пути API в завершённых запросах; отдельные ID объединяются в шаблоны |
Журнал запросов
Откройте «Журнал запросов», чтобы увидеть время, ID, метод, путь, параметры, статус, источник ответа и длительность каждого обращения.
Доступны фильтры «С даты», «По дату», «Метод», «HTTP-статус», «Путь». Например, укажите 429 в статусе, чтобы найти ограничения, или /vacancies в пути, чтобы увидеть поиск и карточки вакансий. В поле пути не нужно вставлять домен или строку ?area=....
После изменения фильтров нажмите «Применить». Чтобы увидеть новые запросы с текущими фильтрами, нажмите «Обновить ↻». Для очистки фильтров опустошите поля, верните метод в «Все» и примените. Данные не обновляются непрерывно сами.
Запросы показаны от новых к старым, по 50 на странице. Переходите кнопками «← Назад» и «Далее →». Итоговые показатели относятся ко всему выбранному набору, а не только к одной странице. При переключении между статистикой и журналом выбранные фильтры сохраняются в текущей открытой странице.
Время строк отображается по Москве, даты фильтров — по UTC. Запрос в 01:30 МСК 23 октября относится к 22 октября UTC. Для поиска ночных запросов при необходимости включите предыдущий день в фильтр.
Документация, вход в кабинет и обновление отчёта не расходуют квоту запросов данных. Запросы без ключа или с недействительным ключом в персональный журнал не попадают. Если вы видите 401, отсутствие строки в журнале само по себе не означает, что запрос не отправлялся.
10. Лимиты, кеш и обработка ошибок
Как отправлять запросы без лишних ограничений
При начальных настройках личная квота пополняется со скоростью 60 запросов в минуту и допускает короткий всплеск до пяти запросов. Общая исходящая скорость к hh.ru — примерно один запрос в секунду на всю лабораторию, до двух одновременно выполняемых обращений.
Отправляйте запросы последовательно. Начальная пауза около 1–2 секунд между ними уменьшает число ограничений, но при одновременной работе группы 429 всё равно возможен. Ответ сервера и Retry-After важнее выбранной вами фиксированной паузы.
Сначала получите нужные справочники один раз и сохраните их для обработки. Не запускайте сотни параллельных запросов и не собирайте все страницы, когда нужно только found.
Что такое кеш
Кеш — сохранённый ответ, который сервер может повторно выдать без нового обращения к hh.ru. Он общий для студентов. Начальные сроки: поиск — до пяти минут, описание — до 30 минут, справочники — до суток. Источник может запретить хранение или сократить эти сроки.
| Заголовок ответа | Для чего полезен |
|---|---|
X-Cache: HIT |
Ответ получен из свежего кеша |
X-Cache: MISS |
Начато обращение к hh.ru; проверьте HTTP-статус результата |
X-Cache: REVALIDATED |
hh.ru подтвердил актуальность сохранённого ответа |
X-Cache: NONE |
Например, локальный отказ до обращения к источнику |
Age |
Возраст ответа из свежего кеша в секундах, если заголовок присутствует |
X-Upstream-Requests |
0 или 1: потребовалось ли исходящее обращение |
X-Request-ID |
Идентификатор для поиска обращения в журнале |
Retry-After |
Когда можно повторить запрос: обычно число секунд; от источника может прийти HTTP-дата |
Кешированные ответы также учитываются в вашей личной квоте и статистике. Кеш объясняет, почему одинаковый запрос иногда возвращает прежнее число вакансий, хотя данные на сайте hh.ru уже могли измениться.
Таблица ошибок
Локальная ошибка обычно выглядит так:
{
"errors": [
{
"type": "student_rate_limit",
"value": "Превышена скорость запросов студента."
}
]
}
Сначала прочитайте HTTP-статус, затем errors. Ошибки hh.ru могут иметь другую структуру внутри массива, поэтому не ограничивайтесь одним текстовым полем.
| Статус / тип | Что делать |
|---|---|
400 |
Проверить параметры, их значения и сочетания по справочнику. Убедиться, что ключ передаётся только в заголовке |
401 |
Проверить полный ключ, пробел после Bearer, актуальность ключа после перевыпуска; при сохранении ошибки обратиться к преподавателю |
403 |
Прочитать ошибку; при captcha_required сообщить преподавателю |
404 |
Проверить путь и ID. Ресурс может отсутствовать или не входить в учебный API |
405 |
Для методов данных использовать GET |
414 |
Сократить слишком длинную строку параметров |
429 student_rate_limit |
Дождаться пополнения личной квоты и уменьшить частоту запросов |
429 global_rate_limit |
Достигнута общая скорость лаборатории; подождать Retry-After |
429 upstream_busy |
Все исходящие обращения заняты; повторить после ожидания |
429 cache_filling |
Такой ответ уже загружается; повторить через указанное время |
429 upstream_cooldown |
Общая временная пауза; дождаться её окончания |
Другой 429 от источника |
Прочитать Retry-After, выдержать паузу; при повторениях сообщить преподавателю |
502 / 504 |
Сбой или таймаут соединения; повторить позже с ограниченным числом попыток |
503 configuration_required |
Преподавателю нужно настроить подключение; сообщить ему |
503 upstream_paused |
Подключение остановлено защитой; требуется проверка преподавателем |
503 storage_unavailable / service_unavailable |
Передать преподавателю время и текст ошибки; перевыпуск ключа не исправит хранилище |
Безопасная для нагрузки логика повторов:
- Для
429прочитайтеRetry-Afterи дождитесь указанного времени. - Добавьте небольшой случайный интервал, чтобы вся группа не повторяла запросы одновременно.
- При
502/504используйте увеличивающуюся паузу, например 1, 2, 4, 8 секунд. - Ограничьте общее число попыток, например пятью, как в готовых Python-примере.
- Для
400,401,403,404,405исправьте причину до повтора. При503прочитайте тип ошибки и обратитесь к преподавателю, если требуется его действие.
Не заменяйте обработку ошибок бесконечным циклом и не перевыпускайте ключ ради устранения 429.
11. Пароль, восстановление доступа и помощь
Сменить собственный пароль
- Откройте «Доступ и пароль» → «Сменить пароль».
- Введите «Текущий пароль» и «Новый пароль».
- Нажмите «Изменить пароль».
- Войдите заново с новым паролем.
Прежние сеансы на всех устройствах станут недействительными. API-ключ сохранится. Если вы получили временный пароль от преподавателя, смените его этим способом.
Если пароль или ключ потерян
| Ситуация | Решение |
|---|---|
| Пароль известен, ключ потерян | Войти и перевыпустить ключ |
| Пароль забыт | Попросить преподавателя сбросить его; восстановления по email в интерфейсе нет |
| Преподаватель разрешил повторную активацию | Открыть «Первый вход», задать новый пароль, затем выпустить новый ключ |
| Преподаватель выдал временный пароль | Открыть «Войти», использовать его, сменить пароль и выпустить новый ключ |
| Доступ заблокирован | Обратиться к преподавателю; создание другой записи не предусмотрено |
| Изменены ФИО или группа | Войти заново с актуальными данными; при сохранённом доступе прежний ключ сохраняется |
После сброса пароля преподавателем прежний ключ отозван. После обычного самостоятельного изменения пароля перевыпуск не требуется.
Что отправить преподавателю при проблеме
Удобный шаблон сообщения:
ФИО и группа: ...
Время ошибки по Москве: ...
Действие: вход / выпуск ключа / запрос API / запуск примера
Метод и URL с параметрами: ...
HTTP-статус: ...
Текст или JSON ошибки: ...
X-Request-ID, если есть: ...
Что уже проверено: ...
Не добавляйте в сообщение пароль, значение Authorization или полный ключ. Перед отправкой скриншота убедитесь, что эти данные скрыты. Если запрос делался с неверным ключом, X-Request-ID может отсутствовать — укажите время и остальные сведения.
Завершая работу на общем компьютере, нажмите «Выйти» и уберите свои ключи из сохранённых файлов и настроек запуска. Если ключ мог остаться доступным другим людям, перевыпустите его с доверенного устройства.