【Python】猎聘网招聘数据爬虫(Python网络爬虫课设简要)

news2024/11/16 3:13:16

【Python】猎聘网招聘数据爬虫(Python网络爬虫课设简要)

注:

  • 本文仅供学习交流使用!

  • 合肥学院-20信管-20302211009

  • 项目文件可自行前往博客主页下载或联系作者qq(3416252112)。

  • 爬取数据耗时约50分钟!

1、背景介绍(废话)

随着全球经济的发展和全球化竞争的加剧,招聘人才对于企业的成功变得至关重要。同时,求职者也面临着日益激烈的就业竞争。在这样的背景下,招聘市场不断发展,招聘过程变得更加复杂和竞争激烈。

互联网的普及和技术的发展给招聘带来了新的机遇和挑战。互联网招聘平台的兴起为企业和求职者提供了更广泛的交流和信息渠道。企业可以在招聘平台上发布招聘信息,同时通过筛选和匹配算法更准确地找到符合要求的人才;求职者可以通过招聘平台查找和申请适合自己的工作岗位。这种高效便捷的招聘方式极大地提高了招聘效率和成功率。

作为国内领先的互联网招聘平台之一,猎聘网汇聚了众多企业和求职者。其庞大的企业用户群体和海量的招聘信息资源使得猎聘网成为了人力资源管理领域的重要参考和决策依据。因此,对于猎聘网招聘数据的爬取和可视化分析具有重要的研究和实践价值。

在接下来的报告中,我们将详细介绍猎聘网招聘数据的爬取与可视化方法,并探讨其在人力资源决策和市场分析中的应用。

2、研究内容与目标(废话)

招聘数据对于人力资源决策具有重要性。通过分析招聘数据,可以了解当前市场的人才需求情况、行业的就业趋势以及薪资水平的变化等信息。这些信息对企业在招聘岗位时可以更好地定位和吸引合适的人才,从而提高招聘的效率和成功率。同时,求职者可以利用招聘数据了解就业市场的动态,选择适合自己的岗位和行业,提升就业竞争力。

猎聘网作为一家知名的招聘平台,拥有庞大的招聘数据资源。理解和利用猎聘网的招聘数据,可以帮助我们深入了解不同行业的人才需求和就业趋势,为企业的人才战略提供有力支持。通过数据爬取和可视化的方法,我们可以将海量的数据转化为直观、易于理解的图表和图形,帮助决策者快速把握关键信息,做出准确的决策。

本报告的目的是介绍猎聘网招聘数据的爬取与可视化方法,通过对招聘数据的分析和可视化,为人力资源决策提供科学依据,提高招聘效率和成功率。同时,我们还希望能够推动数据爬取与可视化技术在招聘领域的应用和研究,促进人力资源管理的创新和发展。

3、爬取对象

爬取数据对象为[‘Java开发’, ‘数据挖掘’, ‘互联网产品经理’, ‘软件测试’, ‘图像算法工程师’],这五个关键字的检索结果,每个关键字共有四百条检索结果,总计2000条记录,最终成功爬取记录数为1581条,表结构如下图所示。

image-20230603155536056

4、功能描述

本次课设数据爬虫功能主要包括以下几个方面:

  • 数据收集:数据爬虫能够自动化地从目标网站上抓取数据。通过指定合适的URL和参数,爬虫可以访问网页并提取所需的信息,例如招聘信息、公司信息、职位要求、工作地点等。爬虫可以遍历多个页面或进行深度抓取,以获取更全面的数据。
  • 数据解析:爬虫可以解析从网页中提取的原始数据,并提取出有用的信息。这包括对HTML、XML等页面结构的解析,以及对文本、图像、链接等内容的提取和分析。通过数据解析,爬虫能够将抓取的数据转化为结构化的格式,以便后续的处理和分析。
  • 数据清洗:抓取的数据往往包含冗余、不完整或错误的信息。数据爬虫可以进行数据清洗,去除重复项、清理无效数据,并进行格式化和规范化,以确保数据的准确性和一致性。数据清洗可以提高后续数据处理和分析的效果。
  • 数据存储:抓取到的数据需要进行存储,以便后续的使用和分析。数据爬虫可以将清洗后的数据保存到合适的存储介质中,如数据库、文件或云存储服务。爬虫还可以管理数据存储的结构和索引,以方便数据的检索和查询。

5、数据爬取及存储流程

数据爬取及存储业务流程共包含以下步骤:

  1. 初始化:创建数据库、创建表、创建全局的数据列表(用于暂时存储爬取结果);
  2. 使用selenium爬取关键字检索结果中的岗位信息链接,并存入txt文件中;
  3. 岗位链接爬取完成之后读取岗位链接,然后通过requests依次爬取岗位页面;
  4. 使用XPath对爬取到的页面进行解析并将解析结果添加到数据列表(同时将岗位的详细信息保存到txt文件中,以备生成词云图);
  5. 页面解析完成后,遍历数据列表,将取出的数据依次插入到数据库表中,最后结束爬取.

流程图如下:

image-20230603155906824

6、爬虫目录结构介绍

爬虫代码总体包含六个方法别为 __init__()get_post_link()get_post_detail()save_data()over()run(),具体功能如下:

  1. __init__:该方法主要作用为创建全局信息(岗位列表、岗位链接列表、岗位数据列表)、创建数据库连接和表、读取用户标识库(User-Agent);

  2. get_post_link:该方法主要功能为使用selenium动态爬取关键字(岗位列表)检索结果的岗位链接,并将链接信息保存到同级目录下的“PostUrls”目录;

  3. get_post_detail:根据“PostUrls”目录下的url信息,使用requests依次爬取岗位详情页,并使用XPath对页面进行解析,将解析后的数据添加到岗位数据列表,以及将岗位详情字段保存到同级目录下得“PostIntroduceDatas”目录下以备生成岗位词云图;

  4. save_data:遍历岗位数据列表使用SQL语句依次将列表中的数据插入到job_database数据库的Jobs表中;

  5. over:该方法用于关闭数据库连接;

  6. run:运行方法,调用get_post_link()、get_post_detail()和over()方法,进行爬虫工作;

代码结构如下图:

image-20230603160026112

7、爬取过程截图

  • 爬取岗位链接截图

image-20230603160109684

  • 提取岗位数据截图

image-20230603160129133

8、爬虫源代码

import random
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
from selenium.webdriver.common.by import By
import requests
import sqlite3
from lxml import etree


class LiePin:
    def __init__(self):
        # 岗位列表
        self.driver = None
        self.post_list = ['Java开发', '数据挖掘', '互联网产品经理', '软件测试', '图像算法工程师']
        # 岗位链接列表
        self.all_link = []
        # 等待3三秒
        time.sleep(3)

        # 随机用户(User_Agent)
        with open('User_Agent_pool.txt', 'r', encoding='utf8') as fp:
            self.user_Agent = fp.readlines()
            self.user_Agent = [i.strip() for i in self.user_Agent]

        # 创建数据库连接对象
        self.conn = sqlite3.connect('job_database.db')
        # 创建游标对象
        self.cursor = self.conn.cursor()
        # 创建jobs表
        self.create_table_sql = "CREATE TABLE Jobs (信息ID INTEGER PRIMARY KEY AUTOINCREMENT, 岗位链接 VARCHAR, 搜索岗位名 VARCHAR, 岗位名称 VARCHAR, " \
                               "企业名称 VARCHAR, 薪资区间 VARCHAR, 工作地点 VARCHAR, 工作经验 VARCHAR, 学历要求 VARCHAR, 岗位介绍 VARCHAR, 其他待遇 VARCHAR , 企业经营范围 VARCHAR)"
        self.cursor.execute(self.create_table_sql)

    def get_post_link(self, post):
        # 创建浏览器对象
        self.driver = webdriver.Chrome()
        # 打开网页
        self.driver.get('https://www.liepin.com/zhaopin/')
        time.sleep(3)
        print("===========开始爬取", post, "岗位链接===========")
        # 定位搜索框并输入关键词
        search_box = self.driver.find_element(By.XPATH, "//div[@id='lp-search-bar-section']//input")
        search_box.send_keys(post)
        search_box.send_keys(Keys.RETURN)
        # 共爬取10页链接
        # 结果数据
        result = []
        for page in range(10):
            print("开始爬取第", page + 1, "页链接…………")
            # 等待页面加载完成
            time.sleep(3)
            # 读取当前页岗位数量
            divs = self.driver.find_elements(By.XPATH, "//div[@class='content-wrap']//div[@class='job-list-box']/div")
            for i in range(1, len(divs) + 1):
                # print(i)
                link = self.driver.find_element(By.XPATH, f"//div[@class='job-list-box']/div[{i}]//a").get_attribute("href")
                # 存储岗位链接信息
                result.append(str(link))
                # print("测试", result[0])
            time.sleep(3)
            # 爬取下一页
            if page == 9:
                break
            self.driver.find_element(By.XPATH, "//div[@class='list-pagination-box']//li["
                                               "@class='ant-pagination-next']/button").click()
        # 将链接列表保存至文件
        self.all_link.append(result)
        with open(f'PostUrls/{post}_url.txt', 'a', encoding='utf-8') as fp:
            for item in result:
                fp.write(item + '\n')

    # 爬取岗位详情信息
    def get_post_detail(self):
        print("==========================开始提取各岗位详情页信息==========================")

        for post in self.post_list:
            print("++++++++++++开始获取", post, "相关岗位详情信息++++++++++++")
            with open(f'PostUrls/{post}_url.txt', 'r', encoding='utf-8') as fp:
                urls = fp.readlines()
            with open(f'PostIntroduceDatas/{post}_detail.txt', 'a', encoding='utf-8') as fp:
                index = 0
                result = []
                for url in urls:
                    index += 1
                    print(f"提取{post}岗位,第", index, "条数据……")
                    time.sleep(1)
                    try:
                        # 发送GET请求
                        response = requests.get(url=url, headers={"User-Agent": random.choice(self.user_Agent)})
                        html_str = etree.HTML(response.text)
                        # 岗位链接
                        post_link = str(url)
                        # 搜索岗位名
                        search_name = post
                        # 岗位名称
                        post_name = html_str.xpath("//body/section[3]//div[@class='name-box']/span[1]")[0].text
                        # 企业名称
                        enterprise_name = html_str.xpath("//aside//div[@class='company-info-container']//div["
                                                         "contains(@class,'name')]")[0].text
                        # 企业经营范围
                        enterprise_scope = html_str.xpath("//aside//div[@class='register-info']/div[contains(@class,"
                                                          "'ellipsis-4')]/span[2]")[0].text
                        # 薪资区间
                        post_salary = html_str.xpath("//body/section[3]//div[@class='name-box']/span[@class='salary']")[0].text
                        # 工作地点
                        post_location = html_str.xpath("//body/section[3]//div[@class='job-properties']/span[1]")[0].text
                        # 工作经验
                        work_experience = html_str.xpath("//body/section[3]//div[@class='job-properties']/span[3]")[0].text
                        # 学历要求
                        educational_requirements = html_str.xpath("//body/section[3]//div["
                                                                  "@class='job-properties']/span[5]")[0].text
                        # 其他待遇
                        about_treatment = ''
                        for sub in html_str.xpath("//body/section[4]//div[@class='labels']/span"):
                            about_treatment += ' ' + sub.text
                        # 岗位介绍
                        post_introduce = html_str.xpath("//main//dl[1]/dd")[0].text
                        # 保存数据
                        # self.save_data(post_link, )
                        detail = {
                            "岗位链接": post_link,
                            "搜索岗位名": search_name,
                            "岗位名称": post_name,
                            "企业名称": enterprise_name,
                            "薪资区间": post_salary,
                            "工作地点": post_location,
                            "工作经验": work_experience,
                            "学历要求": educational_requirements,
                            "岗位介绍": post_introduce,
                            "其他待遇": about_treatment,
                            "企业经营范围": enterprise_scope
                        }
                        # 添加至总结果列表
                        result.append(detail)
                        # print(detail)
                        # 将岗位介绍信息写入txt文件,以备提取词云
                        fp.write(detail['岗位介绍'] + '\n\n')
                    except Exception as e:
                        with open('error_url/error_message.txt', 'a', encoding='utf-8') as f:
                            f.write("爬取失败url:" + url)
            # 将数据存入数据库
            print(f"+++++开始将{post}岗位数据存入数据库+++++")
            self.save_data(result)
        # 保存结果数据
        # self.save_data(result)

    # 保存数据
    def save_data(self, result):
        print("==========开始将数据存入数据库=========")
        print("共", len(result), "条数据,开始存入数据库…………")

        for item in result:
            try:
                insert_sql = f"INSERT INTO Jobs(岗位链接, 搜索岗位名, 岗位名称, 企业名称, 薪资区间, 工作地点, 工作经验, 学历要求, 岗位介绍, 其他待遇, 企业经营范围) " \
                             f"VALUES('{item['岗位链接']}', '{item['搜索岗位名']}', '{item['岗位名称']}', '{item['企业名称']}', '{item['薪资区间']}', '{item['工作地点']}', '{item['工作经验']}', '{item['学历要求']}', '{item['岗位介绍']}', '{item['其他待遇']}', '{item['企业经营范围']}')"
                self.cursor.execute(insert_sql)
            except Exception as e:
                print("当前记录异常,忽略……")
        # 提交事务
        self.conn.commit()
        print("数据存储完毕!")

    def over(self):
        # 关闭数据库连接
        self.conn.close()

    def run(self):
        # 爬取各岗位链接
        for post in self.post_list:
            self.get_post_link(post)
        self.get_post_detail()
        self.over()


if __name__ == '__main__':
    liepin = LiePin()
    liepin.run()
    print("数据采集完毕!")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/605431.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网络安全工程师面试题(附答案解析)

前言 有不少小伙伴面临跳槽或者找工作,本文总结了常见的安全岗位面试题,方便各位复习。祝各位事业顺利,财运亨通。在网络安全的道路上越走越远!。 注:所有的资料都整理成了PDF,面试题和答案将会持续更新&a…

路径规划算法:基于黄金正弦优化的路径规划算法- 附代码

路径规划算法:基于黄金正弦优化的路径规划算法- 附代码 文章目录 路径规划算法:基于黄金正弦优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要:本文主要介绍利用智能优化…

Springboot事件监听

Springboot事件监听中主要有以下对象: 1、事件(event)可以封装和传递监听器中要处理的参数,如对象或字符串,并作为监听器中监听的目标。 2、监听器(listener)具体根据事件发生的业务处理模块&am…

机器学习 day14 ( 神经网络 )

神经网络的发展 最开始的动机:是通过构建软件来模拟大脑,但今天的神经网络几乎与大脑的学习方式无关 我们依据大脑中的神经网络,来构建人工神经网络模型。左图中:一个神经元可以看作一个处理单元,它有很多的输入/树突…

如何解决企业客户签收回执慢,缩短回款周期?

方案应用领域及行业 本方案适用于快消品行业的供应链管理和财务管理 方案应用背景 由于动产物权的政策变化,物权转移从交付时才开始发生效力。也就是说,新政之前,企业发出商品,开出销售发票,即可申请货物回款&#…

LLM 系列 | 05:ChatGPT Prompt的迭代优化

简介 梅子留酸软齿牙,芭蕉分绿与窗纱。日长睡起无情思,闲看儿童捉柳花。小伙伴们好,我是微信公众号 《小窗幽记机器学习》 的小编:卖冰棍的小男孩。 更多、更新文章欢迎关注微信公众号:小窗幽记机器学习。后续会持续…

Ubuntu的安装教程

文章目录 一、Ubuntu 的安装教程1、Ubuntu的镜像下载2、服务器版的安装教程2.1.1、允许 root 远程登录 3、桌面版的安装教程3.1.1、允许 root 远程登录 一、Ubuntu 的安装教程 1、Ubuntu的镜像下载 ​ 这里我选择阿里云的镜像下载你也可以选择Ubuntu的官网下载 Ubuntu官网 如…

【Set集合案例】成绩排序和不重复的随机数

Set集合案例:成绩排序和不重复的随机数 1.成绩排序 需求:用TreeSet集合存储多个学生信息(姓名,语文成绩,数学成绩),并遍历该集合 ​ 要求:按照总分从高到底出现 思路:…

都2023年了,Python 和Java 哪个更适合做自动化测试?

大家好。从事软件测试很多年了,从各个大厂一路摸爬滚打,现在我有幸供职于字节跳动。个人也是从功能测试慢慢爬到了自动化测试这条路上。所以针对这个问题,我还有点发言权。 记得我一开始从功能准备转型到自动化测试,和很多“涉事…

Qt QPushButton背景图片

一、问题 使用控件显示图片缩略图,当点击控件时,弹出窗口显示完整的图片 二、分析 应该用按钮控件,用信号槽连接。按钮控件是有参数icon,但是只能显示控件中,不能覆盖在整个控件上。 三、方法一:使用st…

线段树算法(C++/C)

目录​​​​​​​ 一、线段树算法的概念 二、为什么需要线段树 三、线段树算法的实现 (1)建树 (2)查询 (3)修改 (4)综合代码,求区间和 (5&#xff…

从“互联网+”到“互联网医疗+”,免费互联网医院开创新格局

随着互联网的发展,各行各业都在积极探索“互联网”时代下的创新模式。其中,医疗领域也开始了自己的变革之路,从传统的医疗模式转向了“互联网医疗”的新型格局。免费互联网医院的出现,则更是为这一变革注入了新的活力。 所谓“互联…

【嵌入式系统应用开发】FPGA——基于HC-SR04超声波测距

文章目录 前言环境目标结果 1 实验原理1.1 超声波原理1.2 硬件模块时序图1.3 模块说明 2 设计文件2.1 时钟分频2.2 超声波测距2.3 超声波驱动 3 实验验证3.1 编译3.3 硬件测试 总结 前言 环境 硬件 DE2-115 HC-SR04超声波传感器软件 Quartus 18.1 目标结果 使用DE2-115开发…

【Linux驱动】认识驱动(驱动的概念、驱动分类)

目录 1、什么是驱动? 2、应用程序调用驱动基本流程 3、file_operations 结构体 4、驱动的分类 1、什么是驱动? 驱动就是一段程序,能够获取外设或者传感器数据、控制外设。驱动获取到的数据会提交给应用程序。 在 Linux 中一切皆为文件&…

【实用篇】Elasticsearch02

文章目录 分布式搜索引擎021.DSL查询文档1.1.DSL查询分类1.2.全文检索查询1.2.1.使用场景1.2.2.基本语法1.2.3.示例1.2.4.总结 1.3.精准查询1.3.1.term查询1.3.2.range查询1.3.3.总结 1.4.地理坐标查询1.4.1.矩形范围查询1.4.2.附近查询 1.5.复合查询1.5.1.相关性算分1.5.2.算分…

Linux开机rc.local不自启动执行脚本问题的排查思路及问题解决

Linux开机rc.local不自启动执行脚本问题的排查思路及问题解决 问题 Linux系统中,在rc.local里面配置的启动命令等不能能够在开机的时候进行自启动 问题解决 解决问题排查中最大的麻烦,需要进行reboot重启 查看rc-local的运行状态 systemctl status r…

clickhouse简介与实战

文章目录 1:简介1.1:CH是什么?1.2:CH优缺点1.2.1:优势1.2.2:缺点 1.3:架构设计 2:CH接口3:CH引擎1:数据库引擎3.1.1:mysql引擎 2:表引擎3.2.1&…

路径规划算法:基于模拟退火优化的路径规划算法- 附代码

路径规划算法:基于模拟退火优化的路径规划算法- 附代码 文章目录 路径规划算法:基于模拟退火优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要:本文主要介绍利用智能优化…

基于flask的web应用开发——访问漂亮的html页面以及页面跳转

目录 0. 前言1. html基本知识2. 编写html文本3. 在Flask中设置访问html4. 实现点击跳转 0. 前言 本节学习如何在flask应用程序下让用户访问你提前制作好的html页面 操作系统:Windows10 专业版 开发环境:Pycahrm Comunity 2022.3 Python解释器版本&am…

(学习日记)2023.04.27

写在前面: 由于时间的不足与学习的碎片化,写博客变得有些奢侈。 但是对于记录学习(忘了以后能快速复习)的渴望一天天变得强烈。 既然如此 不如以天为单位,以时间为顺序,仅仅将博客当做一个知识学习的目录&a…