大家好,我是python222_小鋒老師,看到一個不錯的基于Python的招聘職位信息推薦系統(獵聘網數據分析與可視化)(Django+requests庫),分享下哈。
項目視頻演示
【免費】基于Python的招聘職位信息推薦系統(獵聘網數據分析與可視化)(Django+爬蟲) Python畢業設計_嗶哩嗶哩_bilibili
項目介紹
隨著互聯網和信息技術的不斷發展,就業和招聘形式也迎來了深刻的變革。就業推薦系統不僅能夠為求職者提供個性化、精準的匹配,而且還解決了現代就業市場面臨的一系列挑戰問題,另外對于求職者而言,該系統還減輕了信息過載的壓力,幫助畢業生快速找到適合自己技能和興趣的職位,節省了畢業生的求職時間和成本,提高了就業市場的效率,同時為畢業生提供更好的就業機會和就業支持。
本文基于協同過濾算法,設計實現了就業推薦系統,旨在提供高度個性化的職位推薦,以滿足畢業生求職者和雇主的需求。系統首先采用爬蟲技術收集企業公開發布的招聘崗位信息,抽取特征值并且歸一化處理,根據指定的畢業生和求職人員的相似度計算畢業生和企業單位的相似度。然后在得到畢業生和企業單位的相似度的基礎上,根據隨機游走模型算法計算出企業單位的求職熱度。最后計算最終的排序綜合權值,完成基于協同過濾的就業推薦系統的建立。該系統涵蓋了控制臺功能、數據爬取、數據管理、數據可視化和就業推薦等多個核心功能模塊。同時,系統為解決就業場景中企業與畢業生相互匹配的問題,引入企業對畢業生的偏好系數,企業偏好系數是利用改進的隨機游走算法(PersonalRank)計算企業招聘過程中對畢業生特征屬性的招聘偏好值。最終的推薦算法融合企業偏好系數計算出畢業生與企業的符合度,根據符合度為畢業生推薦合適的就業崗位。通過該系統,畢業生用戶可以輕松地管理其就業信息,獲得定制的職位推薦,并通過可視化工具了解就業市場趨勢。
系統的設計過程中使用了先進的技術和開發框架,確保了系統的高性能和可擴展性。整個系統采用 Python 語言編寫,后端基于 Django 的 Web 應用框架,數據庫采用 MySQL設計,使用 ECharts?進行數據可視化顯示。數據獲取使用 Selenium?框架進行數據的采集,然后對數據進行分析并且將結果在前臺進行可視化的展示。獲取的數據解析后存儲到數據庫。該系統的個性化就業職位推薦功能是基于用戶的協同過濾算法設計實現。經過功能測試和性能測試,系統展現出了其在多個方面的有效性和可靠性。總之,本文開發的就業推薦系統為解決現代就業市場的智能化挑戰,提供了一個有前景的解決方案,并為未來功能更加強大的就業推薦系統的研究和應用提供了一定的基礎。
系統展示
部分代碼
{% load static %}
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>登入-職位推薦系統</title><meta name="renderer" content="webkit"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="viewport"content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0"><link rel="stylesheet" href="{% static "layuiadmin/layui/css/layui.css" %}" media="all"><link rel="stylesheet" href="{% static "layuiadmin/style/admin.css" %}" media="all"><link rel="stylesheet" href="{% static "layuiadmin/style/login.css" %}" media="all">
</head>
<body>{# <div class="layadmin-user-login layadmin-user-display-show" id="LAY-user-login" style="display: none;">#}
<div class="layadmin-user-login layadmin-user-display-show" id="LAY-user-login"style="display: none; background-image: url('/static/背景.png'); background-size: cover;"><div class="layadmin-user-login-main"><div class="layadmin-user-login-box layadmin-user-login-header"><h2 style="color: #fff">用戶登錄</h2><p>招聘推薦系統</p></div><div class="layadmin-user-login-box layadmin-user-login-body layui-form"><div class="layui-form-item"><label class="layadmin-user-login-icon layui-icon layui-icon-username"></label><input type="text" name="user" placeholder="賬號" class="layui-input"></div><div class="layui-form-item"><label class="layadmin-user-login-icon layui-icon layui-icon-password"></label><input type="password" name="password" placeholder="密碼" class="layui-input"></div><div class="layui-form-item" style="margin-bottom: 20px;"><a href="{% url "register" %}" class="layadmin-user-jump-change layadmin-link" style="margin-top: 7px;">還沒賬號?</a></div><div class="layui-form-item"><button class="layui-btn layui-btn-fluid" lay-submit lay-filter="LAY-user-login-submit">登 入</button></div></div></div>
</div><script src="{% static "layuiadmin/layui/layui.js" %}"></script>
<script>layui.config({base: '{% static "layuiadmin/" %}' //靜態資源所在路徑}).extend({index: 'lib/index' //主入口模塊}).use(['index', 'form', 'jquery'], function () {var $ = layui.jquery,form = layui.form,layer = layui.layer;//提交form.on('submit(LAY-user-login-submit)', function (obj) {obj = obj.field;if (obj.user == '') {layer.msg('賬號不能為空');return false;}if (obj.password == '') {layer.msg('密碼不能為空');return false;}//請求登入接口$.ajax({type: 'POST',url: '/login/',data: obj,success: function (res) {// 彈窗內容, 樣式if (res.code == 0) {layer.msg(res.msg + ' ' + res.user_name, {icon: 1, time: 1000});setTimeout(function () {location.href = "http://127.0.0.1:8000/index/";}, 1000) // 延遲重定向} else {layer.msg(res.msg);return false;}},error: function (response) {layer.msg(response.msg);}})});});
</script>
</body>
</html>
from django.shortcuts import render, redirect
from django.http import JsonResponse
# Create your views here.
from job import models
import re
from psutil import *
from numpy import *
from job import tools
from job import job_recommendspider_code = 0 # 定義全局變量,用來識別爬蟲的狀態,0空閑,1繁忙# python manage.py inspectdb > job/models.py
# 使用此命令可以將數據庫表導入models生成數據模型def login(request):if request.method == "POST":user = request.POST.get('user')pass_word = request.POST.get('password')print('user------>', user)users_list = list(models.UserList.objects.all().values("user_id"))users_id = [x['user_id'] for x in users_list]print(users_id)ret = models.UserList.objects.filter(user_id=user, pass_word=pass_word)if user not in users_id:return JsonResponse({'code': 1, 'msg': '該賬號不存在!'})elif ret:# 有此用戶 -->> 跳轉到首頁# 登錄成功后,將用戶名和昵稱保存到session 中,request.session['user_id'] = useruser_obj = ret.last()if user_obj: # 檢查用戶對象是否存在user_name = user_obj.user_namerequest.session['user_name'] = user_namereturn JsonResponse({'code': 0, 'msg': '登錄成功!', 'user_name': user_name})else:return JsonResponse({'code': 1, 'msg': '密碼錯誤!'})else:return render(request, "login.html")def register(request):if request.method == "POST":user = request.POST.get('user')pass_word = request.POST.get('password')user_name = request.POST.get('user_name')users_list = list(models.UserList.objects.all().values("user_id"))users_id = [x['user_id'] for x in users_list]if user in users_id:return JsonResponse({'code': 1, 'msg': '該賬號已存在!'})else:models.UserList.objects.create(user_id=user, user_name=user_name, pass_word=pass_word)request.session['user_id'] = user # 設置緩存request.session['user_name'] = user_namereturn JsonResponse({'code': 0, 'msg': '注冊成功!'})else:return render(request, "register.html")# 退出(登出)
def logout(request):# 1. 將session中的用戶名、昵稱刪除request.session.flush()# 2. 重定向到 登錄界面return redirect('login')def index(request):"""此函數用于返回主頁,主頁包括頭部,左側菜單"""return render(request, "index.html")def welcome(request):"""此函數用于處理控制臺頁面"""job_data = models.JobData.objects.all().values() # 查詢所有的職位信息all_job = len(job_data) # 職位信息總數list_1 = [] # 定義一個空列表for job in list(job_data): # 使用循環處理最高哦薪資try: # 使用try...except檢驗最高薪資的提取,如果提取不到則加入0salary_1 = float(re.findall(r'-(\d+)k', job['salary'])[0]) # 使用正則提取最高薪資job['salary_1'] = salary_1 # 添加一個最高薪資list_1.append(salary_1) # 把最高薪資添加到list_1用來計算平均薪資except Exception as e:# print(e)job['salary_1'] = 0list_1.append(0)job_data = sorted(list(job_data), key=lambda x: x['salary_1'], reverse=True) # 反向排序所有職位信息的最高薪資# print(job_data)job_data_10 = job_data[0:10] # 取最高薪資前10用來渲染top—10表格# print(job_data[0:10])job_data_1 = job_data[0] # 取出最高薪資的職位信息mean_salary = int(mean(list_1)) # 計算平均薪資spider_info = models.SpiderInfo.objects.filter(spider_id=1).first() # 查詢爬蟲程序運行的數據記錄# print(spider_info)return render(request, "welcome.html", locals())def spiders(request):global spider_code# print(spider_code)spider_code_1 = spider_codereturn render(request, "spiders.html", locals())def start_spider(request):if request.method == "POST":key_word = request.POST.get("key_word")city = request.POST.get("city")page = request.POST.get("page")role = request.POST.get("role")spider_code = 1 # 改變爬蟲狀態spider_model = models.SpiderInfo.objects.filter(spider_id=1).first()# print(spider_model)spider_model.count += 1 # 給次數+1spider_model.page += int(page) # 給爬取頁數加上選擇的頁數spider_model.save()if role == '獵聘網':# print(key_word,city,page)spider_code = tools.lieSpider(key_word=key_word, city=city, all_page=page)return JsonResponse({"code": 0, "msg": "爬取完畢!"})else:return JsonResponse({"code": 1, "msg": "請使用POST請求"})def job_list(request):return render(request, "job_list.html", locals())def get_job_list(request):"""此函數用來渲染職位信息列表"""page = int(request.GET.get("page", "")) # 獲取請求地址中頁碼limit = int(request.GET.get("limit", "")) # 獲取請求地址中的每頁數據數量keyword = request.GET.get("keyword", "")price_min = request.GET.get("price_min", "")price_max = request.GET.get("price_max", "")edu = request.GET.get("edu", "")city = request.GET.get("city", "")job_data_list = list(models.JobData.objects.filter(name__icontains=keyword, education__icontains=edu,place__icontains=city).values()) # 查詢所有的職位信息job_data = []if price_min != "" or price_max != "":for job in job_data_list:try:salary_1 = '薪資' + job['salary']max_salary = float(re.findall(r'-(\d+)k', salary_1)[0]) # 使用正則提取最高薪資min_salary = float(re.findall(r'薪資(\d+)', salary_1)[0]) # 使用正則提取最低薪資if price_min == "" and price_max != "":if max_salary <= float(price_max):job_data.append(job)elif price_min != "" and price_max == "":if min_salary >= float(price_min):job_data.append(job)else:if min_salary >= float(price_min) and float(price_max) >= max_salary:job_data.append(job)except Exception as e: # 如果篩選不出就跳過continueelse:job_data = job_data_listjob_data_1 = job_data[(page - 1) * limit:limit * page]for job in job_data_1:ret = models.SendList.objects.filter(user_id=request.session.get("user_id"), job_id=job['job_id']).values()if ret:job['send_key'] = 1else:job['send_key'] = 0# print(job_data_1)if len(job_data) == 0 or len(job_data_list) == 0:return JsonResponse({"code": 1, "msg": "沒找到需要查詢的數據!", "count": "{}".format(len(job_data)), "data": job_data_1})return JsonResponse({"code": 0, "msg": "success", "count": "{}".format(len(job_data)), "data": job_data_1})def get_psutil(request):"""此函數用于讀取cpu使用率和內存占用率"""# cpu_percent()可以獲取cpu的使用率,參數interval是獲取的間隔# virtual_memory()[2]可以獲取內存的使用率return JsonResponse({'cpu_data': cpu_percent(interval=1), 'memory_data': virtual_memory()[2]})def get_pie(request):"""此函數用于渲染控制臺餅圖的數據,要求學歷的數據和薪資待遇的數據"""edu_list = ['博士', '碩士', '本科', '大專', '不限']edu_data = []for edu in edu_list:edu_count = len(models.JobData.objects.filter(education__icontains=edu)) # 使用for循環,查詢字段education包含這些學歷的職位信息edu_data.append({'name': edu, "value": edu_count}) # 添加到學歷的數據列表中# print(edu_data)list_5 = []list_10 = []list_15 = []list_20 = []list_30 = []list_50 = []list_51 = []job_data = models.JobData.objects.all().values() # 查詢所有的職位信息for job in list(job_data):try:salary_1 = float(re.findall(r'-(\d+)k', job['salary'])[0]) # 提取薪資待遇的最高薪資要求if salary_1 <= 5: # 小于5K則加入list_5list_5.append(salary_1)elif 10 >= salary_1 > 5: # 在5K和10K之間,加入list_10list_10.append(salary_1)elif 15 >= salary_1 > 10: # 10K-15K加入list_15list_15.append(salary_1)elif 20 >= salary_1 > 15: # 15K-20K加入list_20list_20.append(salary_1)elif 30 >= salary_1 > 20: # 20K-30K 加list_30list_30.append(salary_1)elif 50 >= salary_1 > 30: # 30K-50K加入list_50list_50.append(salary_1)elif salary_1 > 50: # 大于50K加入list_51list_51.append(salary_1)except Exception as e:job['salary_1'] = 0salary_data = [{'name': '5K及以下', 'value': len(list_5)}, # 生成薪資待遇各個階段的數據字典,value是里面職位信息的數量{'name': '5-10K', 'value': len(list_10)},{'name': '10K-15K', 'value': len(list_15)},{'name': '15K-20K', 'value': len(list_20)},{'name': '20K-30K', 'value': len(list_30)},{'name': '30-50K', 'value': len(list_50)},{'name': '50K以上', 'value': len(list_51)}]# print(edu_data)return JsonResponse({'edu_data': edu_data, 'salary_data': salary_data})def send_job(request):"""此函數用于投遞職位和取消投遞"""if request.method == "POST":user_id = request.session.get("user_id")job_id = request.POST.get("job_id")send_key = request.POST.get("send_key")if int(send_key) == 1:models.SendList.objects.filter(user_id=user_id, job_id=job_id).delete()else:models.SendList.objects.create(user_id=user_id, job_id=job_id)return JsonResponse({"Code": 0, "msg": "操作成功"})def job_expect(request):if request.method == "POST":job_name = request.POST.get("key_word")city = request.POST.get("city")ret = models.UserExpect.objects.filter(user=request.session.get("user_id"))# print(ret)if ret:ret.update(key_word=job_name, place=city)else:user_obj = models.UserList.objects.filter(user_id=request.session.get("user_id")).first()models.UserExpect.objects.create(user=user_obj, key_word=job_name, place=city)return JsonResponse({"Code": 0, "msg": "操作成功"})else:ret = models.UserExpect.objects.filter(user=request.session.get("user_id")).values()# print(ret)if len(ret) != 0:keyword = ret[0]['key_word']place = ret[0]['place']else:keyword = ''place = ''return render(request, "expect.html", locals())def get_recommend(request):recommend_list = job_recommend.recommend_by_item_id(request.session.get("user_id"), 9)# print(recommend_list)return render(request, "recommend.html", locals())def send_page(request):return render(request, "send_list.html")def send_list(request):send_list = list(models.JobData.objects.filter(sendlist__user=request.session.get("user_id")).values())for send in send_list:send['send_key'] = 1if len(send_list) == 0:return JsonResponse({"code": 1, "msg": "沒找到需要查詢的數據!", "count": "{}".format(len(send_list)), "data": []})else:return JsonResponse({"code": 0, "msg": "success", "count": "{}".format(len(send_list)), "data": send_list})def pass_page(request):user_obj = models.UserList.objects.filter(user_id=request.session.get("user_id")).first()return render(request, "pass_page.html", locals())def up_info(request):if request.method == "POST":user_name = request.POST.get("user_name")old_pass = request.POST.get("old_pass")pass_word = request.POST.get("pass_word")user_obj = models.UserList.objects.filter(user_id=request.session.get("user_id")).first()if old_pass != user_obj.pass_word:return JsonResponse({"Code": 0, "msg": "原密碼錯誤"})else:models.UserList.objects.filter(user_id=request.session.get("user_id")).update(user_name=user_name,pass_word=pass_word)return JsonResponse({"Code": 0, "msg": "密碼修改成功"})def salary(request):return render(request, "salary.html")def edu(request):return render(request, "edu.html")def bar_page(request):return render(request, "bar_page.html")def bar(request):key_list = [x['key_word'] for x in list(models.JobData.objects.all().values("key_word"))]# print(key_list)bar_x = list(set(key_list))# print(bar_x)bar_y = []for x in bar_x:bar_y.append(key_list.count(x))# print(bar_y)return JsonResponse({"Code": 0, "bar_x": bar_x, "bar_y": bar_y})
源碼下載
鏈接:https://pan.baidu.com/s/1QOrfbB4Q-5nnlixX-S7nvA
提取碼:1234