目录
分析目的
3W需求原则:
where:哪里需要人才,聚集地所在
what:需要怎样的人才,年龄段,经验值,学历高低
when:那些时期需求最多,以及那些公司需求较高
处于数据信息化时代,用数据明面、直观形象的表述,数据分析师的作用在于收集、整理、分析数据,并根据数据进行行业研究、评估和预测,以提高公司的业绩等。本文针对去年12月拉勾招聘网站的职位信息,通过python 编程进行自动化的获取数据,从多维度分析相关数据,绘制直观的图形得到对应职位的要求,结合当下局势的发展得出结论。
数据获取及清洗过程
1.拉勾网站的网页数据获取
- 首先针对某个特定的职业选定某个城市和某个指定的页数分析网页的get 请求参数,可以判断 pn 指页数的变动,city 指城市的变化,Kd 指职位的变化。
图一 网站的get请求参数
- 导入requests 库模拟网页get请求,获取网页的数据,设置随机请求头。
# 定义获取网页数据的函数
def page_data(self,position, _city,_page):
base_url = 'https://www.lagou.com/wn/jobs?px=new' # 请求网址
params = {
'kd': self.position,
'city': _city,
'pn': _page # 循环输入页数的参数,以便多页数的HTML 数据
} # 网址中可变动的参数
# url = 'https://www.lagou.com/wn/jobs?px=new&pn=%skd=%s&city=%s'%(str(i),position,city) # 循环网址的另一种方法
headers = {'User-Agent': str(UserAgent().random in range(5))} # 设置随机请求头
page_text = requests.get(url=base_url, params=params, headers=headers).text # 得到网页的数据
# print(page_text)
图2 获取网页数据
- 分析网页数据的结构,采用xpath 进行网页解析。解析的数据维度包括职位的名称,位置,经验,薪资以及公司的规模、融资情况,所处行业、名称,福利。考虑到特定职位特定城市的页数相对固定,采用循环的操作,在这个过程中,需要将每页获取的数据,逐次添加。
page_tree = etree.HTML(page_text) # 解析字符串格式的html文档对象
print("解析html文档成功")
# 通过 xpath 进行路径解析
name_address = page_tree.xpath('//div[@class="p-top__1F7CL"]/a/text()')
exper = page_tree.xpath('//div[@class="p-bom__JlNur"]/text()')
name = []
address = []
for i in range(len(name_address)): # 将list 进行奇偶拆分为两部分
# name_address[i] = re.sub(r"\s+", '', name_address[i])
if i % 2 == 0:
name1 = re.sub(r"'", '', name_address[i])
name.append(name1)
else:
address.append(_city+name_address[i])
# exper[i] = re.sub(r"\s+",'',exper[i])
# print(name)
# 将 换行符、转义符 改成空值,并判断当列表里的元素是空值则进行去除操作
exper = [re.sub(r"\s+", '', exper[j]) for j in range(len(exper)) if re.sub(r"\s+", '', exper[j]) != '']
price = page_tree.xpath('//span[@class="money__3Lkgq"]/text()')
subject_number = page_tree.xpath('//div[@class="industry__1HBkr"]/text()')
firm = page_tree.xpath('//div[@class="com-logo__1QOwC"]/img/@alt')
# feature1 = page_tree.xpath('//div[@class="ir___QwEG"]/span[1]//text()')
# feature2 = page_tree.xpath('//div[@class="ir___QwEG"]/span[2]//text()')
# feature = np.array(feature1)+np.array(feature2) # 列表大小不一,产生错误
co = page_tree.xpath('//div[@class="il__3lk85"]/text()')
list_mind = [name,address,exper,price,subject_number,firm,co]
for i in range(len(self.rows)): # 每页数据对应字段的扩展
self.rows[i] = self.rows[i]+list_mind[i]
# print(self.rows)
rowss = list(map(list, zip(*self.rows))) # 列表元素转置操作
# print(rowss)
return rowss
图三 解析网页数据
2.获取的网页数据存储以及清洗过程
- 将数据存入excel表中,定义为一个函数,其中要传入两个参数,一个是储存的路径,还有一个就是网页解析之后的数据。
# 定义将数据保存到excel文件的函数
def saveex(self,savepath, da_list):
dalist_pd = pd.DataFrame(data=da_list) # 数据转换
dalist_pd.loc[0] = self.title # 增加首行数据 为字段名称
dalist_pd.to_excel(savepath, encoding='utf-8',header=None,index=False)
print("存入数据成功!")
图四 数据存入excel 表中
- 给定一个城市的列表,自己设定的是北京,上海,广州,成都,深圳,杭州,在这个城市列表里面进行循环反映网页,然而在每个城市下都有相应的页数,自己设定的是30页,所以在循环内嵌套循环访问每页的数据,然后再将30页的数据叠加,叠加之后传入 saveex函数。最后将从网页解析到存储数据的整个流程定义为一个类,类名叫做lagou 。
图五 定义类和固定的参数
图六 类中执行函数和调用类
- 得到获取的实际表格截取片段
- 考虑到某个职位的数据量偏少,因此选用三个职位进行分析,在整个拉勾类调用完之后,会产生输入的三个数据 Excel表。分别读取这三个Excel表并进行里面的去重,去空值,分列,以及增加“类别”列的操作。
# 清洗数据
def Cleandata():
for _class in ['数据挖掘','数据分析师','据产品经理']:
df_wa_class = pd.read_excel(_class + '1.xlsx')
df_wa_class.dropna(how='any') # 去除空值
df_wa_class = df_wa_class
df_wa_class.insert(0, '类别', _class) # 对每个职位的数据加入类别属性
df_wa_class[['城市', '区域']] = df_wa_class['位置'].str.split('[', expand=True) # 将位置分成与城市与区域两列
del df_wa_class['位置'] # 删除位置的那一列
图七 数据清洗
- 清洗之后的数据显示
职位信息可视化
1. 绘制北京,上海,深圳三大城市职位个数的区县图
将三个职位的excel表数据整合在一个Excel总表中,读取总表的excel,并转换为 dataframe 数据类型,根据城市分类,并按照对每个城市对应的区域进行二次分组,分别统计各城市的三个职位的个数,导入 pyecharts 库绘制三个城市的区县图,将这个过程定义为一个叫做Three_Position的函数。其中,调用了一个 自定义的Group_da 的函数,是因为在每次利用pyecharts 绘图时,都用根据分组依据得到统计指,最后将分组后的结果以及对应统计的数据传入到内嵌元组的列表中,故采用调用函数的传入所需要分组的依据以及数据来源表格的两个形参,具体见图八。
图八 分组数据传入列表
图九 绘制三大城市的区县图
2.绘制数据分析岗的公司名称词云图
# 绘制在招数据挖掘岗的公司词云图
def Firm_Ciyun():
image = Image.open('C:/Users/Dell/Desktop/背景1.png') # 作为背景轮廓图
graph = np.array(image)
# 参数分别是指定纸张大小、背景颜色、字体,最大的词的大小、使用给定图作为背景形状
wc = WordCloud(width=1024, height=728, background_color='white',
max_words=120, mask=graph, random_state=22)
# wc = wc.generate(text=text)
df_wa = pd.read_excel('数据挖掘1.xlsx')
df_wa = df_wa.loc[:, '公司名称'].value_counts()
# print(df_wa.head())
# 将df_wa转化成dataframe
df_wa = pd.DataFrame(df_wa.reset_index())
df_wa.columns = ['公司名称', '数量']
# 词
name = list(df_wa.公司名称)
# 词的频率
value = df_wa.数量
for i in range(len(name)):
name[i] = str(name[i])
# 词频以字典形式存储
dic = dict(zip(name, value))
# 根据给定词频生成词云
wc.generate_from_frequencies(dic)
plt.imshow(wc)
# 不显示坐标轴
plt.axis("off")
plt.show()
wc.to_file('词云图.png') # 图片命名
# 获取前10销量
df_wa = df_wa.nlargest(10, '数量')
# print(df_wa)
图十 绘制词云图
3. 绘制数据分析师岗的学历要求的玫瑰图
# 绘制数据分析师岗的学历要求的玫瑰图
def Education_Require():
data_fen = pd.read_excel('数据分析师1.xlsx')
pd_liyan = pd.DataFrame(data_fen)
list_li = Group_da(pd_liyan,'学历')
c = (
Pie(init_opts=opts.InitOpts(theme=ThemeType.MACARONS))
.add(
"",
list_li,
# 饼图的半径,数组的第一项是内半径,第二项是外半径
# 默认设置成百分比,相对于容器高宽中较小的一项的一半
radius=["40%", "75%"],
)
.set_global_opts(
title_opts=opts.TitleOpts(title="数据分析师--学历要求"),
legend_opts=opts.LegendOpts(
orient="vertical", # 图例垂直放置
pos_top="15%", # 图例位置调整
pos_left="2%"),
)
.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
.render("数据分析师学历要求.html")
)
图十一 绘制学历要求的玫瑰图
4. 绘制数据分析岗的所需经验的扇形图
# 绘制 数据分析师职位的所需经验的扇形图
def Need_Experience():
data_fen = pd.read_excel('数据分析师1.xlsx')
pd_liyan = pd.DataFrame(data_fen)
list_yan = Group_da(pd_liyan,'经验')
c = (
Pie(init_opts=opts.InitOpts(theme=ThemeType.MACARONS))
.add(
"",
list_yan,
radius=["30%", "75%"],
center=["55%", "50%"],
rosetype="area",
)
.set_global_opts(
title_opts=opts.TitleOpts(title="数据分析师——经验要求"),
legend_opts = opts.LegendOpts(
orient="vertical", # 图例垂直放置
pos_top="15%", # 图例位置调整
pos_left="2%"),
)
.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
.render("数据分析师所需经验.html")
)
图十二 绘制所需经验的扇形图
结论
- 按招聘城市来看,一线城市和新一线城市需求较为广泛,可以考虑多往这些地方发展,北上广深杭人才需求递减。
- 从招聘公司来看,大厂的需求量较高,规模较大的公司需求更多。
- 学历上看,数据分析岗针对本科学历要求较多,占86% 以上。
- 按工作年限来看,工作3-5年经验的人才需求量最大占比42%,其次是1-3年工作经验的人才;在招的岗位所需应届生也就是在校或者经验在一年以下的要求在15%左右。 随着工作经验的提升,数据分析师平均薪水不断提升,是一个长期的发展方向。
- 最后强调一点:本次所采集的数据仅处于某个时间段的数据,参考价值不太全面,但是按抽样样本可以映射全体数据特点,还是有一定的对比性。