计算机毕设 招聘网站爬取与大数据分析可视化 - python 分析 可视化 flask

文章目录

  • 0 前言
  • 1 课题背景
  • 2 实现效果
  • 3 Flask框架
  • 4 Echarts
  • 5 爬虫
  • 6 最后


0 前言

🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。

为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是

🚩 招聘网站爬取与大数据分析可视化

🥇学长这里给一个题目综合评分(每项满分5分)

  • 难度系数:3分
  • 工作量:3分
  • 创新点:3分

1 课题背景

本项目利用 python 网络爬虫抓取常见招聘网站信息,完成数据清洗和结构化,存储到数据库中,搭建web系统对招聘信息的薪资、待遇等影响因素进行统计分析并可视化展示。

2 实现效果

首页
在这里插入图片描述

岗位地图
在这里插入图片描述

类型、词云
在这里插入图片描述

3 Flask框架

简介

Flask是一个基于Werkzeug和Jinja2的轻量级Web应用程序框架。与其他同类型框架相比,Flask的灵活性、轻便性和安全性更高,而且容易上手,它可以与MVC模式很好地结合进行开发。Flask也有强大的定制性,开发者可以依据实际需要增加相应的功能,在实现丰富的功能和扩展的同时能够保证核心功能的简单。Flask丰富的插件库能够让用户实现网站定制的个性化,从而开发出功能强大的网站。

本项目在Flask开发后端时,前端请求会遇到跨域的问题,解决该问题有修改数据类型为jsonp,采用GET方法,或者在Flask端加上响应头等方式,在此使用安装Flask-CORS库的方式解决跨域问题。此外需要安装请求库axios。

Flask项目结构图
在这里插入图片描述

相关代码:

from flask import Flask as _Flask, jsonify, render_template
from flask.json import JSONEncoder as _JSONEncoder
import decimal
import utilsclass JSONEncoder(_JSONEncoder):def default(self, o):if isinstance(o, decimal.Decimal):return float(o)super(_JSONEncoder, self).default(o)class Flask(_Flask): json_encoder = JSONEncoderapp = Flask(__name__)
# 这里发现flask根本不会调用我在utils中处理数据的代码,所以直接就在这里定义了两个常量
# 如果想要爬取其它招聘岗位信息的话,先运行utils中的代码,然后运行app.py代码,同时,更改下面的datatable和job_name
datatable = 'data_mining'
job_name = '数据挖掘'# 路由解析,每映射到一个路由就调用一个函数
@app.route('/')
def index():return render_template("main.html")@app.route('/title')
def get_title1():return job_name# 获取系统当前时间,每隔1s刷新一次
@app.route('/time')
def get_time1():return utils.get_time()# 对数据库中的数据进行计数、薪资取平均值、省份和学历取众数
@app.route('/c1')
def get_c1_data1():data = utils.get_c1_data(datatable)return jsonify({"employ": data[0], "avg_salary": data[1], "province": data[2], "edu": data[3]})# 对省份进行分组,之后统计其个数,使用jsonify来将数据传输给ajax(中国地图)
@app.route('/c2')
def get_c2_data1():res = []for tup in utils.get_c2_data(datatable):res.append({"name": tup[0], "value": int(tup[1])})return jsonify({"data": res})# 统计每个学历下公司数量和平均薪资(上下坐标折线图)
@app.route('/l1')
# 下面为绘制折线图的代码,如果使用这个的话需要在main.html中引入ec_left1.js,然后在controller.js中重新调用
# def get_l1_data1():
#     data = utils.get_l1_data()
#     edu, avg_salary = [], []
#     for s in data:
#         edu.append(s[0])
#         avg_salary.append(s[1])
#     return jsonify({"edu": edu, "avg_salary": avg_salary})
def get_l1_data1():data = utils.get_l1_data(datatable)edu, sum_company, avg_salary = [], [], []for s in data:edu.append(s[0])sum_company.append(int(s[1]))avg_salary.append(float(s[2]))return jsonify({"edu": edu, "sum_company": sum_company, "avg_salary": avg_salary})# 统计不同学历下公司所招人数和平均经验(折线混柱图)
@app.route('/l2')
def get_l2_data1():data = utils.get_l2_data(datatable)edu, num, exp = [], [], []# 注意sql中会存在decimal的数据类型,我们需要将其转换为int或者float的格式for s in data:edu.append(s[0])num.append(float(s[1]))exp.append(float(s[2]))return jsonify({'edu': edu, 'num': num, 'exp': exp})# 统计不同类型公司所占的数量(饼图)
@app.route('/r1')
def get_r1_data1():res = []for tup in utils.get_r1_data(datatable):res.append({"name": tup[0], "value": int(tup[1])})return jsonify({"data": res})# 对猎聘网上的“岗位要求”文本进行分词后,使用jieba.analyse下的extract_tags来获取全部文本的关键词和权重,再用echarts来可视化词云
@app.route('/r2')
def get_r2_data1():cloud = []text, weight = utils.get_r2_data(datatable)for i in range(len(text)):cloud.append({'name': text[i], 'value': weight[i]})return jsonify({"kws": cloud})if __name__ == '__main__':app.run()

4 Echarts

ECharts(Enterprise Charts)是百度开源的数据可视化工具,底层依赖轻量级Canvas库ZRender。兼容了几乎全部常用浏览器的特点,使它可广泛用于PC客户端和手机客户端。ECharts能辅助开发者整合用户数据,创新性的完成个性化设置可视化图表。支持折线图(区域图)、柱状图(条状图)、散点图(气泡图)、K线图、饼图(环形图)等,通过导入 js 库在 Java Web 项目上运行。

相关代码:

# 导入模块
from pyecharts import options as opts
from pyecharts.charts import Pie
#准备数据
label=['民营公司','上市公司','国企','合资','外资(欧美)','外资(非欧美)''创业公司','事业单位']  
values = [300,300,300,300,44,300,300,300]
# 自定义函数
def pie_base():c = (Pie().add("",[list(z) for z in zip(label,values)]).set_global_opts(title_opts = opts.TitleOpts(title="公司类型分析")).set_series_opts(label_opts=opts.LabelOpts(formatter="{b}:{c} {d}%"))   # 值得一提的是,{d}%为百分比)return c
# 调用自定义函数生成render.html
pie_base().render()

5 爬虫

简介

Scrapy是基于Twisted的爬虫框架,它可以从各种数据源中抓取数据。其架构清晰,模块之间的耦合度低,扩展性极强,爬取效率高,可以灵活完成各种需求。能够方便地用来处理绝大多数反爬网站,是目前Python中应用最广泛的爬虫框架。Scrapy框架主要由五大组件组成,它们分别是调度器(Scheduler)、下载器(Downloader)、爬虫(Spider)和实体管道(Item Pipeline)、Scrapy引擎(Scrapy Engine)。各个组件的作用如下:

  1. 调度器(Scheduler):说白了把它假设成为一个URL(抓取网页的网址或者说是链接)的优先队列,由它来决定下一个要抓取的网址是 什么,同时去除重复的网址(不做无用功)。用户可以自己的需求定制调度器。

  2. 下载器(Downloader):是所有组件中负担最大的,它用于高速地下载网络上的资源。Scrapy的下载器代码不会太复杂,但效率高,主要的原因是Scrapy下载器是建立在twisted这个高效的异步模型上的(其实整个框架都在建立在这个模型上的)。

  3. 爬虫(Spider):是用户最关心的部份。用户定制自己的爬虫(通过定制正则表达式等语法),用于从特定的网页中提取自己需要的信息,即所谓的实体(Item)。 用户也可以从中提取出链接,让Scrapy继续抓取下一个页面。

  4. 实体管道(Item Pipeline):用于处理爬虫(spider)提取的实体。主要的功能是持久化实体、验证实体的有效性、清除不需要的信息。

  5. Scrapy引擎(Scrapy Engine):Scrapy引擎是整个框架的核心.它用来控制调试器、下载器、爬虫。实际上,引擎相当于计算机的CPU,它控制着整个流程。

官网架构图

在这里插入图片描述
相关代码:

# -*- coding: utf-8 -*-import requests
import re
import json
import time
import pandas as pd
from lxml import etree# 为了防止被封IP,下面使用基于redis的IP代理池来获取随机IP,然后每次向服务器请求时都随机更改我们的IP(该ip_pool搭建相对比较繁琐,此处省略搭建细节)
# 假如不想使用代理IP的话,则直接设置下方的time.sleep,并将proxies参数一并删除
proxypool_url = 'http://127.0.0.1:5555/random'
# 定义获取ip_pool中IP的随机函数
def get_random_proxy():proxy = requests.get(proxypool_url).text.strip()proxies = {'http': 'http://' + proxy}return proxies# 前程无忧网站上用来获取每个岗位的字段信息
def job51(datatable, job_name, page):# 浏览器伪装headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36 Edg/93.0.961.47'}# 每个页面提交的参数,降低被封IP的风险params = {'lang': 'c','postchannel': '0000','workyear': '99','cotype': '99','degreefrom': '99','jobterm': '99','companysize': '99','ord_field': '0','dibiaoid': '0'}href, update, job, company, salary, area, company_type, company_field, attribute = [], [], [], [], [], [], [], [], []# 使用session的好处之一便是可以储存每次的cookies,注意使用session时headers一般只需放上user-agentsession = requests.Session()# 查看是否可以完成网页端的请求# print(session.get('https://www.51job.com/', headers=headers, proxies=get_random_proxy()))# 爬取每个页面下所有数据for i in range(1, int(page) + 1):url = f'https://search.51job.com/list/000000,000000,0000,00,9,99,{job_name},2,{i}.html'response = session.get(url, headers=headers, params=params, proxies=get_random_proxy())# 使用正则表达式提取隐藏在html中的岗位数据ss = '{' + re.findall(r'window.__SEARCH_RESULT__ = {(.*)}', response.text)[0] + '}'# 加载成json格式,方便根据字段获取数据s = json.loads(ss)data = s['engine_jds']for info in data:href.append(info['job_href'])update.append(info['issuedate'])job.append(info['job_name'])company.append(info['company_name'])salary.append(info['providesalary_text'])area.append(info['workarea_text'])company_type.append(info['companytype_text'])company_field.append(info['companyind_text'])attribute.append(' '.join(info['attribute_text']))#     time.sleep(np.random.randint(1, 2))# 保存数据到DataFramedf = pd.DataFrame({'岗位链接': href, '发布时间': update, '岗位名称': job, '公司名称': company, '公司类型': company_type, '公司领域': company_field,'薪水': salary, '地域': area, '其他信息': attribute})# 保存数据到csv文件中df.to_csv(f'./data/{datatable}/51job_{datatable}.csv', encoding='gb18030', index=None)# 猎聘网上用来获取每个岗位对应的详细要求文本
def liepin(datatable, job_name, page):# 浏览器伪装和相关参数headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36 Edg/93.0.961.47'}job, salary, area, edu, exp, company, href, content = [], [], [], [], [], [], [], []# 使用session的好处之一便是可以储存每次的cookies,注意使用session时headers一般只需放上user-agentsession = requests.Session()# print(session.get('https://www.liepin.com/zhaopin/', headers=headers, proxies = get_random_proxy()))# 通过输入岗位名称和页数来爬取对应的网页内容# job_name = input('请输入你想要查询的岗位:')# page = input('请输入你想要下载的页数:')# 遍历每一页上的数据for i in range(int(page)):url = f'https://www.liepin.com/zhaopin/?key={job_name}&curPage={i}'# time.sleep(np.random.randint(1, 2))response = session.get(url, headers=headers, proxies = get_random_proxy())html = etree.HTML(response.text)# 每页共有40条岗位信息for j in range(1, 41):# job.append(html.xpath(f'//ul[@class="sojob-list"]/li[{j}]/div/div[1]/h3/@title')[0])# info = html.xpath(f'//ul[@class="sojob-list"]/li[{j}]/div/div[1]/p[1]/@title')[0]# ss = info.split('_')# salary.append(ss[0])# area.append(ss[1])# edu.append(ss[2])# exp.append(ss[-1])# company.append(html.xpath(f'//ul[@class="sojob-list"]/li[{j}]/div/div[2]/p[1]/a/text()')[0])href.append(html.xpath(f'//ul[@class="sojob-list"]/li[{j}]/div/div[1]/h3/a/@href')[0])# 遍历每一个岗位的数据for job_href in href:# time.sleep(np.random.randint(1, 2))# 发现有些岗位详细链接地址不全,需要对缺失部分进行补齐if 'https' not in job_href:job_href = 'https://www.liepin.com' + job_hrefresponse = session.get(job_href, headers=headers, proxies = get_random_proxy())html = etree.HTML(response.text)content.append(html.xpath('//section[@class="job-intro-container"]/dl[1]//text()')[3])# 保存数据# df = pd.DataFrame({'岗位名称': job, '公司': company, '薪水': salary, '地域': area, '学历': edu, '工作经验': exp, '岗位要求': content})df = pd.DataFrame({'岗位要求': content})df.to_csv(f'./data/{datatable}/liepin_{datatable}.csv', encoding='gb18030', index=None)

6 最后

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

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

相关文章

制作长图海报的详细指南,制作长图海报的5个步骤

制作长图海报是宣传活动、产品或服务的重要方式之一。乔拓云后台提供了丰富的海报模板,让你轻松制作出专业级的长图海报。下面将介绍如何使用乔拓云后台制作长图海报的技巧。 一、选择模板 首先,注册并登录乔拓云后台,进入云设计页面。在选择…

A (1087) : DS单链表--类实现

Description 用C语言和类实现单链表&#xff0c;含头结点 属性包括&#xff1a;data数据域、next指针域 操作包括&#xff1a;插入、删除、查找 注意&#xff1a;单链表不是数组&#xff0c;所以位置从1开始对应首结点&#xff0c;头结点不放数据 类定义参考 #include<…

Qt_基础

目录 1概述1.1 什么是QT1.2 QT的发展史1.3 支持的平台1.4 QT版本1.5 下载与安装1.6 QT的优点1.7 成功案例 2 创建 Qt 项目2.1 使用向导创建2.2 .pro文件2.3 帮助文档(QTcreator自带的)2.4 QT应用程序介绍 3 创建第一个小程序3.1 按钮的创建3.1.1 设置主窗口标题的函数3.1.2 **固…

小谈设计模式(23)—桥接模式

小谈设计模式&#xff08;23&#xff09;—桥接模式 专栏介绍专栏地址专栏介绍 桥接模式主要角色抽象部分实现部分分析 核心思想应用场景123 优缺点分析优点123 缺点12 总结 专栏介绍 专栏地址 link 专栏介绍 主要对目前市面上常见的23种设计模式进行逐一分析和总结&#x…

三极管及继电器的使用(单片机如何控制灯泡等大型电器)

1.对于初入硬件的小伙伴一定会用到三极管和继电器&#xff0c;如下图&#xff08;三极管&#xff09; 如下图&#xff08;继电器&#xff09; 当然上述三极管和继电器&#xff0c;只是众多的其中一种&#xff0c;而且继电器是包装好了的&#xff0c;这个应该叫继电器模块&#…

SpringBoot 实现数据脱敏

SpringBoot 实现数据脱敏 前言Hutool 实现数据脱敏引入依赖脱敏工具类代码实现 使用注解的方式定义枚举自定义序列化类定义注解测试 前言 数据脱敏是指对某些敏感信息通过脱敏规则进行数据的变形&#xff0c;实现敏感隐私数据的可靠保护。 数据脱敏常用规则有替换、重排、加密…

MYSQL06高级_为什么使用索引、优缺点、索引的设计、方案、聚簇索引、联合索引、注意事项

文章目录 ①. 为什么使用索引②. 索引及其优缺点③. InnoDb - 索引的设计④. InnoDb中的索引方案⑤. 索引 - 聚簇索引⑥. 索引 - 二级索引⑦. B树索引的注意事项⑧. MyISAM中索引方案 ①. 为什么使用索引 ①. 索引是存储引擎用于快速找到数据记录的一种数据结构,就好比去图书馆…

leetCode 1143.最长公共子序列 动态规划

1143. 最长公共子序列 - 力扣&#xff08;LeetCode&#xff09; 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串…

2021-06-09 51单片机:两个独立按键控制一个led,k1按下松开led闪烁三次,k2按下LED闪烁五次

缘由51单片机:两个独立按键控制一个led,k1按下松开led闪烁三次,k2按下LED闪烁五次_嵌入式-CSDN问答 #include "REG52.h" sbit K1 P1^0; sbit K2 P1^1; sbit LEDP0^0; void main() {unsigned char Xd0,ss0;unsigned int wei0;while(1){if(K10&&Xd0){ss3*2;…

Mysql存储-EAV模式

Mysql存储-EAV模式 最近又又又搞一点新东西&#xff0c;要整合不同业务进行存储和查询&#xff0c;一波学习过后总结了一下可扩展性MAX的eav模式存储。 在eav这里的数据结构设计尤为关键&#xff0c;需要充分考虑你需要使用的字段、使用场景&#xff0c;当数据结构设计完成后便…

单目标应用:猎豹优化算法(The Cheetah Optimizer,CO)求解微电网优化MATLAB

一、微网系统运行优化模型 微电网优化模型介绍&#xff1a; 微电网多目标优化调度模型简介_IT猿手的博客-CSDN博客 二、猎豹优化算法CO 猎豹优化算法&#xff08;The Cheetah Optimizer&#xff0c;CO&#xff09;由MohammadAminAkbari等人于2022年提出&#xff0c;该算法性…

数字IC前端学习笔记:数字乘法器的优化设计(Dadda Tree乘法器)

相关阅读 数字IC前端https://blog.csdn.net/weixin_45791458/category_12173698.html?spm1001.2014.3001.5482 华莱士树仍然是一种比较规则的结构&#xff08;这使得可以方便地生成树的结构&#xff09;&#xff0c;这导致了它所使用的全加器和半加器个数不是最少的&#xff…

大数据概述(林子雨慕课课程)

文章目录 1. 大数据概述1.1 大数据概念和影响1.2 大数据的应用1.3 大数据的关键技术1.4 大数据与云计算和物联网的关系云计算物联网 1. 大数据概述 大数据的四大特点&#xff1a;大量化、快速化、多样化、价值密度低 1.1 大数据概念和影响 大数据摩尔定律 大数据由结构化和非…

C++简单上手helloworld 以及 vscode找不到文件的可能性原因

helloworld #include <iostream>int main() {std::cout << "hello world!" << std::endl;return 0; }输入输出小功能 #include <iostream> using namespace std; /* *主函数 *输出一条语句 */int main() {// 输出一条语句cout << &q…

智慧茶园:茶厂茶园监管可视化视频管理系统解决方案

一、方案背景 我国是茶叶生产大国&#xff0c;茶叶销量全世界第一。随着经济社会的发展和人民生活水平的提高&#xff0c;对健康、天然的茶叶产品的消费需求量也在逐步提高。茶叶的种植、生产和制作过程工序复杂&#xff0c;伴随着人力成本的上升&#xff0c;传统茶厂的运营及…

拉线位移编码器要检查机械装置的安装状态

拉线位移编码器要检查机械装置的安装状态 1、先要检查机械装置的安装状态&#xff0c;看看是不是机械故障的原因&#xff0c;这个原因是很简单的就可以去排除。 2、判别显示器是否有故障&#xff1a;用一台同类型不同量程的高准确度位移传感器当作标准信号发生器来测量。 3、…

【周末闲谈】“PHP是最好的语言”这个梗是怎么来的?

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️周末闲谈】 系列目录 ✨第一周 二进制VS三进制 ✨第二周 文心一言&#xff0c;模仿还是超越&#xff1f; ✨第二周 畅想AR 文章目录 系列目录前言最早的出处关于PHP语言优点缺点网络评价 总结 前言 …

如何快速制作令人惊叹的长图海报

在当今的数字时代&#xff0c;制作一张吸引人的长图海报已成为许多人的需求。无论是为了宣传活动&#xff0c;还是展示产品&#xff0c;一张设计精美的长图海报都能引起人们的注意。下面&#xff0c;我们将介绍一种简单的方法&#xff0c;使用在线海报制作工具来创建长图海报。…

线性数据—栈、队列、链表

一、栈 Stack&#xff08;存取O(1)&#xff09; 先进后出&#xff0c;进去123&#xff0c;出来321。 基于数组&#xff1a;最后一位为栈尾&#xff0c;用于取操作。 基于链表&#xff1a;第一位为栈尾&#xff0c;用于取操作。 1.1、数组栈 /*** 基于数组实现的顺序栈&#…

如何实现 Es 全文检索、高亮文本略缩处理

如何实现 Es 全文检索、高亮文本略缩处理 前言技术选型JAVA 常用语法说明全文检索开发高亮开发Es Map 转对象使用核心代码 Trans 接口&#xff08;支持父类属性的复杂映射&#xff09;Trans 接口的不足真实项目落地效果 前言 最近手上在做 Es 全文检索的需求&#xff0c;类似于…