Share |

вторник, 20 февраля 2018 г.

Как я скачиваю вакансии компаний с HH.ru (на примере Газпрома)



Сразу признаюсь: неделю назад я ничего не знал про API HH, парсинг вакансий с ХХ.ру. Поэтому не претендую на лучший способ парсинга вакансий.
Если Вы предложите более удобный способ - буду благодарен.
Мне вакансии потребовалось парсить в рамках задачи Сравнительный анализ корпоративной культуры Альфабанка и Сбербанка на основе текстов вакансий
Работаю в Python.
И предупреждаю: данный алгоритм будет полезен только для парсинга открытых вакансий конкретных компаний. Для парсинга, например вакансий по определенному запросу с определенной даты в определенном регионе уже потребуется другой алгоритм - обращайтесь, если что.

Алгоритм

Необходимые пакеты

import numpy as np
import requests
from tqdm import tqdm_notebook
import pandas as pd
Давайте на примере Газпрома. Самый типа простой способ
Как я скачиваю вакансии компаний с HH.ru


r = requests.get('https://api.hh.ru/vacancies?employer_id=39305').json() 
r
39305 - это номер работодателя на ХХ, в нашем случае Газпром. Как найти ID компании, думаете не проблема: ищите страницу работодателя в ХХ.ру, там в урле берете ID.
Этот способ нас сразу не устраивает, потому что по дефолту эта команда скачивает только 20 вакансий - вакансии размещаются на страницах по 20 вакансий на каждой, и приведенная команда скачает вакансии только с первой страницы. А у нас всего найдено
'found': 774,

В самом низу выдачи r видим

'pages': 39,
'per_page': 20

Т.е. у нас 774 вакансии на 39 страницах. Запускам цикл, чтобы скачать все страницы с 774 вакансиями Газпрома

vac = []
for i in tqdm_notebook(range(0, 39)):
    vac.append(requests.get("https://api.hh.ru/vacancies?employer_id=39305", params={'page': i, 'per_page':20}).json())
И получаем объект типа лист vac. Но и эта выдача меня не устраивает. Если вы посмотрите на отдельные элементы листа типа v[0], то можете обратить внимание, что описание требований к кандидату и предложение компании обрезаны.

'snippet': {'requirement': 'Высшее образование. Опыт работы в банковской сфере 
не менее одного года. Опыт работы в клиентском сервисе не менее двух лет. ',
    'responsibility': 'Привлечение и обслуживание клиентов премиум сегмента. 
Развитие текущих клиентов (установление долгосрочных отношений). 
Выполнение плана продаж. Финансовое консультирование и продажа инвестиционных...'},
Это значит, что надо искать другой путь. Я сначала скачиваю ID всех вакансий Газпрома

pac=[]
for i in range(0, 39):
    for j in range(0, 20):
        pac.append(vac[i]['items'][j]['alternate_url'])
И мы получаем объект типа лист с всеми урлами вакансий Газпрома. Нам надо еще оставить одни номера урлов, а не сами урлы
lili = [re.sub(r'[^0-9]', '', e) for e in pac]
У вас в этом месте выдаст ошибку, потому что я забыл указать библиотеку regex - установите ее. Теперь у нас набор ID вакансий Газпрома. Но вы заметили, что мы сначала скачали все содержимое вакансий, а из него вытащили уже ID. Это нихт гут, если парсить надо много контента, поэтому можно сразу парсить ID вакансий так

vah = []
for i in tqdm_notebook(range(0, 39)):
    for j in tqdm_notebook(range(0, 20)):
        vah.append(requests.get("https://api.hh.ru/vacancies?employer_id=39305", params={'page': i, 'per_page':20}).json()['items'][j]['alternate_url'])
формула страшная для гуманитариев типа меня. И кстати, по времени парсинга я не заметил сильного отличия с парсингом всех вакансий.
Далее мы скачиваем вакансии уже по этим прямым ID. Сначала опять выделяем только числа из урлов, потом скачиваем


lulu = [re.sub(r'[^0-9]', '', e) for e in vah]
vak_url = 'https://api.hh.ru/vacancies/{}'

var = []
for i in lulu:
    var.append(requests.get(vak_url.format(i)).json())
В общем все, дальше мы превращаем скачанные вакансии в объект pandas
df = pd.DataFrame(var)
И последнюю беду, которую мне лично нужно было решить, это избавиться от тегов урлов, потому что описание вакансий идет в таком виде
df['description']
Чтобы избавиться от тегов, выполняем команду
df['description'] = df['description'].apply(lambda x: (re.sub(r'<.*?>', '', str(x))))
Напомню, что я решал локальную задачу парсинга открытых вакансий конкретной компании, для решения других задач потребуется возможно другой алгоритм.




__________________________________________________________
На этом все, читайте нас в фейсбукетелеграмме и вконтакте





3 комментария:

  1. для парсинга данных с ХХ использую R пакет jsonlite. Какие вы нашли преимущества у питона для данной задачи?

    ОтветитьУдалить
    Ответы
    1. я вам могу дать доступ в свой блог - поделитесь кодом, как вы это делаете

      Удалить

Популярные сообщения

п