рдХреНрдпрд╛ рдЖрдкрдиреЗ рдХрднреА рд░рд┐рдХреНрддрд┐рдпреЛрдВ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд┐рдпрд╛ рд╣реИ?
рдЙрдиреНрд╣реЛрдВрдиреЗ рд╕рд╡рд╛рд▓ рдкреВрдЫрд╛, рд╢реНрд░рдо рдмрд╛рдЬрд╛рд░ рдореЗрдВ рдХреМрди рд╕реА рддрдХрдиреАрдХ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдЪрд╛рд▓реВ рд╣реИ? рдПрдХ рдорд╣реАрдиреЗ рдкрд╣рд▓реЗ? рдПрдХ рд╕рд╛рд▓ рдкрд╣рд▓реЗ?
рдЖрдкрдХреЗ рд╢рд╣рд░ рдХреЗ рдХрд┐рд╕реА рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдирдИ рдЬрд╛рд╡рд╛ рдЬреЙрдм рдУрдкрдирд┐рдВрдЧ рдХрд┐рддрдиреА рдмрд╛рд░ рдЖрддреА рд╣реИ рдФрд░ рд╡реЗ рдХрд┐рддрдиреА рд╕рдХреНрд░рд┐рдпрддрд╛ рд╕реЗ рдмрдВрдж рд╣реЛрддреА рд╣реИрдВ?
рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рдЖрдкрдХреЛ рдмрддрд╛рдКрдВрдЧрд╛ рдХрд┐ рдЖрдк рдХреИрд╕реЗ рд╡рд╛рдВрдЫрд┐рдд рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рд░реБрдЪрд┐ рдХреЗ рд╡рд┐рд╖рдп рдкрд░ рд░рд┐рдкреЛрд░реНрдЯрд┐рдВрдЧ рдкреНрд░рдгрд╛рд▓реА рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЪрд▓реЛ рдЪрд▓рддреЗ рд╣реИрдВ!
(рдЫрд╡рд┐ рд╕реНрд░реЛрдд)рдЪреБрдирд╛рд╡ Headhunter.ru рдкрд░ рдЧрд┐рд░ рдЧрдпрд╛
рд╢рд╛рдпрдж рдЖрдк рдореЗрдВ рд╕реЗ рдХрдИ рдкрд░рд┐рдЪрд┐рдд рд╣реИрдВ рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐
Headhunter.ru рдЬреИрд╕реЗ рд╕рдВрд╕рд╛рдзрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рд╡рд┐рднрд┐рдиреНрди рдХреНрд╖реЗрддреНрд░реЛрдВ рдореЗрдВ рд╣рдЬрд╛рд░реЛрдВ рдирдИ рд░рд┐рдХреНрддрд┐рдпреЛрдВ рдХреЛ рдЗрд╕ рд╕рд╛рдЗрдЯ рдкрд░ рд░реЛрдЬрд╛рдирд╛ рдкреЛрд╕реНрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣реЗрдбрд╣рдВрдЯрд░ рдореЗрдВ рдПрдХ рдПрдкреАрдЖрдИ рднреА рд╣реИ рдЬреЛ рдбреЗрд╡рд▓рдкрд░ рдХреЛ рдЗрд╕ рд╕рдВрд╕рд╛рдзрди рдХреЗ рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
рдЙрдкрдХрд░рдг
рдПрдХ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рд╣рдо рд░рд┐рдкреЛрд░реНрдЯрд┐рдВрдЧ рдкреНрд░рдгрд╛рд▓реА рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рдПрдкреАрдЖрдИ рд╕рд╛рдЗрдЯ Headhunter.ru рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИред рд╕реВрдЪрдирд╛ рдХреЗ рдордзреНрдпрд╡рд░реНрддреА рднрдВрдбрд╛рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ, рд╣рдо рдПрдореНрдмреЗрдбреЗрдб SQLite DBMS рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ, рд╕рдВрд╕рд╛рдзрд┐рдд рдбреЗрдЯрд╛ рдХреЛ рдореБрдЦреНрдп рднрд╛рд╖рд╛ рдХреЗ рд░реВрдк рдореЗрдВ MongoDB рдХреЗ NoSQL рдбреЗрдЯрд╛рдмреЗрд╕, рдкрд╛рдпрдерди 3.4 рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рдПрдЪрдПрдЪ рдПрдкреАрдЖрдИрд╣реЗрдбрд╣рдВрдЯрд░ рдПрдкреАрдЖрдИ рдХреА рдХреНрд╖рдорддрд╛рдПрдВ
рдЧреАрдерд┐рдм рдкрд░ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рджрд╕реНрддрд╛рд╡реЗрдЬ рдореЗрдВ рдХрд╛рдлреА рд╡реНрдпрд╛рдкрдХ рдФрд░ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╡рд░реНрдгрд┐рдд рд╣реИрдВред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдпрд╣ рдЧреБрдордирд╛рдо рдЕрдиреБрд░реЛрдз рднреЗрдЬрдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╣реИ рдЬреЛ рдЬреЙрдиреНрд╕ рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдиреМрдХрд░реА рдХреА рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рд╣рд╛рд▓ рд╣реА рдореЗрдВ, рдХрдИ рддрд░реАрдХреЗ рднреБрдЧрддрд╛рди рдХрд┐рдП рдЧрдП рд╣реИрдВ (рдирд┐рдпреЛрдХреНрддрд╛ рддрд░реАрдХреЗ), рд▓реЗрдХрд┐рди рдЙрдиреНрд╣реЗрдВ рдЗрд╕ рдХрд╛рд░реНрдп рдореЗрдВ рдирд╣реАрдВ рдорд╛рдирд╛ рдЬрд╛рдПрдЧрд╛ред
рдкреНрд░рддреНрдпреЗрдХ рд░рд┐рдХреНрддрд┐ 30 рджрд┐рдиреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рд╛рдЗрдЯ рдкрд░ рд▓рдЯрдХреА рд░рд╣рддреА рд╣реИ, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж, рдпрджрд┐ рдЗрд╕реЗ рдирд╡реАрдиреАрдХреГрдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЗрд╕реЗ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдпрджрд┐ 30 рджрд┐рдиреЛрдВ рдХреА рд╕рдорд╛рдкреНрддрд┐ рд╕реЗ рдкрд╣рд▓реЗ рд░рд┐рдХреНрддрд┐ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рддреЛ рдЗрд╕реЗ рдирд┐рдпреЛрдХреНрддрд╛ рджреНрд╡рд╛рд░рд╛ рдмрдВрдж рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рд╣реЗрдбрд╣рдВрдЯрд░ рдПрдкреАрдЖрдИ (рдЗрд╕рдХреЗ рдмрд╛рдж рдПрдЪрдПрдЪ рдПрдкреАрдЖрдИ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрджрд░реНрднрд┐рдд) рдЖрдкрдХреЛ рдкрд┐рдЫрд▓реЗ 30 рджрд┐рдиреЛрдВ рдореЗрдВ рдХрд┐рд╕реА рднреА рддрд╛рд░реАрдЦ рдХреЗ рд▓рд┐рдП рдкреНрд░рдХрд╛рд╢рд┐рдд рд░рд┐рдХреНрддрд┐рдпреЛрдВ рдХреА рдПрдХ рд╕рд░рдгреА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рд╣рдо рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ - рд╣рдо рджреИрдирд┐рдХ рдЖрдзрд╛рд░ рдкрд░ рдкреНрд░рддреНрдпреЗрдХ рджрд┐рди рдХреЗ рд▓рд┐рдП рдкреНрд░рдХрд╛рд╢рд┐рдд рд░рд┐рдХреНрддрд┐рдпреЛрдВ рдХреЛ рдПрдХрддреНрд░ рдХрд░реЗрдВрдЧреЗред
рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди
- рдХрдиреЗрдХреНрдЯ SQLite DB
import sqlite3 conn_db = sqlite3.connect('hr.db', timeout=10) c = conn_db.cursor()
- рдиреМрдХрд░реА рдХреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рднрдВрдбрд╛рд░рдг рдХреЗ рд▓рд┐рдП рддрд╛рд▓рд┐рдХрд╛
рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП, рд╣рдо SQLite рдбреЗрдЯрд╛рдмреЗрд╕ рдХреА рдПрдХ рд╡рд┐рд╢реЗрд╖ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рд░рд┐рдХреНрддрд┐ рд╕реНрдерд┐рддрд┐ рдкрд░рд┐рд╡рд░реНрддрди (рддрд╛рд░реАрдЦ рддрдХ рдЙрдкрд▓рдмреНрдзрддрд╛) рдХреЗ рдЗрддрд┐рд╣рд╛рд╕ рдХреЛ рдмрдЪрд╛рдПрдВрдЧреЗред рд╡реЗрдХреЗрдВрд╕реА_рд╣реЙрд╕реНрдЯрд░ рдЯреЗрдмрд▓ рдХреА рдмрджреМрд▓рдд, рд╣рдореЗрдВ рд╕рд╛рдЗрдЯ рдкрд░ рд╡реИрдХреЗрдВрд╕реА рдХреА рдЙрдкрд▓рдмреНрдзрддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрддрд╛ рдЪрд▓ рдЬрд╛рдПрдЧрд╛ред рд╡рд╣ рдХрд┐рди рддрд┐рдерд┐рдпреЛрдВ рдореЗрдВ рд╕рдХреНрд░рд┐рдп рдереАред
c.execute(''' create table if not exists vacancy_history ( id_vacancy integer, date_load text, date_from text, date_to text )''')
- рд░рд┐рдХреНрддрд┐ рдЫрд╛рдирдиреЗ рдХрд╛ рдХрд╛рдо
рдПрдХ рдкреНрд░рддрд┐рдмрдВрдз рд╣реИ рдХрд┐ рдПрдХ рдЕрдиреБрд░реЛрдз 2000 рд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрдЧреНрд░рд╣ рдирд╣реАрдВ рд▓реМрдЯрд╛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдЪреВрдВрдХрд┐ рдПрдХ рджрд┐рди рдореЗрдВ рд╕рд╛рдЗрдЯ рдкрд░ рдХрдИ рдФрд░ рд░рд┐рдХреНрддрд┐рдпреЛрдВ рдХреЛ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЕрдиреБрд░реЛрдз рдирд┐рдХрд╛рдп рдореЗрдВ рдПрдХ рдлрд╝рд┐рд▓реНрдЯрд░ рдбрд╛рд▓реЗрдВрдЧреЗ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП: рдХреЗрд╡рд▓ рд╕реЗрдВрдЯ рдкреАрдЯрд░реНрд╕рдмрд░реНрдЧ рдореЗрдВ рд░рд┐рдХреНрддрд┐рдпрд╛рдВ (рдХреНрд╖реЗрддреНрд░ = 2) , рдЖрдИрдЯреА рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рджреНрд╡рд╛рд░рд╛ (рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ = 1)
path = ("/vacancies?area=2&specialization=1&page={}&per_page={}&date_from={}&date_to={}".format(page, per_page, date_from, date_to))
- рдЕрддрд┐рд░рд┐рдХреНрдд рдЪрдпрди рд╢рд░реНрддреЗрдВ
рд╢реНрд░рдо рдмрд╛рдЬрд╛рд░ рддреЗрдЬреА рд╕реЗ рдмрдврд╝ рд░рд╣рд╛ рд╣реИ рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдлрд╝рд┐рд▓реНрдЯрд░ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП, рд░рд┐рдХреНрддрд┐рдпреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ 2000 рд╕реЗ рдЕрдзрд┐рдХ рд╣реЛ рд╕рдХрддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рджрд┐рди рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рд▓реЙрдиреНрдЪ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рд╕реАрдорд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВрдЧреЗ: рджрд┐рди рдХреЗ рдкрд╣рд▓реЗ рдЖрдзреЗ рдХреЗ рд▓рд┐рдП рд░рд┐рдХреНрддрд┐рдпрд╛рдВ рдФрд░ рджреВрд╕рд░реЗ рдЫрдорд╛рд╣реА рдХреЗ рд▓рд┐рдП рд░рд┐рдХреНрддрд┐рдпрд╛рдВред
def get_vacancy_history(): ... count_days = 30 hours = 0 while count_days >= 0: while hours < 24: date_from = (cur_date.replace(hour=hours, minute=0, second=0) - td(days=count_days)).strftime('%Y-%m-%dT%H:%M:%S') date_to = (cur_date.replace(hour=hours + 11, minute=59, second=59) - td(days=count_days)).strftime('%Y-%m-%dT%H:%M:%S') while count == per_page: path = ("/vacancies?area=2&specialization=1&page={} &per_page={}&date_from={}&date_to={}" .format(page, per_page, date_from, date_to)) conn.request("GET", path, headers=headers) response = conn.getresponse() vacancies = response.read() conn.close() count = len(json.loads(vacancies)['items']) ...
рдкрд╣рд▓реЗ рдЙрдкрдпреЛрдЧ рдХрд╛ рдорд╛рдорд▓рд╛рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдо рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕рдордп рдЕрдВрддрд░рд╛рд▓ рдХреЗ рд▓рд┐рдП рдмрдВрдж рдХрд┐рдП рдЧрдП рд░рд┐рдХреНрддрд┐рдпреЛрдВ рдХреА рдкрд╣рдЪрд╛рди рдХрд░рдиреЗ рдХреЗ рдХрд╛рд░реНрдп рдХреЗ рд╕рд╛рде рд╕рд╛рдордирд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЬреБрд▓рд╛рдИ 2018 рдХреЗ рд▓рд┐рдПред рдЗрд╕реЗ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ: рд░рд┐рдХреНрддрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдПрд╕рдХреНрдпреВрдПрд▓ рдХреНрд╡реЗрд░реА рдХрд╛ рдкрд░рд┐рдгрд╛рдо_рд╣реЙрд╕реНрдЯрд░ рдЯреЗрдмрд▓ рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рдЖрд╡рд╢реНрдпрдХ рдбреЗрдЯрд╛ рдХреЛ рд▓реМрдЯрд╛ рджреЗрдЧрд╛, рдЬрд┐рд╕реЗ рдЖрдЧреЗ рдХреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛рдлрд╝реНрд░реЗрдо рдХреЛ рджрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
c.execute(""" select a.id_vacancy, date(a.date_load) as date_last_load, date(a.date_from) as date_publish, ifnull(a.date_next, date(a.date_load, '+1 day')) as date_close from ( select vh1.id_vacancy, vh1.date_load, vh1.date_from, min(vh2.date_load) as date_next from vacancy_history vh1 left join vacancy_history vh2 on vh1.id_vacancy = vh2.id_vacancy and vh1.date_load < vh2.date_load where date(vh1.date_load) between :date_in and :date_out group by vh1.id_vacancy, vh1.date_load, vh1.date_from ) as a where a.date_next is null """, {"date_in" : date_in, "date_out" : date_out}) date_in = dt.datetime(2018, 7, 1) date_out = dt.datetime(2018, 7, 31) closed_vacancies = get_closed_by_period(date_in, date_out) df = pd.DataFrame(closed_vacancies, columns = ['id_vacancy', 'date_last_load', 'date_publish', 'date_close']) df.head()
рд╣рдореЗрдВ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдорд┐рд▓рддрд╛ рд╣реИ:
рдпрджрд┐ рд╣рдо рдПрдХреНрд╕реЗрд▓ рдЯреВрд▓реНрд╕ рдпрд╛ рдерд░реНрдб-рдкрд╛рд░реНрдЯреА рдмреАрдЖрдИ рдЯреВрд▓реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рд░рд┐рдХреНрддрд┐_рд╣рд┐рд╕реНрдЯреНрд░реА рдЯреЗрдмрд▓ рдХреЛ рдФрд░ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реАрдПрд╕рд╡реА рдлрд╛рдЗрд▓ рдореЗрдВ рдЕрдкрд▓реЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
рднрд╛рд░реА рддреЛрдкрдЦрд╛рдиреЗ
рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рд╣рдореЗрдВ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдбреЗрдЯрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ? рдпрд╣рд╛рдБ
MongoDB рджрд╕реНрддрд╛рд╡реЗрдЬрд╝-рдЙрдиреНрдореБрдЦ NoSQL рдбреЗрдЯрд╛рдмреЗрд╕ рдмрдЪрд╛рд╡ рдореЗрдВ рдЖрддрд╛ рд╣реИ, рдЬреЛ рдЖрдкрдХреЛ JSON рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдбреЗрдЯрд╛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
рд░рд┐рдХреНрддрд┐рдпреЛрдВ рдХреЛ рдЗрдХрдЯреНрдард╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрд░реЛрдХреНрдд рдХрд╛рд░реНрдп рджреИрдирд┐рдХ рдЖрдзрд╛рд░ рдкрд░ рд╢реБрд░реВ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рд░ рдмрд╛рд░ рд╕рднреА рд░рд┐рдХреНрддрд┐рдпреЛрдВ рдХреЛ рджреЗрдЦрдиреЗ рдФрд░ рдЙрдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╕реНрддреГрдд рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рд╣рдо рдХреЗрд╡рд▓ рд╡рд╣реА рд▓реЗрдВрдЧреЗ рдЬреЛ рдкрд┐рдЫрд▓реЗ рдкрд╛рдВрдЪ рджрд┐рдиреЛрдВ рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рд╣реБрдП рдереЗред
- SQLite рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдкрд┐рдЫрд▓реЗ 5 рджрд┐рдиреЛрдВ рдХреЗ рд▓рд┐рдП рд░рд┐рдХреНрддрд┐рдпреЛрдВ рдХреА рдПрдХ рд╕рд░рдгреА рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛:
def get_list_of_vacancies_sql(): conn_db = sqlite3.connect('hr.db', timeout=10) conn_db.row_factory = lambda cursor, row: row[0] c = conn_db.cursor() items = c.execute(""" select distinct id_vacancy from vacancy_history where date(date_load) >= date('now', '-5 day') """).fetchall() conn_db.close() return items
- MongoDB рд╕реЗ рдкрд┐рдЫрд▓реЗ рдкрд╛рдВрдЪ рджрд┐рдиреЛрдВ рдХреЗ рд▓рд┐рдП рдиреМрдХрд░рд┐рдпреЛрдВ рдХреА рдПрдХ рд╕рд░рдгреА рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛:
def get_list_of_vacancies_nosql(): date_load = (dt.datetime.now() - td(days=5)).strftime('%Y-%m-%d') vacancies_from_mongo = [] for item in VacancyMongo.find({"date_load" : {"$gte" : date_load}}, {"id" : 1, "_id" : 0}): vacancies_from_mongo.append(int(item['id'])) return vacancies_from_mongo
- рдпрд╣ рджреЛ рд╕рд░рдгрд┐рдпреЛрдВ рдХреЗ рдмреАрдЪ рдЕрдВрддрд░ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдмрдиреА рд╣реБрдИ рд╣реИ, рдЙрди рд░рд┐рдХреНрддрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЬреЛ рдореЛрдВрдЧреЛрдбреАрдмреА рдореЗрдВ рдирд╣реАрдВ рд╣реИрдВ, рд╡рд┐рд╕реНрддреГрдд рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ рдФрд░ рдЗрд╕реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд▓рд┐рдЦреЗрдВ:
sql_list = get_list_of_vacancies_sql() mongo_list = get_list_of_vacancies_nosql() vac_for_pro = [] s = set(mongo_list) vac_for_pro = [x for x in sql_list if x not in s] vac_id_chunks = [vac_for_pro[x: x + 500] for x in range(0, len(vac_for_pro), 500)]
- рдЗрд╕рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдирдИ рд░рд┐рдХреНрддрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд╕рд░рдгреА рд╣реИ рдЬреЛ рдЕрднреА рддрдХ MongoDB рдореЗрдВ рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ рд╣реИрдВ, рдЙрдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХреЗ рд▓рд┐рдП рд╣рдо HH API рдореЗрдВ рдПрдХ рдЕрдиреБрд░реЛрдз рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╡рд┐рд╕реНрддреГрдд рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВрдЧреЗ, рдЗрд╕реЗ рд╕реАрдзреЗ MongoDB рдореЗрдВ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░реЗрдВрдЧреЗ:
- рд╣рдо рд░реВрдмрд▓ рдХреЗ рдмрд░рд╛рдмрд░ рдордЬрджреВрд░реА рдХреА рд░рд╛рд╢рд┐ рд▓рд╛рддреЗ рд╣реИрдВ;
- рдкреНрд░рддреНрдпреЗрдХ рд░рд┐рдХреНрддрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮ рд╕реНрддрд░ рдХрд╛ рд╕реНрдирд╛рддрдХ рдЬреЛрдбрд╝реЗрдВ (рдЬреВрдирд┐рдпрд░ / рдордзреНрдп / рд╡рд░рд┐рд╖реНрда рдЖрджрд┐)
рдпрд╣ рд╕рдм рд░рд┐рдХреНрддрд┐рдпреЛрдВ рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ_рдкреНрд░рдХрд░рдг рдХрд╛рд░реНрдп:
from nltk.stem.snowball import SnowballStemmer stemmer = SnowballStemmer("russian") def vacancies_processing(vacancies_list): cur_date = dt.datetime.now().strftime('%Y-%m-%d') for vacancy_id in vacancies_list: conn = http.client.HTTPSConnection("api.hh.ru") conn.request("GET", "/vacancies/{}".format(vacancy_id), headers=headers) response = conn.getresponse() if response.status != 404: vacancy_txt = response.read() conn.close() vacancy = json.loads(vacancy_txt)
- рдПрдЪрдПрдЪ рдПрдкреАрдЖрдИ рддрдХ рдкрд╣реБрдВрдЪрдХрд░ рд╡рд┐рд╕реНрддреГрдд рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛, рдкреВрд░реНрд╡-рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдкреНрд░рд╛рдкреНрдд рд╣реБрдЖ
MongoDB рдбреЗрдЯрд╛ рдмрд╛рд╣рд░ рд▓реЗ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдЗрд╕реЗ рдХрдИ рдзрд╛рд░рд╛рдУрдВ рдореЗрдВ рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░реЗрдЧрд╛, рдкреНрд░рддреНрдпреЗрдХ рдореЗрдВ 500 рд░рд┐рдХреНрддрд┐рдпрд╛рдВ рд╣реЛрдВрдЧреА:
t_num = 1 threads = [] for vac_id_chunk in vac_id_chunks: print('starting', t_num) t_num = t_num + 1 t = threading.Thread(target=vacancies_processing, kwargs={'vacancies_list': vac_id_chunk}) threads.append(t) t.start() for t in threads: t.join()
MongoDB рдореЗрдВ рдЖрдмрд╛рдж рд╕рдВрдЧреНрд░рд╣ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

рдХреБрдЫ рдФрд░ рдЙрджрд╛рд╣рд░рдг
рд╣рдорд╛рд░реЗ рдирд┐рдкрдЯрд╛рди рдореЗрдВ рдПрдХрддреНрд░рд┐рдд рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рдмрд╛рдж, рд╣рдо рд╡рд┐рднрд┐рдиреНрди рд╡рд┐рд╢реНрд▓реЗрд╖рдгрд╛рддреНрдордХ рдирдореВрдиреЗ рдкреНрд░рджрд░реНрд╢рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рдореИрдВ рд╕реЗрдВрдЯ рдкреАрдЯрд░реНрд╕рдмрд░реНрдЧ рдореЗрдВ рдкрд╛рдпрдерди-рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд╢реАрд░реНрд╖ 10 рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рднреБрдЧрддрд╛рди рдХрд┐рдП рдЧрдП рд░рд┐рдХреНрдд рдкрджреЛрдВ рдХреЛ рдмрд╛рд╣рд░ рд▓рд╛рдКрдВрдЧрд╛:
cursor_mongo = VacancyMongo.find({"name" : {"$regex" : ".*[pP]ython*"}}) df_mongo = pd.DataFrame(list(cursor_mongo)) del df_mongo['_id'] pd.concat([df_mongo.drop(['employer'], axis=1), df_mongo['employer'].apply(pd.Series)['name']], axis=1)[['grade', 'name', 'salary_processed' ]].sort_values('salary_processed', ascending=False)[:10]
рд╢реАрд░реНрд╖ 10 рдкрд╛рдпрдерди рдХреЗ рдЙрдЪреНрдЪрддрдо рднреБрдЧрддрд╛рди рд╡рд╛рд▓реА рдиреМрдХрд░рд┐рдпрд╛рдВрдЧреНрд░реЗрдб | рдирд╛рдо | рдирд╛рдо | salary_processed |
---|
рд╡рд░рд┐рд╖реНрда | рд╡реЗрдм рдЯреАрдо рд▓реАрдб / рд╡рд╛рд╕реНрддреБрдХрд╛рд░ (рдкрд╛рдпрдерди / Django / рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛) | рдЗрдиреНрд╡реЗрд╕реНрдЯреЗрдХреНрд╕ рд▓рд┐ | 293901.0 |
рд╡рд░рд┐рд╖реНрда | рдореЛрдВрдЯреЗрдиреЗрдЧреНрд░реЛ рдореЗрдВ рд╡рд░рд┐рд╖реНрда рдкрд╛рдпрдерди рдбреЗрд╡рд▓рдкрд░ | Betmaster | 277141.0 |
рд╡рд░рд┐рд╖реНрда | рдореЛрдВрдЯреЗрдиреЗрдЧреНрд░реЛ рдореЗрдВ рд╡рд░рд┐рд╖реНрда рдкрд╛рдпрдерди рдбреЗрд╡рд▓рдкрд░ | Betmaster | 275289.0 |
рдмреАрдЪ | рдмреИрдХ-рдПрдВрдб рд╡реЗрдм рдбреЗрд╡рд▓рдкрд░ (рдкрд╛рдпрдерди) | Soshace | 250000.0 |
рдмреАрдЪ | рдмреИрдХ-рдПрдВрдб рд╡реЗрдм рдбреЗрд╡рд▓рдкрд░ (рдкрд╛рдпрдерди) | Soshace | 250000.0 |
рд╡рд░рд┐рд╖реНрда | рд╕реНрд╡рд┐рд╕ рд╕реНрдЯрд╛рд░реНрдЯрдЕрдк рдХреЗ рд▓рд┐рдП рд▓реАрдб рдкрд╛рдпрдерди рдЗрдВрдЬреАрдирд┐рдпрд░ | рдПрд╢рд┐рдпрд╛ рдЗрдВрдЯрд░рдиреЗрд╢рдирд▓ рдПрдЬреА | 250000.0 |
рдмреАрдЪ | рдмреИрдХ-рдПрдВрдб рд╡реЗрдм рдбреЗрд╡рд▓рдкрд░ (рдкрд╛рдпрдерди) | Soshace | 250000.0 |
рдмреАрдЪ | рдмреИрдХ-рдПрдВрдб рд╡реЗрдм рдбреЗрд╡рд▓рдкрд░ (рдкрд╛рдпрдерди) | Soshace | 250000.0 |
рд╡рд░рд┐рд╖реНрда | рдкрд╛рдпрдерди рдЯреАрдорд▓реЗрдб | DigitalHR | 230000.0 |
рд╡рд░рд┐рд╖реНрда | рд▓реАрдб рдбреЗрд╡рд▓рдкрд░ (рдкрд╛рдпрдерди, рдкреАрдПрдЪрдкреА, рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ) | IK рдЧреНрд░реБрдк | 220231.0 |
рдЕрдм рдЖрдЗрдП рдЬрд╛рдиреЗрдВ рдХрд┐ рдХреМрди рд╕реЗ рдореЗрдЯреНрд░реЛ рд╕реНрдЯреЗрд╢рди рдореЗрдВ рдЬрд╛рд╡рд╛ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП рд░рд┐рдХреНрдд рдкрджреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╣реИред рдПрдХ рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рдореИрдВ рдиреМрдХрд░реА рд╢реАрд░реНрд╖рдХ "рдЬрд╛рд╡рд╛" рджреНрд╡рд╛рд░рд╛ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░рддрд╛ рд╣реВрдВ, рдФрд░ рдХреЗрд╡рд▓ рдЙрди рдиреМрдХрд░рд┐рдпреЛрдВ рдХрд╛ рдЪрдпрди рдХрд░рддрд╛ рд╣реВрдВ рдЬрд╣рд╛рдВ рдкрддрд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╣реИ:
cursor_mongo = VacancyMongo.find({"name" : {"$regex" : ".*[jJ]ava[^sS]"}, "address" : {"$ne" : None}}) df_mongo = pd.DataFrame(list(cursor_mongo)) df_mongo['metro'] = df_mongo.apply(lambda x: x['address']['metro']['station_name'] if x['address']['metro'] is not None else None, axis = 1) df_mongo.groupby('metro')['_id'] \ .count() \ .reset_index(name='count') \ .sort_values(['count'], ascending=False) \ [:10]
рдореЗрдЯреНрд░реЛ рд╕реНрдЯреЗрд╢рдиреЛрдВ рдореЗрдВ рдЬрд╛рд╡рд╛ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП рдиреМрдХрд░рд┐рдпрд╛рдВрдореЗрдЯреНрд░реЛ | рдЧрд┐рдирддреА |
---|
Vasileoostrovskaya | 87 |
рдкреЗрдЯреНрд░реЛрдЧреНрд░реИрдб | 68 |
Vyborg | 46 |
рд▓реЗрдирд┐рди рд╕реНрдХреНрд╡рд╛рдпрд░ | 45 |
рдЧреЛрд░реНрдХреА | 45 |
Chkalovskaya | 43 |
рдирд╛рд░реНрд╡рд╛ | 32 |
рд╡рд┐рджреНрд░реЛрд╣реА рд╡рд░реНрдЧ | 29 |
рдкреБрд░рд╛рдирд╛ рдЧрд╛рдБрд╡ | 29 |
Elizarovskaya | 27 |
рдкрд░рд┐рдгрд╛рдо
рддреЛ, рд╡рд┐рдХрд╕рд┐рдд рдкреНрд░рдгрд╛рд▓реА рдХреА рд╡рд┐рд╢реНрд▓реЗрд╖рдгрд╛рддреНрдордХ рдХреНрд╖рдорддрд╛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╡реНрдпрд╛рдкрдХ рд╣реИ рдФрд░ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕реНрдЯрд╛рд░реНрдЯрдЕрдк рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛рдиреЗ рдпрд╛ рдЧрддрд┐рд╡рд┐рдзрд┐ рдХреА рдПрдХ рдирдИ рджрд┐рд╢рд╛ рдЦреЛрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдореИрдВ рдзреНрдпрд╛рди рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдЕрдм рддрдХ рдХреЗрд╡рд▓ рд╕рд┐рд╕реНрдЯрдо рдХреА рдмреБрдирд┐рдпрд╛рджреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдкреНрд░рд╕реНрддреБрдд рдХреА рдЬрд╛рддреА рд╣реИ, рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдЗрд╕реЗ рднреМрдЧреЛрд▓рд┐рдХ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рджреНрд╡рд╛рд░рд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреА рджрд┐рд╢рд╛ рдореЗрдВ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреЗ рдФрд░ рд╢рд╣рд░ рдХреЗ рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рд░рд┐рдХреНрддрд┐рдпреЛрдВ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреА рднрд╡рд┐рд╖реНрдпрд╡рд╛рдгреА рдХрд░рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рд╣реИред
рдЗрд╕ рд▓реЗрдЦ рдХреЗ рд▓рд┐рдП рдкреВрд░реНрдг рд╕реНрд░реЛрдд рдХреЛрдб рдореЗрд░реЗ
GitHub рдХреЗ рд▓рд┐рдВрдХ рдкрд░ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛
рд╣реИ ред
PS рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ рд▓реЗрдЦ рдкрд░ рдЖрдкрдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИ, рдореБрдЭреЗ рдЖрдкрдХреЗ рд╕рднреА рд╕рд╡рд╛рд▓реЛрдВ рдХреЗ рдЬрд╡рд╛рдм рджреЗрдиреЗ рдФрд░ рдЖрдкрдХреА рд░рд╛рдп рдЬрд╛рдирдиреЗ рдореЗрдВ рдЦреБрд╢реА рд╣реЛрдЧреАред рдзрдиреНрдпрд╡рд╛рдж!