爬取拉勾网关于python职位相关的数据信息,并将爬取的数据已csv各式存入文件,然后对csv文件相关字段的数据进行清洗,并对数据可视化展示,包括柱状图展示、直方图展示、词云展示等并根据可视化的数据做进一步的分析,其余分析和展示读者可自行发挥和扩展包括各种分析和不同的存储方式等。。。。。

一、爬取和分析相关依赖包

  1. Python版本: Python3.6
  2. requests: 下载网页
  3. math: 向上取整
  4. time: 暂停进程
  5. pandas:数据分析并保存为csv文件
  6. matplotlib:绘图
  7. pyecharts:绘图
  8. statsmodels:统计建模
  9. wordcloud、scipy、jieba:生成中文词云
  10. pylab:设置画图能显示中文

在以上安装或使用过程中可能读者会遇到安装或导入失败等问题自行百度,选择依赖包的合适版本

二、分析网页结构

通过Chrome搜索'python工程师',然后右键点击检查或者F12,,使用检查功能查看网页源代码,当我们点击下一页观察浏览器的搜索栏的url并没有改变,这是因为拉勾网做了反爬虫机制, 职位信息并不在源代码里,而是保存在JSON的文件里,因此我们直接下载JSON,并使用字典方法直接读取数据.即可拿到我们想要的python职位相关的信息,

待爬取的python工程师职位信息如下:

为了能爬到我们想要的数据,我们要用程序来模拟浏览器来查看网页,所以我们在爬取的过程中会加上头信息,头信息也是我们通过分析网页获取到的,通过网页分析我们知道该请求的头信息,以及请求的信息和请求的方式是POST请求,这样我们就可以该url请求拿到我们想的数据做进一步处理

爬取网页信息代码如下:

import requests

url = ' https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false'

def get_json(url, num):
"""
从指定的url中通过requests请求携带请求头和请求体获取网页中的信息,
:return:
"""
url1 = 'https://www.lagou.com/jobs/list_python%E5%BC%80%E5%8F%91%E5%B7%A5%E7%A8%8B%E5%B8%88?labelWords=&fromSearch=true&suginput='
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36',
'Host': 'www.lagou.com',
'Referer': 'https://www.lagou.com/jobs/list_%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90?labelWords=&fromSearch=true&suginput=',
'X-Anit-Forge-Code': '',
'X-Anit-Forge-Token': 'None',
'X-Requested-With': 'XMLHttpRequest'
}
data = {
'first': 'true',
'pn': num,
'kd': 'python工程师'}
s = requests.Session()
print('建立session:', s, '\n\n')
s.get(url=url1, headers=headers, timeout=3)
cookie = s.cookies
print('获取cookie:', cookie, '\n\n')
res = requests.post(url, headers=headers, data=data, cookies=cookie, timeout=3)
res.raise_for_status()
res.encoding = 'utf-8'
page_data = res.json()
print('请求响应结果:', page_data, '\n\n')
return page_data print(get_json(url, 1))

通过搜索我们知道每页显示15个职位,最多显示30页,通过分析网页源代码知道,可以通过JSON里读取总职位数,通过总的职位数和每页能显示的职位数.我们可以计算出总共有多少页,然后使用循环按页爬取, 最后将职位信息汇总, 写入到CSV格式的文件中.

程序运行结果如图:

爬取所有python相关职位信息如下:

三、数据清洗后入库

数据清洗其实会占用很大一部分工作,我们在这里只做一些简单的数据分析后入库。在拉勾网输入python相关的职位会有18988个。你可以根据工作中需求选择要入库的字段,并对一些字段做进一步的筛选,比如我们可以去除职位名称中为实习生的岗位,过滤指定的字段区域在我们指定区域的职位,取字段薪资的平均值,以最低值和差值的四分之一为平均值等等根据需求自由发挥

import pandas as pd
import matplotlib.pyplot as plt
import statsmodels.api as sm
from wordcloud import WordCloud
from scipy.misc import imread
from imageio import imread
import jieba
from pylab import mpl # 使用matplotlib能够显示中文
mpl.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
# 读取数据
df = pd.read_csv('Python_development_engineer.csv', encoding='utf-8') # 进行数据清洗,过滤掉实习岗位
# df.drop(df[df['职位名称'].str.contains('实习')].index, inplace=True)
# print(df.describe()) # 由于csv文件中的字符是字符串形式,先用正则表达式将字符串转化为列表,在去区间的均值
pattern = '\d+'
# print(df['工作经验'], '\n\n\n')
# print(df['工作经验'].str.findall(pattern))
df['工作年限'] = df['工作经验'].str.findall(pattern)
print(type(df['工作年限']), '\n\n\n')
avg_work_year = []
count = 0
for i in df['工作年限']:
# print('每个职位对应的工作年限',i)
# 如果工作经验为'不限'或'应届毕业生',那么匹配值为空,工作年限为0
if len(i) == 0:
avg_work_year.append(0)
# print('nihao')
count += 1
# 如果匹配值为一个数值,那么返回该数值
elif len(i) == 1:
# print('hello world')
avg_work_year.append(int(''.join(i)))
count += 1
# 如果匹配为一个区间则取平均值
else:
num_list = [int(j) for j in i]
avg_year = sum(num_list) / 2
avg_work_year.append(avg_year)
count += 1
print(count)
df['avg_work_year'] = avg_work_year
# 将字符串转化为列表,薪资取最低值加上区间值得25%,比较贴近现实
df['salary'] = df['薪资'].str.findall(pattern)
#
avg_salary_list = []
for k in df['salary']:
int_list = [int(n) for n in k]
avg_salary = int_list[0] + (int_list[1] - int_list[0]) / 4
avg_salary_list.append(avg_salary)
df['月薪'] = avg_salary_list
# df.to_csv('python.csv', index=False)

四、数据可视化展示

下面是对数据的可视化展示,仅以部分视图进行一些可视化的展示,如果读者想对其他字段做一些展示以及想使用不同的视图类型进行展示,请自行发挥,注:以下代码中引入的模块见最后的完整代码

1、绘制python薪资的频率直方图并保存

如果我们想看看关于互联网行业python工程师相关的岗位大家普遍薪资的一个分部区间在哪个范围,占据了多达的比例我们就可以借助matplotlib库,来将我们保存在csv文件中的数据进行可视化的展示,然我们能够更直观的看到数据的一个分部趋势

# 绘制python薪资的频率直方图并保存
plt.hist(df['月薪'],bins=8,facecolor='#ff6700',edgecolor='blue') # bins是默认的条形数目
plt.xlabel('薪资(单位/千元)')
plt.ylabel('频数/频率')
plt.title('python薪资直方图')
plt.savefig('python薪资分布.jpg')
plt.show()

运行结果如下:

2、绘制python相关职位的地理位置饼状图

通过地理python职位地理位置的分部我们可以大致了解IT行业主要集中分部在哪些城市,这样也更利于我们选择地域进行选择性就业,可以获得更多的面试机会等,参数可自行调试,或根据需要添加。

# 绘制饼状图并保存
city = df['城市'].value_counts()
print(type(city))
# print(len(city))
label = city.keys()
print(label)
city_list = []
count = 0
n = 1
distance = []
for i in city: city_list.append(i)
print('列表长度', len(city_list))
count += 1
if count > 5:
n += 0.1
distance.append(n)
else:
distance.append(0)
plt.pie(city_list, labels=label, labeldistance=1.2, autopct='%2.1f%%', pctdistance=0.6, shadow=True, explode=distance)
plt.axis('equal') # 使饼图为正圆形
plt.legend(loc='upper left', bbox_to_anchor=(-0.1, 1))
plt.savefig('python地理位置分布图.jpg')
plt.show()

运行结果如下:

3、绘制基于pyechart的城市分布柱状图

pycharts是python中调用百度基于js开发的echarts接口,也可以对数据进行各种可视化操作,更多数据可视化图形展示,可参考echarts官网:https://www.echartsjs.com/,echarts官网提供了各种实例供我们参考,如折线图、柱状图、饼图、路径图、树图等等,基于pyecharts的文档可参考以下官网:https://pyecharts.org/#/,更多用法也可自行百度网络资源

city = df['城市'].value_counts()
print(type(city))
print(city)
# print(len(city)) keys = city.index # 等价于keys = city.keys()
values = city.values
from pyecharts import Bar bar = Bar("python职位的城市分布图")
bar.add("城市", keys, values)
bar.print_echarts_options() # 该行只为了打印配置项,方便调试时使用
bar.render(path='a.html')

运行结果如下:

4、绘制python福利相关的词云

词云图又叫文字云,是对文本数据中出现频率较高的关键词予以视觉上的突出,形成"关键词的渲染"就类似云一样的彩色图片,从而过滤掉大量的文本信息,,使人一眼就可以领略文本数据的主要表达意思。利用jieba分词和词云生成WorldCloud(可自定义背景),下面就是对python相关职位的福利做了一个词云的展示,可以更直观的看到大多数公司的福利待遇集中在哪些地方

# 绘制福利待遇的词云
text = ''
for line in df['公司福利']:
if len(eval(line)) == 0:
continue
else:
for word in eval(line):
# print(word)
text += word cut_word = ','.join(jieba.cut(text))
word_background = imread('公主.jpg')
cloud = WordCloud(
font_path=r'C:\Windows\Fonts\simfang.ttf',
background_color='black',
mask=word_background,
max_words=500,
max_font_size=100,
width=400,
height=800 )
word_cloud = cloud.generate(cut_word)
word_cloud.to_file('福利待遇词云.png')
plt.imshow(word_cloud)
plt.axis('off')
plt.show()

运行结果如下:

五、爬虫及可视化完整代码

完整代码在下面,代码均测试可正常运行,感兴趣的小伙伴可去尝试和了解其中的使用方法,如运行或者模块安装等失败可以在评论区进行留言,让我们一同解决吧

如果你觉得对你有帮助可以点个赞哦,原创内容转载需说明出处!!!

1、爬虫完整代码

为了防止我们频繁请求一个网站被限制ip,我们在爬取每一页后选择睡一段时间,当然你也可以使用代理等其他方式自行实现

import requests
import math
import time
import pandas as pd def get_json(url, num):
"""
从指定的url中通过requests请求携带请求头和请求体获取网页中的信息,
:return:
"""
url1 = 'https://www.lagou.com/jobs/list_python%E5%BC%80%E5%8F%91%E5%B7%A5%E7%A8%8B%E5%B8%88?labelWords=&fromSearch=true&suginput='
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36',
'Host': 'www.lagou.com',
'Referer': 'https://www.lagou.com/jobs/list_%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90?labelWords=&fromSearch=true&suginput=',
'X-Anit-Forge-Code': '',
'X-Anit-Forge-Token': 'None',
'X-Requested-With': 'XMLHttpRequest'
}
data = {
'first': 'true',
'pn': num,
'kd': 'python工程师'}
s = requests.Session()
print('建立session:', s, '\n\n')
s.get(url=url1, headers=headers, timeout=3)
cookie = s.cookies
print('获取cookie:', cookie, '\n\n')
res = requests.post(url, headers=headers, data=data, cookies=cookie, timeout=3)
res.raise_for_status()
res.encoding = 'utf-8'
page_data = res.json()
print('请求响应结果:', page_data, '\n\n')
return page_data def get_page_num(count):
"""
计算要抓取的页数,通过在拉勾网输入关键字信息,可以发现最多显示30页信息,每页最多显示15个职位信息
:return:
"""
page_num = math.ceil(count / 15)
if page_num > 30:
return 30
else:
return page_num def get_page_info(jobs_list):
"""
获取职位
:param jobs_list:
:return:
"""
page_info_list = []
for i in jobs_list: # 循环每一页所有职位信息
job_info = []
job_info.append(i['companyFullName'])
job_info.append(i['companyShortName'])
job_info.append(i['companySize'])
job_info.append(i['financeStage'])
job_info.append(i['district'])
job_info.append(i['positionName'])
job_info.append(i['workYear'])
job_info.append(i['education'])
job_info.append(i['salary'])
job_info.append(i['positionAdvantage'])
job_info.append(i['industryField'])
job_info.append(i['firstType'])
job_info.append(i['companyLabelList'])
job_info.append(i['secondType'])
job_info.append(i['city'])
page_info_list.append(job_info)
return page_info_list def main():
url = ' https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false'
first_page = get_json(url, 1)
total_page_count = first_page['content']['positionResult']['totalCount']
num = get_page_num(total_page_count)
total_info = []
time.sleep(10)
print("python开发相关职位总数:{},总页数为:{}".format(total_page_count, num))
for num in range(1, num + 1):
# 获取每一页的职位相关的信息
page_data = get_json(url, num) # 获取响应json
jobs_list = page_data['content']['positionResult']['result'] # 获取每页的所有python相关的职位信息
page_info = get_page_info(jobs_list)
print("每一页python相关的职位信息:%s" % page_info, '\n\n')
total_info += page_info
print('已经爬取到第{}页,职位总数为{}'.format(num, len(total_info)))
time.sleep(20)
# 将总数据转化为data frame再输出,然后在写入到csv各式的文件中
df = pd.DataFrame(data=total_info,
columns=['公司全名', '公司简称', '公司规模', '融资阶段', '区域', '职位名称', '工作经验', '学历要求', '薪资', '职位福利', '经营范围',
'职位类型', '公司福利', '第二职位类型', '城市'])
# df.to_csv('Python_development_engineer.csv', index=False)
print('python相关职位信息已保存') if __name__ == '__main__':
main()

2、可视化完整代码

数据可视化涉及到matplotlib、jieba、wordcloud、pyecharts、pylab、scipy等等模块的使用,读者可以自行了解各个模块的使用方法,和其中涉及的各种参数

import pandas as pd
import matplotlib.pyplot as plt
import statsmodels.api as sm
from wordcloud import WordCloud
from scipy.misc import imread
# from imageio import imread
import jieba
from pylab import mpl # 使用matplotlib能够显示中文
mpl.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
# 读取数据
df = pd.read_csv('Python_development_engineer.csv', encoding='utf-8') # 进行数据清洗,过滤掉实习岗位
# df.drop(df[df['职位名称'].str.contains('实习')].index, inplace=True)
# print(df.describe()) # 由于csv文件中的字符是字符串形式,先用正则表达式将字符串转化为列表,在去区间的均值
pattern = '\d+'
# print(df['工作经验'], '\n\n\n')
# print(df['工作经验'].str.findall(pattern))
df['工作年限'] = df['工作经验'].str.findall(pattern)
print(type(df['工作年限']), '\n\n\n')
avg_work_year = []
count = 0
for i in df['工作年限']:
# print('每个职位对应的工作年限',i)
# 如果工作经验为'不限'或'应届毕业生',那么匹配值为空,工作年限为0
if len(i) == 0:
avg_work_year.append(0)
# print('nihao')
count += 1
# 如果匹配值为一个数值,那么返回该数值
elif len(i) == 1:
# print('hello world')
avg_work_year.append(int(''.join(i)))
count += 1
# 如果匹配为一个区间则取平均值
else:
num_list = [int(j) for j in i]
avg_year = sum(num_list) / 2
avg_work_year.append(avg_year)
count += 1
print(count)
df['avg_work_year'] = avg_work_year
# 将字符串转化为列表,薪资取最低值加上区间值得25%,比较贴近现实
df['salary'] = df['薪资'].str.findall(pattern)
#
avg_salary_list = []
for k in df['salary']:
int_list = [int(n) for n in k]
avg_salary = int_list[0] + (int_list[1] - int_list[0]) / 4
avg_salary_list.append(avg_salary)
df['月薪'] = avg_salary_list
# df.to_csv('python.csv', index=False) """1、绘制python薪资的频率直方图并保存"""
plt.hist(df['月薪'], bins=8, facecolor='#ff6700', edgecolor='blue') # bins是默认的条形数目
plt.xlabel('薪资(单位/千元)')
plt.ylabel('频数/频率')
plt.title('python薪资直方图')
plt.savefig('python薪资分布.jpg')
plt.show() """2、绘制饼状图并保存"""
city = df['城市'].value_counts()
print(type(city))
# print(len(city))
label = city.keys()
print(label)
city_list = []
count = 0
n = 1
distance = []
for i in city: city_list.append(i)
print('列表长度', len(city_list))
count += 1
if count > 5:
n += 0.1
distance.append(n)
else:
distance.append(0)
plt.pie(city_list, labels=label, labeldistance=1.2, autopct='%2.1f%%', pctdistance=0.6, shadow=True, explode=distance)
plt.axis('equal') # 使饼图为正圆形
plt.legend(loc='upper left', bbox_to_anchor=(-0.1, 1))
plt.savefig('python地理位置分布图.jpg')
plt.show() """3、绘制福利待遇的词云"""
text = ''
for line in df['公司福利']:
if len(eval(line)) == 0:
continue
else:
for word in eval(line):
# print(word)
text += word cut_word = ','.join(jieba.cut(text))
word_background = imread('公主.jpg')
cloud = WordCloud(
font_path=r'C:\Windows\Fonts\simfang.ttf',
background_color='black',
mask=word_background,
max_words=500,
max_font_size=100,
width=400,
height=800 )
word_cloud = cloud.generate(cut_word)
word_cloud.to_file('福利待遇词云.png')
plt.imshow(word_cloud)
plt.axis('off')
plt.show() """4、基于pyechart的柱状图"""
city = df['城市'].value_counts()
print(type(city))
print(city)
# print(len(city)) keys = city.index # 等价于keys = city.keys()
values = city.values
from pyecharts import Bar bar = Bar("python职位的城市分布图")
bar.add("城市", keys, values)
bar.print_echarts_options() # 该行只为了打印配置项,方便调试时使用
bar.render(path='a.html')

python爬取拉勾网数据并进行数据可视化的更多相关文章

  1. python 爬取天猫美的评论数据

    笔者最近迷上了数据挖掘和机器学习,要做数据分析首先得有数据才行.对于我等平民来说,最廉价的获取数据的方法,应该是用爬虫在网络上爬取数据了.本文记录一下笔者爬取天猫某商品的全过程,淘宝上面的店铺也是类似 ...

  2. 爬虫实战(三) 用Python爬取拉勾网

    目录 0.前言 1.初始化 2.爬取数据 3.保存数据 4.数据可视化 5.大功告成 0.前言 最近,博主面临着选方向的困难(唉,选择困难症患者 >﹏<),所以希望了解一下目前不同岗位的就 ...

  3. python爬取拉勾网职位数据

    今天写的这篇文章是关于python爬虫简单的一个使用,选取的爬取对象是著名的招聘网站--拉钩网,由于和大家的职业息息相关,所以爬取拉钩的数据进行分析,对于职业规划和求职时的信息提供有很大的帮助. 完成 ...

  4. Python爬取6271家死亡公司数据,一眼看尽十年创业公司消亡史!

    ​ 小五利用python将其中的死亡公司数据爬取下来,借此来观察最近十年创业公司消亡史. 获取数据 F12,Network查看异步请求XHR,翻页. ​ 成功找到返回json格式数据的url, 很多人 ...

  5. Python 爬取大众点评 50 页数据,最好吃的成都火锅竟是它!

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 胡萝卜酱 PS:如有需要Python学习资料的小伙伴可以加点击下方链 ...

  6. Python爬取上交所一年大盘数据

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 半个码农2018 PS:如有需要Python学习资料的小伙伴可以加点 ...

  7. Python爬取6271家死亡公司数据,看十年创业公司消亡史

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 朱小五 凹凸玩数据 PS:如有需要Python学习资料的小伙伴可以加 ...

  8. Python爬取某网站文档数据完整教程(附源码)

    基本开发环境 (https://jq.qq.com/?_wv=1027&k=NofUEYzs) Python 3.6 Pycharm 相关模块的使用 (https://jq.qq.com/?_ ...

  9. 使用python爬取东方财富网机构调研数据

    最近有一个需求,需要爬取东方财富网的机构调研数据.数据所在的网页地址为: 机构调研 网页如下所示: 可见数据共有8464页,此处不能直接使用scrapy爬虫进行爬取,因为点击下一页时,浏览器只是发起了 ...

随机推荐

  1. ASP.NET Core 用户注册 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core 用户注册 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 用户注册 上一章节我们终于迁移完了 Identity 的数据,也创建 ...

  2. 如何加入该网站for Linux(绑定域名)

    [路径跟踪配置由阿里云提供的标准环境的路径为准,假设你单独安装.请根据实际的安装路径配置].   1.cd /alidata/server/httpd/conf/vhosts/ 进入绑定域名所在文件夹 ...

  3. 各种Message中文解释(一部分)

    函数功能:该函数将指定的消息发送到一个或多个窗口.此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回.该函数是应用程序和应用程序之间进行消息传递的主要手段之一.    函数原型:LRESUL ...

  4. WPF - 资源收集

    原文:WPF - 资源收集 OpenExpressApp的UI现在是使用WPF,所以熟悉WPF是必须的,以下我将可能用到的一些相关内容随时记录下来,以备查阅.此篇文章将不断更新,感兴趣的可以看看,也欢 ...

  5. WPF之动态换肤

    原文:WPF之动态换肤 如何实现换肤呢,对于复杂的换肤操作,如,更换按钮样式.窗口样式等,我们需要写多个资源字典来表示不同的皮肤,通过动态加载不同的资源字典来实现换肤的效果:对于简单的换肤操作,如更改 ...

  6. Convert和RelativeSource

    自定义Converter 后台Converter类实现接口IValueConverter方法Convert是值->UI方法ConvertBack是UI->值初始化走Convert publ ...

  7. 协程在Web服务器中的应用(配的图还不错)

    协程(纤程,微线程)这个概念早就有之,各家互联网公司也都有研究,但在国内各大论坛和大会热起来,还是今年的事. 最近参与讨论开放平台建设和架构设计过程中,有同事提到了使用协程代替线程,能够很大幅度的提高 ...

  8. WPF 用代码增加路由事件的方法

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

  9. js如何通过变量调用函数,函数名在变量里面

    js如何通过变量调用函数,函数名在变量里面. 有时候函数名是动态定义的,这时候我们就需要用到这个方法了. //赋值函数名称 var a = "b"; //定义函数 function ...

  10. Win8 Metro(C#)数字图像处理--2.48Canny边缘检测算法

    原文:Win8 Metro(C#)数字图像处理--2.48Canny边缘检测算法  [算法说明] Canny边缘检测算法可以分为4步:高斯滤波器平滑处理.梯度计算.非极大值抑制.双阈值边缘检 测和 ...