数据分析师+前途无忧爬虫分析

首先说明这篇文章的数据来源,为前程无忧中所有“数据分析师”这一职位信息所得来的。并且主要分析了数据分析师在全国不同地区的需求情况、总体薪酬情况、不同城市薪酬分布、不同学历薪酬分布、不同地区学历要求情况、不同经验需求与薪酬分布情况。

本文行文思路:

数据采取
数据清洗
数据分析
分析结论
思考总结

1.数据采集

定位数据位置
首先进入前程无忧首页,然后在职位搜索中检索数据分析师,不加其他限定条件,点击搜索可得到以下结果:
在这里插入图片描述
可以看到关于数据分析师的岗位信息一共10263条。

爬虫代码调试及运行
本文代码参照Python网络爬虫爬取智联招聘职位,之前不会爬虫,花了半天时间研究了一下,自己改了改,调试了一番,最后能勉强运行了。代码见下:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import urllib2,re,sys,pandas as pd
reload(sys)
sys.setdefaultencoding( "utf-8" )

result11=[]
result21=[]
result31=[]
result41=[]  
result51=[]  
result61=[]
result71=[]
  
headers = {'User-agent' : 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0'}

def zhuanhuan(y):
    result=[]
    
    for i in y:
        result.append(i.decode("gbk"))
    return result
    
for k in range(1,208):
    html=urllib2.urlopen("http://search.51job.com/jobsearch/search_result.php?fromJs=1&jobarea=000000%2C00&district=000000&funtype=0000&industrytype=00&issuedate=9&providesalary=99&keyword=%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E5%B8%88&keywordtype=2&curr_page="+str(k)+"&lang=c&stype=1&postchannel=0000&workyear=99&cotype=99&degreefrom=99&jobterm=99&companysize=99&lonlat=0%2C0&radius=-1&ord_field=0&list_type=0&dibiaoid=0&confirmdate=9").read()

    pat1 = '<a target="_blank" title=(.*?) οnmοusedοwn='
    pat1_a ='"(.*?)" href="'
    pat1_b ='" href="(.*?)"'
    pat2 = '<span class="t2"><a target="_blank" title="(.*?)" href="'
    pat3 = '<span class="t3">(.*?)</span>'
    pat4 = '<span class="t4">(.*?)</span>'
    pat5 = '<span class="sp4"><em class="i1"></em>(.*?)</span>'
    pat6 = 'ass="sp4"><em class="i2"></em>(.*?)</span>'

    a=''
    result1 = re.compile(pat1).findall(html)
    for i in result1:
        a=a+str(i)

    result1 = re.compile(pat1_a).findall(a)
    result2 = re.compile(pat2).findall(html)
    result3 = re.compile(pat3).findall(html)[1:]
    result4 = re.compile(pat4).findall(html)[1:]

    
    result5 = re.compile(pat1_b).findall(a)
    for i in result5:
        request = urllib2.Request(i, headers = headers)
        try:
            response = urllib2.urlopen(request,timeout=20).read()
            html1 = response
            if re.compile(pat5).findall(html1):
                result61.extend(re.compile(pat5).findall(html1))
            else:
                result61.extend([''])
            if re.compile(pat6).findall(html1):
                result71.extend(re.compile(pat6).findall(html1))
            else:
                result71.extend([''])
        except:
            result61.extend([''])
            result71.extend([''])
       
    result11.extend(result1)
    result21.extend(result2)
    result31.extend(result3)
    result41.extend(result4)
    result51.extend(result5)
    if len(result1)!=len(result2):
        print k
        break
    print k

result11=zhuanhuan(result11)    
result21=zhuanhuan(result21)    
result31=zhuanhuan(result31)    
result41=zhuanhuan(result41)    
result51=zhuanhuan(result51)

result61=zhuanhuan(result61)    
result71=zhuanhuan(result71)    


print len(result11)    
print len(result21)    
print len(result31)    
print len(result41)
print len(result51)    
print len(result61)    
print len(result71)    

df2=pd.DataFrame({u"职位名":result11,u"公司名":result21,u"工作地":result31,u"薪资":result41,u"工作经验":result61,u"学历要求":result71})  #
df2.to_excel('foo.xlsx', sheet_name='Sheet1')

对于写过爬虫的,上面代码可能比较简单,主要涉及反爬伪造http头部,正则表达,Python中文编码,pandas库运用,和一些基本的循环之类东西。

代码缺点也很明显:1.运行时间慢,需要1个多小时,因为要爬取1万多个页面。2.爬取信息过少,因为本人正则表达和Python字符串处理不精通,行业信息、企业规模、企业性质未能匹配出来。

最后爬出10163行岗位数据,与原网页10263相差100行数据,结果存储为一个名为foo.xlsx的excel文件。
在这里插入图片描述

2.数据清洗

本案例要进行清洗的要点主要涉及以下几点:

重复数据的删除
空值的填充
工作地点重置为市级
薪资单位转换及去区间化
重复数据删除
本案例要进行清洗的要点主要涉及以下几点:

重复数据的删除
空值的填充
工作地点重置为市级
薪资单位转换及去区间化
重复数据删除

import pandas as pd

my = pd.DataFrame(pd.read_excel('foo.xlsx'))
my = my.drop_duplicates()

HR经常会因为招聘压力,发布重复招聘信息,这里需要删除重复数据,经过去重操作后,总数据量由10163变为8696。看来hr们压力挺大的,也是蛮拼。

空值处理

首先需要查看空值分布在那几列中

a = [u"公司名",u"学历要求",u"工作地",u"工作经验",u"职位名",u"薪资"]
for i in a:
    my[i].isnull().value_counts()
可以得到以下输出

False    8696
Name: 公司名, dtype: int64
False    6256
True     2440
Name: 学历要求, dtype: int64
False    8696
Name: 工作地, dtype: int64
False    8505
True      191
Name: 工作经验, dtype: int64
False    8696
Name: 职位名, dtype: int64
False    8275
True      421
Name: 薪资, dtype: int64

以上数据可以看出,学历要求中2440条空值、工作经验中191条空值、薪资中421条空值。

学历空值填充为不限,工作经验填充为无经验要求、薪资空值删除整行。

my[u"学历要求"] = my[u"学历要求"].fillna(u"不限")
my[u"工作经验"] = my[u"工作经验"].fillna(u"无工作经验")
my = my.dropna(axis = 0)

工作地重置为市级

将市级与区级的工作地,统一为市级工作地,以统一标准。

def cut_word(word):
    position=word.find('-')       
    length=len(word)         
    if position !=-1:
        new_city = word[:position]
    else:
        new_city = word
    return new_city

my[u"市级_工作地"] = my[u"工作地"].apply(cut_word)

薪资单位转换及去区间化

薪资数据中,单位不一致,元/天、千/月、万/月、万/年,这里全部统一为千/月。

而很多数据都是区间存在的,这里取平均值代替区间。代码见下:

def cut_salary(word):
    position=word.find('-')     
    length=len(word)
    if u"月" in word and u"千" in word:
        danwei = 1
    if u"月" in word and u"万" in word:
        danwei = 10
    if u"年" in word and u"万" in word:
        danwei = 10.0/12
    if u"天" in word and u"元" in word:
        danwei = 0.02175    
num_position = max(word.find(u'元'),word.find(u'千'),word.find(u'万'))

if position !=-1:       
    b_salary=word[:position]
    t_salary=word[position+1:num_position]
else:
    b_salary = t_salary = word[:num_position]
return (float(b_salary)+float(t_salary))*danwei/2.0
my[u"新_薪资"] = my[u"薪资"].apply(cut_salary)
my.to_excel('foo.xlsx',sheet_name='Sheet1')

至此,数据清洗完毕,将数据保存至本地,然后开始分析之旅吧。

3.数据分析

需求人数城市分布

pandas的数据透视调试半天都是错误,这里就用这个excel制作的柱形图凑合一下。

可以看到,北上两座城市明显超过其他城市,深广只能算第二梯队。
薪资总体分布

import matplotlib.pyplot as plt
salary = my[u"新_薪资"]
bins = [0,5,10,15,20,25,30,35,40,45,50,55,60]
plt.hist(salary, bins, histtype='g', rwidth=0.8)
plt.xlabel('salary')
plt.show()

从上表可以看出,大部分岗位的薪资位于5-15之间,其中5-10之间最多,只有极少数岗位提供较高薪资,另一方面,也存在部分0-5之间的岗位,且岗位数占到近18%。由此来看,大多数数据分析岗,拿着一般般的薪资,而并非网上那般,被炒得虚高。

城市薪资分布
my_1=my[my[u"市级_工作地"]==u"北京"]
my_2=my[my[u"市级_工作地"]==u"上海"]
my_3=my[my[u"市级_工作地"]==u"广州"]
my_4=my[my[u"市级_工作地"]==u"深圳"]
my_5=my[my[u"市级_工作地"]==u"武汉"]
my_6=my[my[u"市级_工作地"]==u"成都"]
my_7=my[my[u"市级_工作地"]==u"杭州"]
my_8=my[my[u"市级_工作地"]==u"天津"]
my_9=my[my[u"市级_工作地"]==u"南京"]
my_10=my[my[u"市级_工作地"]==u"长沙"]
frames = [my_1,my_2,my_3,my_4,my_5,my_6,my_7,my_8,my_9,my_10]
result=pd.concat(frames)

ax=result.boxplot(column=u'新_薪资',by=u'市级_工作地',figsize=(9,7))
ax.title(u"哈哈")
for label in ax.get_xticklabels():
    label.set_fontproperties(zh_font)
plt.show()

城市薪资分布
可以看到,各大城市中位数均未超过10k,北上最高约9k,深圳、南京、杭州紧随其后。

但在top区域,可以看到,一线城市和二线城市就拉的比较开,天津、武汉、长沙在20k以上的样本几乎没有,所以,对于那些经验比较丰富,且寻求高薪的人士,上海,北京和深圳是求职的好去处。

不同学历的薪酬分布

ax=result.boxplot(column=u'新_薪资',by=u'学历要求',figsize=(9,7))
for label in ax.get_xticklabels():
    label.set_fontproperties(zh_font)
plt.savefig("ed.png")

博士的薪资的中位数和众数一马当先,硕士、本科紧随其后,但是在top端,博士表现不佳,原因可能是,极高薪的数据反而对学历要求没那么高,大专在top区域都有比较亮眼的数据表现。但是在中端的数据岗,对学历有一定的要求。

相同工作年限不同城市薪资分布

df_bj_sh=result[result['city'].isin([u'上海',u'北京'])]
ax=df_bj_sh.boxplot(column=u'新_薪资',by=[u'工作经验','city'],figsize=(19,6))
for label_x in ax.get_xticklabels():
    label_x.set_fontproperties(zh_font)
plt.savefig("ed.png")

可以看到,相同工作经验下,上海薪资要略高于北京,但是在8-9年工作经验一块,出现了一个异常数据,上海的8-9年岗位薪资水平不足10k,显然是异常数据,后期需要核对一下。

分析结论
从需求城市上看,北京和上海是两座对数据分析人才需求量最大两座城市,约占全国的1/3

,深圳、广州各占10%左右。数据分析方面的求职者可多关注四座城市。

从总体薪资构成来看,大多数数据分析师的薪资水平不超过10k,此岗位并非网上被炒的过热那般。

从城市薪资构成来看,一二线城市薪资中位数和众数并未拉开,但是看极值表现,二线城市在top岗位上稍显欠缺。

而单看学历、薪资图,会发现,中等偏上水平薪资的岗位更倾向于寻求博士生,而top水平薪资的岗位则青睐本科、硕士、专科。

上海与北京相同工作年限的对比可以看出,要求同等经验的岗位,上海的薪资高于北京。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值