|
|
|
|
移动端

数据分析行业薪资的秘密,你想知道的都在这里(1)

数据分析师的收入怎么样?哪些因素对于数据分析的薪资影响最大?哪些行业对数据分析人才的需求量最高?我想跳槽,应该选择大公司大平台还是初创的小公司?按我目前的教育程度,工作经验,和掌握的工具和技能,能获得什么样水平的薪资呢?

作者:王彦平来源:36大数据|2017-08-15 15:35

数据分析行业薪资的秘密,你想知道的都在这里(1)

第一部分,数据分析职位信息抓取

数据分析师的收入怎么样?哪些因素对于数据分析的薪资影响最大?哪些行业对数据分析人才的需求量最高?我想跳槽,应该选择大公司大平台还是初创的小公司?按我目前的教育程度,工作经验,和掌握的工具和技能,能获得什么样水平的薪资呢?

我们使用python抓取了2017年6月26日拉钩网站内搜索“数据分析”关键词下的450条职位信息。通过对这些职位信息的分析和建模来给你答案。

本系列文章共分为五个部分,分别是数据分析职位信息抓取,数据清洗及预处理,数据分析职位需求分析,数据分析职位薪影响因素分析,以及数据分析职位薪资建模及预测。这是第一篇:数据分析职位信息抓取。

数据抓取前的准备工作

首先我们需要获取职位信息的数据,方法是使用python进行抓取。整个抓取过程分为两部分,第一部分是抓取拉钩列表页中包含的职位信息,例如职位名称,薪资范围,学历要求,工作地点等。第二部分是抓取每个职位详情页中的任职资格和职位描述信息。然后我们将使用结巴分词和nltk对职位描述中的文字信息进行处理和信息提取。下面我们开始介绍每一步的操作过程。

首先,导入抓取和数据处理所需的库文件,这里不再赘述。

  1. #导入抓取所需库文件 
  2. import requests 
  3. import numpy as np 
  4. import pandas as pd 
  5. import json 
  6. import time 
  7. from bs4 import BeautifulSoup  

然后设置头部信息和Cookie信息。

  1. #设置头部信息 
  2. headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11'
  3.     'Accept':'text/html;q=0.9,*/*;q=0.8'
  4.     'Accept-Charset':'ISO-8859-1,utf-8;q=0.7,*;q=0.3'
  5.     'Connection':'close'
  6.     'Referer':'https://www.baidu.com/' 
  7.     } 
  8.   
  9. #设置Cookie信息 
  10. cookie={'TrackID':'1_VWwvLYiy1FUr7wSr6HHmHhadG8d1-Qv-TVaw8JwcFG4EksqyLyx1SO7O06_Y_XUCyQMksp3RVb2ezA'
  11.     '__jda':'122270672.1507607632.1423495705.1479785414.1479794553.92'
  12.     '__jdb':'122270672.1.1507607632|92.1479794553'
  13.     '__jdc':'122270672'
  14.     '__jdu':'1507607632'
  15.     '__jdv':'122270672|direct|-|none|-|1478747025001'
  16.     'areaId':'1'
  17.     'cn':'0'
  18.     'ipLoc-djd':'1-72-2799-0'
  19.     'ipLocation':'%u5317%u4EAC'
  20.     'mx':'0_X'
  21.     'rkv':'V0800'
  22.     'user-key':'216123d5-4ed3-47b0-9289-12345'
  23.     'xtest':'4657.553.d9798cdf31c02d86b8b81cc119d94836.b7a782741f667201b54880c925faec4b' 

抓取职位列表信息

设置要抓取的页面URL,拉钩的职位信息列表是JS动态加载的,不在所显示的页面URL中。所以直接抓取列表页并不能获得职位信息。这里我们使用Chrome浏览器里的开发者工具进行查找。具体方法是在商品详情页点击鼠标右键,选择检查,在弹出的开发者工具界面中选择Network,设置为禁用缓存(Disable cache)和只查看XHR类型的请求。然后刷新页面。一共有4个请求,选择包含positionAjax关键字的链接就是我们要抓取的URL地址。具体过程如下面截图所示。

这里有一个问题,要抓取的URL地址中只有第一页的15个职位信息,并且URL参数中也没有包含页码。而我们要抓取的是全部30多页的职位列表。如何翻页呢?后面我们将解决这个问题。

  1. #设置抓取页面的URL 
  2.  
  3. url='https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false'  

职位列表中包含了多个职位相关的信息,我们先建立一些空list用于存储这些信息。

  1. #创建list用于存储数据 
  2. positionName=[] 
  3. workYear=[] 
  4. education=[] 
  5. district=[] 
  6. jobNature=[] 
  7. salary=[] 
  8. city=[] 
  9. businessZones=[] 
  10. companyLabelList=[] 
  11. companySize=[] 
  12. financeStage=[] 
  13. industryField=[] 
  14. secondType=[] 
  15. positionId=[]  

开始抓取列表页中的职位信息,建立一个30页的循环然后将页码作为请求参数与头部信息和Cookie一起传给服务器。获取返回的信息后对页面内容进行解码,然后从json数据中提取所需的职位信息,并保存在上一步创建的list中。用于后续的组表。这里的最后一个信息是职位id,也就是拉钩职位详情页URL中的一部分。通过这个id我们可以生成与列表页职位相对应的详情页URL。并从中提取任职资格和职位描述信息。

  1. #循环抓取列表页信息 
  2. for x in range(1,31): 
  3.         #设置查询关键词及当前页码 
  4.         para = {'first''true','pn': x, 'kd'"数据分析"
  5.         #抓取列表页信息 
  6.         r=requests.get(url=url,headers=headers,cookies=cookie,params=para) 
  7.         #存储bytes型页面数据 
  8.         html=r.content 
  9.         #对页面内容进行解码 
  10.         html = html.decode() 
  11.         #将json串转化为dict 
  12.         html_json=json.loads(html) 
  13.         #逐层获取职位列表信息 
  14.         content=html_json.get('content'
  15.         positionResult=content.get('positionResult'
  16.         result=positionResult.get('result'
  17.         #循环提取职位列表中的关键信息 
  18.         for i in result: 
  19.             #获取职位名称,工作年限,教育程度,城市及薪资范围等信息。 
  20.             positionName.append(i.get('positionName')) 
  21.             workYear.append(i.get('workYear')) 
  22.             education.append(i.get('education')) 
  23.             district.append(i.get('district')) 
  24.             jobNature.append(i.get('jobNature')) 
  25.             salary.append(i.get('salary')) 
  26.             city.append(i.get('city')) 
  27.             businessZones.append(i.get('businessZones')) 
  28.             companyLabelList.append(i.get('companyLabelList')) 
  29.             companySize.append(i.get('companySize')) 
  30.             financeStage.append(i.get('financeStage')) 
  31.             industryField.append(i.get('industryField')) 
  32.             secondType.append(i.get('secondType')) 
  33.             #获取职位的Id编码。 
  34.             positionId.append(i.get('positionId'))  

设置一个当前的日期字段,用于标记数据获取的时间。

  1. #设置日期字段 
  2. date=time.strftime('%Y-%m-%d',time.localtime(time.time()))  

将前面抓取到的职位信息,以及当前的日期一起组成Dataframe。便于后续的处理和分析。

  1. #设置DataFrame表格顺序 
  2. columns = ['date','positionName',  
  3.   
  4. 'workYear','education','jobNature','businessZones','salary','city','companyLabelList','companySize','financeStage','industryField','d 
  5.   
  6. istrict','secondType','positionId'] 
  7. #将获取到的字段信息合并为DataFrame 
  8. table=pd.DataFrame({'date':date
  9.                     'positionName':positionName, 
  10.                     'workYear':workYear, 
  11.                     'education':education, 
  12.                     'jobNature':jobNature, 
  13.                     'businessZones':businessZones, 
  14.                     'salary':salary, 
  15.                     'city':city, 
  16.                     'companyLabelList':companyLabelList, 
  17.                     'companySize':companySize, 
  18.                     'financeStage':financeStage, 
  19.                     'industryField':industryField, 
  20.                     'district':district, 
  21.                     'secondType':secondType, 
  22.                     'positionId':positionId}, 
  23.                     columns=columns)  

查看生成的数据表,其中包含了我们在列表页中抓取的信息,以及下一步要使用的职位id信息。

  1. #查看数据表 
  2.  
  3. table 

这里你可以保存一个版本,也可以忽略这一步,继续后面的职位详情页信息抓取。

  1. #存储数据表 
  2.  
  3. table.to_csv('lagou_' + date + '.csv' 

抓取职位详情信息(职位描述)

抓取职位详情页的信息,首先需要通过拼接生成职位详情页的URL。我们预先写好URL的开始和结束部分,这两部分是固定的,抓取过程中不会发生变化 ,中间动态填充职位的id。

  1. #设置详情页的URL固定部分 
  2.  
  3. url1='https://www.lagou.com/jobs/' 
  4.  
  5. url2='.html'  

创建一个list用于存储抓取到的职位描述信息。

  1. #创建job_detail用于存储职位描述 
  2.  
  3. job_detail=[]  

从前面抓取的职位id(positionId)字段循环提取每一个id信息,与URL的另外两部分组成要抓取的职位详情页URL。并从中提取职位描述信息。这里的职位信息不是js动态加载的,因此直接抓取页面信息保存在之前创建的list中就可以了。

  1. #循环抓取详情页的职位描述 
  2. for d in positionId: 
  3.     #更改positionId格式 
  4.     d=str(d) 
  5.     #拼接详情页URL 
  6.     url3=(url1 + d + url2) 
  7.     #抓取详情页信息 
  8.     r=requests.get(url=url3,headers=headers,cookies=cookie) 
  9.     #存储bytes型页面数据yu 
  10.     detail=r.content 
  11.     #创建 beautifulsoup 对象 
  12.     lagou_detail=BeautifulSoup(detail) 
  13.     #提取职位描述信息 
  14.     gwzz=lagou_detail.find_all('dd',attrs={'class':'job_bt'})    
  15.     for j in gwzz: 
  16.         gwzz_text=j.get_text() 
  17.         job_detail.append(gwzz_text)  

查看并检查一下提取到的职位描述信息。然后将职位描述信息拼接到之前创建的Dataframe中。

  1. #查看职位描述信息 
  2.  
  3. job_detail 

完整的职位抓取代码

以下是完整的抓取代码,步骤和前面介绍的略有不同,最后生成一个包含所有职位信息和描述的完整数据表。用于下一步的数据清洗,预处理,分析和建模的工作。

  1. def lagou(p): 
  2.     import requests 
  3.     import numpy as np 
  4.     import pandas as pd 
  5.     import json 
  6.     import time 
  7.     from bs4 import BeautifulSoup 
  8.     import jieba as jb 
  9.     import jieba.analyse 
  10.     headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11'
  11.     'Accept':'text/html;q=0.9,*/*;q=0.8'
  12.     'Accept-Charset':'ISO-8859-1,utf-8;q=0.7,*;q=0.3'
  13.     'Connection':'close'
  14.     'Referer':'https://www.jd.com/' 
  15.     } 
  16.     cookie={'TrackID':'1_VWwvLYiy1FUr7wSr6HHmHhadG8d1-Qv-TVaw8JwcFG4EksqyLyx1SO7O06_Y_XUCyQMksp3RVb2ezA'
  17.     '__jda':'122270672.1507607632.1423495705.1479785414.1479794553.92'
  18.     '__jdb':'122270672.1.1507607632|92.1479794553'
  19.     '__jdc':'122270672'
  20.     '__jdu':'1507607632'
  21.     '__jdv':'122270672|direct|-|none|-|1478747025001'
  22.     'areaId':'1'
  23.     'cn':'0'
  24.     'ipLoc-djd':'1-72-2799-0'
  25.     'ipLocation':'%u5317%u4EAC'
  26.     'mx':'0_X'
  27.     'rkv':'V0800'
  28.     'user-key':'216123d5-4ed3-47b0-9289-12345'
  29.     'xtest':'4657.553.d9798cdf31c02d86b8b81cc119d94836.b7a782741f667201b54880c925faec4b'
  30.     url='https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false' 
  31.     positionName=[] 
  32.     workYear=[] 
  33.     education=[] 
  34.     district=[] 
  35.     jobNature=[] 
  36.     salary=[] 
  37.     city=[] 
  38.     businessZones=[] 
  39.     companyLabelList=[] 
  40.     companySize=[] 
  41.     financeStage=[] 
  42.     industryField=[] 
  43.     secondType=[] 
  44.     positionId=[] 
  45.     for x in range(1,31): 
  46.         para = {'first''true','pn': x, 'kd': p} 
  47.         r=requests.get(url=url,headers=headers,cookies=cookie,params=para) 
  48.         html=r.content 
  49.         html = html.decode() 
  50.         html_json=json.loads(html) 
  51.         content=html_json.get('content'
  52.         positionResult=content.get('positionResult'
  53.         result=positionResult.get('result'
  54.         for i in result: 
  55.             positionName.append(i.get('positionName')) 
  56.             workYear.append(i.get('workYear')) 
  57.             education.append(i.get('education')) 
  58.             district.append(i.get('district')) 
  59.             jobNature.append(i.get('jobNature')) 
  60.             salary.append(i.get('salary')) 
  61.             city.append(i.get('city')) 
  62.             businessZones.append(i.get('businessZones')) 
  63.             companyLabelList.append(i.get('companyLabelList')) 
  64.             companySize.append(i.get('companySize')) 
  65.             financeStage.append(i.get('financeStage')) 
  66.             industryField.append(i.get('industryField')) 
  67.             secondType.append(i.get('secondType')) 
  68.             positionId.append(i.get('positionId')) 
  69.     url1='https://www.lagou.com/jobs/' 
  70.     url2='.html' 
  71.     job_detail=[] 
  72.     for d in positionId: 
  73.         d=str(d) 
  74.         url3=(url1 + d + url2) 
  75.         r=requests.get(url=url3,headers=headers,cookies=cookie) 
  76.         detail=r.content 
  77.         lagou_detail=BeautifulSoup(detail) 
  78.         gwzz=lagou_detail.find_all('dd',attrs={'class':'job_bt'})    
  79.         for j in gwzz: 
  80.             gwzz_text=j.get_text() 
  81.             job_detail.append(gwzz_text) 
  82.     date=time.strftime('%Y-%m-%d',time.localtime(time.time())) 
  83.     columns = ['date','positionName''workYear','education','jobNature','businessZones','salary','city','companyLabelList','companySize','financeStage','industryField','district','secondType','positionId','job_detail'
  84.     table=pd.DataFrame({'date':date
  85.                         'positionName':positionName, 
  86.                         'workYear':workYear, 
  87.                         'education':education, 
  88.                         'jobNature':jobNature, 
  89.                         'businessZones':businessZones, 
  90.                         'salary':salary, 
  91.                         'city':city, 
  92.                         'companyLabelList':companyLabelList, 
  93.                         'companySize':companySize, 
  94.                         'financeStage':financeStage, 
  95.                         'industryField':industryField, 
  96.                         'district':district, 
  97.                         'secondType':secondType, 
  98.                         'positionId':positionId, 
  99.                         'job_detail':job_detail}, 
  100.                         columns=columns) 
  101.     table.to_csv('lagou_' + p + date + '.csv'
  102.   
  103. lagou("数据分析"

  

到这里我们已经获取了拉钩网的450个数据分析职位信息及职位描述。我们将在后面的文章中对这450个职位信息进行分析和建模。

【编辑推荐】

  1. 用大数据精准预测地震,每年将有1.3万人免于受难
  2. 支付宝「占领」全球,看大数据时代下的人民购物
  3. FMI2017----让人工智能与大数据为时代赋能
  4. 果断收藏!六大主流大数据采集平台架构分析
  5. 大数据迁徙图:逃离北上广,他们竟然去了这里
【责任编辑:庞桂玉 TEL:(010)68476606】

点赞 0
分享:
大家都在看
猜你喜欢

读 书 +更多

用户体验要素

本书是AJAX之父的经典之作。本书用简洁的语言系统化地诠释了设计、技术和商业融合是最重要的发展趋势。全书共8章,包括关于用户体验以及为...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊