BOSS直聘資料抓取之初級爬蟲(資料分析)
目前國內使用較多的招聘網站是boss直聘網,它有個優點就是可實時聊天溝通,免去了求職者胡亂海投,而且中間可能很多都沒有招聘回覆,對求職者非常友好。但海量的職位資料,我們有時也會蒙圈,不知道到底哪些職位才適合自己。 所以我們可能會想抓取一些職位回來分析。通過招聘職位資料,我們可以分析出自己所處行業的平均薪資,需求使用者數,然後更好的制定自己的職業規劃。
廢話不多說,我們直接擼個小爬蟲來實現這個簡單的需求。(本文 原始碼可加我索要, 也可以留下郵箱,我會定期批量發出)
為了完成本次需求,你需要了解或者熟悉初級的程式設計知識,如python語法,爬蟲相關的python庫等,對於技術細節我不會講解太多,網上都有現成的,感興趣的同學可以百度去搜一下教程
用到的技術如下(都是開源免費的技術):
Python3.7.7
playwright==1.15.3
lxml==4.6.3
以上幾個包需要自己先安裝好,實在不會的可加我詢問。接下來我們一步步來實現吧!
進入boss直聘官網,現在可以免登入就可以瀏覽。假定我們的關注的行業是是北京-資料分析師。我們在網頁中搜索,如圖所示:
官網截圖然後拉到下面可以看到,可以最多翻頁10頁,每頁30條資料,所以我們就抓取這300條資料用來做個簡單的分析。
playwright 就是我們小爬蟲用到的一個重要工具了,它可以模擬人工做很多自動化的操作,比如開啟連結,點選,移動等,反正基本上手工能做的操作,它都能實現。
先在檔案開始匯入用到的包:
1 import os 2 3 import time 4 5 import platform 6 7 import traceback 8 9 from ioimport StringIO 10 11 from lxmlimport etree 12 13 from playwright.sync_apiimport sync_playwright 14 15 接下來定義一些變數: 16 17 # 全域性變數 18 19 totalCount =0 20 21 totalNewCount =0 22 23 page_count =024 25 got_blocked =False 26 27 city_name ='' 28 29 job_data_list = []# 用於儲存所有的職位資訊 30 31 # 儲存使用者的瀏覽器目錄(Mac電腦的目錄) 32 33 USER_DATA_BASE_DIR ='/Users/xiaowang/Documents/my/playwright-user-data/' 34 35 OUTPUT_DIR ='/Users/xiaowang/Documents/test_files/' 36 37 if platform.system() !='Darwin': 38 39 # Windows的目錄 40 41 USER_DATA_BASE_DIR ='F:/projects/userdata/' 42 43 OUTPUT_DIR ='F:/projects/test_files/'
然後定義一個 解析函式,用於解析抓取到的職位列表頁面,這裡用到了不少知識點,如xpath,它就用來在html網頁中準確定位元素的一個語言,而python的lxml庫就實現了它,用起來也是相當的方便。
def parse_and_update_result_job(response): """ 解析職位列表 """ global totalCount, page_count, job_data_list content = response.body().decode("utf-8") tree = get_tree(content) divxp ="//div[@id='main']/div[@class='job-box']/div[@class='job-list']/ul/li" page_count =0 for n, iin enumerate(tree.xpath(divxp)): print('index: {}'.format(n+1)) jobName = get_first_text(i, "./div[@class='job-primary']/div[@class='info-primary']/div[@class='primary-wrapper']/div[@class='primary-box']/div[@class='job-title']/span[@class='job-name']/a") # /job_detail/0f5d152d524d87771nJ80tm8ElJR.html href = get_first(i, "./div[@class='job-primary']/div[@class='info-primary']/div[@class='primary-wrapper']/div[@class='primary-box']/div[@class='job-title']/span[@class='job-name']/a/@href") print('name: {}'.format(jobName)) job_id = href.split('/')[-1].split('.')[0] logo = get_first(i, "./div[@class='job-primary']/div[@class='info-primary']/div[@class='info-company']/a/img[@class='company-logo']/@src") brandName = get_first_text(i, "./div[@class='job-primary']/div[@class='info-primary']/div[@class='info-company']/div[@class='company-text']/h3[@class='name']/a") # /gongsi/3c1c53145ad9e62903Rz29U~.html company_href = get_first(i, "./div[@class='job-primary']/div[@class='info-primary']/div[@class='info-company']/div[@class='company-text']/h3[@class='name']/a/@href") company_id = company_href.split('.')[0].split('/')[-1] # 廣州·天河區·珠江新城 area = get_first_text(i, ".//div[@class='job-title']/span[@class='job-area-wrapper']/span[@class='job-area']") salaryDesc = get_first(i, ".//div[@class='job-limit clearfix']/span[@class='red']/text()") gs_info = get_joined_str(i, ".//div[@class='info-company']/div[@class='company-text']/p//text()", '|') dic = { 'job_id': job_id, 'jobName': jobName, 'brandLogo': logo, 'brandName': brandName, 'company_id': company_id, 'city': area.split('·')[0], 'cityName': area.split('·')[0], 'area': area, 'href':'https://www.zhipin.com{}'.format(href), 'salaryDesc': salaryDesc, 'gs_info': gs_info } for k, vin dic.items(): print('{} -> {}'.format(k, v)) job_data_list.append(dic) print('成功抓取一條資料 \n') totalCount +=1 page_count +=1 print('--> 已經成功抓取總個數: {}'.format(totalCount)) print('\n')
接下來就是爬蟲的主要部分了,涉及到playwright的功能,比如開啟,導航,翻頁等
class MainRunner(object): def __init__(self, p): super(MainRunner, self).__init__() self.browser = p.chromium# .launch(headless=False) self.max_page_job =10 # 職位最多抓取10頁 def run_job(self): """ 開始執行 """ global got_blocked, page_count, job_data_list print('職位抓取...') url_tmpl ='https://www.zhipin.com/c101010100/?query=%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90&page={p}&ka=page-{p}' site_name ='zhipin' user_data_dir = os.path.join(USER_DATA_BASE_DIR, '{}1'.format(site_name)) context =self.browser.launch_persistent_context( user_data_dir, headless=False, ) # 取第一個tab頁面 page = context.pages[0] # 註冊頁面監控事件 page.on("response", lambda response: process_response_job(response)) # 先開啟首頁 page.goto('https://www.zhipin.com/') time.sleep(5) scrapyed_url = [] code ='c101010100' city_name ='北京' for pgin range(1, self.max_page_job +1): url = url_tmpl.format(code=code, p=pg) if urlin scrapyed_url: print('重複的url: {}, continue'.format(url)) continue print(u'{} page:{}, 抓取: {}'.format(city_name, pg, url)) try: page.goto(url) print('本頁已開啟完成...') except: print(u'* 開啟網頁遇到問題: {}'.format(traceback.format_exc())) scrapyed_url.append(url) print(u'end, {} page:{}, 抓取: {}'.format(city_name, pg, url)) time.sleep(5) if got_blocked: print('開始sleep.......') time.sleep(2 *3600) got_blocked =False # 開始寫入excel檔案 time.sleep(3) tmp_file_name ='bosszhipin_job_data_{}.csv'.format(int(time.time())) final_file = os.path.join(OUTPUT_DIR, tmp_file_name) print('最終輸出檔案: {}'.format(final_file)) with open(final_file, 'w')as f: f.write('名稱,編號,公司,城市,區,薪水,公司情況,網址\n') for din job_data_list: row ='{},{},{},{},{},{},{},{}\n'.format(d['jobName'], d['job_id'], d['brandName'], d['city'], d['area'], d['salaryDesc'], d['gs_info'], d['href']) f.write(row) print('檔案寫入完成..') print('全部處理完成,直接退出.') page.close() if __name__ =='__main__': with sync_playwright()as p: runner = MainRunner(p) # 抓取職位 北京 資料分析師 runner.run_job()
上面的主程式的最後部分,是將抓取到的職位列表,寫入一個本地的csv檔案中,可以用WPS開啟檢視,當然細節的話你可以自己調整,比如轉化薪水為年薪,然後算出平均年薪,這樣對自己就有一個心理價位了。
這樣爬蟲就實現完成了,但這個簡書的顯示效果真是很不行,沒能自動識別出程式語言,有要程式碼的可加我微信或留下郵箱。下面我就截圖看看執行效果:
爬蟲執行結果然後下面是匯出的檔案,接下來你就可以自己在excel中分析了,當然本程式可擴充套件的地方就太多了,看自己的喜好,比如儲存到資料庫中,將公司的資訊分類儲存,這樣就能輕易分析出成千上萬的職位了。當然了,本指令碼只是用於簡單的分析,請不要做一些違規的用途。
資料匯出csv檔案用wps開啟感興趣的同學如有問題可一起討論(newtime9244請備註說明來意,否則不會通過)本人做資料分析類的工作,歡迎一起學習。
歡迎評論