數(shù)據(jù)分析行業(yè)薪資的秘密,你想知道的都在這里(1)
***部分,數(shù)據(jù)分析職位信息抓取
數(shù)據(jù)分析師的收入怎么樣?哪些因素對(duì)于數(shù)據(jù)分析的薪資影響***?哪些行業(yè)對(duì)數(shù)據(jù)分析人才的需求量***?我想跳槽,應(yīng)該選擇大公司大平臺(tái)還是初創(chuàng)的小公司?按我目前的教育程度,工作經(jīng)驗(yàn),和掌握的工具和技能,能獲得什么樣水平的薪資呢?
我們使用python抓取了2017年6月26日拉鉤網(wǎng)站內(nèi)搜索“數(shù)據(jù)分析”關(guān)鍵詞下的450條職位信息。通過對(duì)這些職位信息的分析和建模來給你答案。
本系列文章共分為五個(gè)部分,分別是數(shù)據(jù)分析職位信息抓取,數(shù)據(jù)清洗及預(yù)處理,數(shù)據(jù)分析職位需求分析,數(shù)據(jù)分析職位薪影響因素分析,以及數(shù)據(jù)分析職位薪資建模及預(yù)測(cè)。這是***篇:數(shù)據(jù)分析職位信息抓取。
數(shù)據(jù)抓取前的準(zhǔn)備工作
首先我們需要獲取職位信息的數(shù)據(jù),方法是使用python進(jìn)行抓取。整個(gè)抓取過程分為兩部分,***部分是抓取拉鉤列表頁中包含的職位信息,例如職位名稱,薪資范圍,學(xué)歷要求,工作地點(diǎn)等。第二部分是抓取每個(gè)職位詳情頁中的任職資格和職位描述信息。然后我們將使用結(jié)巴分詞和nltk對(duì)職位描述中的文字信息進(jìn)行處理和信息提取。下面我們開始介紹每一步的操作過程。
首先,導(dǎo)入抓取和數(shù)據(jù)處理所需的庫文件,這里不再贅述。
- #導(dǎo)入抓取所需庫文件
- import requests
- import numpy as np
- import pandas as pd
- import json
- import time
- from bs4 import BeautifulSoup
然后設(shè)置頭部信息和Cookie信息。
- #設(shè)置頭部信息
- 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/'
- }
- #設(shè)置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'}
抓取職位列表信息
設(shè)置要抓取的頁面URL,拉鉤的職位信息列表是JS動(dòng)態(tài)加載的,不在所顯示的頁面URL中。所以直接抓取列表頁并不能獲得職位信息。這里我們使用Chrome瀏覽器里的開發(fā)者工具進(jìn)行查找。具體方法是在商品詳情頁點(diǎn)擊鼠標(biāo)右鍵,選擇檢查,在彈出的開發(fā)者工具界面中選擇Network,設(shè)置為禁用緩存(Disable cache)和只查看XHR類型的請(qǐng)求。然后刷新頁面。一共有4個(gè)請(qǐng)求,選擇包含positionAjax關(guān)鍵字的鏈接就是我們要抓取的URL地址。具體過程如下面截圖所示。
這里有一個(gè)問題,要抓取的URL地址中只有***頁的15個(gè)職位信息,并且URL參數(shù)中也沒有包含頁碼。而我們要抓取的是全部30多頁的職位列表。如何翻頁呢?后面我們將解決這個(gè)問題。
- #設(shè)置抓取頁面的URL
- url='https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false'
職位列表中包含了多個(gè)職位相關(guān)的信息,我們先建立一些空list用于存儲(chǔ)這些信息。
- #創(chuàng)建list用于存儲(chǔ)數(shù)據(jù)
- positionName=[]
- workYear=[]
- education=[]
- district=[]
- jobNature=[]
- salary=[]
- city=[]
- businessZones=[]
- companyLabelList=[]
- companySize=[]
- financeStage=[]
- industryField=[]
- secondType=[]
- positionId=[]
開始抓取列表頁中的職位信息,建立一個(gè)30頁的循環(huán)然后將頁碼作為請(qǐng)求參數(shù)與頭部信息和Cookie一起傳給服務(wù)器。獲取返回的信息后對(duì)頁面內(nèi)容進(jìn)行解碼,然后從json數(shù)據(jù)中提取所需的職位信息,并保存在上一步創(chuàng)建的list中。用于后續(xù)的組表。這里的***一個(gè)信息是職位id,也就是拉鉤職位詳情頁URL中的一部分。通過這個(gè)id我們可以生成與列表頁職位相對(duì)應(yīng)的詳情頁URL。并從中提取任職資格和職位描述信息。
- #循環(huán)抓取列表頁信息
- for x in range(1,31):
- #設(shè)置查詢關(guān)鍵詞及當(dāng)前頁碼
- para = {'first': 'true','pn': x, 'kd': "數(shù)據(jù)分析"}
- #抓取列表頁信息
- r=requests.get(url=url,headers=headers,cookies=cookie,params=para)
- #存儲(chǔ)bytes型頁面數(shù)據(jù)
- html=r.content
- #對(duì)頁面內(nèi)容進(jìn)行解碼
- html = html.decode()
- #將json串轉(zhuǎn)化為dict
- html_json=json.loads(html)
- #逐層獲取職位列表信息
- content=html_json.get('content')
- positionResult=content.get('positionResult')
- result=positionResult.get('result')
- #循環(huán)提取職位列表中的關(guān)鍵信息
- 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'))
設(shè)置一個(gè)當(dāng)前的日期字段,用于標(biāo)記數(shù)據(jù)獲取的時(shí)間。
- #設(shè)置日期字段
- date=time.strftime('%Y-%m-%d',time.localtime(time.time()))
將前面抓取到的職位信息,以及當(dāng)前的日期一起組成Dataframe。便于后續(xù)的處理和分析。
- #設(shè)置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)
查看生成的數(shù)據(jù)表,其中包含了我們?cè)诹斜眄撝凶ト〉男畔?,以及下一步要使用的職位id信息。
- #查看數(shù)據(jù)表
- table
這里你可以保存一個(gè)版本,也可以忽略這一步,繼續(xù)后面的職位詳情頁信息抓取。
- #存儲(chǔ)數(shù)據(jù)表
- table.to_csv('lagou_' + date + '.csv')
抓取職位詳情信息(職位描述)
抓取職位詳情頁的信息,首先需要通過拼接生成職位詳情頁的URL。我們預(yù)先寫好URL的開始和結(jié)束部分,這兩部分是固定的,抓取過程中不會(huì)發(fā)生變化 ,中間動(dòng)態(tài)填充職位的id。
- #設(shè)置詳情頁的URL固定部分
- url1='https://www.lagou.com/jobs/'
- url2='.html'
創(chuàng)建一個(gè)list用于存儲(chǔ)抓取到的職位描述信息。
- #創(chuàng)建job_detail用于存儲(chǔ)職位描述
- job_detail=[]
從前面抓取的職位id(positionId)字段循環(huán)提取每一個(gè)id信息,與URL的另外兩部分組成要抓取的職位詳情頁URL。并從中提取職位描述信息。這里的職位信息不是js動(dòng)態(tài)加載的,因此直接抓取頁面信息保存在之前創(chuàng)建的list中就可以了。
- #循環(huán)抓取詳情頁的職位描述
- for d in positionId:
- #更改positionId格式
- d=str(d)
- #拼接詳情頁URL
- url3=(url1 + d + url2)
- #抓取詳情頁信息
- r=requests.get(url=url3,headers=headers,cookies=cookie)
- #存儲(chǔ)bytes型頁面數(shù)據(jù)yu
- detail=r.content
- #創(chuàng)建 beautifulsoup 對(duì)象
- 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)
查看并檢查一下提取到的職位描述信息。然后將職位描述信息拼接到之前創(chuàng)建的Dataframe中。
- #查看職位描述信息
- job_detail
完整的職位抓取代碼
以下是完整的抓取代碼,步驟和前面介紹的略有不同,***生成一個(gè)包含所有職位信息和描述的完整數(shù)據(jù)表。用于下一步的數(shù)據(jù)清洗,預(yù)處理,分析和建模的工作。
- 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("數(shù)據(jù)分析")
到這里我們已經(jīng)獲取了拉鉤網(wǎng)的450個(gè)數(shù)據(jù)分析職位信息及職位描述。我們將在后面的文章中對(duì)這450個(gè)職位信息進(jìn)行分析和建模。