python爬取前程无忧和拉勾数据分析岗位并分析

一、明确需求

分析数据分析岗位的招聘情况,包括地区分布、薪资水平、职位要求等,了解最新数据分析岗位的情况。

环境:python 3.6

设计的工具:Tableau工具(主要是生成图方便,用matplotlib也可以达到同样的效果)

二、数据采集

 首先编写爬虫,这里主要是爬取前程无忧和拉勾网,直接上前程无忧的代码:

关于前程无忧爬虫代码,网上有很多教程,不过大部分只取了地区、职位、工资和日期这几个字段,没有涉及到岗位要求和岗位职责,因为要了解职位的需求以及后面方便画词云,我就自己写了一个代码。说一下拉勾和前程无忧两者的区别,前程无忧爬了2000页,不过大概只有前24页是跟数据分析有关的岗位,拉勾网的数据量比较少,全国主要城市爬下来,一共也才2000多条,而且基本集中在北京上海杭州。调整一下前程无忧爬虫格式跟拉勾一样,把两个表格合并起来一起分析。

# -*- coding:utf-8 -*-
import urllib
import re, codecs
import time, random
import requests
from lxml import html
from urllib import parse

key = '数据分析'
key = parse.quote(parse.quote(key))
headers = {'Host': 'search.51job.com',
           'Upgrade-Insecure-Requests': '1',
           'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}


def get_links(page):
    url = 'http://search.51job.com/list/000000,000000,0000,00,9,99,' + key + ',2,' + str(page) + '.html'
    r = requests.get(url, headers=headers, timeout=10)
    s = requests.session()
    s.keep_alive = False
    r.encoding = 'gb18030'
    reg = re.compile(r'"type":.*?"job_href":"(.*?)","job_name.*?"providesalary_text":"(.*?)","workarea":".*?"companyind_text"', re.S)
    links = re.findall(reg, r.text)
    return links


# 多页处理,下载到文件
def get_content(link,salary):
    hds={'Host': 'jobs.51job.com',
         'Upgrade-Insecure-Requests': '1',
         'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}
    r1 = requests.get(link, headers=hds, timeout=10)
    s = requests.session()
    s.keep_alive = False
    r1.encoding = 'gb18030'
    t1 = html.fromstring(r1.text)
    l=[]
    try:
        job = t1.xpath('//div[@class="tHeader tHjob"]//h1/text()')[0]
        company = t1.xpath('//p[@class="cname"]/a/text()')[0]
        label = t1.xpath('//div[@class="t1"]/span/text()')
        education = t1.xpath('//div[@class="cn"]/p[2]/text()')[2]
        salary = salary
        area = t1.xpath('//div[@class="cn"]/p[2]/text()')[0]
        companytype = 'Null'
        workyear = t1.xpath('//div[@class="cn"]/p[2]/text()')[1]
        describe = re.findall(re.compile(r'<div class="bmsg job_msg inbox">(.*?)<div class="mt10">', re.S), r1.text)
        require = re.findall(re.compile(r'<div class="bmsg job_msg inbox">.*?任职要求(.*?)<div class="mt10">', re.S),
                             r1.text)
        try:
            file = codecs.open('51job.xls', 'a+','utf-8')
            item = str(company) + '\t' + str(job) + '\t' + str(education) + '\t' + str(label) + '\t' + str(
                salary) + '\t' + str(companytype) + '\t' + str(workyear) + '\t' + str(area) + '\t' + str(
                workyear) + str(describe) + '\t' + str(require) + '\n'
            file.write(item)
            file.close()
            return True
        except Exception as e:
            print(e)
            return None
        # output='{},{},{},{},{},{},{},{}\n'.format(company,job,education,label,salary,area,describe,require)
        # with open('51job.csv', 'a+', encoding='utf-8') as f:
        # f.write(output)
    except:
        print('None')
    print(l)
    return l


for i in range(1, 20):
    print('正在爬取第{}页信息'.format(i))
    try:
        # time.sleep(random.random()+random.randint(1,5))
        links = get_links(i)
        for link in links:
            url=link[0].replace('\\','')
            salary=link[1].replace('\\','')
            try:
                get_content(url,salary)
            except:
                pass
            # time.sleep(random.random()+random.randint(0,1))
    except:
        continue
        print('有点问题')

2021.06:因为后来51job修改了网络结构,我稍微调整了一下代码。如果写入Excel是乱码的话,右键-打开方式选择记事本-另存为-编码选择ANSI,再用Excel打开就可以了。

后面如果网络结构换了,修改一下xpath和正则提取内容就可以了。

 

三、数据探索和预处理:

 

 

数据爬取完了,大概有十万条数据,看起来还不错。

 

然而问题来了:

1.数据有重复,需要去重。

2.岗位不是全部是数据分析,也有招聘店长、销售、运营之类的岗位,需要去除无关数据。

利用pandas模块,短短几行代码就可以实现了,而且数据很快。

# -*- coding: UTF-8 -*-
import pandas as pd
import numpy as np

data=pd.read_excel('51joball.xlsx',sheet_name='Sheet1',header=0)
df=pd.DataFrame(data)
df=df[True- df.公司.duplicated()]#去重
df=df[df.职位.str.contains(r'.*?数据.*?|.*?分析.*?')]#提取包含数据或者分析的岗位
df.to_excel('new51job.xlsx')

接下来还有一个问题需要处理,就是数据规范化,薪资待遇这栏,有的是千/月,有的是万每年,有的是元/天,有的是K每月,不规划化,无法进行分析。地区这一栏,有的有区,有的没区,我们规划到城市这个级别就好了。这里利用xlrd模块读取Excel表格,当然换成pandas一样也可以。

#coding:utf8
import xlrd
import codecs
import re
#加载Excel数据,获得工作表和行数
def load_from_xlsx(file):
    data = xlrd.open_workbook(file)
    table0 = data.sheet_by_name('Sheet1')
    nrows = table0.nrows
    return table0, nrows
#利用正则表达式提取月薪,把待遇规范成千/月的形式
def get_salary(salary):
    if '-'in salary: #针对1-2万/月或者10-20万/年的情况,包含-
        low_salary=re.findall(re.compile('(\d*\.?\d+)'),salary)[0]
        high_salary=re.findall(re.compile('(\d?\.?\d+)'),salary)[1]
        if u'万' in salary and u'年' in salary:#单位统一成千/月的形式
            low_salary = float(low_salary) / 12 * 10
            high_salary = float(high_salary) / 12 * 10
        elif u'万' in salary and u'月' in salary:
            low_salary = float(low_salary) * 10
            high_salary = float(high_salary) * 10
    else:#针对20万以上/年和100元/天这种情况,不包含-,取最低工资,没有最高工资
        low_salary = re.findall(re.compile('(\d*\.?\d+)'), salary)[0]
        high_salary=""
        if u'万' in salary and u'年' in salary:#单位统一成千/月的形式
            low_salary = float(low_salary) / 12 * 10
        elif u'万' in salary and u'月' in salary:
            low_salary = float(low_salary) * 10
        elif u'元'in salary and u'天'in salary:
            low_salary=float(low_salary)/1000*21#每月工作日21天
    return low_salary,high_salary

def main():
    data = load_from_xlsx(r'new51job.xlsx')
    table, nrows = data[0], data[1]
    print('一共有{}行数据,开始清洗数据'.format(nrows))
    for i in range(1,nrows):
        id=table.row_values(i)[0]
        company=table.row_values(i)[1]
        position = table.row_values(i)[2]
        education = table.row_values(i)[3]
        welfare = table.row_values(i)[4]
        salary=table.row_values(i)[5]
        area = table.row_values(i)[6][:2]#地区取到城市,把区域去掉
        companytype = table.row_values(i)[7]
        companysize = table.row_values(i)[8]
        field = table.row_values(i)[9]
        experience = table.row_values(i)[10]
        responsibility = table.row_values(i)[11]
        requirement = table.row_values(i)[12]
        if salary:#如果待遇这栏不为空,计算最低最高待遇
            getsalary=get_salary(salary)
            low_salary=getsalary[0]
            high_salary=getsalary[1]
        else:
            low_salary=high_salary=""
        print('正在写入第{}条,最低工资是{}k,最高工资是{}k'.format(i,low_salary,high_salary))
        output = '{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\n'.format(id, company, position, education, welfare,low_salary, high_salary, area, companytype,companysize, field, experience, responsibility,requirement)
        f=codecs.open('51jobanaly.xls','a+')
        f.write(output)
        f.close()
if __name__=='__main__':
    main()

看看清洗之后的效果

四、数据可视化与分析

1.各地区招聘公司数量和平均待遇。

    用tebleau生成地理图十分方便强大。可以看出不论是招聘公司的数据还是平均待遇水平主要都是北上广深杭州占优势。成都紧随其后。

2.公司类型

可以看出招聘的公司主要是民营企业和一些创业公司为主。

3.公司规模和公司领域

可以看出招聘公司的规模在50-500人规模为主,招聘的领域主要是互联网公司,金融紧随其后。

4.经验和学历要求

学历这里主要是大专本科为主,要求不算很高。

5岗位要求和岗位职责

直接生成现在最流行的词云,具体代码看python生成词云

 

 

  • 59
    点赞
  • 342
    收藏
    觉得还不错? 一键收藏
  • 201
    评论
评论 201
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值