研究背景
在当今社会,随着经济的发展和就业市场的竞争日益激烈,求职者面临着越来越多的招聘信息和选择。然而,对于求职者来说,如何快速准确地找到符合自己需求和兴趣的职位成为一个挑战。
传统的求职方式往往是通过招聘网站或招聘广告进行搜索,然后逐个查看招聘信息,并进行筛选和比较。这种方式存在着信息过载、效率低下的问题,使得求职者需要花费大量的时间和精力来寻找合适的工作机会。
因此,基于数据分析和推荐算法的招聘系统逐渐受到关注和重视。通过收集、整理和分析大量的招聘数据,可以提供更加精准和个性化的职位推荐,帮助求职者快速找到符合自己要求的工作机会。
同时,通过对招聘市场的数据分析,可以揭示不同城市、行业、公司等的就业趋势和需求,为求职者提供有价值的就业信息和决策支持。
然而,在实现招聘数据分析和推荐系统时,仍然存在一些挑战和问题。例如,如何从海量的招聘数据中准确提取关键信息、如何构建有效的推荐算法、如何处理用户偏好和动态变化等。
因此,为了解决这些问题并提供更好的求职体验,本研究将基于Python Flask框架开发一个招聘数据分析推荐系统。通过利用数据库和数据分析技术,结合用户需求和职位要求,系统可以快速筛选和推荐符合用户兴趣和要求的工作机会。同时,通过可视化和统计分析,系统还可以为用户提供有关就业市场的相关信息和趋势。
通过这个研究,我们希望能够提高求职者的就业效率和满意度,减少他们在招聘过程中的时间和精力消耗,同时也为企业提供更好的人才匹配和招聘效果评估手段。
功能需求
Python Flask招聘数据分析推荐系统是一个基于Flask框架开发的Web应用程序,旨在帮助用户分析和推荐符合其需求的招聘信息。该系统主要包括以下功能和实现方式:
用户登录与注册:通过提供登录和注册页面,用户可以创建账户或使用已有账户登录。用户的用户名和密码将保存在数据库中,并通过SQLAlchemy库进行数据库操作。
数据库连接与查询:系统通过SQLAlchemy库与MySQL数据库建立连接,并利用ORM(对象关系映射)模式,通过定义实体类(如Users、Job1)与数据库表之间的映射关系,对数据库进行增删改查操作。
首页推荐公司页面:根据用户的输入和要求,在数据库中筛选出符合条件的招聘信息,并将结果展示在首页。用户可以根据薪资、职位、城市等参数进行筛选,并通过模糊匹配算法(fuzzywuzzy)计算招聘信息与用户要求的匹配度。
职位分析页面:用户可以在此页面搜索特定职位,系统将根据职位名称在数据库中进行模糊匹配,并统计相关数据,如薪资分布、招聘地点分布等。最终将结果以图表形式展示给用户。
城市分析页面:用户可以选择具体城市,在数据库中筛选出该城市的招聘信息,并统计薪资分布情况。系统将结果以图表形式呈现给用户。
公司性质分析页面:系统从数据库中获取招聘信息中的公司性质数据,并进行统计和分析。最终将结果以图表形式展示给用户,帮助他们了解不同公司类型的就业机会。
职位需求分析页面:系统从数据库中获取招聘信息中的经验要求和学历要求数据,并进行统计和分析。最终将结果以图表形式展示给用户,帮助他们了解就业市场对经验和学历的需求情况。
用户信息管理页面:用户可以在此页面修改个人信息,如密码、目标城市、目标职位、期望薪资等。用户提交修改后,系统将更新数据库中相应的用户信息。
数据可视化:系统利用Python的数据可视化库(如Matplotlib、WordCloud)将统计结果以图表或词云的形式展示给用户,提供直观的数据分析效果。
通过这个系统,用户可以方便地搜索、分析和推荐符合自己需求的招聘信息,为就业决策提供参考和洞察。系统的开发和运行需要依赖Flask框架、SQLAlchemy库和其他相关的Python库,并使用MySQL数据库作为数据存储和查询的后端。
主要代码
from flask import Flask,redirect,url\_for,request,render\_template
from sqlalchemy import create\_engine
from dbCon import DB\_URI
from sqlalchemy.orm import sessionmaker
from model.entity import Users,Job1
from fuzzywuzzy import fuzz
from collections import Counter
import re
app=Flask(\_\_name\_\_)
user\_name='momo'
\# 把用户名定义成一个全局变量
@app.route('/')
\# 欢迎界面
def welcome():
return render\_template("welcome.html")
@app.route('/login')
\# 跳转到登陆页面login.html
def login():
return render\_template("login.html")
@app.route('/logininfo',methods=\["post","get"\])
\# 接收login表单中的数据
def logininfo():
global user\_name
user\_name=request.form\['name'\]
password = request.form\['pass'\]
engine = create\_engine(DB\_URI, echo=False)
Session = sessionmaker(bind=engine)
session = Session()
user = session.query(Users).filter(Users.user\_name == user_name).first()
if user is None:
# 判断该用户名是否存在,若不存在,反馈给页面
return render\_template('login.html', flag=1)
if password==user.password:
# 判断两次输入的密码是否一致,若不一致,反馈给页面
return render\_template("main.html", user\_name=user\_name)
if password!=user.password:
return render\_template('login.html', flag=1)
@app.route('/register')
\# 跳转到注册页面register.html
def register():
return render\_template("register.html")
@app.route('/registerinfo',methods=\["post","get"\])
\# 接收register表单中的数据
def registerinfo():
global user\_name
user\_name=request.form\['name'\]
password=request.form\['pass'\]
repassword=request.form\['repass'\]
engine = create\_engine(DB\_URI, echo=False)
Session = sessionmaker(bind=engine)
session = Session()
user = session.query(Users).filter(Users.user\_name == user\_name).all()
if len(user)!=0:
# 判断此用户名是否被使用,若被使用,反馈给页面
return render\_template('register.html',flag=1)
if password==repassword:
# 判断两次输入的密码是否一致,若一致,添加信息,否则,反馈给页面
ed\_users = Users(user\_name=user\_name, password=password)
session.add(ed\_users)
session.commit()
return render\_template('login.html',user\_name=user\_name)
else:
return render\_template('register.html',flag = 2)
@app.route('/index')
\# 跳转到首页(推荐公司页面)index.html
def index():
engine = create\_engine(DB\_URI, echo=False)
Session = sessionmaker(bind=engine)
session = Session()
user = session.query(Users).filter(Users.user\_name == user\_name).first()
job=session.query(Job1).all()
res1=\[\]
res2=\[\]
res3=\[\]
res4=\[\]
if user.user\_targetjob is not None:
# 从job中筛选出符合职位要求的向量组,并写入res1
for item in job:
if fuzz.partial\_ratio(item.job\_name,user.user\_targetjob)>80:
# 筛选出职位匹配度大于80的job向量组
res1.append(item)
else: res1=job
if user.user\_targetcity is not None:
# 从res1中筛选出符合城市要求的向量组,并写入res2
for item in res1:
if item.place==user.user\_targetcity:
res2.append(item)
else: res2=res1
if user.user\_minsalary is not None:
# 从res2中筛选出大于最低薪资要求要求的向量组,并写入res3
for item in res2:
if int(item.salary\_min)\*1000>int(user.user\_minsalary):
res3.append(item)
else: res3=res2
if user.user\_maxsalary is not None:
# 从res3中筛选出小于最高薪资要求的向量组,并写入res4
for item in res3:
if int(item.salary\_max)\*1000<=int(user.user\_maxsalary):
res4.append(item)
else: res4=res3
if len(res4)==0:
return render\_template('index.html',flag=0)
# 如果没有找到符合所有要求的向量组,返回flag
else:
return render\_template('index.html',\*\*{'job':res4})
@app.route('/post')
\# 跳转到职位分析页面post.html
def post():
return render\_template('post.html')
@app.route('/postinfo',methods=\["GET","POST"\])
\# 接收post.html表单中的信息
def postinfo():
# 表单获取搜索内容
job\_name=request.form\['job\_name'\]
engine = create\_engine(DB\_URI, echo=False)
Session = sessionmaker(bind=engine)
session = Session()
job = session.query(Job1).all()
place=\[\]
res=\[\]
for item in job:
if fuzz.partial\_ratio(item.job\_name, job\_name) > 80:
# 筛选出职位匹配度大于80的job向量组
place.append(item.place)
res.append(item)
res1=\[\]
res3=\[\]
res2=list()
if place is not None:
res3=Counter(place)
res1=res3.most\_common(10)
if res is not None:
res2.append(\["小于 3k", 0\])
res2.append(\["3k-7k", 0\])
res2.append(\["7k-10k", 0\])
res2.append(\["10k-15k", 0\])
res2.append(\["15k-20k", 0\])
res2.append(\["大于 20k", 0\])
i=0
for x in res:
if int(x.salary\_min) < 3:
res2\[0\]\[1\] = res2\[0\]\[1\] + 1
elif int(x.salary\_min) >= 3 and int(x.salary\_min) < 7:
res2\[1\]\[1\] = res2\[1\]\[1\] + 1
elif int(x.salary\_min) >= 7 and int(x.salary\_min) < 10:
res2\[2\]\[1\] = res2\[2\]\[1\] + 1
elif int(x.salary\_min) >= 10 and int(x.salary\_min) < 15:
res2\[3\]\[1\] = res2\[3\]\[1\] + 1
elif int(x.salary\_min) >= 15 and int(x.salary\_min) < 20:
res2\[4\]\[1\] = res2\[4\]\[1\] + 1
elif int(x.salary\_min) >= 20:
res2\[5\]\[1\] = res2\[5\]\[1\] + 1
return render\_template('post.html',place=res1,salary\_min=res2,job\_name=job\_name,flag=1)
@app.route('/city')
\# 跳转到城市分析页面city.html
def city():
return render\_template('city.html')
@app.route('/city/serach',methods=\["post"\])
\# 接收city.html的表单信息
def city\_serach():
engine = create\_engine(DB\_URI, echo=False)
Session = sessionmaker(bind=engine)
session = Session()
city=request.form\['place'\]
print(city)
tag=session.query(Job1).filter(Job1.place==city).first()
if tag is None:
print("2")
return render\_template('city.html',flag = 1)
res=session.query(Job1).filter(Job1.place==city).all()
res1=list()
res1.append(\["小于 3k",0\])
res1.append(\["3k-5k",0\])
res1.append(\["5k-7k",0\])
res1.append(\["7k-9k",0\])
res1.append(\["9k-11k",0\])
res1.append(\["大于 11k",0\])
for x in res:
if int(x.salary\_min) < 3:
res1\[0\]\[1\]=res1\[0\]\[1\]+1
elif int(x.salary\_min)>=3 and int(x.salary\_min) < 5:
res1\[1\]\[1\]=res1\[1\]\[1\]+1
elif int(x.salary\_min)>=5 and int(x.salary\_min) < 7:
res1\[2\]\[1\]=res1\[2\]\[1\]+1
elif int(x.salary\_min)>=7 and int(x.salary\_min) < 9:
res1\[3\]\[1\]=res1\[3\]\[1\]+1
elif int(x.salary\_min)>=9 and int(x.salary\_min) < 11:
res1\[4\]\[1\]=res1\[4\]\[1\]+1
elif int(x.salary\_min)>=11:
res1\[5\]\[1\]=res1\[5\]\[1\]+1
return render\_template('city.html',data=res1,city=city,flag2=1)
@app.route('/company')
\# 跳转到公司性质分析页面company.html
def company():
engine = create\_engine(DB\_URI, echo=False)
Session = sessionmaker(bind=engine)
session = Session()
job = session.query(Job1).all()
res=\[\]
for item in job:
res.append(item.company\_type)
res1=Counter(res)
res2=res1.most\_common(12)
return render\_template('company.html',\*\*{'type':res2})
@app.route('/require')
\# 跳转到职位需求分析页面require.html
def require():
engine = create\_engine(DB\_URI, echo=False)
Session = sessionmaker(bind=engine)
session = Session()
res = session.query(Job1).all()
res1 = list()
res1.append(\["应届生", 0\])
res1.append(\["1年以内经验", 0\])
res1.append(\["1-3年经验", 0\])
res1.append(\["3-5年经验", 0\])
res1.append(\["5-10年经验", 0\])
res1.append(\["10年以上经验", 0\])
for exp in res:
if exp.experience=='在校生/应届生':
res1\[0\]\[1\] = res1\[0\]\[1\] + 1
elif exp.experience=='1年以内经验':
res1\[1\]\[1\] = res1\[1\]\[1\] + 1
elif exp.experience=='1-3年经验':
res1\[2\]\[1\] = res1\[2\]\[1\] + 1
elif exp.experience=='3-5年经验':
res1\[3\]\[1\] = res1\[3\]\[1\] + 1
elif exp.experience=='5-10年经验':
res1\[4\]\[1\] = res1\[4\]\[1\] + 1
elif exp.experience=='10年以上经验':
res1\[5\]\[1\] = res1\[5\]\[1\] + 1
res2 = list()
res2.append(\["学历不限", 0\])
res2.append(\["初中", 0\])
res2.append(\["中专", 0\])
res2.append(\["高中", 0\])
res2.append(\["大专", 0\])
res2.append(\["本科", 0\])
res2.append(\["硕士", 0\])
res2.append(\["博士", 0\])
for edu in res:
if edu.education == '学历不限':
res2\[0\]\[1\] = res2\[0\]\[1\] + 1
elif edu.education == '初中及以下':
res2\[1\]\[1\] = res2\[1\]\[1\] + 1
elif edu.education == '中技/中专':
res2\[2\]\[1\] = res2\[2\]\[1\] + 1
elif edu.education == '高中':
res2\[3\]\[1\] = res2\[3\]\[1\] + 1
elif edu.education == '大专':
res2\[4\]\[1\] = res2\[4\]\[1\] + 1
elif edu.education == '本科':
res2\[5\]\[1\] = res2\[5\]\[1\] + 1
elif edu.education == '硕士':
res2\[6\]\[1\] = res2\[6\]\[1\] + 1
elif edu.education == '博士':
res2\[7\]\[1\] = res2\[7\]\[1\] + 1
return render\_template('require.html',data=res1, data1=res2,flag=1)
@app.route('/user\_info')
\# 跳转到修改信息页面user\_information.html,并传递数据
def user\_info():
engine = create\_engine(DB\_URI, echo=False)
Session = sessionmaker(bind=engine)
session = Session()
user = session.query(Users).filter(Users.user\_name == user\_name).first()
# 表示当前信息数据暂未被修改
return render\_template("user\_information.html",user=user)
@app.route('/user\_infoAlter/<edict>')
\# 跳转到修改信息页面user\_information.html,提示信息修改成功,并传递修改后的数据数据
def user\_infoAlter(edict):
engine = create\_engine(DB\_URI, echo=False)
Session = sessionmaker(bind=engine)
session = Session()
user = session.query(Users).filter(Users.user\_name == user\_name).first()
return render\_template("user\_information.html",user=user,edict=edict)
@app.route('/user\_information',methods=\["post","get"\])
\# 接收添加/修改用户信息页面的数据
def user\_information():
password = request.form\['pass'\]
user\_targetcity=request.form\['city'\]
user\_targetjob=request.form\['job'\]
user\_minsalary=request.form\['minsalary'\]
user\_maxsalary=request.form\['maxsalary'\]
if user\_targetcity=='':
user\_targetcity=None
# 前端传到后端的空值需要令其为空
if user\_targetjob=='':
user\_targetjob=None
if user\_minsalary=='':
user\_minsalary=None
if user\_maxsalary=='':
user\_maxsalary=None
engine = create\_engine(DB\_URI, echo=False)
Session = sessionmaker(bind=engine)
session = Session()
user = session.query(Users).filter(Users.user\_name == user\_name).first()
if password==user.password:
#判断密码是否输入正确
edict='修改成功'
user.user\_targetcity = user\_targetcity
user.user\_targetjob = user\_targetjob
user.user\_minsalary=user\_minsalary
user.user\_maxsalary=user\_maxsalary
# 对user的数据进行更新,并传入数据库
session.commit()
else:
edict='密码输入错误,修改失败'
return redirect(url\_for('user\_infoAlter',edict=edict))
# 信息修改成功,跳转到user\_info\_alter函数