天天看點

資料分析行業薪資的秘密,你想知道的都在這裡(1)

<a href="http://s1.51cto.com/wyfs02/M02/9E/82/wKioL1mSpyfBl1s_AAMvpJbtRcw697.jpg-wh_651x-s_1320620508.jpg" target="_blank"></a>

第一部分,資料分析職位資訊抓取

資料分析師的收入怎麼樣?哪些因素對于資料分析的薪資影響最大?哪些行業對資料分析人才的需求量最高?我想跳槽,應該選擇大公司大平台還是初創的小公司?按我目前的教育程度,工作經驗,和掌握的工具和技能,能獲得什麼樣水準的薪資呢?

我們使用python抓取了2017年6月26日拉鈎網站内搜尋“資料分析”關鍵詞下的450條職位資訊。通過對這些職位資訊的分析和模組化來給你答案。

<a href="http://s4.51cto.com/wyfs02/M02/9E/82/wKioL1mSp0Ti5kBeAALnK8AOyQc498.png" target="_blank"></a>

本系列文章共分為五個部分,分别是資料分析職位資訊抓取,資料清洗及預處理,資料分析職位需求分析,資料分析職位薪影響因素分析,以及資料分析職位薪資模組化及預測。這是第一篇:資料分析職位資訊抓取。

資料抓取前的準備工作

首先我們需要擷取職位資訊的資料,方法是使用python進行抓取。整個抓取過程分為兩部分,第一部分是抓取拉鈎清單頁中包含的職位資訊,例如職位名稱,薪資範圍,學曆要求,工作地點等。第二部分是抓取每個職位詳情頁中的任職資格和職位描述資訊。然後我們将使用結巴分詞和nltk對職位描述中的文字資訊進行處理和資訊提取。下面我們開始介紹每一步的操作過程。

首先,導入抓取和資料處理所需的庫檔案,這裡不再贅述。

#導入抓取所需庫檔案 

import requests 

import numpy as np 

import pandas as pd 

import json 

import time 

from bs4 import BeautifulSoup  

然後設定頭部資訊和Cookie資訊。

#設定頭部資訊 

headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11', 

    'Accept':'text/html;q=0.9,*/*;q=0.8', 

    'Accept-Charset':'ISO-8859-1,utf-8;q=0.7,*;q=0.3', 

    'Connection':'close', 

    'Referer':'https://www.baidu.com/' 

    } 

#設定Cookie資訊 

cookie={'TrackID':'1_VWwvLYiy1FUr7wSr6HHmHhadG8d1-Qv-TVaw8JwcFG4EksqyLyx1SO7O06_Y_XUCyQMksp3RVb2ezA', 

    '__jda':'122270672.1507607632.1423495705.1479785414.1479794553.92', 

    '__jdb':'122270672.1.1507607632|92.1479794553', 

    '__jdc':'122270672', 

    '__jdu':'1507607632', 

    '__jdv':'122270672|direct|-|none|-|1478747025001', 

    'areaId':'1', 

    'cn':'0', 

    'ipLoc-djd':'1-72-2799-0', 

    'ipLocation':'%u5317%u4EAC', 

    'mx':'0_X', 

    'rkv':'V0800', 

    'user-key':'216123d5-4ed3-47b0-9289-12345', 

    'xtest':'4657.553.d9798cdf31c02d86b8b81cc119d94836.b7a782741f667201b54880c925faec4b'}  

抓取職位清單資訊

設定要抓取的頁面URL,拉鈎的職位資訊清單是JS動态加載的,不在所顯示的頁面URL中。是以直接抓取清單頁并不能獲得職位資訊。這裡我們使用Chrome浏覽器裡的開發者工具進行查找。具體方法是在商品詳情頁點選滑鼠右鍵,選擇檢查,在彈出的開發者工具界面中選擇Network,設定為禁用緩存(Disable cache)和隻檢視XHR類型的請求。然後重新整理頁面。一共有4個請求,選擇包含positionAjax關鍵字的連結就是我們要抓取的URL位址。具體過程如下面截圖所示。

<a href="http://s4.51cto.com/wyfs02/M02/9E/93/wKiom1mSp5bSIZUFAAF0tsS2ZqU945.jpg" target="_blank"></a>

這裡有一個問題,要抓取的URL位址中隻有第一頁的15個職位資訊,并且URL參數中也沒有包含頁碼。而我們要抓取的是全部30多頁的職位清單。如何翻頁呢?後面我們将解決這個問題。

#設定抓取頁面的URL 

url='https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false'  

職位清單中包含了多個職位相關的資訊,我們先建立一些空list用于存儲這些資訊。

#建立list用于存儲資料 

positionName=[] 

workYear=[] 

education=[] 

district=[] 

jobNature=[] 

salary=[] 

city=[] 

businessZones=[] 

companyLabelList=[] 

companySize=[] 

financeStage=[] 

industryField=[] 

secondType=[] 

positionId=[]  

開始抓取清單頁中的職位資訊,建立一個30頁的循環然後将頁碼作為請求參數與頭部資訊和Cookie一起傳給伺服器。擷取傳回的資訊後對頁面内容進行解碼,然後從json資料中提取所需的職位資訊,并儲存在上一步建立的list中。用于後續的組表。這裡的最後一個資訊是職位id,也就是拉鈎職位詳情頁URL中的一部分。通過這個id我們可以生成與清單頁職位相對應的詳情頁URL。并從中提取任職資格和職位描述資訊。

#循環抓取清單頁資訊 

for x in range(1,31): 

        #設定查詢關鍵詞及目前頁碼 

        para = {'first': 'true','pn': x, 'kd': "資料分析"} 

        #抓取清單頁資訊 

        r=requests.get(url=url,headers=headers,cookies=cookie,params=para) 

        #存儲bytes型頁面資料 

        html=r.content 

        #對頁面内容進行解碼 

        html = html.decode() 

        #将json串轉化為dict 

        html_json=json.loads(html) 

        #逐層擷取職位清單資訊 

        content=html_json.get('content') 

        positionResult=content.get('positionResult') 

        result=positionResult.get('result') 

        #循環提取職位清單中的關鍵資訊 

        for i in result: 

            #擷取職位名稱,工作年限,教育程度,城市及薪資範圍等資訊。 

            positionName.append(i.get('positionName')) 

            workYear.append(i.get('workYear')) 

            education.append(i.get('education')) 

            district.append(i.get('district')) 

            jobNature.append(i.get('jobNature')) 

            salary.append(i.get('salary')) 

            city.append(i.get('city')) 

            businessZones.append(i.get('businessZones')) 

            companyLabelList.append(i.get('companyLabelList')) 

            companySize.append(i.get('companySize')) 

            financeStage.append(i.get('financeStage')) 

            industryField.append(i.get('industryField')) 

            secondType.append(i.get('secondType')) 

            #擷取職位的Id編碼。 

            positionId.append(i.get('positionId'))  

設定一個目前的日期字段,用于标記資料擷取的時間。

#設定日期字段 

date=time.strftime('%Y-%m-%d',time.localtime(time.time()))  

将前面抓取到的職位資訊,以及目前的日期一起組成Dataframe。便于後續的處理和分析。

#設定DataFrame表格順序 

columns = ['date','positionName',  

'workYear','education','jobNature','businessZones','salary','city','companyLabelList','companySize','financeStage','industryField','d 

istrict','secondType','positionId'] 

#将擷取到的字段資訊合并為DataFrame 

table=pd.DataFrame({'date':date, 

                    'positionName':positionName, 

                    'workYear':workYear, 

                    'education':education, 

                    'jobNature':jobNature, 

                    'businessZones':businessZones, 

                    'salary':salary, 

                    'city':city, 

                    'companyLabelList':companyLabelList, 

                    'companySize':companySize, 

                    'financeStage':financeStage, 

                    'industryField':industryField, 

                    'district':district, 

                    'secondType':secondType, 

                    'positionId':positionId}, 

                    columns=columns)  

檢視生成的資料表,其中包含了我們在清單頁中抓取的資訊,以及下一步要使用的職位id資訊。

#檢視資料表 

table 

<a href="http://s1.51cto.com/wyfs02/M00/9E/82/wKioL1mSqB_Qj63jAAEr12RKfAc664.jpg" target="_blank"></a>

這裡你可以儲存一個版本,也可以忽略這一步,繼續後面的職位詳情頁資訊抓取。

#存儲資料表 

table.to_csv('lagou_' + date + '.csv')  

抓取職位詳情資訊(職位描述)

抓取職位詳情頁的資訊,首先需要通過拼接生成職位詳情頁的URL。我們預先寫好URL的開始和結束部分,這兩部分是固定的,抓取過程中不會發生變化 ,中間動态填充職位的id。

#設定詳情頁的URL固定部分 

url1='https://www.lagou.com/jobs/' 

url2='.html'  

建立一個list用于存儲抓取到的職位描述資訊。

#建立job_detail用于存儲職位描述 

job_detail=[]  

從前面抓取的職位id(positionId)字段循環提取每一個id資訊,與URL的另外兩部分組成要抓取的職位詳情頁URL。并從中提取職位描述資訊。這裡的職位資訊不是js動态加載的,是以直接抓取頁面資訊儲存在之前建立的list中就可以了。

#循環抓取詳情頁的職位描述 

for d in positionId: 

    #更改positionId格式 

    d=str(d) 

    #拼接詳情頁URL 

    url3=(url1 + d + url2) 

    #抓取詳情頁資訊 

    r=requests.get(url=url3,headers=headers,cookies=cookie) 

    #存儲bytes型頁面資料yu 

    detail=r.content 

    #建立 beautifulsoup 對象 

    lagou_detail=BeautifulSoup(detail) 

    #提取職位描述資訊 

    gwzz=lagou_detail.find_all('dd',attrs={'class':'job_bt'})    

    for j in gwzz: 

        gwzz_text=j.get_text() 

        job_detail.append(gwzz_text)  

檢視并檢查一下提取到的職位描述資訊。然後将職位描述資訊拼接到之前建立的Dataframe中。

#檢視職位描述資訊 

job_detail 

<a href="http://s3.51cto.com/wyfs02/M02/9E/94/wKiom1mSqG6RCR8BAAHvEUORd9I023.jpg" target="_blank"></a>

完整的職位抓取代碼

以下是完整的抓取代碼,步驟和前面介紹的略有不同,最後生成一個包含所有職位資訊和描述的完整資料表。用于下一步的資料清洗,預處理,分析和模組化的工作。

def lagou(p): 

    import requests 

    import numpy as np 

    import pandas as pd 

    import json 

    import time 

    from bs4 import BeautifulSoup 

    import jieba as jb 

    import jieba.analyse 

    headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11', 

    'Referer':'https://www.jd.com/' 

    cookie={'TrackID':'1_VWwvLYiy1FUr7wSr6HHmHhadG8d1-Qv-TVaw8JwcFG4EksqyLyx1SO7O06_Y_XUCyQMksp3RVb2ezA', 

    'xtest':'4657.553.d9798cdf31c02d86b8b81cc119d94836.b7a782741f667201b54880c925faec4b'} 

    url='https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false' 

    positionName=[] 

    workYear=[] 

    education=[] 

    district=[] 

    jobNature=[] 

    salary=[] 

    city=[] 

    businessZones=[] 

    companyLabelList=[] 

    companySize=[] 

    financeStage=[] 

    industryField=[] 

    secondType=[] 

    positionId=[] 

    for x in range(1,31): 

        para = {'first': 'true','pn': x, 'kd': p} 

            positionId.append(i.get('positionId')) 

    url1='https://www.lagou.com/jobs/' 

    url2='.html' 

    job_detail=[] 

    for d in positionId: 

        d=str(d) 

        url3=(url1 + d + url2) 

        r=requests.get(url=url3,headers=headers,cookies=cookie) 

        detail=r.content 

        lagou_detail=BeautifulSoup(detail) 

        gwzz=lagou_detail.find_all('dd',attrs={'class':'job_bt'})    

        for j in gwzz: 

            gwzz_text=j.get_text() 

            job_detail.append(gwzz_text) 

    date=time.strftime('%Y-%m-%d',time.localtime(time.time())) 

    columns = ['date','positionName', 'workYear','education','jobNature','businessZones','salary','city','companyLabelList','companySize','financeStage','industryField','district','secondType','positionId','job_detail'] 

    table=pd.DataFrame({'date':date, 

                        'positionName':positionName, 

                        'workYear':workYear, 

                        'education':education, 

                        'jobNature':jobNature, 

                        'businessZones':businessZones, 

                        'salary':salary, 

                        'city':city, 

                        'companyLabelList':companyLabelList, 

                        'companySize':companySize, 

                        'financeStage':financeStage, 

                        'industryField':industryField, 

                        'district':district, 

                        'secondType':secondType, 

                        'positionId':positionId, 

                        'job_detail':job_detail}, 

                        columns=columns) 

    table.to_csv('lagou_' + p + date + '.csv') 

lagou("資料分析") 

到這裡我們已經擷取了拉鈎網的450個資料分析職位資訊及職位描述。我們将在後面的文章中對這450個職位資訊進行分析和模組化。 

本文作者:王彥平

來源:51CTO