No project description provided
Project description
HH Applicant Tool
Утилита для автоматизации действий на HH таких как отклик на подходящие вакансии.
Системные требования:
- socat
- python >= 3.10
Нужную версию можно поставить через asdf/pyenv, а вот socat придется доставить.
Данная утилита не может работать от root. Я не планирую добавлять поддержку Windows, но никто не мешает вам ее реализовать.
Предыстория.
Был один знакомый знакомого, который работал хером. Этот чувак не заморачивался с чтением резюме, а тупо скриптами рассылал предложения о работе... Бывают, конечно, филологини, которые не могут отлчить Java от JavaScript, но я думаю, что в значительном числе случаев, тут имеют место такие вот рассылки... И я просто перенял эту порочную практику. Мне уже просто лень читать весь этот бред, что пишут в описании вакансий. Там стандартное ООП, алгоритмы и прочая хуета... Вроде все подходят, а вроде хз — все не мое. Поэтому тупло спамлю в надежде на идеальную работу. Долгое время (пару недель в октябре 2022) я делал массовые заявки с помощью консоли браузера:
$$('[data-qa="vacancy-serp__vacancy_response"]').forEach((el) => el.click());
И оно работает, хоть и не идеально. Я даже пробовал автоматизировать рассылки через p[yu]ppeeter
, пока не прочитал документацию. И не обнаружил, что он (интерфейс) содержит все необходимые мне методы. Headhunter позволяет создать свое приложение, но там ручная модерация, и наврядли кто-то разрешит мне создать приложение для спама заявками. Я декомпилировал официальное приложение для Android и получил CLIENT_ID и CLIENT_SECRET, необходимые для работы через API.
Установка:
# Через pypi
# Можно использовать и обычный pip
$ pipx install hh-applicant-tool
# Если хочется использовать самую последнюю версию, то можно установить ее через git
$ pipx install git+https://github.com/s3rgeym/hh-applicant-tool
Использование
$ hh-applicant-tool -h
$ hh-applicant-tool OPERATION
Операция | Описание |
---|---|
add-handler | Добавляет обработчик протокола hhandroid |
authorize | Открывает сайт hh.ru для авторизации и перехваетывает перенаправление на hhadnroid://oauthresponse |
whoami | Выводит информацию об авторизованном пользователе |
list-resume | Список резюме |
update-resumes | Обновить все резюме. Аналогично нажатию кнопки «Обновить дату». |
apply-similar | Откликнуться на все подходящие вакансии. Лимит=200 в день, если приходит отказ, то можно дальше спамить заявками |
clear-negotiations | Удаляет отказы и отменяет заявки, которые долго висят |
Для начала нужно добавить обработчик протокола hhandroid
, который используется Android-приложением для усложнения жизни честным автоматизаторам:
$ hh-applicant-tool -vv add-handler
[I] saved /home/sergey/.local/share/applications/hhandroid.desktop
✅ Обработчик добавлен!
Флаг -v
используется для вывода отладочной информации. Два таких флага, например, выводят запросы к API.
Авторизуемся:
$ hh_applicant_tool -vv authorize
Пробуем открыть в браузере: https://hh.ru/oauth/authorize?client_id=HIOMIAS39CA9DICTA7JIO64LQKQJF5AGIK74G9ITJKLNEDAOH5FHS5G1JI7FOEGD&response_type=code
Авторизуйтесь и нажмите <Подтвердить>
[I] 🚀 Стартуем TCP-сервер по адресу unix:///tmp/hhandroid.sock
Gtk-Message: 20:52:59.280: Failed to load module "canberra-gtk-module"
Gtk-Message: 20:52:59.975: Failed to load module "canberra-gtk-module"
[54:54:0305/205300.038812:ERROR:gl_factory.cc(128)] Requested GL implementation (gl=desktop-gl,angle=none) not found in allowed implementations: [(gl=egl-angle,angle=default),(gl=egl-gles2,angle=none),(gl=egl-angle,angle=swiftshader)].
[54:54:0305/205300.041723:ERROR:viz_main_impl.cc(186)] Exiting GPU process due to errors during initialization
Opening in existing browser session.
[D] hhandroid://oauthresponse?code=99Q9G1RII75D8R2FTU06BF2FDNI7JF16MGBIB4OEQ973819OOJI90S69I1CL9U96
[D] 200 POST https://hh.ru/oauth/token
[D] Сохраняем токен
🔓 Авторизация прошла успешно!
Тут надо выбирать Open xdg-open
.
После смотрим в консоль и если видим сообщение об успехе, закрываем вкладку.
В случае успешной авторизации токены будут сохранены ~/.config/hh-applicant-tool/config.json
:
{
"token": {
"access_token": "...",
"created_at": 1678151427,
"expires_in": 1209599,
"refresh_token": "...",
"token_type": "bearer"
}
}
При авторизации можно указать redirect_uri
, но любые адреса кроме того, что с протоколом hhandroid
, будут приводить к ошибке. Поэтому и нужно добавление обработчика кастомного протокола. При котором создается desktop-файл, где в секции Exec
всего пару команд для того чтобы записать полученный uri в сокет. TCP-сервер, который запускается при авторизации, как раз слушает этот сокет... Использование АВТОРИЗАЦИИ ДЛЯ САЙТОВ в мобильном приложении выглядит странной, так как десктопные и мобильные приложения обычно авторизуются напрямую, но у чуваков свое понимание не только протокола OAuth...
Проверка авторизации:
$ 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"
}
Полное удаление:
rm -rf ~/.config/hh-applicant-tool
rm -f ~/.local/share/applications/hhandroid.desktop
Утилита использует систему плагинов. Все они лежат в operations. Модули расположенные там автоматически добавляются как доступные операции. За основу для своего плагина можно взять whoami.py.
Отдельные замечания у меня к API HH. Оно пиздец какое кривое. Например, при создании заявки возвращается пустой ответ либо редирект, хотя по логике должен возвраться созданный объект. Так же в ответах сервера нет Content-Length
. Из-за этого нельзя узнать есть тело у ответа сервера нужно его пробовать прочитать. Я так понял там какой-то прокси оборачивает все запросы и отдает всегда Transfer-Encoding: Chunked
. А еще он возвращает 502 ошибку, когда бекенд на Java падает либо долго отвечает (таймаут)? А вот язык запросов мне понравился. Можно что-то типа этого использовать NOT (!ID:123 OR !ID:456 OR !ID:789)
что бы отсеить какие-то вакансии.
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
Built Distribution
Hashes for hh_applicant_tool-0.1.3-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | edd0bd7772b7a5527c3062efe80e57b3ea86a3eab3709348cdb08a4380eeb59d |
|
MD5 | 489c309c1da6a277462338c1f2b1e66b |
|
BLAKE2b-256 | 924000c21c60a7623851b325432d0197cad0fbfd8de7f2a41c98c9242b4b1962 |