1. 程式人生 > 其它 >BOSS直聘資料抓取之初級爬蟲(資料分析)

BOSS直聘資料抓取之初級爬蟲(資料分析)

目前國內使用較多的招聘網站是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 =0
24 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請備註說明來意,否則不會通過)本人做資料分析類的工作,歡迎一起學習。

歡迎評論