基于Flask的岗位就业可视化系统(二)

🌟欢迎来到 我的博客 —— 探索技术的无限可能!


🌟博客的简介(文章目录)

前言

  • 本项目综合了基本数据分析的流程,包括数据采集(爬虫)、数据清洗、数据存储、数据前后端可视化等

  • 推荐阅读顺序为:数据采集——>数据清洗——>数据库存储——>基于Flask的前后端交互,有问题的话可以留言,有时间我会解疑~

  • 感谢阅读、点赞和关注

开发环境

  • 系统:Window 10 家庭中文版。
  • 语言:Python(3.9)、MySQL。
  • Python所需的库:pymysql、pandas、numpy、time、datetime、requests、etree、jieba、re、json、decimal、flask(没有的话pip安装一下就好)。
  • 编辑器:jupyter notebook、Pycharm、SQLyog。
    (如果下面代码在jupyter中运行不完全,建议直接使用Pycharm中运行)

文件说明

在这里插入图片描述
本项目下面有四个.ipynb的文件,下面分别阐述各个文件所对应的功能:(有py版本 可后台留言)

  • 数据采集:分别从前程无忧网站和猎聘网上以关键词数据挖掘爬取相关数据。其中,前程无忧上爬取了270页,有超过1万多条数据;而猎聘网上只爬取了400多条数据,主要为岗位要求文本数据,最后将爬取到的数据全部储存到csv文件中。

  • 数据清洗:对爬取到的数据进行清洗,包括去重去缺失值、变量重编码、特征字段创造、文本分词等。

  • 数据库存储:将清洗后的数据全部储存到MySQL中,其中对文本数据使用jieba.analyse下的extract_tags来获取文本中的关键词和权重大小,方便绘制词云。

  • 基于Flask的前后端交互:使用Python一个小型轻量的Flask框架来进行Web可视化系统的搭建,在static中有css和js文件,js中大多为百度开源的ECharts,再通过自定义controller.js来使用ajax调用flask已设定好的路由,将数据异步刷新到templates下的main.html中。

技术栈

  • Python爬虫:(requests和xpath
  • 数据清洗:详细了解项目中数据预处理的步骤,包括去重去缺失值、变量重编码、特征字段创造和文本数据预处理 (pandas、numpy
  • 数据库知识:select、insert等操作,(增删查改&pymysql) 。
  • 前后端知识:(HTML、JQuery、JavaScript、Ajax)。
  • Flask知识:一个轻量级的Web框架,利用Python实现前后端交互。(Flask

二、数据清洗

招聘岗位数据清洗

import re
import pandas as pd
import numpy as np
read_csv读取数据集
data.head()

读取数据
在这里插入图片描述

去重去缺失

查看缺失值的缺失比例

data.isnull().mean()

在这里插入图片描述
考虑舍弃薪水和工作职责上的缺失数据

data.dropna(subset = ['薪水'], inplace = True)
# 去除重复值
data.drop_duplicates(inplace = True)
# 索引重置
data.index = range(data.shape[0])
data.shape

在这里插入图片描述

薪水字段重编码

初始化列表来接收正则提取后的每个字符串

# 初始化列表来接收正则提取后的每个字符串
salary_list = []
for i in range(len(data)):
    
    # 使用正则表达式需要将每一列都转换为字符串形式
    data['薪水'][i] = str(data['薪水'][i])
    
    # 注意join之后便为一个字符串,我们使用正则筛选掉数字和其它符号,findall在下列中只会切割每个字,[]表示或,()表示与,{}表示匹配次数
    salary_list.append(''.join(re.findall(r'[^0-9\.]', data['薪水'][i])))

# 使用unique知道有多少种写法
np.unique(salary_list)

在这里插入图片描述

代码过长这边就大概描述(对薪水这一列的表示方法都统一规范为数字(千/月))
在这里插入图片描述

地域字段重编码

对地域这一列进行字段重编码

data['地区'] = data['地域'].apply(lambda x: x.split('-')[0])
data

在这里插入图片描述

进行省份的划分
在这里插入图片描述
对31个省市进行遍历


在这里插入图片描述

人数、学历和经验特征提取

生成人数这一列

num_list = []
k = 0
for i in range(len(data)):
    s = str(data['其他信息'][i])
    num_str = s.split(' ')[-1]
    if re.findall(r'\d', num_str):
        num_list.append(int(re.findall(r'\d', num_str)[0]))
    else:
        num_list.append(np.nan)
        k += 1
data['人数'] = num_list

print('招聘人数缺失数量有%s条,占总样本比例为%s' %(k, k / data.shape[0]))

在这里插入图片描述

生成学历这一列

k = 0
edu_list = []
for i in range(len(data)):
    s = str(data['其他信息'][i])
    edu_str = s.split(' ')[-2]
    if edu_str in ['博士', '硕士', '本科', '大专', '中专', '高中', '初中及以下']:
        edu_list.append(edu_str)
    else:
        edu_list.append(np.nan)
        k += 1
data['学历'] = edu_list
print('学历未标明的数量有%s条,占总样本比例为%s' %(k, k / data.shape[0]))

在这里插入图片描述
生成经验这一列

jingyan_list = []
for i in range(len(data)):
    try:
        ss = data['其他信息'][i].split(' ')[-3]
        if '经验' in ss:
            if re.findall(r'(.*)\-(.*)\年', ss):
                ss_num = re.findall(r'(.*)\-(.*)年', ss)[0]
                jingyan = np.round((float(ss_num[0]) + float(ss_num[1])) / 2, 0)
                jingyan_list.append(format(jingyan, '.0f'))
            elif re.findall(r'(.*)\年', ss):
                ss_num = re.findall(r'(.*)\年', ss)[0]
                jingyan_list.append(format(float(ss_num), '.0f'))
            else:
                jingyan_list.append(0)
        else:
            jingyan_list.append(0)
    except:
        jingyan_list.append(0)
data['经验'] = jingyan_list
data[:2]

在这里插入图片描述

将人数和学历的缺失值全部去除

data.dropna(subset = ['人数', '学历'], inplace = True)
data.index = range(data.shape[0])

去除无意义的字段

data.drop(labels = ['其他信息', '地域', '地区'], axis = 1, inplace = True)
data['公司类型'] = data['公司类型'].fillna(data['公司类型'].mode().values[0])
data.shape

在这里插入图片描述

保存数据

data.to_csv('./51job_data_preprocessing.csv', encoding = 'gb18030', index = None)
data.isnull().mean()

在这里插入图片描述

清洗岗位上的要求文本

read_csv数据集
df

在这里插入图片描述

考虑到工作职责上爬取信息时出现的空缺或爬取不到数据的情况,接下来,我们需要对工作职责这一列进行数据清洗

遍历工作职责这一列,若发现字符串长度小于30,则删除掉这一行的数据,若字符串大于30且匹配到的?占字符串长度的40%以上,同样删除掉这一行的数据

for i in range(len(df)):
    df['岗位要求'][i] = str(df['岗位要求'][i])

    if len(df['岗位要求'][i]) < 30 or len(re.findall(r'\?', df['岗位要求'][i])) / len(df['岗位要求'][i]) > 0.4:
        df.drop(i, axis=0, inplace=True)

# 索引重置
df.index = range(df.shape[0])
df.shape

导入停用词

read_csv

自定义函数来实现分词和去除停用词操作

import jieba
def m_cut(tmpstr):
    return [w.strip() for w in jieba.lcut(tmpstr) if w not in stoplist and len(w) > 1]

导入自定义词典

dic = './自定义词典.txt'
jieba.load_userdict(dic)

先去除部分不相关的词汇,之后调用上述函数进行分词及去除停用词的操作

在这里插入图片描述

将处理后的数据保存下来

df0.to_csv('./liepin_job_detail.csv', encoding = 'gb18030', index = None)
  • 15
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZShiJ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值