[]() []() []() []() []()
Утилита для успешных волчат, служащая для автоматизации действий на HH.RU таких как рассылка откликов на подходящие вакансии и обновление всех резюме. Поддержка осуществляется строго в группе https://t.me/+aSjr8qM_AP85ZDBi (в ней разрешены мат, п*рнография, оскорбления всех участников кроме админа, а так же слив любой информации про хуевых работодателей и нерадивых херок).
Работает с Python >= 3.10. Нужную версию Python можно поставить через asdf/pyenv/conda и что-то еще...
Данная утилита написана для Linux, но будет работать и на Ga..Mac OS, и в Windows, но с WSL не будет, так как для авторизации требуются оконный сервер X11 либо Wayland — только прямая установка пакета через pip в Windows. После авторизации вы можете перенести конфиг на сервер и запускать утилиту через systemd или cron. Столь странный процесс связан с тем, что на странице авторизации запускается море скриптов, которые шифруют данные на клиенте перед отправкой на сервер, а так же выполняется куча запросов чтобы проверить не бот ли ты. Хорошо, что после авторизации никаких проверок по факту нет, даже айпи не проверяется на соответсвие тому с какого была авторизация. В этой лапше мне лень разбираться. Так же при наличии рутованного телефона можно вытащить access
и refresh
токены из официального приложения и добавить их в конфиг.
Пример работы:
Был один знакомый знакомого, который работал хрюшей. Этот чувак не заморачивался с чтением резюме, а тупо скриптами рассылал предложения о работе... Бывают, конечно, филологини, которые не могут отличить Java от JavaScript, но я думаю, что в значительном числе случаев, тут имеют место такие вот рассылки они просто идиотки... И я тупо стал спамить как они. Мне уже было просто лень читать весь этот бред, что пишут долбоебы в описании вакансий. Там стандартное ООП, алгоритмы и прочая хуета... Вроде все подходят, а вроде хз — все не мое.
Долгое время я делал массовые заявки с помощью консоли браузера:
$$('[data-qa="vacancy-serp__vacancy_response"]').forEach((el) => el.click());
Оно работает, хоть и не идеально. Я даже пробовал автоматизировать рассылки через p[yu]ppeeter
, пока не прочитал документацию. И не обнаружил, что API (интерфейс) содержит все необходимые мне методы. Headhunter позволяет создать свое приложение, но там ручная модерация, и наврядли кто-то разрешит мне создать приложение для спама заявками. Я декомпилировал официальное приложение для Android и получил CLIENT_ID и CLIENT_SECRET, необходимые для работы через API.
# Версия с поддержкой авторизации через запуск окна с браузером (эта версия очень много весит)
# Можно использовать обычный pip
$ pipx install 'hh-applicant-tool[qt]'
# Если хочется использовать самую последнюю версию, то можно установить ее через git
$ pipx install git+https://github.com/s3rgeym/hh-applicant-tool
# Для обновления до новой версии
$ pipx upgrade hh-applicant-tool
Отдельно я распишу процесс установки в Windows в подробностях:
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted
Данная политика разрешает текущему пользователю (от которого зашли) запускать скрипты. Без нее не будут работать виртуальные окружения.
PS> python -m pip venv hh-applicant-venv
PS> .\hh-applicant-venv\Scripts\activate
hh-applicant-venv
:
(hh-applicant-venv) PS> pip install hh-applicant-tool[qt]
(hh-applicant-venv) PS> hh-applicant-tool -h
$ hh-applicant-tool -vv authorize
В Windows не забудьте разрешить доступ к сети (Allow access) в всплывающем окне.
Проверка авторизации:
$ hh-applicant-tool whoami
{
"auth_type": "applicant",
"counters": {
"new_resume_views": 1488,
"resumes_count": 1,
"unread_negotiations": 228
},
"email": "vasya.pupkin@gmail.com",
"employer": null,
"first_name": "Вася",
"id": "1234567890",
"is_admin": false,
"is_anonymous": false,
"is_applicant": true,
"is_application": false,
"is_employer": false,
"is_in_search": true,
"last_name": "Пупкин",
"manager": null,
"mid_name": null,
"middle_name": null,
"negotiations_url": "https://api.hh.ru/negotiations",
"personal_manager": null,
"phone": "79012345678",
"profile_videos": {
"items": []
},
"resumes_url": "https://api.hh.ru/resumes/mine"
}
В случае успешной авторизации токены будут сохранены в config.json
:
{
"token": {
"access_token": "...",
"created_at": 1678151427,
"expires_in": 1209599,
"refresh_token": "...",
"token_type": "bearer"
}
}
Токен доступа выдается на две недели. После его нужно обновить:
$ hh-applicant-tool refresh-token
OS | Путь |
---|---|
Windows | C:\Users\%username%\AppData\Roaming\hh-applicant-tool\config.json |
macOS | ~/Library/Application Support/hh-applicant-tool/config.json |
Linux | ~/.config/hh-applicant-tool/config.json |
Через конфиг можно задать дополнительные настройки:
Имя атрибута | Описание |
---|---|
user_agent |
Кастомный юзерагент, передаваемый при кажом запросе, например, Mozilla/5.0 YablanBrowser |
proxy_url |
Прокси, используемый для всех запросов, например, socks5h://127.0.0.1:9050 |
reply_message |
Сообщение для ответа работодателю при отклике на вакансии, см. формат сообщений |
$ hh-applicant-tool [ GLOBAL_FLAGS ] [ OPERATION [ OPERATION_FLAGS ] ]
# Справка по глобальным флагам и список операций
$ hh-applicant-tool -h
# Справка по операции
$ hh-applicant-tool apply-similar -h
# Авторизуемся
$ hh-applicant-tool authorize
# Рассылаем заявки
$ hh-applicant-tool apply-similar
# Поднимаем резюме
$ hh-applicant-tool update-resumes
# Чистим заявки и баним за отказы говноконторы
$ hh-applicant-tool clear-negotiations --blacklist-discard
Можно вызвать любой метод API:
$ 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
https://hh.ru/employer/8932785
https://hh.ru/employer/9451699
https://hh.ru/employer/766478
https://hh.ru/employer/4168187
https://hh.ru/employer/9274777
https://hh.ru/employer/1763330
https://hh.ru/employer/5926815
https://hh.ru/employer/1592535
https://hh.ru/employer/9627641
https://hh.ru/employer/4073857
https://hh.ru/employer/2667859
https://hh.ru/employer/4053700
https://hh.ru/employer/5190600
https://hh.ru/employer/607484
https://hh.ru/employer/9386615
https://hh.ru/employer/80660
https://hh.ru/employer/6078902
https://hh.ru/employer/1918903
Данная возможность полезна для написания Bash-скриптов.
Глобальные флаги:
-v
используется для вывода отладочной информации. Два таких флага, например, выводят запросы к API.-c <path>
можно создать путь до конфига. С помощью этого флага можно одновременно использовать несколько профилей.Операция | Описание |
---|---|
authorize | Открывает сайт hh.ru для авторизации и перехватывает перенаправление на hhadnroid://oauthresponse |
whoami | Выводит информацию об авторизованном пользователе |
list-resumes | Список резюме |
update-resumes | Обновить все резюме. Аналогично нажатию кнопки «Обновить дату». |
apply-similar | Откликнуться на все подходящие вакансии. Лимит = 200 в день. На HH есть спам-фильтры, так что лучше не рассылайте отклики со ссылками. |
reply-employers | Ответить во все чаты с работодателями, где нет ответа либо не прочитали ваш предыдущий ответ |
clear-negotiations | Удаляет отказы и отменяет заявки, которые долго висят |
call-api | Вызов произвольного метода API с выводом результата. |
refresh-token | Обновляет access_token. |
get-employer-contacts | Получить список контактов работодателя, даже если тот не высылал приглашения. Контакты получаются строго из публичного доступа, например, с сайта фирмы и могут быть удалены только по просьбе уполнамоченного лица. Данная функция готова и будет доступна после 100 ⭐ |
Команда apply-similar
поддерживает специальный формат сообщений.
Так же в сообщении можно использовать плейсхолдеры:
%(vacancy_name)s
: Название вакансии.%(employer_name)s
: Название работодателя.%(first_name)s
: Имя пользователя.%(last_name)s
: Фамилия пользователя.%(email)s
: Email пользователя.%(phone)s
: Телефон пользователя.Эти плейсхолдеры могут быть использованы в сообщениях для отклика на вакансии, чтобы динамически подставлять соответствующие данные в текст сообщения. Например:
Меня заинтересовала ваша вакансия %(vacancy_name)s. Прошу рассмотреть мою кандидатуру. С уважением, %(first_name)s %(last_name)s.
Так же можно делать текст уникальным с помощью {}
. Внутри них через |
перечисляются варианты, один из которых будет случайно выбран:
{Здоров|Привет}, {как {ты|сам}|что делаешь}?
В итоге получится что-то типа:
Привет, как ты?
Утилита использует систему плагинов. Все они лежат в operations. Модули расположенные там автоматически добавляются как доступные операции. За основу для своего плагина можно взять whoami.py.
Отдельные замечания у меня к API HH. Оно пиздец какое кривое. Например, при создании заявки возвращается пустой ответ либо редирект, хотя по логике должен возвраться созданный объект. Так же в ответах сервера нет Content-Length
. Из-за этого нельзя узнать есть тело у ответа сервера нужно его пробовать прочитать. Я так понял там какой-то прокси оборачивает все запросы и отдает всегда Transfer-Encoding: Chunked
. А еще он возвращает 502 ошибку, когда бекенд на Java падает либо долго отвечает (таймаут)? А вот язык запросов мне понравился. Можно что-то типа этого использовать NOT (!ID:123 OR !ID:456 OR !ID:789)
что бы отсеить какие-то вакансии.
Для создания своих плагинов прочитайте документацию:
Для тестирования запросов к API используйте команду call-api
и jq
для вывода JSON в удобочитаемом формате.
Сбор и передачу данных о вакансиях и работодателях можно отключить, но так никакие персональные данные пользователя не передаются, то можно ничего не менять. Так как утилита бесплатна, то передачу вышеуказанной телеметрии можете рассматривать как плату за пользование.
Утилита по умолчанию собирает и передает на сервер разработчика следующие данные: