數據分析行業薪資的秘密,你想知道的都在這里
第一部分,數據分析職位信息抓取
數據分析師的收入怎么樣?哪些因素對于數據分析的薪資影響最大?哪些行業對數據分析人才的需求量最高?我想跳槽,應該選擇大公司大平臺還是初創的小公司?按我目前的教育程度,工作經驗,和掌握的工具和技能,能獲得什么樣水平的薪資呢?
我們使用python抓取了2017年6月26日拉鉤網站內搜索“數據分析”關鍵詞下的450條職位信息。通過對這些職位信息的分析和建模來給你答案。
本系列文章共分為五個部分,分別是數據分析職位信息抓取,數據清洗及預處理,數據分析職位需求分析,數據分析職位薪影響因素分析,以及數據分析職位薪資建模及預測。這是第一篇:數據分析職位信息抓取。
數據抓取前的準備工作
首先我們需要獲取職位信息的數據,方法是使用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地址。具體過程如下面截圖所示。
這里有一個問題,要抓取的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
這里你可以保存一個版本,也可以忽略這一步,繼續后面的職位詳情頁信息抓取。
-
#存儲數據表
-
-
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
完整的職位抓取代碼
以下是完整的抓取代碼,步驟和前面介紹的略有不同,最后生成一個包含所有職位信息和描述的完整數據表。用于下一步的數據清洗,預處理,分析和建模的工作。
-
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',
-
'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.jd.com/'
-
}
-
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='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}
-
r=requests.get(url=url,headers=headers,cookies=cookie,params=para)
-
html=r.content
-
html = html.decode()
-
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'))
-
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個職位信息進行分析和建模。
CDA數據分析師考試相關入口一覽(建議收藏):
? 想報名CDA認證考試,點擊>>>
“CDA報名”
了解CDA考試詳情;
? 想學習CDA考試教材,點擊>>> “CDA教材” 了解CDA考試詳情;
? 想加入CDA考試題庫,點擊>>> “CDA題庫” 了解CDA考試詳情;
? 想了解CDA考試含金量,點擊>>> “CDA含金量” 了解CDA考試詳情;