美文网首页
数据分析师薪酬?拉勾网职位爬取+分析

数据分析师薪酬?拉勾网职位爬取+分析

作者: 汝心若知 | 来源:发表于2018-06-03 12:14 被阅读0次
    我是封面

    ——2018.06.01——
    最近几天看到了很多文章写拉勾网职位爬取,那些基本是基于requests + json,但是貌似所给url打不开,还有可能被封ip的风险。
    本文主要用selenium + BautifulSoup + xpath工具,爬取不同城市的数据分析师薪酬,闲话不多说,上菜。

    • 爬虫 selenium + BautifulSoup + xpath
    • 储存数据 MySQL
    • 数据清理
    • 薪酬和职位需求分析 seaborn + pyecharts
      ——
      编译环境:Python 3.5
      IDE:jupyter notebook

    1.网页爬取

    第一步,导入所需的模块:

    import re
    import time
    import random
    #爬虫工具
    from selenium import webdriver 
    from selenium.webdriver.chrome.options import Options
    #解析工具
    from bs4 import BeautifulSoup
    from lxml import etree
    

    第二步,设置浏览器参数:

    #设置无头的chrome浏览器参数
    chrome_options = Options()
    chrome_options.add_argument('--headless')
    chrome_options.add_argument('--disable-gpu')
    #运行浏览器
    driver = webdriver.Chrome(chrome_options=chrome_options)
    #备注::selenium 3.0+版本已不支持PhantomJS,所以这里使用无头的chrome brower
    

    第三步,找到合适url开始爬虫,这里以长沙为例:

    url = "https://www.lagou.com/jobs/list_数据分析师?px=default&city={}#filterBox".format('长沙')
    driver.get(url)
    time.sleep(3) #设置等待时间,强烈建议
    

    第四步,解析网页

    # BeautifulSoup解析获取职位的福利和标签
    s = BeautifulSoup(driver.page_source,'lxml')
    labels=[]
    treatment=[]
    for i in s.findAll('div','list_item_bot'):
        labels.append(i.text.split('“')[0].strip().replace('\n',','))
        treatment.append(i.text.split('“')[1].strip().replace('”',''))
        
    # xpath 工具获取公司名称、链接、id等其他数据
    selector=etree.HTML(driver.page_source)
    company_link=selector.xpath('//div[@class="company_name"]/a/@href')
    company_name=selector.xpath('//div[@class="company_name"]/a/text()')
    job_name =selector.xpath('//a[@class="position_link"]/h3/text()')
    job_link = selector.xpath('//a[@class="position_link"]/@href')
    address =selector.xpath('//span[@class="add"]/em/text()')
    temp_1 =selector.xpath('//div[@class="p_bot"]/div[@class="li_b_l"]/text()')
    salary = selector.xpath('//span[@class="money"]/text()')
    temp_2 = selector.xpath('//div[@class="industry"]/text()')
    treatment = selector.xpath('//div[@class="li_b_r"]/text()')
        
    #利用自定义的分隔函数,得到所需的值
    def spt(temp):
        list1,list2 = [],[]
        for i in temp:
            if i.strip():
                list1.append(i.split('/')[0].strip())
                list2.append(i.split('/')[1].strip())
        return list1,list2
    experience,education = spt(temp_1)
    industry,scale = spt(temp_2)
        
    #从链接中获取职位ID和所属公司的ID
    companyID = list(map(lambda x:re.findall(r'\d+',x)[0],company_link))
    jobID = list(map(lambda x:re.findall(r'\d+',x)[0],job_link))
    

    2.将数据存入MySQL数据库中

    在Python链接之前,已在MySQL数据库,创建数据库lagou,数据表job,company

    #导入模块 pymysql
    import pymysql  
    
    db = pymysql.connect("localhost", "root", "123456", "lagou",use_unicode=True, charset="utf8")
    cursor = db.cursor()
    
    #定义一个插入到数据库的函数
    def insert(x_zip,table):    
        for m in x_zip:
            sql = '''INSERT INTO {} values {}'''.format(table,m)
            try:
                cursor = db.cursor()
                cursor.execute(sql)
                db.commit()
            except Exception as error:
                db.rollback()
                print(error)
    #将数据插入到数据库中
    companys = zip(companyID,company_name,company_link,industry,scale)
    insert(companys,"company")
    jobs = zip(jobID,job_name,address,experience,salary,treatment,job_link,companyID,education,labels,['长沙']*len(jobID))
    insert(jobs,"job")
    

    ——
    翻页问题:
    拉勾上的职位内容基于js动态加载,所以点击下一页后,地址仍不生变化。但是仔细观察elements,最后一页会存在标签:<span …… class = 'pager_next pager_next_disabled' ,我们可以利用这个标签来定位。

    if s.findAll('span','pager_next pager_next_disabled'):
        break
    else:
        submitBtn = driver.find_element_by_class_name("pager_next")
        driver.execute_script("arguments[0].scrollIntoView()", submitBtn) # js滚动加载,缺少此步,action无法生效
        submitBtn.click()
        time.sleep(random.randint(3,20)) #爬虫礼仪,减少访问服务器的频率
    

    以上就是拉勾数据分析师职位数据爬取和储存,这里为了显得整洁,分别存储在job,company两个表中。为了便于阅读,完整代码放在文末链接中,有需要可以自己去fork。

    3.数据清理

    首先,导入数据:

    import pandas as pd
    from sqlalchemy import create_engine
    import pymysql
    
    #创建engine
    engine = create_engine('mysql://root:123456@localhost:3306/lagou?charset=utf8') 
    
    #从数据库读取数据
    #由于python 3 不支持MySQLdb,所以这里将文件中的MySQLdb,改为pymysql便可运行
    job = pd.read_sql('job',engine)
    company = pd.read_sql('company',engine)
    

    第二步,数据基本情况查看

    job.head()  #前几条数据查看
    
    image
    job.shape   #查看形状
    
    image
    sum(job.duplicated())   #查看重复情况
    
    image
    job.info() #查看数据类型,空值存在情况
    
    image

    从以上的基本情况上,可以看到以下问题:

    1. 职位名称中含有实习等因素,为了方便统计,这里去除实习职位的影响。
    2. experience、salary都是一个区间,后续探讨experience、salary 和education 的关系需要将具体数值提取出来,转换为float型数据
    3. 含有重复职位数据,这里需要剔除。

    第三步,清洗数据

    #完全复制原dataframe中不重复的数据,方便后续的数据修改
    job_df = job.drop_duplicates().copy()
    #去除实习数据
    job_df.drop(job_df[job_df.name.str.contains('实习')].index,inplace=True)
    
    #新建工资水平high\low
    job_df['lowS'] = job_df['salary'].apply(lambda x: x.lower().split('-')[0].replace('k','')).astype(int)
    job_df['highS'] = job_df['salary'].apply(lambda x: x.lower().split('-')[1].replace('k','')).astype(int)
    #为了更符合实际,取工资的区间前25%
    job_df['avgS'] = job_df['lowS']+(job_df['highS']-job_df['lowS'])/4 
    
    #新建一个工作年限,处理经验问题
    #若为不限/应届毕业生,值为0;
    #若为1年以下或10年以上,值分别为1,10;
    #若为1到3年之类的,值取二者均值
    job_df['workyear'] = job_df['experience'].str.findall(r'\d+')
    def avg_year(i):
        m = 0
        if len(i) == 0:
            m = 0
        elif len(i) == 1:
            m = int(i[0])
        else:
            m = sum(list(map(int,i)))/2
        return m
    job_df['workyear'] = job_df['workyear'].apply(avg_year)
    

    4.薪酬和职位分析

    from pyecharts import Geo
    import seaborn as sns
    import matplotlib
    import matplotlib.pyplot as plt
    %matplotlib inline
    
    matplotlib.rc('font', **{'family' : 'SimHei'}) #解决中文乱码问题,必选
    plt.style.use("ggplot")
    #这里若不加plt.style.use("ggplot"),中文仍然乱码
    
    • 薪酬整体分布状况
    plt.figure(figsize=(10,5))
    sns.distplot(job_df['avgS'],color="r",kde=False)
    plt.title('整体薪酬分布状况');
    
    image

    薪酬集中在12000附近,整体上呈偏右分布。

    • 不同城市之间的薪水差异?
    plt.figure(figsize=(14,5))
    sns.boxplot(x='city',y='avgS',data=job_df,color="r")
    plt.title('不同城市之间的平均薪水差异');
    
    image

    放在中国地图上:

    data_x = job_df.groupby('city')['avgS'].mean().reset_index()
    geot = Geo("全国数据分析师平均薪酬分布", "数据来源:拉勾", title_color="#fff",
              title_pos="center", width=1200,
              height=600, background_color='#404a59')
    attr= data_x['city'].values.tolist()
    value = data_x['avgS'].values.tolist()
    geot.add("",attr,value,type="heatmap", is_visualmap=True, visual_range=[0, 300],visual_text_color='#fff')
    geot.render()
    
    image

    在地域分布的薪酬方面,北京、杭州和深圳的中位数薪酬牢牢的占据第一梯队高于15k,其次就是上海、成都、武汉等城市,中位数薪酬也在11k左右,最低的是天津,这有可能是于需求上人才都转移到北京去了。

    • 学历对薪酬的影响?
    plt.figure(figsize=(14,5))
    sns.boxplot(x='education',y='avgS',data=job_df,color="r")
    plt.title('不同学历之间的薪水差异');
    
    image

    学历越高,获得高薪的机会也就越高,这说明读书发家还是有机会的。

    • 工作经验对薪酬的影响?
    plt.figure(figsize=(14,5))
    sns.boxplot(x="experience", y="avgS", data=job_df)
    sns.stripplot(x='experience',y='avgS',data=job_df,jitter=True, color ='.3')
    plt.title('不同工作经验之间的薪水差异');
    
    image

    拟合来看:

    sns.regplot(x='workyear',y='avgS',data=job_df,x_jitter=.1,)
    plt.title('工作年限与薪酬的拟合关系')
    
    image

    整体上来看,随着工作经验的增加,薪酬也在不断上升。低的工作经验有也高薪的机会,但可能需要更高的技能要求(如普通业务运营数据分析师和大数据挖掘工程师),不断提升自我的能力才是王道。

    • 数据分析师的工作福利和技能
    #定义词云制作函数
    def wordclouds(s):
        text = ''
        for line in job_df[s]:
            text = text+' '+line.strip().replace(',',' ')
        color_mask = imread('qqq.png')
        wordcloud = WordCloud(
                    width=1000,height=600,
                    font_path = 'simhei.ttf',
                    background_color = 'white',
                    mask = color_mask,
                    max_words = 1000,
                    max_font_size = 100, 
                    collocations=False
                    ).generate(text)
        wordcloud.to_file('{}.png'.format(s))
        plt.imshow(wordcloud)
        plt.axis("off")
        plt.show()
    
    #调用定义的词云制作函数
    wordclouds('labels')
    wordclouds('treatment')
    
    image image

    在职位标签上,更多的是数据挖掘类的工作,当然像金融、大数据、业务运营、机器学习这几块也必不可少的。
    五险一金作为基本的福利牢牢站在第一福利关键词,有些公司给出了六险一金(补充商业险)的待遇也很不错的,带薪年假弹性工作、周末双休牢牢吸引着眼球吧。
    最后,我们探讨一下,数据分析师的需求问题:

    • 数据分析师的主要分布行业?
    #合并工作职位和企业
    df = company_df[['id','name','industry','scale']].merge(job_df[['id','company_id','avgS']],left_on='id',right_on='company_id')
    
    #将industy里面的关键词取出来
    industry_df = pd.DataFrame(df.industry.apply(lambda x: x.replace(' ,',' ').replace(',',' ').replace('、',' ').strip().split(' ')).tolist())
    industry_df_new = industry_df.stack().reset_index().rename(columns={'level_0':'df_index',0:'industry_name'})
    industry_df_new.drop('level_1', axis=1, inplace=True)
    
    t = df.merge(industry_df_new,right_on='df_index',left_index=True)
    tt['industry_name'].value_counts().plot.bar(figsize =(10,4),title=('数据分析师的需求行业分布'));
    
    image

    移动互联网需求独占鳌头,其次就是金融、数据服务类、电子商务类公司需求较大,当然可能会有部分企业行业标签重合。

    • 全国各地职位需求数分布问题?
    #提取每个城市的职位数
    data = job_df.groupby('city')['name'].count().reset_index()
    
    #作图scatter
    geo = Geo("全国数据分析师的需求分布", "数据来源:拉勾", title_color="#fff",
              title_pos="center", width=1200,
              height=600, background_color='#404a59')
    attr= data['city'].values.tolist()
    value = data['name'].values.tolist()
    geo.add("",attr,value,type="scatter", is_visualmap=True, visual_range=[50, 2000],visual_text_color='#fff',visual_type='size', visual_range_size=[20, 80])
    geo.render()
    
    image

    求职机会上,虽然说一线城市机会多,但一些准一线城市也在蓬勃发展中。

    结论​

    1. 数据分析师的平均薪水集中在12k附近,整体上呈右分布
    2. 随着经验和学历的增加,整体上来看数据分析师的薪酬在不断上升中。
    3. 目前市场上数据分析师的人才缺口,更多的是需要掌握数据挖掘的技能。
    4. 数据分析师的需求方面,移动互联网需求独占鳌头,其次就是金融、数据服务类、电子商务类公司需求较大
    5. 数据分析师的求职方面,虽然说一线城市机会多,但一些准一线城市也在蓬勃发展中。

    局限性:

    1. 事实上,一线城市北上广深杭的职位可能会远多于其他城市,因为拉勾仅限获取前30页,这些城市的职位或多或少大于30页的。
    2. 数据分析师的技能是影响薪酬的重要因素,但本次分析并没有体现出来。

    ——
    爬虫+分析完整代码:https://github.com/mimicolois/lagou

    PS:
    1.git 是非常强大的工具,学会使用git,从注册一个github账号开始
    2.嫌弃国内访问速度,代码托管国内有码云
    3.git 入门指南:廖雪峰老师的Git教程

    相关文章

      网友评论

          本文标题:数据分析师薪酬?拉勾网职位爬取+分析

          本文链接:https://www.haomeiwen.com/subject/aklksftx.html