最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

畢業(yè)設(shè)計(jì) 招聘大數(shù)據(jù)分析與可視化系統(tǒng)

2023-02-28 11:03 作者:丹成學(xué)長  | 我要投稿

0 前言

?? 這兩年開始畢業(yè)設(shè)計(jì)和畢業(yè)答辯的要求和難度不斷提升,傳統(tǒng)的畢設(shè)題目缺少創(chuàng)新和亮點(diǎn),往往達(dá)不到畢業(yè)答辯的要求,這兩年不斷有學(xué)弟學(xué)妹告訴學(xué)長自己做的項(xiàng)目系統(tǒng)達(dá)不到老師的要求。

為了大家能夠順利以及最少的精力通過畢設(shè),學(xué)長分享優(yōu)質(zhì)畢業(yè)設(shè)計(jì)項(xiàng)目,今天要分享的是

?? ?招聘網(wǎng)站爬取與大數(shù)據(jù)分析可視化

??學(xué)長這里給一個(gè)題目綜合評分(每項(xiàng)滿分5分)

  • 難度系數(shù):3分

  • 工作量:3分

  • 創(chuàng)新點(diǎn):3分

畢設(shè)幫助,選題指導(dǎo),技術(shù)解答,歡迎打擾,見B站個(gè)人主頁

https://space.bilibili.com/33886978

1 課題背景

本項(xiàng)目利用 python 網(wǎng)絡(luò)爬蟲抓取常見招聘網(wǎng)站信息,完成數(shù)據(jù)清洗和結(jié)構(gòu)化,存儲到數(shù)據(jù)庫中,搭建web系統(tǒng)對招聘信息的薪資、待遇等影響因素進(jìn)行統(tǒng)計(jì)分析并可視化展示。

2 實(shí)現(xiàn)效果

首頁

在這里插入圖片描述

崗位地圖

在這里插入圖片描述

類型、詞云

在這里插入圖片描述


3 Flask框架

簡介

Flask是一個(gè)基于Werkzeug和Jinja2的輕量級Web應(yīng)用程序框架。與其他同類型框架相比,F(xiàn)lask的靈活性、輕便性和安全性更高,而且容易上手,它可以與MVC模式很好地結(jié)合進(jìn)行開發(fā)。Flask也有強(qiáng)大的定制性,開發(fā)者可以依據(jù)實(shí)際需要增加相應(yīng)的功能,在實(shí)現(xiàn)豐富的功能和擴(kuò)展的同時(shí)能夠保證核心功能的簡單。Flask豐富的插件庫能夠讓用戶實(shí)現(xiàn)網(wǎng)站定制的個(gè)性化,從而開發(fā)出功能強(qiáng)大的網(wǎng)站。

本項(xiàng)目在Flask開發(fā)后端時(shí),前端請求會遇到跨域的問題,解決該問題有修改數(shù)據(jù)類型為jsonp,采用GET方法,或者在Flask端加上響應(yīng)頭等方式,在此使用安裝Flask-CORS庫的方式解決跨域問題。此外需要安裝請求庫axios。

Flask項(xiàng)目結(jié)構(gòu)圖

在這里插入圖片描述

相關(guān)代碼:

from flask import Flask as _Flask, jsonify, render_template
from flask.json import JSONEncoder as _JSONEncoder
import decimal
import utils


class JSONEncoder(_JSONEncoder):
? ?def default(self, o):
? ? ? ?if isinstance(o, decimal.Decimal):
? ? ? ? ? ?return float(o)
? ? ? ?super(_JSONEncoder, self).default(o)


class Flask(_Flask):
? ?json_encoder = JSONEncoder


app = Flask(__name__)
# 這里發(fā)現(xiàn)flask根本不會調(diào)用我在utils中處理數(shù)據(jù)的代碼,所以直接就在這里定義了兩個(gè)常量
# 如果想要爬取其它招聘崗位信息的話,先運(yùn)行utils中的代碼,然后運(yùn)行app.py代碼,同時(shí),更改下面的datatable和job_name
datatable = 'data_mining'
job_name = '數(shù)據(jù)挖掘'


# 路由解析,每映射到一個(gè)路由就調(diào)用一個(gè)函數(shù)
@app.route('/')
def index():
? ?return render_template("main.html")


@app.route('/title')
def get_title1():
? ?return job_name


# 獲取系統(tǒng)當(dāng)前時(shí)間,每隔1s刷新一次
@app.route('/time')
def get_time1():
? ?return utils.get_time()


# 對數(shù)據(jù)庫中的數(shù)據(jù)進(jìn)行計(jì)數(shù)、薪資取平均值、省份和學(xué)歷取眾數(shù)
@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]})


# 對省份進(jìn)行分組,之后統(tǒng)計(jì)其個(gè)數(shù),使用jsonify來將數(shù)據(jù)傳輸給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})


# 統(tǒng)計(jì)每個(gè)學(xué)歷下公司數(shù)量和平均薪資(上下坐標(biāo)折線圖)
@app.route('/l1')
# 下面為繪制折線圖的代碼,如果使用這個(gè)的話需要在main.html中引入ec_left1.js,然后在controller.js中重新調(diào)用
# 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})


# 統(tǒng)計(jì)不同學(xué)歷下公司所招人數(shù)和平均經(jīng)驗(yàn)(折線混柱圖)
@app.route('/l2')
def get_l2_data1():
? ?data = utils.get_l2_data(datatable)
? ?edu, num, exp = [], [], []
? ?# 注意sql中會存在decimal的數(shù)據(jù)類型,我們需要將其轉(zhuǎn)換為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})


# 統(tǒng)計(jì)不同類型公司所占的數(shù)量(餅圖)
@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})


# 對獵聘網(wǎng)上的“崗位要求”文本進(jìn)行分詞后,使用jieba.analyse下的extract_tags來獲取全部文本的關(guān)鍵詞和權(quán)重,再用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)是百度開源的數(shù)據(jù)可視化工具,底層依賴輕量級Canvas庫ZRender。兼容了幾乎全部常用瀏覽器的特點(diǎn),使它可廣泛用于PC客戶端和手機(jī)客戶端。ECharts能輔助開發(fā)者整合用戶數(shù)據(jù),創(chuàng)新性的完成個(gè)性化設(shè)置可視化圖表。支持折線圖(區(qū)域圖)、柱狀圖(條狀圖)、散點(diǎn)圖(氣泡圖)、K線圖、餅圖(環(huán)形圖)等,通過導(dǎo)入 js 庫在 Java Web 項(xiàng)目上運(yùn)行。

相關(guān)代碼:

# 導(dǎo)入模塊
from pyecharts import options as opts
from pyecharts.charts import Pie
#準(zhǔn)備數(shù)據(jù)
label=['民營公司','上市公司','國企','合資','外資(歐美)','外資(非歐美)','創(chuàng)業(yè)公司','事業(yè)單位'] ?
values = [300,300,300,300,44,300,300,300]
# 自定義函數(shù)
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=":{c} s0sssss00s%")) ? # 值得一提的是,s0sssss00s%為百分比
? ?)
? ?return c
# 調(diào)用自定義函數(shù)生成render.html
pie_base().render()

5 爬蟲

簡介

Scrapy是基于Twisted的爬蟲框架,它可以從各種數(shù)據(jù)源中抓取數(shù)據(jù)。其架構(gòu)清晰,模塊之間的耦合度低,擴(kuò)展性極強(qiáng),爬取效率高,可以靈活完成各種需求。能夠方便地用來處理絕大多數(shù)反爬網(wǎng)站,是目前Python中應(yīng)用最廣泛的爬蟲框架。Scrapy框架主要由五大組件組成,它們分別是調(diào)度器(Scheduler)、下載器(Downloader)、爬蟲(Spider)和實(shí)體管道(Item Pipeline)、Scrapy引擎(Scrapy Engine)。各個(gè)組件的作用如下:

  1. 調(diào)度器(Scheduler):說白了把它假設(shè)成為一個(gè)URL(抓取網(wǎng)頁的網(wǎng)址或者說是鏈接)的優(yōu)先隊(duì)列,由它來決定下一個(gè)要抓取的網(wǎng)址是 什么,同時(shí)去除重復(fù)的網(wǎng)址(不做無用功)。用戶可以自己的需求定制調(diào)度器。

  2. 下載器(Downloader):是所有組件中負(fù)擔(dān)最大的,它用于高速地下載網(wǎng)絡(luò)上的資源。Scrapy的下載器代碼不會太復(fù)雜,但效率高,主要的原因是Scrapy下載器是建立在twisted這個(gè)高效的異步模型上的(其實(shí)整個(gè)框架都在建立在這個(gè)模型上的)。

  3. 爬蟲(Spider):是用戶最關(guān)心的部份。用戶定制自己的爬蟲(通過定制正則表達(dá)式等語法),用于從特定的網(wǎng)頁中提取自己需要的信息,即所謂的實(shí)體(Item)。 用戶也可以從中提取出鏈接,讓Scrapy繼續(xù)抓取下一個(gè)頁面。

  4. 實(shí)體管道(Item Pipeline):用于處理爬蟲(spider)提取的實(shí)體。主要的功能是持久化實(shí)體、驗(yàn)證實(shí)體的有效性、清除不需要的信息。

  5. Scrapy引擎(Scrapy Engine):Scrapy引擎是整個(gè)框架的核心.它用來控制調(diào)試器、下載器、爬蟲。實(shí)際上,引擎相當(dāng)于計(jì)算機(jī)的CPU,它控制著整個(gè)流程。


官網(wǎng)架構(gòu)圖

在這里插入圖片描述

相關(guān)代碼:

# -*- coding: utf-8 -*-

import requests
import re
import json
import time
import pandas as pd
from lxml import etree


# 為了防止被封IP,下面使用基于redis的IP代理池來獲取隨機(jī)IP,然后每次向服務(wù)器請求時(shí)都隨機(jī)更改我們的IP(該ip_pool搭建相對比較繁瑣,此處省略搭建細(xì)節(jié))
# 假如不想使用代理IP的話,則直接設(shè)置下方的time.sleep,并將proxies參數(shù)一并刪除
proxypool_url = 'http://127.0.0.1:5555/random'
# 定義獲取ip_pool中IP的隨機(jī)函數(shù)
def get_random_proxy():
? ?proxy = requests.get(proxypool_url).text.strip()
? ?proxies = {'http': 'http://' + proxy}
? ?return proxies


# 前程無憂網(wǎng)站上用來獲取每個(gè)崗位的字段信息
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'
? ?}
? ?# 每個(gè)頁面提交的參數(shù),降低被封IP的風(fēng)險(xiǎn)
? ?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時(shí)headers一般只需放上user-agent
? ?session = requests.Session()
? ?# 查看是否可以完成網(wǎng)頁端的請求
? ?# print(session.get('https://www.51job.com/', headers=headers, proxies=get_random_proxy()))
? ?# 爬取每個(gè)頁面下所有數(shù)據(jù)
? ?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())
? ? ? ?# 使用正則表達(dá)式提取隱藏在html中的崗位數(shù)據(jù)
? ? ? ?ss = '{' + re.findall(r'window.__SEARCH_RESULT__ = {(.*)}', response.text)[0] + '}'
? ? ? ?# 加載成json格式,方便根據(jù)字段獲取數(shù)據(jù)
? ? ? ?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))
? ?# 保存數(shù)據(jù)到DataFrame
? ?df = pd.DataFrame(
? ? ? ?{'崗位鏈接': href, '發(fā)布時(shí)間': update, '崗位名稱': job, '公司名稱': company, '公司類型': company_type, '公司領(lǐng)域': company_field,
? ? ? ? '薪水': salary, '地域': area, '其他信息': attribute})
? ?# 保存數(shù)據(jù)到csv文件中
? ?df.to_csv(f'./data/{datatable}/51job_{datatable}.csv', encoding='gb18030', index=None)


# 獵聘網(wǎng)上用來獲取每個(gè)崗位對應(yīng)的詳細(xì)要求文本
def liepin(datatable, job_name, page):
? ?# 瀏覽器偽裝和相關(guān)參數(shù)
? ?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時(shí)headers一般只需放上user-agent
? ?session = requests.Session()
? ?# print(session.get('https://www.liepin.com/zhaopin/', headers=headers, proxies = get_random_proxy()))
? ?# 通過輸入崗位名稱和頁數(shù)來爬取對應(yīng)的網(wǎng)頁內(nèi)容
? ?# job_name = input('請輸入你想要查詢的崗位:')
? ?# page = input('請輸入你想要下載的頁數(shù):')
? ?# 遍歷每一頁上的數(shù)據(jù)
? ?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])
? ?# 遍歷每一個(gè)崗位的數(shù)據(jù)
? ?for job_href in href:
? ? ? ?# time.sleep(np.random.randint(1, 2))
? ? ? ?# 發(fā)現(xiàn)有些崗位詳細(xì)鏈接地址不全,需要對缺失部分進(jìn)行補(bǔ)齊
? ? ? ?if 'https' not in job_href:
? ? ? ? ? ?job_href = 'https://www.liepin.com' + job_href
? ? ? ?response = 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])
? ?# 保存數(shù)據(jù)
? ?# df = pd.DataFrame({'崗位名稱': job, '公司': company, '薪水': salary, '地域': area, '學(xué)歷': edu, '工作經(jīng)驗(yàn)': exp, '崗位要求': content})
? ?df = pd.DataFrame({'崗位要求': content})
? ?df.to_csv(f'./data/{datatable}/liepin_{datatable}.csv', encoding='gb18030', index=None)

6 最后

畢設(shè)幫助,選題指導(dǎo),技術(shù)解答,歡迎打擾,見B站個(gè)人主頁

https://space.bilibili.com/33886978

畢業(yè)設(shè)計(jì) 招聘大數(shù)據(jù)分析與可視化系統(tǒng)的評論 (共 條)

分享到微博請遵守國家法律
长武县| 左云县| 伊宁县| 突泉县| 石屏县| 通道| 诏安县| 太白县| 高雄县| 长乐市| 凯里市| 东明县| 宁夏| 闻喜县| 乐至县| 禹城市| 丹凤县| 许昌县| 昌吉市| 扶风县| 临湘市| 灵台县| 枝江市| 辉县市| 绥棱县| 玛纳斯县| 鱼台县| 五家渠市| 海阳市| 苍溪县| 伊宁县| 平和县| 江北区| 荥阳市| 佛坪县| 鹤庆县| 缙云县| 隆安县| 沙河市| 伊宁市| 会泽县|