Применение Python для анализа смежных востребованных навыков у разработчиков

в 9:02, , рубрики: data mining, hh.ru, python, вакансии для программистов
Применение Python для анализа смежных востребованных навыков у разработчиков - 1

Сегодня в Сети можно найти огромное количество разнородной информации о наиболее востребованных языках программирования, библиотеках, фреймворках, операционных системах и прочих сущностях — назовём их технологиями. Число этих технологий постоянно растёт и становится ясно, что каждому, желающему пойти путём разработчика, необходимо фокусироваться на изучении некоторого наиболее востребованного стека, связанного с какой-либо ключевой технологией.

Тут возникает первый вопрос — как можно определить востребованность той или иной технологии? На этот вопрос можно ответить, например, так: на технологию есть спрос, когда работодатели упоминают ее в качестве требования к соискателю при описании вакансии. Иными словами, если при просмотре 100 вакансий технология A была упомянута 60 раз, а технология B — 20 раз, можно считать технологию А более востребованной чем B.

Второй вопрос состоит в том, что считать ключевыми технологиями?

Исходя из большого интереса к статьям об анализе популярности языков программирования, будем считать ключевой технологией именно язык программирования.

Таким образом, задачу можно сформулировать следующим образом – во множестве вакансий необходимо выделить подмножество, связанное с ключевой технологией, и в этом подмножестве подсчитать частоты упоминания прочих технологий.

В качестве базы данных вакансий будем использовать портал hh.ru, в силу его большой популярности и наличия HeadHunter API. Язык программирования — Python 3.4.

Чтобы сократить объем статьи, техническая сторона вопроса получения и обработки данных подробно рассматриваться не будет, но на некоторых ключевых моментах стоит остановиться. Исходный код проекта открыт и доступен на GitHub.

Получение перечня вакансий

Для получения перечня вакансий, относящихся к программистам Python, сделаем следующий get запрос при помощи библиотеки requests:

import requests
import json
l = "Python"
params = {"text": "Программист " + l, "search_field": "name", "area": 2, "period": 30, "page": 0}
r = requests.get("https://api.hh.ru/vacancies", params=params)
jr = json.loads(r.text)

В результате получим словарь со следующими элементами:

  • page: class 'int'
  • clusters: class 'NoneType'
  • per_page: class 'int'
  • alternate_url: class 'str'
  • found: class 'int'
  • arguments: class 'NoneType'
  • items: class 'list'
  • pages: class 'int'

Нас интересует:

  • ключ pages, значение которого содержит количество страниц с вакансиями,
  • ключ items, указывающий на список с вакансиями на странице.

Из каждого элемента списка items, который представляет собой словарь, нам понадобится ключ url. Значение по этому ключу является ссылкой на детальное описание вакансии. Последовательно изменяя параметр page можно перебрать все вакансии по запросу и создать список, необходимых для дальнейшего анализа ссылок. Для ускорения процесса загрузки информации о вакансиях используется несколько параллельных потоков из библиотеки threading:

from math import ceil
import requests
from threading import Thread
import json

class DownloadThread(Thread):
   def __init__(self, urls, number, res):
       Thread.__init__(self)
       self.number = number
       self.urls = urls
       self.res = res

   def run(self):
       for url in self.urls:
           resp = requests.get(url)
           if resp.status_code == requests.codes.ok:
               self.res.append(json.loads(requests.get(url).text))
           else:
               print("Status code: " + str(resp.status_code))
               print(url)


def start_dl_threads(urls, th_num, res):
   threads = []
   n = ceil(len(urls) / th_num)
   for i in range(th_num):
       t = DownloadThread(urls[i * n: (i + 1) * n], i, res)
       threads.append(t)
       t.start()
   for t in threads:
       t.join()

После построения зависимости скорости загрузки тестового набора из 274 вакансий от количества потоков загрузки было решено использовать 10 потоков, поскольку, в данном случае, большее их число практически не сокращает время работы скрипта.

Применение Python для анализа смежных востребованных навыков у разработчиков - 2

Формирование словаря навыков и поиск навыков в описании вакансии

Изначально предполагалось создание словаря ключевых навыков вручную. Однако, после анализа структуры описания вакансии, стало ясно, что процесс можно во многом автоматизировать. Для этого нам понадобится доступный по ключу key_skills список, содержащий ключевые навыки данной вакансии. К сожалению, немногие вакансии содержат информацию о ключевых навыках. Кроме того, эта информация может расходиться с основным описанием. Поэтому, обработка только этих данных не дала бы полной картины.

Были собраны все уникальные ключевые навыки по вакансиям имеющим в наименовании “Программист ” + («Java», «JavaScript», «1С», «Python», «C», «C++», «C#», «Objective-C», «Perl», «Ruby», «PHP»), а использованы — первые 150 наиболее часто встречающихся.

os.makedirs("data", exist_ok=True)
langs = ("Java", "JavaScript",
         "1С", "Python",
         "C", "C++",
         "C#", "Objective-C",
         "Perl", "Ruby",
         "PHP")

par = {"text": "", "search_field": "name", "area": 2, "period": 30}
o = {"skills": 1, "urls": 0, "vacs": 0}
for l in langs:
   par["text"] = "Программист " + l
   with open("datadata_" + par["text"] + str(datetime.date.today())
             + ".json", "w") as f:
       json.dump(get_info_from_hh(par, 10, o), f, indent=4, ensure_ascii=False)

data = Counter()
for fn in os.listdir("data"):
   if os.path.isfile("data/" + fn):
       with open("data/" + fn, "r") as rf:
           data += Counter(json.load(rf)["skills"])

for item in data.most_common(150):
   print(item)
jsdict = {item[0]: item[0] for item in data.most_common(150)}
with open("kw.json", "w") as wf:
   json.dump(jsdict, wf, indent=4, ensure_ascii=False, sort_keys=True)

Поиск ключевых слов в описаниях вакансий осуществлялся при помощи регулярного выражения вида:

pattern = r"(?i)[^а-яА-Яa-zA-Z0-9_|^]%s[^а-яА-Яa-zA-Z0-9_|$]" % kw[item]

Поскольку некоторые технологии являются обобщением нескольких более частных, при подсчете по ключу sql, например, использовалось значение вида:

"sql": "sql|mysql|postgresql|ms sql"

Также, для учёта различных названий, относящихся к одной и той же технологии использовались выражения вида:

"шаблоны проектирования": "шаблон.+проектирования|паттерн.+проектирования|design patterns",
"английский язык": "английск.+?|english",
"машинное обучение": "машинн.+?обучен.+?|нейр.+?сет.+?|neural"

Финальный файл ключевых слов можно найти в GitHub репозитории.

При выборе ключевых технологий использовался список топ-20 языков по количеству вакансий (упоминание в названии). При этом оставлены только те языки, которые совместно со словом “Программист” в названии дают более 20 вакансий в Санкт-Петербурге.

Результаты

Результат обработки такого абстрактного понятия как “программист” хорошо отражает общую картину вакансий отрасли. Во-первых видно, что каждый второй работодатель хочет получить от программиста знания sql и английского языка. Каждый третий работодатель хочет, чтобы программист владел системой контроля версий git. В силу ориентации разработки на web, востребованными технологиями являются html и css. Это особенно важно для языков JavaScript и PHP. Несколько неожиданно, но программисту, наверняка, придется работать в команде.

Среди общих технологий, вошедших в двадцатку первых, есть объектно ориентированное программирование, базы данных, алгоритмы и шаблоны проектирования.

В качестве операционной системы предпочтение стоит отдать Linux.

При рассмотрении конкретных языков можно увидеть, что рядом с первой строкой располагается наиболее популярный фреймворк или библиотека. Для Java это Spring и Hibernate, для C#.net и asp.net, Python-программисту наверняка будет нужен Django, а для JavaScript понадобится React.

Особенным и самым нетребовательным является отечественный комплекс . Многим работодателям будет достаточно знания только этой платформы (не имею ни малейшего понятия много это или мало). Полезными навыками станут: работа в команде, понимание процессов тестирования и умение работать с базами данных.

В силу особенностей работы поискового движка hh по запросу “Программист C” было выдано множество результатов с технологией 1С. Поэтому результаты по этому языку получились некорректными.

Полученные результаты по Санкт-Петербургу, привожу ниже.

Применение Python для анализа смежных востребованных навыков у разработчиков - 3
Применение Python для анализа смежных востребованных навыков у разработчиков - 4
Применение Python для анализа смежных востребованных навыков у разработчиков - 5
Применение Python для анализа смежных востребованных навыков у разработчиков - 6
Применение Python для анализа смежных востребованных навыков у разработчиков - 7
Применение Python для анализа смежных востребованных навыков у разработчиков - 8
Применение Python для анализа смежных востребованных навыков у разработчиков - 9
Применение Python для анализа смежных востребованных навыков у разработчиков - 10

Автор: Balexander

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js