新手向:爬取分析拉勾网招聘信息

2023-11-04 00:20

本文主要是介绍新手向:爬取分析拉勾网招聘信息,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

爱写bug(ID:icodebugs)

作者:爱写bug

前言:

看了很多网站,只发现获取拉勾网招聘信息是只用post方式就可以得到,应当是非常简单了。推荐刚接触数据分析和爬虫的朋友试一下。

在python3.7、acaconda3环境下运行通过

数据爬取篇:

1、伪造浏览器访问拉勾网

打开Chrome浏览器,进入拉勾网官网,右键->检查,调出开发者模式。

然后在拉勾网搜索关键词 算法工程师 回车,然后点击下一页、下一页,此时开发者工具里的Network 下XHR(表示该网站是以Ajax方式获取刷新信息的)应当如下图(图中已标明了一些关键信息):

640?wx_fmt=png


每次点击下一页图中XHR下以PositionAjax开头的请求就会多一条,图下方 Form Data 里 page numberpn 就会增加1,网站地址:https://www.lagou.com/jobs/list_ + 搜索关键词 city= + 城市名称 +&cl=false&fromSearch=true&labelWords=&suginput=

当然搜索关键词是中文的话一定要 unicode 转码。这里我们以关键字为算法工程师,地区为全国 为例,所以URL:

转码前:https://www.lagou.com/jobs/list_算法工程师?city=全国&cl=false&fromSearch=true&labelWords=&suginput=转码后:https://www.lagou.com/jobs/list_%E7%AE%97%E6%B3%95%E5%B7%A5%E7%A8%8B%E5%B8%88?city=%E5%85%A8%E5%9B%BD&cl=false&fromSearch=true&labelWords=&suginput=

根据图中 Request Headers 构造请求头伪造成浏览器访问:

headers = {        'Accept': "application/json, text/javascript, */*; q=0.01",        'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36",        'Referer': "https://www.lagou.com/jobs/list_%E7%AE%97%E6%B3%95%E5%B7%A5%E7%A8%8B%E5%B8%88?city=%E5%85%A8%E5%9B%BD&cl=false&fromSearch=true&labelWords=&suginput="    }

然后根据图中 Form Data来构造表单,只有pn表示的当前所在页数需要不断改变,所以 pn定义一个变量num表示当前页数:

form_data = {        'first': 'true',        'pn': num,        'kd': '算法工程师'    }

然后试一下:

request=requests.post(url,data=form_data,headers=headers)print(request.text)

但是尴尬的是这个时候post请求获得的回复是:

{"status":false,"msg":"您操作太频繁,请稍后再访问","clientIp":"182.245.65.138","state":2402}

由于该网站的反爬措施,此时无论把请求头构造的多好都没用,哪怕用本地的Cookie。

所以我们采用 Seesion 对话方式:

s = requests.Session()  # 创建一个session对象s.get(url_start, headers=headers, timeout=3) # 使用session维持同一个会话cookie = s.cookies # 使用该会话的cookieresponse = s.post(url, data=form_data, headers=headers, cookies=cookie, timeout=3)

连接成功!

2、获取招聘数据

然后解析返回的 json 对象。我们先在开发者工具里把 PositionAjax 项的 Headers 改到 Preview 看一下Chrome帮我们格式化好的 json 内容:

640?wx_fmt=png

出现了,我们想要的数据 在 content -> positionResult -> result , 一共从0到14共15条信息,这对应了网站每页现实的信息数。而最下面还有 totalCount: 16945 这是搜索该关键词 算法工程师 下的总条目数。可以根据这个算出一共有多页的信息(16945 / 15)而不是网站上显示的只有30页。由于时间关系,本次示例只获取29页数据。本次示例只获取29页数据。

def parse_page(job_json):    job_list = job_json['content']['positionResult']['result']    company_info = []    for job in job_list:        job_info = []        job_info.append(job['companyFullName'])#公司全称        job_info.append(job['companySize'])#规模        job_info.append(job['financeStage'])#融资情况        job_info.append(job['district'])#位置        job_info.append(job['positionName'])#职位        job_info.append(job['workYear'])#工作经验要求        job_info.append(job['education'])#学历        job_info.append(job['salary'])#工资        job_info.append(job['positionAdvantage'])#福利待遇        company_info.append(job_info)#把所有职位情况添加到网页信息page_info    return company_info

我们就把每个公司的各类招聘情况存储在 company_info 里了。

最后把所有 company_info 汇总在一起:

result = parse_page(job_json)all_company += result # 所有公司招聘信息汇在一起

接着以CSV格式存储在本地:

path = 'A:\Temp\\'  # 指定csv数据存储路径df.to_csv(path + 'lagou_algorithm_data.csv', index=False)print('保存路径:' + path + 'lagou_algorithm_data.csv')

数据图片:


640?wx_fmt=png

数据分析篇:

1、数据清洗:

我们获得的数据都是以字符串形式存储的,而且像工资(20k—30k)、工作经验(3—5年)都是以区间的形式表现出来的,应该求其平均值(工资25k,工作经验4年)。另外像工作经验 不限、应届毕业生等,我们应该把该公司要求年限 改为0。

pattern = '\d+'  # 正则表达式-匹配连续数字# 统计每个公司的平均经验要求lagou_data['平均经验'] = lagou_data['经验'].str.findall(    pattern)  # findall查找所有['经验']下的数字字符串avg_work_year = []for i in lagou_data['平均经验']:    if len(i) == 0:  # 长度为0则意为着没数字,既工作经验为不限、应届毕业生等,即没有工作经验要求        avg_work_year.append(0)    else:  # 匹配的是两个数值的工作经验区间 几年到几年,,        year_list = [int(j) for j in i]  # 得到每一个数转为int型        avg_year = sum(year_list)/2  # 求工作区间的平均值,平均年限        avg_work_year.append(avg_year)lagou_data['平均经验'] = avg_work_year# 统计每个公司给出的平均工资lagou_data['平均工资'] = lagou_data['工资'].str.findall(pattern)avg_salary = []for k in lagou_data['平均工资']:    salary_list = [int(n) for n in k]    salary = sum(salary_list)/2    avg_salary.append(salary)lagou_data['平均工资'] = avg_salary # 新列一项平均工资

存储的csv文件(你需要先存到本地才能看得到)会多两列 平均经验 和 平均工资:

640?wx_fmt=png

2、数据可视化:

由于本篇为基础篇只画两个最简单的图且不做过多渲染美化,数据可视化都是一些简单的绘图,只有一个中文显示乱码问题,其他并没有什么坑,所以不做过多描述。

解决中文乱码问题:

plt.rcParams['font.sans-serif'] = ['SimHei']  # 替换sans-serif字体显示中文plt.rcParams['axes.unicode_minus'] = False  # 解决坐标轴负数的负号显示问题
平均工资直方图:
# 绘制工资频率直方图plt.hist(lagou_data['平均工资'], alpha=0.8, color='steelblue')plt.xlabel('工资/千元')plt.ylabel('频数')plt.title("算法工程师平均工资直方图")plt.savefig(path+'lagou_algorithm_salary.jpg')  # 指定保存路径plt.show()

640?wx_fmt=jpeg


平均工作经验要求直方图(代码与上面相似,省略):

640?wx_fmt=jpeg

学历要求饼状图:
# 绘制学历要求饼图count = lagou_data['学历'].value_counts()plt.pie(count, labels=count.keys(), shadow=True,autopct='%2.2f%%')plt.savefig(path+'lagou_algorithm_education.jpg')plt.show()

640?wx_fmt=jpeg

绘制福利待遇词云:

这里要注意一下,上面设置的全局显示字体仅对matplotlib,有效,所以这里要指定一下字体防止中文乱码。

# 绘制福利待遇词云color_mask = imread(path+'china_map.jpg')strs = ''for line in lagou_data['福利']:    strs += line  # 连接所有字符串cut_strs = ' '.join(jieba.cut(strs))  # 使用中文分词jieba,将字符串分割成列表word_cloud = WordCloud(font_path='C:\Windows\Fonts\微软雅黑\msyh.ttc',mask=color_mask,background_color='white').generate(cut_strs)  # 指定显示字体避免中文乱码word_cloud.to_file(path+'lagou_algorithm_wordcloud.jpg') # 存储图片plt.imshow(word_cloud)plt.show()

这里词云背景指定为中国地图:

640?wx_fmt=jpeg


公司福利词云最终效果图:

640?wx_fmt=jpeg


总结:

本文面向新手,文中不可避免有一些设置不合理的问题(数据量过少、工资取平均值代表不了实际情况),但还是可以从一定程度上反映出这个岗位的待遇和工资水平。

工资绝大部分集中在 2万到3万之间真的是相当高了。不过要求也不低,在多年的工作经验要求下,依然要求硕士毕业学历的公司依然占比 33%。相信过不了多久,本科和硕士的学历要求占比就会换一下位置了。五(六)险一金是开的最多的福利待遇,算是公司准则了。现在公司都流行用弹性工作、氛围什么的精神福利来招人了么。

注:

文章主要参考:

  • Python Data Science Handbook(Python数据科学手册)

  • pandas API 文档:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html

  • 可视化WordCloud: https://www.jianshu.com/p/daa54db9045d

  • matplotlib中文乱码问题 :https://www.cnblogs.com/hhh5460/p/4323985.html

网站反爬机制日新月异,所以本文有较强的时效性,无法保证您在实践时是否还可行.

所有数据、操作仅作学习交流,不会用于商业用途。

640?wx_fmt=jpeg



这篇关于新手向:爬取分析拉勾网招聘信息的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/341886

相关文章

慢sql提前分析预警和动态sql替换-Mybatis-SQL

《慢sql提前分析预警和动态sql替换-Mybatis-SQL》为防止慢SQL问题而开发的MyBatis组件,该组件能够在开发、测试阶段自动分析SQL语句,并在出现慢SQL问题时通过Ducc配置实现动... 目录背景解决思路开源方案调研设计方案详细设计使用方法1、引入依赖jar包2、配置组件XML3、核心配

Java NoClassDefFoundError运行时错误分析解决

《JavaNoClassDefFoundError运行时错误分析解决》在Java开发中,NoClassDefFoundError是一种常见的运行时错误,它通常表明Java虚拟机在尝试加载一个类时未能... 目录前言一、问题分析二、报错原因三、解决思路检查类路径配置检查依赖库检查类文件调试类加载器问题四、常见

Python中的Walrus运算符分析示例详解

《Python中的Walrus运算符分析示例详解》Python中的Walrus运算符(:=)是Python3.8引入的一个新特性,允许在表达式中同时赋值和返回值,它的核心作用是减少重复计算,提升代码简... 目录1. 在循环中避免重复计算2. 在条件判断中同时赋值变量3. 在列表推导式或字典推导式中简化逻辑

Go语言开发实现查询IP信息的MCP服务器

《Go语言开发实现查询IP信息的MCP服务器》随着MCP的快速普及和广泛应用,MCP服务器也层出不穷,本文将详细介绍如何在Go语言中使用go-mcp库来开发一个查询IP信息的MCP... 目录前言mcp-ip-geo 服务器目录结构说明查询 IP 信息功能实现工具实现工具管理查询单个 IP 信息工具的实现服

使用Python从PPT文档中提取图片和图片信息(如坐标、宽度和高度等)

《使用Python从PPT文档中提取图片和图片信息(如坐标、宽度和高度等)》PPT是一种高效的信息展示工具,广泛应用于教育、商务和设计等多个领域,PPT文档中常常包含丰富的图片内容,这些图片不仅提升了... 目录一、引言二、环境与工具三、python 提取PPT背景图片3.1 提取幻灯片背景图片3.2 提取

Java程序进程起来了但是不打印日志的原因分析

《Java程序进程起来了但是不打印日志的原因分析》:本文主要介绍Java程序进程起来了但是不打印日志的原因分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java程序进程起来了但是不打印日志的原因1、日志配置问题2、日志文件权限问题3、日志文件路径问题4、程序

Linux下如何使用C++获取硬件信息

《Linux下如何使用C++获取硬件信息》这篇文章主要为大家详细介绍了如何使用C++实现获取CPU,主板,磁盘,BIOS信息等硬件信息,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录方法获取CPU信息:读取"/proc/cpuinfo"文件获取磁盘信息:读取"/proc/diskstats"文

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

Python 迭代器和生成器概念及场景分析

《Python迭代器和生成器概念及场景分析》yield是Python中实现惰性计算和协程的核心工具,结合send()、throw()、close()等方法,能够构建高效、灵活的数据流和控制流模型,这... 目录迭代器的介绍自定义迭代器省略的迭代器生产器的介绍yield的普通用法yield的高级用法yidle

C++ Sort函数使用场景分析

《C++Sort函数使用场景分析》sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变,如果某些场景需要保持相同元素间的相对顺序,可使... 目录C++ Sort函数详解一、sort函数调用的两种方式二、sort函数使用场景三、sort函数排序