Skip to main content

HH-Applicant-Tool: An automation utility for HeadHunter (hh.ru) designed to streamline the job search process by auto-applying to relevant vacancies and periodically refreshing resumes to stay at the top of recruiter searches.

Project description

HH Applicant Tool

[!NOTE] Ищу почасовую или проектную @feedback_s3rgeym_bot (Python, Vue.js, Devops).

Publish to PyPI PyPi Version Python Versions GitHub code size in bytes PyPI - Downloads Total Downloads

☕ Поддержать проект

Donate BTC

BTC Address: BC1QWQXZX6D5Q0J5QVGH2VYXTFXX9Y6EPPGCW3REHS


✨ Ключевые особенности

  • 💸 Полностью бесплатно. В то время как сервисы в интернете или Telegram с аналогичным функционалом просят за свои услуги от 5.000 до 12.000 рублей в месяц.

  • ✉️ Генерация сопроводительных писем с помощью шаблонов и ChatGPT. На абсолютное большинство вакансий сегодня не откликнуться без сопроводительного письма. Их безмозглые куски пиздятины, конечно, не читает, но легенды гласят, что за красивые сопроводительные могут сразу директором взять как талантливых детей депутатов и чиновников, которых в элитных школах учат мастерству написания оных.

  • 🧩 Выполнение тестов при отклике. С выбором случайных ответов либо через недо-ИИ. Данные тесты стали использовать для отсева ботов после массового увлечения автоматическими рассылками на фоне роста безработицы, падения количества вакансий и прочих гео-политических побед, которые совпали с внедрением нейро-глючных ATS, рассылающих отказы как из пулемета, а раз у тебя одни отказы, то нужно почаще откликаться, чтоб хоть куда-то пригласили. Про ботов: дело в том, что в API нет методов для решения тестов, а все боты для откликов работали именно через него.

  • 📧 Отправка писем при отклике. Вы можете настроить дополнительную отправку письма на контактный email работодателя, указанный в контактах, либо если тот указан на его сайте.

  • 💬 Рассылка сообщений по чатам работодателей. Помогает не затеряться на фоне огромного количества откликов от других соискателей (в 2024 их было по 300 штук на вакансию джуна, сейчас по 3000).

  • 🔒 Безопасность персональных данных. Ваши email, телефон, пароль и другие личные данные никуда не передаются в отличие от сторонних сервисов. В этом можно убедиться, изучив открытый исходный код. Владельцы сторонних сервисов никогда вам не покажут исходники. Они знают о вас все и эти данные спокойно продадут каким-нибудь жуликам, либо те утекут в результате взлома.

  • 💾 Сохранение контактов работодателей и прочей информации. Контакты работодалей и информация о них и их вакансиях сохраняется в базе данных на вашем устройстве, что позволяет производить быстрый поиск нужной информации в отличии от сайта при минимальном опыте с SQL (язык запросов, придуманный в свое время для домохозяек).

  • 🛡️ Гарантия от блокировок. Утилита выполняет запросы с вашего устройства, имитируя обычного пользователя. Сервисы рассылают запросы для сотен аккаунтов с одного сервера, что повышает вероятность блокировки вашего аккаунта до 100%.

  • 😎 Простота в использовании. С утилитой разберется любой начинающий пользователь компьютера... даже женщина.

  • 👯 Поддержка работы с несколькими аккаунтами и резюме. Утилита благодаря профилям может работать с неограниченным количеством аккаунтов и резюме. Когда у вас кончаются вакансии для откликов, вы просто дублируете резюме и начинаете на все откликаться по второму кругу, повышая свои шансы быдть замеченным.

  • 🖥️ Полноценный CLI и работа на серверах. Утилита имеет чистый консольный интерфейс. Несмотря на то, что для обхода защиты при авторизации используется браузер, он работает по умолчанию в фоновом (headless) режиме. Для hh-applicant-tool не нужна видеокарта или графическая оболочка (X-сервер), что позволяет авторизоваться даже с сервера или из докер-контейнера. Капча так же выводится прямо в терминал при использовании флагов --kitty/--sixel.

  • 🚀 Скриптинг. Вы можете использовать утилиту из своих Python-скриптов.

  • 🤖 Борьба с ATS и HR. россиянские говнокомпании (других тут в принципе нет) массово внедрилиATS, которые отклоняют отклик в течение 5 секунд (мой рекорд). Отказ может прийти даже из-за отсутствия одного слова в резюме. Виной всему аналоговнетные отечественные нейрозаменители, возможности которых не дотягивают даже до 0.001% от того, что умела первая версия ChatGPT. Доверия к ним не добавляет и то, что они были обучены на наших "любимых" психуйлогинях с их оригинальными "логарифмами" отбора. Не говоря уже о тупопездом фильтре, отсеивающем по знаку зодиака на следующем этапе (раньше в интерфейсе этого сайта для тупоЁблых овчаров даже знак зодиака показывался). Это обесценивает ваши усилия на написание сопроводительных писем (по совету ебанашек с ютуба) и чтение бесконечных портянок бреда, сгенерированных нейронкой. Если тупые ичары решили себя не утруждать чтением резюме (они сейчас и сами перестали писать), то и вам незачем читать высеры этих психологинь (психология — псевдонаука как физиогномика или астрология, столь любимые свинками). Утилита избавляет вас от этой рутины, превращающей поиск работы в полноценную работу. Сейчас доля отказов составляет 98-99%, включая "молчунов" и прочих долбоебов (это скрытые отказы в CRM/ATS чтобы не портить овчар-бренд), и единственный способ увеличить шансы просто попасть на собеседование — это автоматическая рассылка откликов на все подходящие вакансии. У большинства телефоны с двумя симками, а значит каждый может разослать до 400 откликов в сутки, а если нарегать акков на родню — еще больше! Из-за нейродурки сейчас спамят откликами все, поэтому на вакансию приходится в среднем 400-1000 откликов (больше всего откликов не на фронтенд, а на Golang-разработчиков, так как это очень простой язык — Pascal 21-го века). Да, подобных функционал с недавних пор предоставляет сам красный сайт, но ограничивается он максимум пятью откликами, и мало того дал хрюшам кнопку чтобы скипать такие отклики (поводили шершавым по губам дуракам заплатившим за это). Данная утилита никак не палится и эмулирует в своей работе приложение под Android и браузер, поэтому не подпадает под подобные фильтры.

Наглядно о раб_отном рынке в ресурсной федерации

image image

Содержание


Описание

[!IMPORTANT] Данной утилите похуй на "запрет" доступа к API HH сторонним приложениям, так как она прикидывается официальным приложением под Android

[!NOTE] Утилита для генерации сопроводительного письма может использовать AI, в т. ч. ChatGPT. Подробное описание ниже

Утилита для успешных волчат и старых волков с опытом, служащая для автоматизации действий на HH.RU, таких как рассылка откликов на подходящие вакансии и обновление всех резюме (бесплатный аналог услуги на HH). Утилита локально хранит информацию об откликах, в т. ч. полученные контакты. Это удобно, так как контакт сохранится, даже если вышлют отказ в дальнейшем. Мой совет: скрывайте свой номер от работодателя, если рассылаете отклики через утилиту, а то количество жуликов на красном сайте, мягко говоря, зашкаливает. У утилиты есть канал в телеграме HH Applicant Tool и чат. В чате (тот на который ссылку до этого кинул, а не личный чат с ботом) через Сеньора Овчарку с помощью команды /search вы можете поискать контакты работовладельцев (большинство кабанчиков и их свинок там именно заедушных рабов и дураков ищут, а осутствие последних называют дефицитом кадров), например, чтобы послать нахуй хрюшу, выславшую отказ. Старый канал HH Resume Automate был выпилен по крысиной жалобе администрации сайта Хуй-Хуй (Ха-Ха, Хе-Хе и тп), так как красный круг с двумя буквами h, нарисованный мною лично — это нарушение их авторских прав...

Работает с Python >= 3.11. Нужную версию Python можно поставить через asdf/pyenv/conda и что-то еще. В школотронской Manjaro и даже в последних Ubuntu версия Python новее.

Данная утилита кроссплатформенна. Она гарантированно работает на Linux, Mac и Windows, в т. ч. WSL. При наличии рутованного телефона можно вытащить access и refresh токены из официального приложения и добавить их в конфиг.

Пример работы:

image

[!IMPORTANT] Когда зачанчиваются подходящие вакансии (это видно по логу), то клонируйте резюме и делайте его активным

[!NOTE] Утилита автоматически подхватывает прокси из переменных окружения типа http_proxy или HTTPS_PROXY


Предыстория

Долгое время я делал массовые заявки с помощью консоли браузера:

$$('[data-qa="vacancy-serp__vacancy_response"]').forEach((el) => el.click());

Оно работало, хоть и не идеально, например, при отклике на некоторые вакансии перебрасывало на другую страницу. Поэтому я пробовал автоматизировать рассылки через p[yu]ppeteer (ныне заменен playwright), пока не прочитал документацию, и не обнаружил, что API (интерфейс) содержит все необходимые мне методы. Headhunter позволял создавать свое приложение, но там была ручная модерация, а палиться в нарушении правил пользованием сайта (автоматические отклики запрещены) не хотелось. И тогда я декомпилировал официальное приложение для Android, получил CLIENT_ID и CLIENT_SECRET, необходимые для работы через API. Сейчас же утилита работает в гибридном режиме через API и веб-версию, так как ряд действий типа решения тестов можно выполнить только через сайт. Меня интересовала именно возможность рассылки со своего сервера, а для этого нужна работа через CLI, те какого-то графического фронтенда нет и не планируется, но никто не запрещает его вам написать.


Запуск через Docker

Это рекомендованный способ разработчиком. Если не работает стандартная установка, то используйте его. Так же это самый простой способ запуска и использования утилиты, требующий скопипастить 5 команд. Он подойдет обладателям выделенных серверов, используемых под VPN. Единственным недостатком использования docker является требовательность его к месту, так как для запуска хромиума, который используется при авторизации, нужно половину убунты поставить (более гига).

Для начала нужно установить docker и docker-compose:

sudo apt install docker.io docker-compose-v2

Выкачиваем репозиторий и переходим в каталог:

git clone https://github.com/s3rgeym/hh-applicant-tool
cd hh-applicant-tool

[!IMPORTANT] Команды с docker-compose нужно запускать строго, находясь в данном каталоге!

Теперь авторизуемся:

docker-compose run -u docker -it hh_applicant_tool \
  hh-applicant-tool -vv auth -k

Пример вывода:

👤 Введите email или телефон: your-mail@gmail.com
📨 Код был отправлен. Проверьте почту или SMS.
📩 Введите полученный код: 1234
🔓 Авторизация прошла успешно!

Авторизация с заданными логином и паролем выглядит так:

docker-compose run -u docker -it hh_applicant_tool \
  hh-applicant-tool -vv auth -k '<login>' -p '<password>'

Капча отобразится только в терминале с поддержкой протокола kitty, например, в Kitty, Ghostty или Konsole.

Если ваш терминал не поддерживает kitty protocol, то иожно попробовать использовать sixel protocol:

docker-compose run -u docker -it hh_applicant_tool \
  hh-applicant-tool -vv auth -s

Подробно про авторизацию можно почитать здесь.

В случае успешной авторизации можно запускать рассылку откликов по крону:

docker-compose up -d

Что будет делать?

  • Рассылать отклики со всех опубликованных резюме.
  • Поднимать резюме.

Просмотр логов cron:

docker compose logs -f

В выводе должно быть что-то типа:

hh_applicant_tool  | [Wed Jan 14 08:33:53 MSK 2026] Running startup tasks...
hh_applicant_tool  | ℹ️ Токен не истек, обновление не требуется.
hh_applicant_tool  |  Обновлено Программист

Чтобы прекратить просмотр логов, нажмите Ctrl-C.

Информацию об ошибках можно посмотреть в файле config/log.txt, а контакты работодателей — в config/data с помощью sqlite3. В config/config.json хранятся токены, дающие доступ к аккаунту.

Так же советую отредактировать файл letter.txt.

Запущенные сервисы докер стартуют автоматически после перезагрузки. Остановить их можно выполнив:

docker-compose down

Чтобы обновить утилиту в большинству случаев достаточно в каталоге выполнить:

git pull

В редких случаях нужно пересобрать все:

docker compose up -d --build

Чтобы рассылать отклики с нескольких аккаунтов, нужно переписать docker-compose.yml:

services:
  # Не меняем ничего тут
  hh_applicant_tool:
    # ...

  # Добавляем новые строки

  # Просто копипастим, меняя имя сервиса, container_name и значение HH_PROFILE_ID
  hh_second:
    extends: hh_applicant_tool
    container_name: hh_second
    environment:
      - HH_PROFILE_ID=second

  hh_third:
    extends: hh_applicant_tool
    container_name: hh_third
    environment:
      - HH_PROFILE_ID=third

  # Общий шаблон для новых профилей
  уникальное_имя_сервиса:
    extends: hh_applicant_tool
    # может совпадать с именем сервиса
    container_name: уникальное_имя_контейнера
    environment:
      - HH_PROFILE_ID=название_профиля

[!IMPORTANT] В этом файле важны отступы!

Обратите внимание на HH_PROFILE_ID — его значение указывается при авторизации, если профиль отличен от дефолтного. Далее нужно авторизоваться в каждом профиле:

# Авторизуемся со второго профиля
docker-compose exec -u docker -it hh_applicant_tool \
  hh-applicant-tool --profile-id second auth -k

# Авторизуемся с третьего профиля
docker-compose exec -u docker -it hh_applicant_tool \
  hh-applicant-tool --profile-id third auth -k

# И так далее

Ну и выполнить docker-compose up -d чтобы запустить новые сервисы.

Команды можно потестировать в запущенном контейнере:

$ docker-compose exec -u docker -it hh_applicant_tool bash
docker@1897bdd7c80b:/app$ hh-applicant-tool config -p
/app/config/config.json
docker@1897bdd7c80b:/app$ hh-applicant-tool refresh-token
ℹ️ Токен не истек, обновление не требуется.
docker@1897bdd7c80b:/app$

[!IMPORTANT] Обратите внимание, что docker-compose exec/docker-compose run запускаются с аргументами -u docker. Только для пользователя docker установлен chromium, необходимый для авторизации, а так же это избавляет от проблем с правами, когда созданные файлы для изменения требуют root-права.

Если хотите команду apply-vacancies вызывать с какими-то аргументами, то создайте в корне файл apply-vacancies.sh:

#!/bin/bash

# Пример с фильтрацией по исключаемым словам
/usr/local/bin/python -m hh_applicant_tool apply-vacancies \
  -l letter.txt \
  --excluded-filter "fullstack|junior|php" # укажите любые аргументы

В файлах startup.sh и crontab замените /usr/local/bin/python -m hh_applicant_tool apply-vacancies на /bin/sh /app/apply-vacancies.sh.


Стандартная установка

Установка утилиты

Универсальный способ с использованием pipx (требует пакета python-pipx в Arch):

# Полная версия с поддержкой авторизации, включает Node.js и различные утилиты
# Обычный пакет без [playwright] можно использовать на сервере, если перенести туда конфиг, и весит
# он почти на 500МБ меньше. Думаем (c) s3rgeym. Подписаться
$ pipx install 'hh-applicant-tool[playwright]'

# Чтобы выводить капчу через sixel нужен pillow
$ pipx install 'hh-applicant-tool[playwright,pillow]'

# Если хочется использовать самую последнюю версию, то можно установить ее через git
$ pipx install "git+https://github.com/s3rgeym/hh-applicant-tool"

# Для обновления до новой версии
$ pipx upgrade hh-applicant-tool

pipx добавляет исполняемый файл hh-applicant-tool в ~/.local/bin, делая эту команду доступной. Путь до ~/.local/bin должен быть в $PATH (в большинстве дистрибутивов он добавлен).

Традиционный способ для Linux/Mac:

mkdir -p ~/.venvs
python -m venv ~/.venvs/hh-applicant-tool
# Это придется делать постоянно, чтобы команда hh-applicant-tool стала доступна
.  ~/.venvs/hh-applicant-tool/bin/activate
pip install 'hh-applicant-tool[playwright]'

Отдельно я распишу процесс установки в Windows в подробностях:

  • Для начала поставьте последнюю версию Python 3 любым удобным способом.

  • Запустите PowerShell (не CMD.EXE, блять, а именно поверщель) от Администратора и выполните:

    Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted
    

    Данная политика разрешает текущему пользователю (от которого зашли) запускать скрипты. Без нее не будут работать виртуальные окружения.

Далее можно поставить pipx и вернуться к инструкции в верху раздела:

  • Все так же от администратора выполните:

    python -m pip install --user pipx
    

    А затем:

    python -m pipx ensurepath
    
  • Перезапускаем Terminal/Powershell и проверяем:

    pipx -h
    

С использованием вирт. окружений:

  • Создайте и активируйте виртуальное окружение:

    PS> python -m venv hh-applicant-venv
    PS> .\hh-applicant-venv\Scripts\activate
    
  • Поставьте все пакеты в виртуальное окружение hh-applicant-venv:

    (hh-applicant-venv) PS> pip install 'hh-applicant-tool[playwright]'
    
  • Проверьте, работает ли оно:

    (hh-applicant-venv) PS> hh-applicant-tool -h
    
  • В случае неудачи вернитесь к первому шагу.

  • Для последующих запусков сначала активируйте виртуальное окружение.

Дополнительные зависимости

После вышеописанного нужно установить зависимости в виде Chromium и др:

hh-applicant-tool install

Этот шаг необязателен. Все это нужно только для авторизации.


Авторизация

Прямая авторизация:

hh-applicant-tool authorize '<ваш телефон или email>' -p '<пароль>'

Если вы пропустили пункт про установку зависимостей, то увидите такую ошибку:

[E] BrowserType.launch: Executable doesn't exist at...

Если по какой-то причине не был установлен playwright:

[E] name 'async_playwright' is not defined

Если не помните пароль или др. причины, то можно авторизоваться с помощью одноразового кода:

$ hh-applicant-tool authorize '<ваш телефон или email>'
📨 Код был отправлен. Проверьте почту или SMS.
📩 Введите полученный код: 1387
🔓 Авторизация прошла успешно!

Если же при вводе правильных данных возникает ошибка авторизации, то, скорее всего, требуется ввод капчи.

Капчу можно ввести через терминал, если тот поддерживает kitty protocol (например, Kitty, Konsole, Ghostty и др):

hh-applicant-tool authorize --use-kitty
Untitled

Так же для вывода капчи можно использовать sixel protocol: --use-sixel/--sixel/-s. Это старый протокол, реализованный во множестве терминалов в Linux/BSD (MacOS). Он так же поддерживается в Windows Terminal, начиная с версии 1.22.

Из популярных современных терминалов вывод графики не поддерживает Alacritty.

Ручная авторизация с запуском встроенного браузера:

hh-applicant-tool authorize --manual

Проверка авторизации:

$ hh-applicant-tool whoami
🆔 27405918 Кузнецов Андрей Владимирович [ 📄 1 | 👁️ +115 | ✉️ +28 ]

В случае успешной авторизации токены будут сохранены в config.json.

При удачной авторизации логин (почта или телефон) и пароль, если последний был передан, запоминаются и будут подставляться автоматически, если не указать их явно.

Токен доступа выдается на две недели. Он обновляется автоматически. Для его ручного обновления нужно выполнить:

hh-applicant-tool refresh-token

Помните, что у refresh_token тоже есть время жизни, поэтому может потребоваться полная авторизация.


Описание команд

Примеры команд:

# Общий вид: сначала глобальные настройки, затем команда и её аргументы
$ hh-applicant-tool [options] <operation> [args]

# Справка по глобальным флагам и список операций
$ hh-applicant-tool -h

# Справка по операции
$ hh-applicant-tool authorize -h

# Авторизуемся
$ hh-applicant-tool authorize

# Авторизация с использованием другого профиля
$ hh-applicant-tool --profile profile123 authorize

# Рассылаем заявки
$ hh-applicant-tool apply-vacancies

# Для тестирования поисковой строки и других параметров, используйте --dry-run.
# С ним отклики не отправляются, а лишь выводятся сообщения
$ hh-applicant-tool -vv apply-vacancies --search "Python программист" --per-page 3 --total-pages 1 --dry-run

# Фильтруем вакансии по исключаемым словам (fullstack, junior, php и т.п.)
$ hh-applicant-tool apply-vacancies --search "Python backend" --excluded-filter "fullstack,junior,php,java" --dry-run

# Поднимаем резюме
$ hh-applicant-tool update-resumes

# Ответить работодателям
$ hh-applicant-tool reply-employers

# Просмотр лога в реальном времени
$ hh-applicant-tool log -f

# Посмотреть содержимое конфига
$ hh-applicant-tool config

# Редактировать конфиг в стандартном редакторе
$ hh-applicant-tool config -e

# Вывести значение из конфига
$ hh-applicant-tool config -k token.access_token

# Установить значение в конфиге, например, socks-прокси
$ hh-applicant-tool config -s proxy_url socks5h://localhost:1080

# Удалить значение из конфига
$ hh-applicant-tool config -u proxy_url

# Утилита все данные об откликах хранит в SQLite
$ hh-applicant-tool query 'select count(*) from vacancy_contacts;'
+----------+
| count(*) |
+----------+
|    42    |
+----------+

# Экспорт контактов в csv
$ hh-applicant-tool query 'select * from vacancy_contacts' --csv -o
contacts.csv

# Выполнение запросов в интерактивном режиме
$ hh-applicant-tool query

# Чистим отказы
$ hh-applicant-tool clear-negotiations

# При обновлении может сломаться схема БД, для ее починки нужно выполнить
# поочерёдно все миграции, добавленные после выхода последней версии
$ hh-applicant-tool migrate
List of migrations:

  [1]: 2026-01-07

Choose migration [1] (Keep empty to exit): 1 Success!

# Вывести все настройки
$ hh-applicant-tool settings
+----------+-------------------------+-------------------------+
| Тип      | Ключ                    | Значение                |
+----------+-------------------------+-------------------------+
| str      | user.email              | dmitry.kozlov@yandex.ru |
+----------+-------------------------+-------------------------+

# Получить значение по ключу
$ hh-applicant-tool settings auth.username

# Установить email, используемый для автологина
$ hh-applicant-tool settings auth.username 'user@example.com'

Глобальные настройки:

  • -v используется для вывода отладочной информации. Два таких флага, например, выводят запросы к API.
  • -c <path> путь до каталога, где хранятся конфигурации.
  • --profile <profile-id> можно указать профиль, данные которого будут храниться в подкаталоге.
Операция Описание
authorize, auth Авторизация на hh.ru. Введенные логин и пароль "запоминаются" и будут использованы при следующем вызове команды.
logout Выйти из профиля (отозвать токен)
whoami, id Выводит информацию об авторизованном пользователе
list-resumes, list, ls Список резюме
update-resumes, update Обновить все резюме. Аналогично нажатию кнопки «Обновить дату».
clone-resume Клонировать резюме
apply-vacancies, apply Откликнуться на подходящие вакансии. Если указана строка для поиска (--search), то поиск будет произведен по вакансиям, иначе по списку рекомендованных вакансий. Лимит = 200 в день. На HH есть спам-фильтры, так что лучше не рассылайте отклики со ссылками, иначе рискуете попасть в теневой бан.
reply-employers, reply Ответить во все чаты с работодателями, где нет ответа либо не прочитали ваш предыдущий ответ
clear-negotiations Отмена откликов
call-api, api Вызов произвольного метода API с выводом результата.
refresh-token, refresh Обновляет access_token.
config Показывает содержимое конфига. С флагом -e открывает его для редактирования.
settings Просмотр и управление настройками в базе данных. Простое key-value хранилище.
install Устанавливает зависимости, такие как браузер Chromium, необходимые для авторизации.
uninstall Удаляет браузер Chromium, используемый для авторизации.
check-proxy Проверяет используемые прокси
migrate Починить базу
query Выполнение SQL-запросов к базе. Схема БД находится в файле schema.sql. Если скормить ее DeepSeek, то он поможет написать любой запрос.
log Просмотр файла-лога. С флагом -f будет следить за изменениями. В логах частично скрыты идентефикаторы в целях безопасности.

[!IMPORTANT] Почитайте про язык для поисковых запросов. Он позволяет отсеивать мусор при поиске подходящих вакансий, например, (Go OR Golang) NOT PHP NOT JavaScript.

Утилита использует систему плагинов. Все они лежат в operations. Модули, расположенные там, автоматически добавляются как доступные команды. За основу для своего плагина можно взять whoami.py.

Для тестирования запросов к API используйте команду call-api совместно с jq для обработки JSON.

Пример поиска работодателей:

$ hh-applicant-tool call-api /employers text="IT" only_with_vacancies=true | jq -r '.items[].alternate_url'
https://hh.ru/employer/1966364
https://hh.ru/employer/4679771
...

Синтаксис call-api немного похож на httpie или curlie:

hh-applicant-tool call-api [-m {GET|POST|PUT|DELETE}] <endpoint> [<key=value> ...]

Если используется метод GET или DELETE (или ничего не указано), то параметры будут переданы как query string. Во всех остальных случаях парметры передаются как application/x-www-form-urlencoded в теле запроса.

Для поиска вакансий по региону в apply-vacancies нужно указать параметр area. Можно его указывать как для страны (каз - 40, бел - 2238), так и отдельного города (мск - 1).

Список area id по стране:

hh-applicant-tool -vv api /areas | jq -r '.[] | select(.name == "Беларусь")'

Документация для работы с API соискателей была удалена с ха-ха.сру и его корпоративного репозитория. Можете не искать, они затерли даже историю репозитория. Но я через веб-архив выкачал документацию. Чтобы ее посмотреть, клонируйте этот репозиторий и откройте файл ./docs/hhapi/openapi.yml, например, с помощью Swagger Viewer.

image

Так же существуют cli-утилиты:

sudo pacman -S openapi-tui

openapi-tui --input docs/hhapi/openapi.yml

Для тех кто любит просматривать документацию в браузере:

npx @redocly/cli preview -d docs/hhapi

Потом нужно открыть в браузере http://localhost:4000.

[!NOTE] Отдельные замечания у меня к API HH. Оно пиздец какое кривое. Например, при создании заявки возвращается пустой ответ либо редирект, хотя по логике должен возвращаться созданный объект. Так же в ответах сервера нет Content-Length. Из-за этого нельзя узнать, есть ли тело у ответа сервера, нужно его пробовать прочитать. Я так понял, там какой-то прокси оборачивает все запросы и отдает всегда Transfer-Encoding: Chunked. А еще он возвращает 502 ошибку, когда бэкенд на Java падает либо долго отвечает (таймаут). По сути, никакие дополнительные команды, кроме имеющихся, не нужны. Вы можете сделать что угодно с помощью call-api, но если хочется чего-то особенного, можно добавить свои команды.


Использование AI

Для генерации опроводительных писем при откликах и ответа в чаты работодателей (reply-employers) можно использовать OpenAI (ChatGPT).

Пример рассылки откликов с генерированным письмом:

hh-applicant-tool apply-vacancies -f --ai

Генерацию сопроводительных писем в откликах я считаю лишним, так как их никто не читает. Экономнее воспользоваться шаблонами сообщений.


OpenAI/ChatGPT

Отредактируйте конфиг:

hh-applicant-tool config -e

Добавьте в него эти строки:

{
  "openai": {
    "token": "ВАШ_API_КЛЮЧ_OPENAI",
    "model": "ВАША_МОДЕЛЬ",
    // Это дефолтные значения, которые можно переопределить
    "temperature": 0.7,
    "max_completion_tokens": 1000,
    // Вместо ChatGPT можно использовать другие сервисы
    // Учтите, что при исп-ии Docker нужно указывать 192.168... вместо localhost
    "completion_endpoint": "http://localhost:3000..."
  }
}

Шаблоны сообщений

Команды apply-vacancies и reply-employers поддерживают специальный формат сообщений.

Так же в сообщении можно использовать плейсхолдеры:

  • %(vacancy_name)s: Название вакансии.
  • %(employer_name)s: Название работодателя.
  • %(first_name)s: Имя пользователя.
  • %(last_name)s: Фамилия пользователя.
  • %(email)s: Email пользователя.
  • %(phone)s: Телефон пользователя.
  • %(resume_title)s: Название резюме.
  • %(resume_hash)s: Идентификатор резюме.
  • %(resume_url)s: Ссылка на резюме.

Эти плейсхолдеры могут быть использованы в сообщениях для отклика на вакансии, чтобы динамически подставлять соответствующие данные в текст сообщения. Например:

Меня заинтересовала ваша вакансия %(vacancy_name)s. Прошу рассмотреть мою кандидатуру. С уважением, %(first_name)s %(last_name)s.

Так же можно делать текст уникальным с помощью {}. Внутри них через | перечисляются варианты, один из которых будет случайно выбран:

Увольте того {идиота|придурка}, который придумал этот {тупой|сраный|дурацкий} вопрос.

В итоге получится что-то вроде:

Увольте того идиота, который придумал этот сраный вопрос.

{} могут быть вложенными.


Данные приложения

Данные приложения хранятся по следующим путям:

OS Путь
Windows C:\Users\%username%\AppData\Roaming\hh-applicant-tool\
macOS ~/Library/Application Support/hh-applicant-tool/
Linux ~/.config/hh-applicant-tool/

Конфигурационный файл

Главный конфиг называется config.json. Он содержит токены. Полный путь до конфигурационного файла можно вывести с помощью команды:

hh-applicant-tool config -p

Через конфиг можно задать дополнительные настройки:

Имя атрибута Описание
proxy_url Прокси, используемый для всех запросов, например, socks5h://localhost:1080
api_delay Минимальная между отправкой запросов к API HH
reply_message Сообщение для ответа работодателю при отклике на вакансии, см. формат сообщений
vacancy_test_answer Ответ на вопрос из теста. Можно использовать синтаксис шаблонов.
user_agent Кастомный юзерагент, передаваемый при каждом запросе. По умолчанию используется от Android
client_id Идентификатор клиента, используемый для авторизации. По умолчанию используется от Android
client_secret Секретный ключ клиента, используемый для авторизации. По умолчанию используется от Android

Если вы залогинитесь под другим аккаунтом, то данные не исчезнут.

При использовании профиля, отличного от дефолтного, данные хранятся в подкаталоге.

Логи

В log.txt всегда можно посмотреть подробную информацию об ошибках. В целях безопасности токены, идентефикаторы резюме и тп затираются.

База данных

Данные о работодателях и их вакансиях хранятся в файле data. Это обычная база sqlite3, вы ее можете просматривать через DB Browser и т. п.

Что хранится в базе:

  • все просмотренные вакансии;
  • профили работодателей;
  • контакты работодателей;
  • данные об откликах;
  • иные данные, важные для работы.

cookies.txt

В cookies.txt хранятся куки, установленные при авторизации на сайте. Они нужны для решения тестов при отклике на вакансию. Не редактируйте этот файл вручную.


Отправка писем при отклике

Для рассылки писем на почту рекрутера используйте флаг --send-email добавьте в конфиг:

{
  "smtp": {
    "host": "smtp.yandex.ru",
    "port": 465,
    "user": "your_login@yandex.ru",
    "password": "your_app_password",
    "ssl": true,
    "from": "Иван Иванов <your_login@yandex.ru>"
  },
  "apply_mail_subject": "{Отклик|Резюме} на вакансию %(vacancy_name)s",
  "apply_mail_body": "{Здравствуйте|Добрый день}!\n\nМеня заинтересовала ваша вакансия %(vacancy_name)s.\nМое резюме: %(resume_url)s\n\nС уважением, %(first_name)s."
}

Использование в скриптах

Если хотите использовать hh-applicant-tool в своих скриптах, то можно это сделать так:

from hh_applicant_tool import HHApplicantTool

tool = HHApplicantTool([
    # Передаем глобальные настройки как обычно
    "--proxy-url", "socks5://localhost:1080",
    "--config-path", "/path/to/config"
])

print(tool.api_client.get('/me'))

# Какую-то вспомогательную информацию можно сохранять в настройках
import datetime as dt

tool.storage.settings.set_value("_last_script_run", dt.datetime.now())

# Учтите что в таком случае токены, которые могут обновиться при выполнении запросов,
# нужно сохранять вручную
tool.save_token()

Команды тоже можно вызывать:

>>> from hh_applicant_tool import HHApplicantTool
>>> HHApplicantTool(['authorize', 'your-email@gmail.com']).run()
📨 Код был отправлен. Проверьте почту или SMS.
📩 Введите полученный код:

Дополнительные настройки

Отключение проверки версии с выводом предупреждения:

hh-applicant-tool settings disable_version_check true

Связанные проекты


Лицензионное соглашение (Limited Non-Commercial License)

Данное программное обеспечение распространяется на условиях ограниченной некоммерческой лицензии.

  • Разрешённое использование

    • Личное использование и изучение: Разрешается копирование и модификация кода исключительно для личного ознакомления, обучения и отладки без права публикации или распространения изменений.
    • Интеграция в программное обеспечение: Разрешается включение данного кода в состав сторонних бесплатных некоммерческих продуктов только при полном сохранении исходного кода в неизменном виде.
    • Атрибуция: Любое распространение, демонстрация или использование кода (в том числе в составе других продуктов) допускается только при обязательном указании автора и ссылки на оригинальный репозиторий.
  • Ограничения на использование Строго запрещается использование данного кода в любых коммерческих целях без предварительного письменного согласия автора, включая, но не ограничиваясь:

    • Интеграцией в платные сервисы, приложения, веб-сайты либо использованием в рамках оказания платных услуг.
    • Публикацией, распространением или передачей третьим лицам модифицированных (изменённых) версий кода.
    • Перепродажей, сублицензированием либо использованием кода в интересах коммерческих организаций.
  • Отказ от ответственности Программное обеспечение предоставляется по принципу «как есть» (AS IS). Автор не несёт ответственности за любые прямые или косвенные убытки, включая, но не ограничиваясь, блокировкой аккаунтов, потерей данных или иными негативными последствиями, возникшими в результате использования данного программного обеспечения.

© 2023-2026 Sergey M. Все права защищены.

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hh_applicant_tool-1.8.0.tar.gz (90.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hh_applicant_tool-1.8.0-py3-none-any.whl (100.9 kB view details)

Uploaded Python 3

File details

Details for the file hh_applicant_tool-1.8.0.tar.gz.

File metadata

  • Download URL: hh_applicant_tool-1.8.0.tar.gz
  • Upload date:
  • Size: 90.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.2 CPython/3.11.0 Linux/6.14.0-1017-azure

File hashes

Hashes for hh_applicant_tool-1.8.0.tar.gz
Algorithm Hash digest
SHA256 f3d68e04af01e3898bc965049e26cf12a9099b55c3fc15dc9d4cde86961d744b
MD5 7e4c5915a26842e9f01fff413fedd6b3
BLAKE2b-256 c9c6fe561e62c6896620a91472b91f630c7378acdd939cbb95d92d54279803c3

See more details on using hashes here.

File details

Details for the file hh_applicant_tool-1.8.0-py3-none-any.whl.

File metadata

  • Download URL: hh_applicant_tool-1.8.0-py3-none-any.whl
  • Upload date:
  • Size: 100.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.2 CPython/3.11.0 Linux/6.14.0-1017-azure

File hashes

Hashes for hh_applicant_tool-1.8.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c0fe017bdf8662fcacda01ae73244fbaf862f477aac2637c453e1f82ed59ebda
MD5 7ac02220073c0572ba39308640b765bc
BLAKE2b-256 50ff875d0b9603cc45ebb03d28c743edf323793c8c9b80b95e6360f00138d503

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page