hh-applicant-tool 0.6.12__py3-none-any.whl → 1.4.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hh_applicant_tool/__init__.py +1 -0
- hh_applicant_tool/__main__.py +1 -1
- hh_applicant_tool/ai/base.py +2 -0
- hh_applicant_tool/ai/openai.py +24 -30
- hh_applicant_tool/api/client.py +82 -98
- hh_applicant_tool/api/errors.py +57 -8
- hh_applicant_tool/constants.py +0 -3
- hh_applicant_tool/datatypes.py +291 -0
- hh_applicant_tool/main.py +236 -82
- hh_applicant_tool/operations/apply_similar.py +268 -348
- hh_applicant_tool/operations/authorize.py +245 -70
- hh_applicant_tool/operations/call_api.py +18 -8
- hh_applicant_tool/operations/check_negotiations.py +102 -0
- hh_applicant_tool/operations/check_proxy.py +30 -0
- hh_applicant_tool/operations/config.py +119 -18
- hh_applicant_tool/operations/install.py +34 -0
- hh_applicant_tool/operations/list_resumes.py +24 -10
- hh_applicant_tool/operations/log.py +77 -0
- hh_applicant_tool/operations/migrate_db.py +65 -0
- hh_applicant_tool/operations/query.py +120 -0
- hh_applicant_tool/operations/refresh_token.py +14 -13
- hh_applicant_tool/operations/reply_employers.py +148 -167
- hh_applicant_tool/operations/settings.py +95 -0
- hh_applicant_tool/operations/uninstall.py +26 -0
- hh_applicant_tool/operations/update_resumes.py +21 -10
- hh_applicant_tool/operations/whoami.py +40 -7
- hh_applicant_tool/storage/__init__.py +4 -0
- hh_applicant_tool/storage/facade.py +24 -0
- hh_applicant_tool/storage/models/__init__.py +0 -0
- hh_applicant_tool/storage/models/base.py +169 -0
- hh_applicant_tool/storage/models/contact.py +16 -0
- hh_applicant_tool/storage/models/employer.py +12 -0
- hh_applicant_tool/storage/models/negotiation.py +16 -0
- hh_applicant_tool/storage/models/resume.py +19 -0
- hh_applicant_tool/storage/models/setting.py +6 -0
- hh_applicant_tool/storage/models/vacancy.py +36 -0
- hh_applicant_tool/storage/queries/migrations/.gitkeep +0 -0
- hh_applicant_tool/storage/queries/schema.sql +119 -0
- hh_applicant_tool/storage/repositories/__init__.py +0 -0
- hh_applicant_tool/storage/repositories/base.py +176 -0
- hh_applicant_tool/storage/repositories/contacts.py +19 -0
- hh_applicant_tool/storage/repositories/employers.py +13 -0
- hh_applicant_tool/storage/repositories/negotiations.py +12 -0
- hh_applicant_tool/storage/repositories/resumes.py +14 -0
- hh_applicant_tool/storage/repositories/settings.py +34 -0
- hh_applicant_tool/storage/repositories/vacancies.py +8 -0
- hh_applicant_tool/storage/utils.py +49 -0
- hh_applicant_tool/utils/__init__.py +31 -0
- hh_applicant_tool/utils/attrdict.py +6 -0
- hh_applicant_tool/utils/binpack.py +167 -0
- hh_applicant_tool/utils/config.py +55 -0
- hh_applicant_tool/utils/dateutil.py +19 -0
- hh_applicant_tool/{jsonc.py → utils/jsonc.py} +12 -6
- hh_applicant_tool/utils/jsonutil.py +61 -0
- hh_applicant_tool/utils/log.py +144 -0
- hh_applicant_tool/utils/misc.py +12 -0
- hh_applicant_tool/utils/mixins.py +220 -0
- hh_applicant_tool/utils/string.py +27 -0
- hh_applicant_tool/utils/terminal.py +19 -0
- hh_applicant_tool/utils/user_agent.py +17 -0
- hh_applicant_tool-1.4.7.dist-info/METADATA +628 -0
- hh_applicant_tool-1.4.7.dist-info/RECORD +67 -0
- hh_applicant_tool/ai/blackbox.py +0 -55
- hh_applicant_tool/color_log.py +0 -35
- hh_applicant_tool/mixins.py +0 -13
- hh_applicant_tool/operations/clear_negotiations.py +0 -113
- hh_applicant_tool/operations/delete_telemetry.py +0 -30
- hh_applicant_tool/operations/get_employer_contacts.py +0 -293
- hh_applicant_tool/telemetry_client.py +0 -106
- hh_applicant_tool/types.py +0 -45
- hh_applicant_tool/utils.py +0 -104
- hh_applicant_tool-0.6.12.dist-info/METADATA +0 -349
- hh_applicant_tool-0.6.12.dist-info/RECORD +0 -33
- {hh_applicant_tool-0.6.12.dist-info → hh_applicant_tool-1.4.7.dist-info}/WHEEL +0 -0
- {hh_applicant_tool-0.6.12.dist-info → hh_applicant_tool-1.4.7.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,628 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: hh-applicant-tool
|
|
3
|
+
Version: 1.4.7
|
|
4
|
+
Summary: 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.
|
|
5
|
+
Author: Senior YAML Developer
|
|
6
|
+
Author-email: yamldeveloper@proton.me
|
|
7
|
+
Requires-Python: >=3.10,<4.0
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
14
|
+
Provides-Extra: playwright
|
|
15
|
+
Requires-Dist: playwright (>=1.57.0,<2.0.0) ; extra == "playwright"
|
|
16
|
+
Requires-Dist: prettytable (>=3.6.0,<4.0.0)
|
|
17
|
+
Requires-Dist: requests[socks] (>=2.32.3,<3.0.0)
|
|
18
|
+
Project-URL: Homepage, https://github.com/s3rgeym/hh-applicant-tool
|
|
19
|
+
Project-URL: Repository, https://github.com/s3rgeym/hh-applicant-tool
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
## HH Applicant Tool
|
|
23
|
+
|
|
24
|
+

|
|
25
|
+
[]()
|
|
26
|
+
[]()
|
|
27
|
+
[]()
|
|
28
|
+
[]()
|
|
29
|
+
[]()
|
|
30
|
+
|
|
31
|
+
<div align="center">
|
|
32
|
+
<img src="https://github.com/user-attachments/assets/29d91490-2c83-4e3f-a573-c7a6182a4044" width="500">
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
### ✨ Ключевые преимущества
|
|
36
|
+
|
|
37
|
+
- 💸 **Бесплатно.** В то время как сервисы в интернете или Telegram с аналогичным функционалом просят за свои услуги от 5.000 до 12.000 рублей в месяц.
|
|
38
|
+
|
|
39
|
+
- 🔒 **Безопасность личных данных.** Ваши email, телефон, пароль и другие личные данные никуда не передаются в отличие от сторонних сервисов. В этом можно убедиться, изучив [открытый исходный код](https://github.com/s3rgeym/hh-applicant-tool/tree/main/hh_applicant_tool). Владельцы сторонних сервисов никогда вам не покажут исходники. Они знают о вас все и эти данные спокойно продадут каким-нибудь жуликам, либо те утекут в результате взлома.
|
|
40
|
+
|
|
41
|
+
- 🛡️ **Гарантия от блокировок.** Утилита выполняет запросы с вашего устройства, имитируя обычного пользователя. Сервисы рассылают запросы для сотен аккаунтов с одного сервера, что повышает вероятность блокировки вашего аккаунта до 100%.
|
|
42
|
+
|
|
43
|
+
- 😎 **Простота в использовании.** С утилитой разберется любой начинающий пользователь компьютера. Настолько, что херки в своем чате уже жалуются на массовые отклики от подростков 14-17 лет, которые успешно освоили данный инструмент.
|
|
44
|
+
|
|
45
|
+
- 👯 **Мультиаккаунтность и управление резюме.** Вы можете использовать неограниченное количество профилей (аккаунтов), переключаясь между ними через разные файлы конфигурации. Утилита умеет работать со всеми вашими резюме: обновлять их даты публикации и подбирать вакансии под каждое из них.
|
|
46
|
+
|
|
47
|
+
- 🖥️ **Полноценный CLI и работа на серверах.** Утилита имеет чистый консольный интерфейс. Несмотря на то, что для обхода защиты при авторизации используется браузер, он работает по умолчанию в фоновом (headless) режиме. Для `hh-applicant-tool` не нужна видеокарта или графическая оболочка (X-сервер), что позволяет авторизоваться даже с сервера или из докер-контейнера.
|
|
48
|
+
|
|
49
|
+
- 🚀 **Скриптинг.** Вы можете использовать утилиту из Python-скриптов!!! Благодаря этому вы можете ее интегрировать, например, в своего Telegram-бота.
|
|
50
|
+
|
|
51
|
+
- 🤖 **Борьба с ATS и HR.** Компании уже массово внедрили ATS-системы с нейронными сетями, которые отклоняют ваш отклик в течение 30 секунд. Отказ может прийти из-за отсутствия одного ключевого слова в резюме, это уже не говоря о давно существующих фильтрах по полу, возрасту и даже региону происхождения (безопасники в банках отказывают даже русским, рожденным в Дагестане). Это обесценивает ваши усилия на написание сопроводительных писем и чтение бесконечных портянок бреда, сгенерированных нейронками по запросу каких-то дур. Если тупые кобылы решили себя не утруждать чтением резюме (они сейчас и сами перестали писать), то и вам незачем читать их высеры. Утилита избавляет вас от этой рутины, превращающей поиск работы в полноценную работу. Сейчас доля отказов составляет 98-99%, включая "молчунов", и единственный способ увеличить шансы просто попасть на собеседование — это автоматическая рассылка откликов на все подходящие вакансии.
|
|
52
|
+
|
|
53
|
+
### Содержание
|
|
54
|
+
|
|
55
|
+
- [HH Applicant Tool](#hh-applicant-tool)
|
|
56
|
+
- [✨ Ключевые преимущества](#-ключевые-преимущества)
|
|
57
|
+
- [Содержание](#содержание)
|
|
58
|
+
- [Описание](#описание)
|
|
59
|
+
- [Внимание!!!](#внимание)
|
|
60
|
+
- [Предыстория](#предыстория)
|
|
61
|
+
- [Установка](#установка)
|
|
62
|
+
- [Установка утилиты](#установка-утилиты)
|
|
63
|
+
- [Установка зависимостей](#установка-зависимостей)
|
|
64
|
+
- [Авторизация](#авторизация)
|
|
65
|
+
- [Конфигурация](#конфигурация)
|
|
66
|
+
- [Описание команд](#описание-команд)
|
|
67
|
+
- [Формат текста сообщений](#формат-текста-сообщений)
|
|
68
|
+
- [Использование AI](#использование-ai)
|
|
69
|
+
- [OpenAI/ChatGPT](#openaichatgpt)
|
|
70
|
+
- [Использование в скриптах](#использование-в-скриптах)
|
|
71
|
+
- [Дополнительные настройки](#дополнительные-настройки)
|
|
72
|
+
- [Лицензия / License](#лицензия--license)
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
### Описание
|
|
77
|
+
|
|
78
|
+
> Данной утилите похуй на "запрет" доступа к API HH сторонним приложениям, так как она прикидывается официальным приложением под Android
|
|
79
|
+
|
|
80
|
+
> Утилита для генерации сопроводительного письма может использовать AI, в т. ч. ChatGPT. Подробное описание ниже
|
|
81
|
+
|
|
82
|
+
Утилита для успешных волчат и старых волков с опытом, служащая для автоматизации действий на HH.RU, таких как рассылка откликов на подходящие вакансии и обновление всех резюме (бесплатный аналог услуги на HH). Утилита локально хранит информацию об откликах, в т. ч. полученные контакты. Это удобно, так как контакт сохранится, даже если вышлют отказ в дальнейшем. Мой совет: скрывайте свой номер от работодателя, если рассылаете отклики через утилиту, а то количество жуликов на красном сайте, мягко говоря, зашкаливает. У утилиты есть канал в дуровграме: [HH Applicant Tool](https://t.me/hh_applicant_tool). Старый <s>[HH Resume Automate](https://t.me/hh_resume_automate)</s> был выпилен какими-то долбоёбами, углядевшими во флаге Японии с двумя буквами «h» нарушение авторских прав...
|
|
83
|
+
|
|
84
|
+
Работает с Python >= 3.10. Нужную версию Python можно поставить через
|
|
85
|
+
asdf/pyenv/conda и что-то еще. В школотронской Manjaro и даже в последних Ubuntu
|
|
86
|
+
версия Python новее.
|
|
87
|
+
|
|
88
|
+
Данная утилита кроссплатформенна. Она гарантированно работает на Linux, Mac и Windows, в т. ч. WSL. При наличии рутованного телефона можно вытащить `access` и `refresh` токены из официального приложения и добавить их в конфиг.
|
|
89
|
+
|
|
90
|
+
Пример работы:
|
|
91
|
+
|
|
92
|
+

|
|
93
|
+
|
|
94
|
+
> Если в веб-интерфейсе выставить фильтры, то они будут применяться в скрипте при отклике на подходящие
|
|
95
|
+
|
|
96
|
+
> Утилита автоматически подхватывает прокси из переменных окружения типа http_proxy или HTTPS_PROXY
|
|
97
|
+
|
|
98
|
+
Данные об откликах, вакансиях и работодателях хранятся локально в БД. Для ее просмотра советую использовать **DB Browser**:
|
|
99
|
+
|
|
100
|
+
<img width="1306" height="1000" alt="image" src="https://github.com/user-attachments/assets/67742b8d-a16c-4304-bd79-7ac99d53ed38" />
|
|
101
|
+
|
|
102
|
+
### Внимание!!!
|
|
103
|
+
|
|
104
|
+
Если для Вас проблема установить данную утилиту, лень разбираться с ее настройкой, то Вы можете установить мое приложение под **Android** [HH Resume Automate](https://github.com/s3rgeym/hh-resume-automate/). Оно обладает минимальным функционалом: обновление резюме (одного) и рассылка откликов (чистить их и т. п. нельзя).
|
|
105
|
+
|
|
106
|
+
### Предыстория
|
|
107
|
+
|
|
108
|
+
Долгое время я делал массовые заявки с помощью консоли браузера:
|
|
109
|
+
|
|
110
|
+
```js
|
|
111
|
+
$$('[data-qa="vacancy-serp__vacancy_response"]').forEach((el) => el.click());
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Оно работает, хоть и не идеально. Я даже пробовал автоматизировать рассылки через `p[yu]ppeteer`, пока не прочитал [документацию](https://github.com/hhru/api). И не обнаружил, что **API** (интерфейс) содержит все необходимые мне методы. Headhunter позволяет создать свое приложение, но там ручная модерация, и навряд ли кто-то разрешит мне создать приложение для спама заявками. Я [декомпилировал](https://gist.github.com/s3rgeym/eee96bbf91b04f7eb46b7449f8884a00) официальное приложение для **Android** и получил **CLIENT_ID** и **CLIENT_SECRET**, необходимые для работы через **API**.
|
|
115
|
+
|
|
116
|
+
### Установка
|
|
117
|
+
|
|
118
|
+
#### Установка утилиты
|
|
119
|
+
|
|
120
|
+
Универсальный с использованием pipx (требует пакета `python-pipx` в Arch):
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# Полная версия с поддержкой авторизации, включает Node.js и различные утилиты
|
|
124
|
+
# Обычный пакет без [playwright] можно использовать на сервере, если перенести туда конфиг, и весит
|
|
125
|
+
# он почти на 500МБ меньше. Думаем (c) s3rgeym. Подписаться
|
|
126
|
+
$ pipx install 'hh-applicant-tool[playwright]'
|
|
127
|
+
|
|
128
|
+
# Если хочется использовать самую последнюю версию, то можно установить ее через git
|
|
129
|
+
$ pipx install "git+https://github.com/s3rgeym/hh-applicant-tool[playwright]"
|
|
130
|
+
|
|
131
|
+
# Для обновления до новой версии
|
|
132
|
+
$ pipx upgrade hh-applicant-tool
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
pipx добавляет исполняемый файл `hh-applicant-tool` в `~/.local/bin`, делая эту команду доступной. Путь до `~/.local/bin` должен быть в `$PATH` (в большинстве дистрибутивов он добавлен).
|
|
136
|
+
|
|
137
|
+
Традиционный способ для Linux/Mac:
|
|
138
|
+
|
|
139
|
+
```sh
|
|
140
|
+
mkdir -p ~/.venvs
|
|
141
|
+
python -m venv ~/.venvs/hh-applicant-tool
|
|
142
|
+
# Это придется делать постоянно, чтобы команда hh-applicant-tool стала доступна
|
|
143
|
+
. ~/.venvs/hh-applicant-tool/bin/activate
|
|
144
|
+
pip install 'hh-applicant-tool[playwright]'
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Отдельно я распишу процесс установки в **Windows** в подробностях:
|
|
148
|
+
|
|
149
|
+
- Для начала поставьте последнюю версию **Python 3** любым удобным способом.
|
|
150
|
+
- Запустите **Terminal** или **PowerShell** от Администратора и выполните:
|
|
151
|
+
```ps
|
|
152
|
+
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted
|
|
153
|
+
```
|
|
154
|
+
Данная политика разрешает текущему пользователю (от которого зашли) запускать скрипты. Без нее не будут работать виртуальные окружения.
|
|
155
|
+
|
|
156
|
+
Далее можно поставить `pipx` и вернуться к инструкции в верху раздела:
|
|
157
|
+
|
|
158
|
+
- Все так же от администратора выполните:
|
|
159
|
+
```ps
|
|
160
|
+
python -m pip install --user pipx
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
А затем:
|
|
164
|
+
|
|
165
|
+
```ps
|
|
166
|
+
python -m pipx ensurepath
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
- Перезапускаем Terminal/Powershell и проверяем:
|
|
170
|
+
|
|
171
|
+
```ps
|
|
172
|
+
pipx -h
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
С использованием вирт. окружений:
|
|
176
|
+
|
|
177
|
+
- Создайте и активируйте виртуальное окружение:
|
|
178
|
+
|
|
179
|
+
```ps
|
|
180
|
+
PS> python -m venv hh-applicant-venv
|
|
181
|
+
PS> .\hh-applicant-venv\Scripts\activate
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
- Поставьте все пакеты в виртуальное окружение `hh-applicant-venv`:
|
|
185
|
+
```ps
|
|
186
|
+
(hh-applicant-venv) PS> pip install 'hh-applicant-tool[playwright]'
|
|
187
|
+
```
|
|
188
|
+
- Проверьте, работает ли оно:
|
|
189
|
+
```ps
|
|
190
|
+
(hh-applicant-venv) PS> hh-applicant-tool -h
|
|
191
|
+
```
|
|
192
|
+
- В случае неудачи вернитесь к первому шагу.
|
|
193
|
+
- Для последующих запусков сначала активируйте виртуальное окружение.
|
|
194
|
+
|
|
195
|
+
#### Установка зависимостей
|
|
196
|
+
|
|
197
|
+
После вышеописанного нужно установить зависимости в виде Chromium и других средств отладки:
|
|
198
|
+
|
|
199
|
+
```sh
|
|
200
|
+
$ hh-applicant-tool install
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Этот шаг необязателен. Все это нужно только для авторизации.
|
|
204
|
+
|
|
205
|
+
### Авторизация
|
|
206
|
+
|
|
207
|
+
Прямая авторизация:
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
$ hh-applicant-tool authorize '<ваш телефон или email>' -p '<пароль>'
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Если вы пропустили пункт про установку зависимостей, то увидите такую ошибку:
|
|
214
|
+
|
|
215
|
+
```sh
|
|
216
|
+
[E] BrowserType.launch: Executable doesn't exist at...
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Если по какой-то причине не был установлен `playwright`:
|
|
220
|
+
|
|
221
|
+
```sh
|
|
222
|
+
[E] name 'async_playwright' is not defined
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
Если не помните пароль или др. причины, то можно авторизоваться с помощью одноразового кода:
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
$ hh-applicant-tool authorize '<ваш телефон или email>'
|
|
230
|
+
📨 Код был отправлен. Проверьте почту или SMS.
|
|
231
|
+
📩 Введите полученный код: 1387
|
|
232
|
+
🔓 Авторизация прошла успешно!
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
- Если вы ввели телефон, то код придет через SMS
|
|
236
|
+
- Если был введен Email, то проверьте почту
|
|
237
|
+
|
|
238
|
+
Если же при вводе правильных данных возникает ошибка авторизации, то, скорее всего, требуется ввод капчи.
|
|
239
|
+
|
|
240
|
+
Для ввода данных вручную:
|
|
241
|
+
|
|
242
|
+
```sh
|
|
243
|
+
hh-applicant-tool authorize --manual
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
> Этот флаг не будет работать на сервере, так как требует наличия графического окружения
|
|
247
|
+
|
|
248
|
+
Проверка авторизации:
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
$ hh-applicant-tool whoami
|
|
252
|
+
🆔 27405918 Кузнецов Андрей Владимирович [ 📄 1 | 👁️ +115 | ✉️ +28 ]
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
В случае успешной авторизации токены будут сохранены в `config.json`.
|
|
256
|
+
|
|
257
|
+
Токен доступа выдается на две недели. Он обновляется автоматически. Для его ручного обновления нужно выполнить:
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
$ hh-applicant-tool refresh-token
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Помните, что у `refresh_token` тоже есть время жизни, поэтому может потребоваться полная авторизация.
|
|
264
|
+
|
|
265
|
+
### Конфигурация
|
|
266
|
+
|
|
267
|
+
Конфигурации хранятся по следующим путям:
|
|
268
|
+
|
|
269
|
+
| OS | Путь |
|
|
270
|
+
| ----------- | -------------------------------------------------------- |
|
|
271
|
+
| **Windows** | `C:\Users\%username%\AppData\Roaming\hh-applicant-tool\` |
|
|
272
|
+
| **macOS** | `~/Library/Application Support/hh-applicant-tool/` |
|
|
273
|
+
| **Linux** | `~/.config/hh-applicant-tool/` |
|
|
274
|
+
|
|
275
|
+
Главный конфиг называется `config.json`. Он содержит токены. Полный путь до конфигурационного файла можно вывести с помощью команды:
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
hh-applicant-tool config -p
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
Через конфиг можно задать дополнительные настройки:
|
|
282
|
+
|
|
283
|
+
| Имя атрибута | Описание |
|
|
284
|
+
| --------------- | ------------------------------------------------------------------------------------------ |
|
|
285
|
+
| `proxy_url` | Прокси, используемый для всех запросов, например, `socks5h://127.0.0.1:9050` |
|
|
286
|
+
| `reply_message` | Сообщение для ответа работодателю при отклике на вакансии, см. формат сообщений |
|
|
287
|
+
| `user_agent` | Кастомный юзерагент, передаваемый при каждом запросе. По умолчанию используется от Android |
|
|
288
|
+
| `client_id` | Идентификатор клиента, используемый для авторизации. По умолчанию используется от Android |
|
|
289
|
+
| `client_secret` | Секретный ключ клиента, используемый для авторизации. По умолчанию используется от Android |
|
|
290
|
+
|
|
291
|
+
В `log.txt` всегда можно посмотреть подробную информацию об ошибках. В целях безопасности токены, идентефикаторы резюме и тп затираются.
|
|
292
|
+
|
|
293
|
+
Данные о работодателях и их вакансиях хранятся в файле `data`. Это обычная база `sqlite3`, вы ее можете просматривать через `DB Browser` и т. п.
|
|
294
|
+
|
|
295
|
+
Что хранится в базе:
|
|
296
|
+
|
|
297
|
+
* все просмотренные вакансии;
|
|
298
|
+
* профили работодателей;
|
|
299
|
+
* контакты работодателей;
|
|
300
|
+
* данные об откликах;
|
|
301
|
+
* иные данные, важные для работы.
|
|
302
|
+
|
|
303
|
+
Если вы залогинитесь под другим аккаунтом, то данные не исчезнут.
|
|
304
|
+
|
|
305
|
+
При использовании профиля, отличного от дефолтного, данные хранятся в подкаталоге.
|
|
306
|
+
|
|
307
|
+
### Описание команд
|
|
308
|
+
|
|
309
|
+
Примеры команд:
|
|
310
|
+
|
|
311
|
+
```bash
|
|
312
|
+
# Общий вид: сначала глобальные настройки, затем команда и её аргументы
|
|
313
|
+
$ hh-applicant-tool [options] <operation> [args]
|
|
314
|
+
|
|
315
|
+
# Справка по глобальным флагам и список операций
|
|
316
|
+
$ hh-applicant-tool -h
|
|
317
|
+
|
|
318
|
+
# Справка по операции
|
|
319
|
+
$ hh-applicant-tool authorize -h
|
|
320
|
+
|
|
321
|
+
# Авторизуемся
|
|
322
|
+
$ hh-applicant-tool authorize
|
|
323
|
+
|
|
324
|
+
# Авторизация с использованием другого профиля
|
|
325
|
+
$ hh-applicant-tool --profile profile123 authorize
|
|
326
|
+
|
|
327
|
+
# Рассылаем заявки
|
|
328
|
+
$ hh-applicant-tool apply-similar
|
|
329
|
+
|
|
330
|
+
# Для тестирования поисковой строки и других параметров, используйте --dry-run.
|
|
331
|
+
# С ним отклики не отправляются, а лишь выводятся сообщения
|
|
332
|
+
$ hh-applicant-tool -vv apply-similar --search "Python программист" --per-page 3 --total-pages 1 --dry-run
|
|
333
|
+
|
|
334
|
+
# Поднимаем резюме
|
|
335
|
+
$ hh-applicant-tool update-resumes
|
|
336
|
+
|
|
337
|
+
# Ответить работодателям
|
|
338
|
+
$ hh-applicant-tool reply-employers
|
|
339
|
+
|
|
340
|
+
# Просмотр лога в реальном времени
|
|
341
|
+
$ hh-applicant-tool log -f
|
|
342
|
+
|
|
343
|
+
# Посмотреть содержимое конфига
|
|
344
|
+
$ hh-applicant-tool config
|
|
345
|
+
|
|
346
|
+
# Редактировать конфиг в стандартном редакторе
|
|
347
|
+
$ hh-applicant-tool config -e
|
|
348
|
+
|
|
349
|
+
# Вывести значение из конфига
|
|
350
|
+
$ hh-applicant-tool config -k token.access_token
|
|
351
|
+
|
|
352
|
+
# Установить значение в конфиге, например, socks-прокси
|
|
353
|
+
$ hh-applicant-tool config -s proxy_url socks5h://localhost:1080
|
|
354
|
+
|
|
355
|
+
# Удалить значение из конфига
|
|
356
|
+
$ hh-applicant-tool config -u proxy_url
|
|
357
|
+
|
|
358
|
+
# Утилита все данные об откликах хранит в SQLite
|
|
359
|
+
$ hh-applicant-tool query 'select count(*) from employer_contacts;'
|
|
360
|
+
+----------+
|
|
361
|
+
| count(*) |
|
|
362
|
+
+----------+
|
|
363
|
+
| 42 |
|
|
364
|
+
+----------+
|
|
365
|
+
|
|
366
|
+
# Экспорт контактов в csv
|
|
367
|
+
$ hh-applicant-tool query 'select * from employer_contacts' --csv -o
|
|
368
|
+
contacts.csv
|
|
369
|
+
|
|
370
|
+
# Выполнение запросов в интерактивном режиме
|
|
371
|
+
$ hh-applicant-tool query
|
|
372
|
+
|
|
373
|
+
# Вывести приглашения с удаленкой и зарплатой от 200.000 рублей
|
|
374
|
+
$ hh-applicant-tool query <<<"SELECT
|
|
375
|
+
v.alternate_url,
|
|
376
|
+
v.name AS vacancy_name,
|
|
377
|
+
v.salary_from,
|
|
378
|
+
v.salary_to,
|
|
379
|
+
e.name AS employer_name,
|
|
380
|
+
e.site_url,
|
|
381
|
+
ec.name,
|
|
382
|
+
ec.email,
|
|
383
|
+
ec.phone_numbers
|
|
384
|
+
FROM vacancies v
|
|
385
|
+
JOIN negotiations n ON v.id = n.vacancy_id
|
|
386
|
+
JOIN employers e ON n.employer_id = e.id
|
|
387
|
+
LEFT JOIN employer_contacts ec ON e.id = ec.employer_id
|
|
388
|
+
WHERE v.salary_from >= 200000
|
|
389
|
+
AND v.currency = 'RUR'
|
|
390
|
+
AND v.remote = 1
|
|
391
|
+
AND n.state IN ('invitation', 'interview', 'hired')
|
|
392
|
+
ORDER BY v.salary_from DESC, v.salary_to DESC;"
|
|
393
|
+
|
|
394
|
+
# Перед выполнением запросов к базе желательно синхронизировать отклики
|
|
395
|
+
$ hh-applicant-tool sync-negotiations
|
|
396
|
+
|
|
397
|
+
# Чистим отказы
|
|
398
|
+
$ hh-applicant-tool sync --clean
|
|
399
|
+
|
|
400
|
+
# При обновлении может сломаться схема БД, для ее починки нужно выполнить
|
|
401
|
+
# поочерёдно все миграции, добавленные после выхода последней версии
|
|
402
|
+
$ hh-applicant-tool migrate
|
|
403
|
+
List of migrations:
|
|
404
|
+
|
|
405
|
+
[1]: 2026-01-07
|
|
406
|
+
|
|
407
|
+
Choose migration [1] (Keep empty to exit): 1
|
|
408
|
+
✅ Success!
|
|
409
|
+
|
|
410
|
+
# Вывести все настройки
|
|
411
|
+
$ hh-applicant-tool settings
|
|
412
|
+
+----------+-------------------------+-------------------------+
|
|
413
|
+
| Тип | Ключ | Значение |
|
|
414
|
+
+----------+-------------------------+-------------------------+
|
|
415
|
+
| str | user.email | dmitry.kozlov@yandex.ru |
|
|
416
|
+
| int | auth.last_login | 1768462521 |
|
|
417
|
+
+----------+-------------------------+-------------------------+
|
|
418
|
+
|
|
419
|
+
# Получить значение по ключу
|
|
420
|
+
$ hh-applicant-tool settings auth.username
|
|
421
|
+
|
|
422
|
+
# Установить email, используемый для автологина
|
|
423
|
+
$ hh-applicant-tool settings auth.username 'user@example.com'
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
Глобальные настройки:
|
|
427
|
+
|
|
428
|
+
- `-v` используется для вывода отладочной информации. Два таких флага, например, выводят запросы к **API**.
|
|
429
|
+
- `-c <path>` путь до каталога, где хранятся конфигурации.
|
|
430
|
+
- `--profile <profile-id>` можно указать профиль, данные которого будут храниться в подкаталоге.
|
|
431
|
+
|
|
432
|
+
| Операция | Описание |
|
|
433
|
+
| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
434
|
+
| **authorize**, **auth** | Авторизация на hh.ru. Введенные логин и пароль "запоминаются" и будут использованы при следующем вызове команды. |
|
|
435
|
+
| **whoami**, **id** | Выводит информацию об авторизованном пользователе |
|
|
436
|
+
| **list-resumes**, **list**, **ls** | Список резюме |
|
|
437
|
+
| **update-resumes**, **update** | Обновить все резюме. Аналогично нажатию кнопки «Обновить дату». |
|
|
438
|
+
| **apply-similar** | Откликнуться на все подходящие вакансии. Лимит = 200 в день. На HH есть спам-фильтры, так что лучше не рассылайте отклики со ссылками, иначе рискуете попасть в теневой бан. |
|
|
439
|
+
| **reply-employers**, **reply** | Ответить во все чаты с работодателями, где нет ответа либо не прочитали ваш предыдущий ответ |
|
|
440
|
+
| **check-negotiations** | Синхронизация откликов с возможностью их отмены |
|
|
441
|
+
| **call-api**, **api** | Вызов произвольного метода API с выводом результата. |
|
|
442
|
+
| **refresh-token**, **refresh** | Обновляет access_token. |
|
|
443
|
+
| **config** | Показывает содержимое конфига. С флагом -e открывает его для редактирования. |
|
|
444
|
+
| **settings** | Просмотр и управление настройками в базе данных. Простое key-value хранилище. |
|
|
445
|
+
| **install** | Устанавливает зависимости, такие как браузер Chromium, необходимые для авторизации. |
|
|
446
|
+
| **uninstall** | Удаляет браузер Chromium, используемый для авторизации. |
|
|
447
|
+
| **check-proxy** | Проверяет используемые прокси |
|
|
448
|
+
| **migrate** | Починить базу |
|
|
449
|
+
| **query** | Выполнение SQL-запросов к базе. Схема БД находится в файле [schema.sql](./hh_hh_applicant_tool/storage/queries/schema.sql). Если скормить ее [DeepSeek](https://chat.deepseek.com), то он поможет написать любой запрос. |
|
|
450
|
+
| **log** | Просмотр файла-лога. С флагом -f будет следить за изменениями. |
|
|
451
|
+
|
|
452
|
+
Утилита использует систему плагинов. Все они лежат в [operations](https://github.com/s3rgeym/hh-applicant-tool/tree/main/hh_applicant_tool/operations). Модули, расположенные там, автоматически добавляются как доступные команды. За основу для своего плагина можно взять [whoami.py](https://github.com/s3rgeym/hh-applicant-tool/tree/main/hh_applicant_tool/operations/whoami.py).
|
|
453
|
+
|
|
454
|
+
Для тестирования запросов к API используйте команду `call-api` совместно с `jq` для обработки JSON.
|
|
455
|
+
|
|
456
|
+
Примеры поиска работодателей:
|
|
457
|
+
|
|
458
|
+
```bash
|
|
459
|
+
$ hh-applicant-tool call-api /employers text="IT" only_with_vacancies=true | jq -r '.items[].alternate_url'
|
|
460
|
+
https://hh.ru/employer/1966364
|
|
461
|
+
https://hh.ru/employer/4679771
|
|
462
|
+
...
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
Синтаксис `call-api` немного похож на `httpie` или `curlie`:
|
|
466
|
+
|
|
467
|
+
```sh
|
|
468
|
+
$ hh-applicant-tool call-api -m {GET|POST|PUT|DELETE} /path/to/endpoint key1=value1 ... keyN=valueN
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
Если используется метод `GET` или `DELETE` (или ничего не указано), то параметры будут переданы как query string. Во всех остальных случаях парметры передаются как `application/x-www-form-urlencoded` в теле запроса.
|
|
472
|
+
|
|
473
|
+
Данная возможность полезна для написания Bash-скриптов.
|
|
474
|
+
|
|
475
|
+
Документация для работы с API соискателей была удалена с ха-ха.сру и его корпоративного репозитория. Можете не искать, они затерли даже историю репозитория. Но я через веб-архив выкачал документацию. Чтобы ее посмотреть, клонируйте этот репозиторий и откройте файл, например, с помощью [Swagger Viewer](https://marketplace.visualstudio.com/items?itemName=Arjun.swagger-viewer).
|
|
476
|
+
|
|
477
|
+
<img width="740" height="768" alt="image" src="https://github.com/user-attachments/assets/597fa31e-8bab-48c8-8601-ab9dfc9075b1" />
|
|
478
|
+
|
|
479
|
+
Так же существуют cli-утилиты:
|
|
480
|
+
|
|
481
|
+
```sh
|
|
482
|
+
npx @redocly/cli preview -d docs/hhapi
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
Потом нужно открыть в браузере [http://localhost:4000](http://localhost:4000).
|
|
486
|
+
|
|
487
|
+
> Отдельные замечания у меня к API HH. Оно пиздец какое кривое. Например, при создании заявки возвращается пустой ответ либо редирект, хотя по логике должен возвращаться созданный объект. Так же в ответах сервера нет `Content-Length`. Из-за этого нельзя узнать, есть ли тело у ответа сервера, нужно его пробовать прочитать. Я так понял, там какой-то прокси оборачивает все запросы и отдает всегда `Transfer-Encoding: Chunked`. А еще он возвращает 502 ошибку, когда бэкенд на Java падает либо долго отвечает (таймаут)? А вот [язык запросов](https://hh.ru/article/1175) мне понравился. Можно что-то вроде этого использовать `NOT (!ID:123 OR !ID:456 OR !ID:789)`, чтобы отсеить какие-то вакансии.
|
|
488
|
+
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
По сути, никакие дополнительные команды, кроме имеющихся, не нужны. Вы можете сделать что угодно с помощью `call-api`, но если хочется чего-то особенного, можно добавить свои команды.
|
|
492
|
+
|
|
493
|
+
### Формат текста сообщений
|
|
494
|
+
|
|
495
|
+
Команда `apply-similar` поддерживает специальный формат сообщений.
|
|
496
|
+
|
|
497
|
+
Так же в сообщении можно использовать плейсхолдеры:
|
|
498
|
+
|
|
499
|
+
- **`%(vacancy_name)s`**: Название вакансии.
|
|
500
|
+
- **`%(employer_name)s`**: Название работодателя.
|
|
501
|
+
- **`%(first_name)s`**: Имя пользователя.
|
|
502
|
+
- **`%(last_name)s`**: Фамилия пользователя.
|
|
503
|
+
- **`%(email)s`**: Email пользователя.
|
|
504
|
+
- **`%(phone)s`**: Телефон пользователя.
|
|
505
|
+
|
|
506
|
+
Эти плейсхолдеры могут быть использованы в сообщениях для отклика на вакансии, чтобы динамически подставлять соответствующие данные в текст сообщения. Например:
|
|
507
|
+
|
|
508
|
+
```
|
|
509
|
+
Меня заинтересовала ваша вакансия %(vacancy_name)s. Прошу рассмотреть мою кандидатуру. С уважением, %(first_name)s %(last_name)s.
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
Так же можно делать текст уникальным с помощью `{}`. Внутри них через `|` перечисляются варианты, один из которых будет случайно выбран:
|
|
513
|
+
|
|
514
|
+
```
|
|
515
|
+
{Здоров|Привет}, {как {ты|сам}|что делаешь}}?
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
В итоге получится что-то вроде:
|
|
519
|
+
|
|
520
|
+
```
|
|
521
|
+
Привет, как ты?
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
### Использование AI
|
|
525
|
+
|
|
526
|
+
Для генерации опроводительных писем при откликах и ответа в чаты работодателей (`reply-employers`) можно использовать OpenAI (ChatGPT).
|
|
527
|
+
|
|
528
|
+
Пример рассылки откликов с генерированным письмом:
|
|
529
|
+
|
|
530
|
+
```sh
|
|
531
|
+
hh-applicant-tool apply-similar -f --ai
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
#### OpenAI/ChatGPT
|
|
535
|
+
|
|
536
|
+
Отредактируйте конфиг:
|
|
537
|
+
|
|
538
|
+
```sh
|
|
539
|
+
hh-applicant-tool config -e
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
Добавьте в него эти строки:
|
|
543
|
+
|
|
544
|
+
```json
|
|
545
|
+
{
|
|
546
|
+
"openai": {
|
|
547
|
+
"token": "ВАШ_API_КЛЮЧ_OPENAI",
|
|
548
|
+
"model": "ВАША_МОДЕЛЬ",
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
### Использование в скриптах
|
|
554
|
+
|
|
555
|
+
Если хотите использовать `hh-applicant-tool` в своих скриптах, то можно это сделать так:
|
|
556
|
+
|
|
557
|
+
```python
|
|
558
|
+
from hh_applicant_tool import HHApplicantTool
|
|
559
|
+
|
|
560
|
+
tool = HHApplicantTool([
|
|
561
|
+
# Передаем глобальные настройки как обычно
|
|
562
|
+
"--proxy-url", "socks5://localhost:1080",
|
|
563
|
+
"--config-path", "/path/to/config"
|
|
564
|
+
])
|
|
565
|
+
|
|
566
|
+
print(tool.api_client.get('/me'))
|
|
567
|
+
|
|
568
|
+
# Какую-то вспомогательную информацию можно сохранять в настройках
|
|
569
|
+
import datetime as dt
|
|
570
|
+
|
|
571
|
+
tool.storage.settings.set_value("_last_script_run", dt.datetime.now())
|
|
572
|
+
|
|
573
|
+
# Учтите что в таком случае токены, которые могут обновиться при выполнении запросов,
|
|
574
|
+
# нужно сохранять вручную
|
|
575
|
+
tool.save_token()
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
Команды тоже можно вызывать:
|
|
579
|
+
|
|
580
|
+
```python
|
|
581
|
+
>>> from hh_applicant_tool import HHApplicantTool
|
|
582
|
+
>>> HHApplicantTool(['authorize', 'your-email@gmail.com']).run()
|
|
583
|
+
📨 Код был отправлен. Проверьте почту или SMS.
|
|
584
|
+
📩 Введите полученный код:
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
### Дополнительные настройки
|
|
588
|
+
|
|
589
|
+
Если вы обычный пользователь, то ничего лучше не трогайте.
|
|
590
|
+
|
|
591
|
+
Отключение проверки версии с выводом предупреждения:
|
|
592
|
+
|
|
593
|
+
```sh
|
|
594
|
+
$ hh-applicant-tool settings disable_version_check true
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
Утилита ищет в логах информацию о Python-ошибках. Они отправляются на сервер разработчика с целью их оперативного исправления, однако, вы можете отключить отправку отчетов:
|
|
598
|
+
|
|
599
|
+
```sh
|
|
600
|
+
$ hh-applicant-tool settings send_error_reports false
|
|
601
|
+
```
|
|
602
|
+
</details>
|
|
603
|
+
|
|
604
|
+
### Лицензия / License
|
|
605
|
+
|
|
606
|
+
**© 2023-2026 Sergey M. Все права защищены.**
|
|
607
|
+
|
|
608
|
+
Данное программное обеспечение предоставляется на условиях **ограниченной некоммерческой лицензии**.
|
|
609
|
+
|
|
610
|
+
- Разрешенное использование
|
|
611
|
+
* Разрешается бесплатное использование, копирование и модификация кода исключительно в **личных**, **образовательных** и **ознакомительных** целях.
|
|
612
|
+
* Разрешено использование в свободном некоммерческом ПО с открытым исходным кодом СТРОГО С УКАЗАНИЕМ ССЫЛОК НА ДАННЫЙ РЕПОЗИТОРИЙ И АВТОРА.
|
|
613
|
+
|
|
614
|
+
- Ограничения в использовании
|
|
615
|
+
Категорически запрещается использование данного кода (а также его частей или производных) в любых коммерческих целях без предварительного псогласия автора. Это включает, но не ограничивается:
|
|
616
|
+
* Интеграцию кода в платные сервисы, приложения или веб-сайты.
|
|
617
|
+
* Использование кода для оказания платных услуг (SaaS, консалтинг, техподдержка).
|
|
618
|
+
* Перепродажу или сублицензирование кода.
|
|
619
|
+
|
|
620
|
+
- Отказ от ответственности
|
|
621
|
+
Программа предоставляется на условиях «как есть» (AS IS). Автор не несет ответственности за любые прямые или косвенные убытки, возникшие в результате использования данного ПО.
|
|
622
|
+
|
|
623
|
+
---
|
|
624
|
+
|
|
625
|
+
**Copyright (c) 2023-2026 Sergey M. All rights reserved.**
|
|
626
|
+
|
|
627
|
+
This software is provided for **FREE PERSONAL USE ONLY**. Any commercial use, including integration into paid services or commercial consulting, is **STRICTLY PROHIBITED**.
|
|
628
|
+
|