
Apakah Anda ingin tahu apa situasinya di pasar tenaga kerja, terutama di bidang ilmu data?
Jika Anda mengenal Python dan Pandas, parsing headhunter sepertinya adalah cara paling andal dan mudah.
Kode berfungsi pada Python3.6 dan Pandas 0.24.2
Ipython dapat diunduh di sini .
Untuk memeriksa versi konsol Pandas (Linux / MacOS):
ipython
Dan kemudian pada baris perintah
#ipython import pandas as pd pd.__version__
# () pip install pandas==0.24.2
Sudah mengkonfigurasi semuanya? Ayo pergi!
Parsim dengan Python
HH memungkinkan Anda menemukan pekerjaan di Rusia. Sumber daya perekrutan ini memiliki database lowongan terbesar. HH berbagi api yang nyaman.
Googled sedikit dan ternyata menulis parser.
# https://gist.github.com/fuwiak/9c695b51c33b2e052c5a721383705a9c # (BASH) python3 hh_parser.py import requests import pandas as pd number_of_pages = 100 #number_of_ads = number_of_pages * per_page job_title = ["'Data Analyst' and 'data scientist'"] for job in job_title: data=[] for i in range(number_of_pages): url = 'https://api.hh.ru/vacancies' par = {'text': job, 'area':'113','per_page':'10', 'page':i} r = requests.get(url, params=par) e=r.json() data.append(e) vacancy_details = data[0]['items'][0].keys() df = pd.DataFrame(columns= list(vacancy_details)) ind = 0 for i in range(len(data)): for j in range(len(data[i]['items'])): df.loc[ind] = data[i]['items'][j] ind+=1 csv_name = job+".csv" df.to_csv(csv_name)
Akibatnya, kami mendapat file csv dengan nama yang ditentukan di job_title.
Dalam satu file tertentu dengan lowongan dengan frasa akan diunduh
"Analis Data" dan "ilmuwan data." Jika Anda ingin secara terpisah mengubah jalur ke
job_title=['Data Analyst', 'Data Scientist']
Maka Anda mendapatkan 2 file dengan nama-nama ini.
Menariknya, ada operator lain selain "dan". Dengan bantuan mereka, Anda dapat mencari pasangan yang tepat. Lebih detail di sini.
https://hh.ru/article/309400
Jam berapa sekarang? Waktu Pandanya!
Iklan yang dikumpulkan dengan cara ini akan dibagi menjadi beberapa kelompok sesuai dengan informasi yang terkandung di dalamnya atau deskripsi metadata mereka. Sebagai contoh: kota; posisi pasang pembayaran; kategori pekerjaan. Dalam hal ini, satu iklan dapat menjadi bagian dari beberapa kategori.
Saya akan mengurus data yang terkait dengan posisi "ilmuwan data" menggunakan jupyter-notebook. https://jupyter.org/

Apa yang harus dilakukan untuk mengubah nama kolom "Tanpa Nama"?

Pertanyaan paling penting - ZP
import ast # run code from string for example ast.literal_eval("1+1") salaries = df.salary.dropna() # remove all NA's from dataframe currencies = [ast.literal_eval(salaries.iloc[i])['currency'] for i in range(len(salaries))] curr = set(currencies) #{'EUR', 'RUR', 'USD'} #divide dataframe salararies by currency rur = [ast.literal_eval(salaries.iloc[i]) for i in range(len(salaries)) if ast.literal_eval(salaries.iloc[i])['currency']=='RUR'] eur = [ast.literal_eval(salaries.iloc[i]) for i in range(len(salaries)) if ast.literal_eval(salaries.iloc[i])['currency']=='EUR'] usd = [ast.literal_eval(salaries.iloc[i]) for i in range(len(salaries)) if ast.literal_eval(salaries.iloc[i])['currency']=='USD']
Ternyata untuk membagi gaji menjadi mata uang, Anda sendiri bisa mencoba melakukan analisis misalnya hanya untuk euro. Saya hanya akan berurusan dengan gaji rubel sekarang
fr = [x['from'] for x in rur] # lower range of salary fr = list(filter(lambda x: x is not None, fr)) # remove NA's from lower range [0, 100, 200,...] to = [x['to'] for x in rur] #upper range of salary to = list(filter(lambda x: x is not None, to)) #remove NA's from upper range [100, 200, 300,...] import numpy as np salary_range = list(zip(fr, to)) # concatenate upper and lower range [(0,100), (100, 200), (200, 300)...] av = map(np.mean, salary_range) # convert [(0,100), (100, 200), (200, 300)...] to [50, 150, 250,...] av = round(np.mean(list(av)),1) # average value from [50, 150, 250,...] print("average salary as Data Scientist ", av, "rubles")
Akhirnya, kami belajar sekitar 150 ribu rubel, seperti yang diharapkan .
Untuk gaji rata-rata, saya memiliki ketentuan berikut:
- tidak mempertimbangkan lowongan di mana tidak ada gaji yang ditentukan (df.salary.dropna)
- hanya mengambil gaji dalam rubel
- jika ada colokan, maka ambil nilai rata-rata (misalnya, colokan dari 10.000 gosok menjadi 20.000 gosok β 15.000 gosok).
Saya akan mengatakan yang berikut kepada troll, orang-orang yang berpikiran lemah dan amatir untuk mencari makna rahasia: Saya bukan karyawan hh.ru; Artikel ini bukan iklan; Saya tidak mendapatkan satu sen untuknya. Semoga beruntung untuk semuanya.
Bonus
Bagaimana Juni permintaan di bidang Ilmu Data?

from collections import Counter vacancy_names = df.name # change here to change source of data/words etc cloud = Counter(vacancy_names) from wordcloud import WordCloud, STOPWORDS stopwords = set(STOPWORDS) cloud = '' for x in list(vacancy_names): cloud+=x+' ' wordcloud = WordCloud(width = 800, height = 800, stopwords = stopwords, min_font_size = 8,background_color='white' ).generate(cloud) import matplotlib.pylab as plt plt.figure(figsize = (16, 16)) plt.imshow(wordcloud) plt.savefig('vacancy_cloud.png')
[REPO] ( https://github.com/fuwiak/HH )
EDIT:
Versi Pengguna Zoldaten
Parser hh
Kode ini bukan hak cipta, kecuali untuk beberapa kruk.
# !/usr/bin/python3 # -*- coding: utf-8 -*- import sys import xlsxwriter # pip install XlsxWriter import requests # pip install requests from bs4 import BeautifulSoup as bs # pip install beautifulsoup4 headers = {'accept': '*/*', 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'} vacancy = input(' : ') base_url = f'https://hh.ru/search/vacancy?area=1&search_period=30&text={vacancy}&page=' # area=1 - , search_period=3 - 30 pages = int(input(' - : ')) #+ jobs =[] def hh_parse(base_url, headers): zero = 0 while pages > zero: zero = str(zero) session = requests.Session() request = session.get(base_url + zero, headers = headers) if request.status_code == 200: soup = bs(request.content, 'html.parser') divs = soup.find_all('div', attrs = {'data-qa': 'vacancy-serp__vacancy'}) for div in divs: title = div.find('a', attrs = {'data-qa': 'vacancy-serp__vacancy-title'}).text compensation = div.find('div', attrs={'data-qa': 'vacancy-serp__vacancy-compensation'}) if compensation == None: # compensation = 'None' else: compensation = div.find('div', attrs={'data-qa': 'vacancy-serp__vacancy-compensation'}).text href = div.find('a', attrs = {'data-qa': 'vacancy-serp__vacancy-title'})['href'] try: company = div.find('a', attrs = {'data-qa': 'vacancy-serp__vacancy-employer'}).text except: company = 'None' text1 = div.find('div', attrs = {'data-qa': 'vacancy-serp__vacancy_snippet_responsibility'}).text text2 = div.find('div', attrs = {'data-qa': 'vacancy-serp__vacancy_snippet_requirement'}).text content = text1 + ' ' + text2 all_txt = [title, compensation, company, content, href] jobs.append(all_txt) zero = int(zero) zero += 1 else: print('error') # Excel workbook = xlsxwriter.Workbook('Vacancy.xlsx') worksheet = workbook.add_worksheet() # bold = workbook.add_format({'bold': 1}) bold.set_align('center') center_H_V = workbook.add_format() center_H_V.set_align('center') center_H_V.set_align('vcenter') center_V = workbook.add_format() center_V.set_align('vcenter') cell_wrap = workbook.add_format() cell_wrap.set_text_wrap() # worksheet.set_column(0, 0, 35) # A https://xlsxwriter.readthedocs.io/worksheet.html#set_column worksheet.set_column(1, 1, 20) # B worksheet.set_column(2, 2, 40) # C worksheet.set_column(3, 3, 135) # D worksheet.set_column(4, 4, 45) # E worksheet.write('A1', '', bold) worksheet.write('B1', '', bold) worksheet.write('C1', '', bold) worksheet.write('D1', '', bold) worksheet.write('E1', '', bold) row = 1 col = 0 for i in jobs: worksheet.write_string (row, col, i[0], center_V) worksheet.write_string (row, col + 1, i[1], center_H_V) worksheet.write_string (row, col + 2, i[2], center_H_V) worksheet.write_string (row, col + 3, i[3], cell_wrap) # worksheet.write_url (row, col + 4, i[4], center_H_V) worksheet.write_url (row, col + 4, i[4]) row += 1 print('OK') workbook.close() hh_parse(base_url, headers)