Hh.ru — неплохой сайт, не нуждающийся в дополнительном представлении. Поиск вакансий на нем удобен и прозаичен. Однако, порой интереснее посмотреть со стороны работодателя:

  • как выглядит выдача резюме по целевому запросу,
  • как видно собственное резюме в выдаче,
  • как «проседает» резюме со временем, заодно собрать резюме коллег-юристов для построения мини-статистики.

Несмотря на то, что у hh есть собственное api и оно добротно задокументировано, доступ к нему тщательно оберегается.

Доступ к api осуществляется как и в ситуации со многими api соц. сетей — через предварительную регистрацию приложения в web-кабинете аккаунта, в данном случае, работодателя на hh.ru/employer:



Чтобы попасть туда необходимо зарегистрироваться как работодатель, подтвердить сведения о принадлежности организации (вам позвонят) и далее перейти по ссылке: dev.hh.ru
Однако, на данном этапе работа с api в полном объеме еще недоступна, так как заявка на регистрацию приложения на hh.ru может рассматриваться до 20 рабочих дней. Долго.

Поэтому, поработаем без api, используя возможности python и фреймворка selenium.

В selenium скормим url-запроса от имени работодателя, в котором будут следующие позиции:

  • Ключевые слова: Юрист;
  • Профессиональная область: Любая;
  • Регион: Москва,
  • Зарплата: Не показывать резюме без зарплаты;
  • Образование: Не имеет значения;
  • Гражданство: Любое;
  • Разрешение на работу: Любое;
  • Возраст и фотография: Только с фотографией;
  • Пол: Не имеет значения;
  • Сортировка: По дате изменения;
  • Выводить: За месяц;
  • Показывать на странице:100 резюме.

Несмотря на то, что в выдаче будет много результатов, доступно будет всего лишь 5000 резюме. Ограничение для бесплатно работающего работодателя.

В коде это так:

Импорт модулей и вход на сайт
from selenium import webdriver
import time,csv
browser = webdriver.Firefox()
time.sleep (5) # долго грузится - делаем задержку
browser.get ('https://hh.ru/employer')
time.sleep (5)


Авторизация на сайте
a = browser.find_element_by_css_selector('.bloko-icon_cancel')
a.click()
time.sleep (2)
a=browser.find_element_by_css_selector('div.supernova-navi-item:nth-child(6) > a:nth-child(1)')
a.click()
time.sleep (3)    
emailElem = browser.find_element_by_css_selector('.HH-AuthForm-Login')
emailElem.click()
time.sleep (1)
emailElem.send_keys('example@yandex.ru')    
time.sleep (1)
passElem = browser.find_element_by_css_selector('.HH-AuthForm-Password')
passElem.click()
time.sleep (1)
passElem.send_keys('password')
passElem.submit()
time.sleep (3)


example@yandex.ru и password — заменить на email работодателя, password — на пассворд.

Блок записи в csv
def write_csv(data):
    with open('hh.csv','a',encoding='utf8') as f:
        writer=csv.writer(f)
        writer.writerow((data['name'],
                         data['age'],
                         data['salary'],                         
                         data['stag'],
                         #data['post_job_place'],
                         data['resume_link'],
                         data['photo_big']
                         #data['job_places'],
                         #data['education'],
                         #data['address'],
                         #data['update']
                         )) 


Блок парсинга
def resume_get():    
    #сбор резюме
    a=browser.find_elements_by_class_name('resume-search-item__content-wrapper') #резюме 100 штук
    #len(a)
    #resume-search-item__description-content - стаж работы
    for i in a:
        b=i.find_element_by_class_name('resume-search-item__header')
        name=b.find_element_by_class_name('resume-search-item__name').text # Юрисконсульт
        age=b.find_element_by_class_name('resume-search-item__fullname').text # 52 года
        salary=b.find_element_by_class_name('resume-search-item__compensation').text # 40000 руб.
        stag=i.find_elements_by_class_name('resume-search-item__description-content')[0].text # '7 лет и 8 месяцев'
        resume_link=i.find_element_by_class_name('resume-search-item__name').get_attribute('href') #ссылка на резюме
        #post_job_place=i.find_elements_by_class_name('resume-search-item__description-content')[1].text #послед. место работы
        #job_places=b.find_elements_by_class_name('resume-search-item__description-content')[1:3] #где работал
        #education=i.find_elements_by_class_name('resume-search-item__description-content')[-1].text #где учился
        #photo_small=browser.find_element_by_class_name('resume-userpic').find_element_by_class_name('resume-userpic__photo').get_attribute('src') #ссылка на фото маленькое
        try:
            photo_big=i.find_element_by_class_name('bloko-modal-content').find_element_by_tag_name('img').get_attribute('src') #ссылка на фото-крупно
        except:
            photo_big=''

     
        #update=i.find_element_by_class_name('output__addition').text #дата обновления резюме
        data={    'name':name,
                  'age':age,
                  'salary':salary,
                  'stag':stag,                  
                  #'post_job_place':post_job_place,
                  'resume_link':resume_link,
                  'photo_big':photo_big
                  #'job_places':job_places,
                  #'education':education,
                  #'address':address,
                  #'update':update
                  }
        #print(data)
        write_csv(data)


Итерация по пагинации из 50 страниц с резюме
resume_get()
x=0

while x!=50:
    browser.get (url+'&page='+str(x+1))
    time.sleep(7)
    resume_get()
    x+=1


*закоментированные фрагменты для желающих добавить информации в выборку.

После отработки программы и загрузки результатов в excel, получим таблицу:



Как найти свое резюме? Самый простой способ — отфильтровать возраст кандидатов.

Как посмотреть где оказалось резюме после n-го периода времени? Прогнать программу через n-е количество времени и снова найти себя. Позиция, на которую опустилось резюме в чарте и будет позицией в выдаче, так как программа последовательно собирает все резюме по запросу.

Напоследок небольшая графика-статистика по резюме юристов-«москвичей» (2000 резюме).





ps. Резюме без обновления на сайте проседает на 2000 позиций за сутки по запросу «Корпоративный+юрист».

Программа — скачать
Excel-таблица — скачать