计算机毕设 招聘网站爬取与大数据分析可视化 - 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.hqwc.cn/news/127361.html

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

相关文章

[引擎开发] 杂谈ue4中的Vulkan

接触Vulkan大概也有大半年,概述一下自己这段时间了解到的东西。本文实际上是杂谈性质而非综述性质,带有严重的主观认知,因此并没有那么严谨。 使用Vulkan会带来什么呢?简单来说就是对底层更好的控制。这意味着我们能够有更多的手段…

理解一致性哈希算法

摘要:一致性哈希是什么,使用场景,解决了什么问题? 本文分享自华为云社区《16 张图解 | 一致性哈希算法》,作者:小林coding。 如何分配请求? 大多数网站背后肯定不是只有一台服务器…

适老产品反“坑老”,美的智能化家电是否能坐稳银发经济顺风车?

随着我国老龄化程度不断加深,银发经济崛起早已成为不争的共识。早在2013年,《中国老年人家电需求研究报告》就曾预测,仅在城镇空巢老年人家庭,每年产生的老年家电需求规模就超过600亿元,加上非空巢老人的需求&#xff…

<el-input> textarea文本域显示滚动条(超过高度就自动显示)+ <el-input >不能正常输入,输入了也不能删除的问题

需求&#xff1a;首先是给定高度&#xff0c;输入文本框要自适应这个高度。文本超出高度就会显示滚动条否则不显示。 <el-row class"textarea-row"><el-col :span"3" class"first-row-title">天气</el-col><el-col :span&…

智能化物流管理:全国快递物流查询API的角色与优势

前言 当今社会&#xff0c;物流行业已经成为了国民经济的重要组成部分&#xff0c;而快递物流则是物流行业中的一个重要分支。随着信息技术的不断发展&#xff0c;智能化物流管理正逐渐成为快递物流领域的趋势&#xff0c;而全国快递物流查询API作为其中的一部分&#xff0c;在…

虚拟机Ubuntu18.04安装对应ROS版本详细教程!(含错误提示解决)

参考链接&#xff1a; Ubuntu18.04安装Ros(最新最详细亲测)_向日葵骑士Faraday的博客-CSDN博客 1.4 ROS的安装与配置_哔哩哔哩_bilibili ROS官网&#xff1a;http://wiki.ros.org/melodic/Installation/Ubuntu 一、检查cmake 安装ROS时会自动安装旧版的Cmake3.10.2。所以在…

mysql MVCC(多版本并发控制)理解

最近看MVCC相关资料&#xff0c;这边做一个记录总结&#xff0c;方便后续理解。 目录 一、MVCC相关概念 二、MVCC实现原理 1.隐藏字段 2.undo log 3.Read View 4.MVCC的整体处理流程 5. RC&#xff0c;RR级级别下的innoDB快照读有什么不同 6.总结 一、MVCC相关概念 1…

什么是业务流程图(TFD),数据字典(DD),数据流程图(DFD)

什么是业务流程图&#xff08;TFD&#xff09;&#xff0c;数据字典&#xff08;DD&#xff09;&#xff0c;数据流程图&#xff08;DFD&#xff09;&#xff1f; 答: TFD是一种描述系统内各单位、人员之间的业务关系、作业顺序和管理流向的图表&#xff0c;利用它可以帮助分析…

震撼消息!OpenAI考虑加入AI芯片制造联盟

原创 | 文 BFT机器人 OpenAI是著名的ChatGPT背后的强大力量&#xff0c;可能很快就会深入研究人工智能芯片制造的动态世界。据路透社最新报道&#xff0c;该公司正在积极考虑创建其独特的人工智能芯片&#xff0c;甚至正在考虑收购该领域的潜在目标。 全球对人工智能芯片的需求…

一些流程图(自用)

前端一次访问后端程序的请求流程 web程序运行流程

竹云筑基,量子加密| 竹云携手国盾量子构建量子身份安全防护体系

9月23日-24日&#xff0c;2023量子产业大会在安徽合肥举行。作为量子科技领域行业盛会&#xff0c;2023年量子产业大会以“协同创新 量点未来”为主题&#xff0c;展示了前沿的量子信息技术、产业创新成果&#xff0c;并举办主旨论坛、量子科普讲座等系列专项活动。量子信息作为…

Windows技巧

Windows应用 无限延长Windows10 自动更新时间 管理员身份打开cmd 输入以下代码 这里设置的是3000天&#xff0c;需要恢复更新可以将其设置为1天 reg add “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings” /v FlightSettingsMaxPauseDays /t reg_dword…