毕业设计:Django招聘数据采集分析可视化系统 Vue框架+scrapy爬虫

184 篇文章 45 订阅
178 篇文章 9 订阅

毕业设计:2023-2024年计算机专业毕业设计选题汇总(建议收藏)

毕业设计:2023-2024年最新最全计算机专业毕设选题推荐汇总

🍅感兴趣的可以先收藏起来,点赞、关注不迷路,大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助同学们顺利毕业 。🍅

1、项目介绍

技术栈:
Python语言、Django框架、MySQL数据库、scrapy爬虫、django-simpleui 后台ui框架、vue前端框架、HTML

2、项目界面

(1)全国工作地区分析

在这里插入图片描述

(2)工作经验分析

在这里插入图片描述

(3)薪资水平分析

在这里插入图片描述

(4)学历水平分析

在这里插入图片描述

(5)招聘数据

在这里插入图片描述

(6)薪资预测

在这里插入图片描述

(7)注册登录界面

在这里插入图片描述

(8)后台数据管理

在这里插入图片描述

3、项目说明

后端技术栈(python):
- django
- django-simpleui 后台ui框架
- mysql 数据库
- sqlite3 数据库
数据爬虫(python):
- scrapy 爬虫框架
- requests 轻量爬虫工具
- xpath 页面数据抽取
前端技术栈(nodejs+vue3):
- vue3
- element-plus vue3组件库
- element-plus-admin 页面框架

我们正在寻找一名熟悉以下技术栈的开发人员,来构建一个数据采集分析可视化系统。

技术栈包括Python语言、Django框架、MySQL数据库、scrapy爬虫、django-simpleui后台ui框架、vue前端框架以及HTML。

该系统旨在帮助用户采集各种数据并进行分析和可视化展示。用户可以使用系统中的爬虫模块来采集数据,并将数据存储到MySQL数据库中。同时,用户还可以使用系统中提供的分析工具来对数据进行处理和分析,以便得出有用的结论。

为了方便用户使用,我们将使用django-simpleui作为后台ui框架来构建一个简洁而直观的用户界面。用户可以通过该界面来管理数据采集任务、查看已采集的数据以及进行数据分析和可视化操作。

此外,我们将使用vue前端框架来构建系统的前端界面,以提供更加流畅和响应式的用户体验。前端界面将使用HTML进行布局和渲染。

如果你熟悉上述技术栈,并对数据采集、分析和可视化有一定的了解,那么我们非常欢迎你加入我们的团队,一起构建这个功能强大的数据采集分析可视化系统。

4、核心代码

# 工具函数
def to_dict(l):
    def _todict(obj):
        j = {k: v for k, v in obj.__dict__.items() if not k.startswith('_')}
        return j
    return [_todict(i) for i in l]

# 推荐职位视图
def recommand(request):
    # 需要登陆才能访问
    if not request.user.is_authenticated:
        return error('...')
    try:
        data = simplejson.loads(request.body)
    except:
        data = {}
    params = {}
    pagesize = data.get('pagesize', 12)
    page = data.get('page', 1)
    # 找到用户信息
    profile = Profile.objects.filter(userid=request.user.id)
    # 如果存在用户信息,就将用户填写的个人资料作为查询条件,用以筛选职位信息
    if profile:
        profile = profile[0]
        if profile.workarea:
            # 如果用户信息填写了工作地区,将它加入职位筛选条件
            params['workarea_text__icontains'] = profile.workarea
        if profile.workyear:
            # 如果用户信息填写了工作年限,将它加入职位筛选条件
            params['workyear_text'] = profile.workyear
        if profile.job_name:
            # 如果用户信息填写了职位名,将它加入职位筛选条件
            params['job_name__icontains'] = profile.job_name
        if profile.degree:
            # 如果用户信息填写了学历,将它加入职位筛选条件
            params['degreefrom_text'] = profile.degree
    params_q = Q(**params)
    # 筛选职位,并按照职位id倒排
    objs = Job.objects.filter(params_q).order_by('-jobid').all()
    pg = Paginator(objs, pagesize)
    # 分页
    page = pg.page(page)
    # 返回数据
    return JsonResponse({'code': 200, 'content': {
        'total': pg.count,
        'results': to_dict(page.object_list)
    }})

# 薪资水平预测视图
def predict_salary(request):
    try:
        data = simplejson.loads(request.body)
    except:
        data = {}
    not_q = ('total', 'page', 'pagesize', 'providesalary')
    params = {k: v for k, v in data.items() if k not in not_q and v}
    params_q = Q(**params) & Q(providesalary_max__gt=0)
    # 按所给条件查询职位信息,并聚合,算出最低薪资、最高薪资、平均薪资
    data = Job.objects.filter(params_q).aggregate(min=Min(
        'providesalary_min'), max=Max('providesalary_min'), avg=Avg('providesalary_min'))
    # 返回数据
    return JsonResponse(data)

# 职位信息分页查询
def get_jobs(request):
    try:
        data = simplejson.loads(request.body)
    except:
        data = {}
    not_q = ('total', 'page', 'pagesize', 'providesalary')
    pagesize = data.get('pagesize', 12)
    page = data.get('page', 1)
    # 加入筛选条件
    params = {k: v for k, v in data.items() if k not in not_q and v}
    # 薪资范围筛选条件做特别处理
    if 'providesalary' in data and data['providesalary']:
        q = salary_q[data['providesalary']]
        params_q = Q(**params) & q
    # 其余筛选条件直接加入
    else:
        params_q = Q(**params)
    # 筛选职位,并按照职位id倒排
    objs = Job.objects.filter(params_q).order_by('-jobid').all()
    pg = Paginator(objs, pagesize)
    # 分页
    page = pg.page(page)
    # 返回数据
    return JsonResponse({'code': 200, 'content': {
        'total': pg.count,
        'results': to_dict(page.object_list)
    }})

# 获取单个职位详细信息
def get_job(request, jobid):
    # 按所给职位id,查出职位信息并返回
    obj = get_object_or_404(Job, jobid=jobid)
    return JsonResponse(to_dict([obj])[0])

# 工作年限分析图
def workyear_chart(request):
    try:
        data = simplejson.loads(request.body)
    except:
        data = {}
    not_q = ('total', 'page', 'pagesize', 'providesalary')
    # 加入筛选条件
    params = {k: v for k, v in data.items() if k not in not_q and v}
    # 薪资范围筛选条件做特别处理
    if 'providesalary' in data and data['providesalary']:
        q = salary_q[data['providesalary']]
        params_q = Q(**params) & q
    # 其余筛选条件直接加入
    else:
        params_q = Q(**params)

    # 按所给条件查询职位信息,并按id聚合,统计出所有职位信息的工作年限
    data = {i['workyear_text']: i['count'] for i in Job.objects.filter(
        params_q).values('workyear_text').annotate(count=Count('id'))}
    # 用饼图展示统计数据
    c = (
        Pie()
        .add("", list(data.items()), label_opts=opts.LabelOpts(is_show=False))
        .set_global_opts(title_opts=opts.TitleOpts(title="工作经验分析", pos_left="40%"),
                         legend_opts=opts.LegendOpts(type_="scroll", pos_right="80%", orient="vertical"))
    )
    # 返回数据
    return HttpResponse(c.dump_options(), content_type="application/json")

# 工作地区分析图
def workarea_chart(request):
    try:
        data = simplejson.loads(request.body)
    except:
        data = {}
    not_q = ('total', 'page', 'pagesize', 'providesalary')
    # 加入筛选条件
    params = {k: v for k, v in data.items() if k not in not_q and v}
    # 薪资范围筛选条件做特别处理
    if 'providesalary' in data and data['providesalary']:
        q = salary_q[data['providesalary']]
        params_q = Q(**params) & q
    # 其余筛选条件直接加入
    else:
        params_q = Q(**params)
    # 按所给条件查询职位信息,并按id聚合,统计出所有职位信息的工作地区
    data = [(i['workarea_text'], i['count']) for i in Job.objects.filter(params_q).values(
        'workarea_text').annotate(count=Count('id'))]
    total = []
    # 数据预处理
    for i in data:
        city = i[0].split('-')[0]
        total.extend([city]*i[1])
    # 真正统计出每个地区有多少职位
    counter = list(Counter(total).items())
    # 用地图展示统计数据
    m = (
        Map()
        .add("城市", counter, "china-cities",  is_roam=False, is_map_symbol_show=False, label_opts=opts.LabelOpts(is_show=False),)
        .set_global_opts(
            title_opts=opts.TitleOpts(title="工作地区分析"),
            visualmap_opts=opts.VisualMapOpts(),
            legend_opts=opts.LegendOpts(is_show=False),
        )
    )
    # m.render("map_china_cities.html")
    # 返回数据
    return HttpResponse(m.dump_options(), content_type="aplication/text")

# 薪资水平分析图
def salary_chart(request):
    try:
        data = simplejson.loads(request.body)
    except:
        data = {}
    not_q = ('total', 'page', 'pagesize', 'providesalary')
    # 加入筛选条件
    params = {k: v for k, v in data.items() if k not in not_q and v}
    # 薪资范围筛选条件做特别处理
    if 'providesalary' in data and data['providesalary']:
        q = salary_q[data['providesalary']]
        params_q = Q(**params) & q
    # 其余筛选条件直接加入
    else:
        params_q = Q(**params)
    # 拿到所有职位数据的最低薪资与最高薪资
    data = list(Job.objects.filter(params_q).values(
        'providesalary_min', 'providesalary_max'))
    # 进行薪资范围分组
    salary_groups = {
        '面议': lambda i, a: i == 0 and a == 0,
        '3K以下': lambda i, a: 0 < a <= 3,
        '3-5K': lambda i, a: 3 < a <= 5,
        '5-10K': lambda i, a: 5 < a <= 10,
        '10-15K': lambda i, a: 10 < a <= 15,
        '15-20K': lambda i, a: 15 < a <= 20,
        '20-30K': lambda i, a: 20 < a <= 30,
        '30-50K': lambda i, a: 30 < a <= 50,
        '50K以上': lambda i, a: a > 50
    }
    # 统计并将数据进行分组
    counter = defaultdict(int)
    for i in data:
        providesalary_min, providesalary_max = i['providesalary_min'], i['providesalary_max']
        for k, v in salary_groups.items():
            if v(providesalary_min, providesalary_max):
                counter[k] += 1
                break
    # 用柱状图展示统计数据
    c = (
        Bar()
        .add_xaxis([i[0] for i in counter.items()])
        .add_yaxis("", [i[1] for i in counter.items()], label_opts=opts.LabelOpts(is_show=False))
        .reversal_axis()
        .set_global_opts(
            title_opts=opts.TitleOpts(title="薪资水平分析"),
            # datazoom_opts=opts.DataZoomOpts(orient="vertical"),
            yaxis_opts=opts.AxisOpts(
                type_="category",
                axispointer_opts=opts.AxisPointerOpts(
                    is_show=True, type_="shadow"),
            )
        )
    )
    # 返回数据
    return HttpResponse(c.dump_options(), content_type="application/json")

# 学历分析图
def degree_chart(request):
    try:
        data = simplejson.loads(request.body)
    except:
        data = {}
    not_q = ('total', 'page', 'pagesize', 'providesalary')
    # 加入筛选条件
    params = {k: v for k, v in data.items() if k not in not_q and v}
    # 薪资范围筛选条件做特别处理
    if 'providesalary' in data and data['providesalary']:
        q = salary_q[data['providesalary']]
        params_q = Q(**params) & q
    # 其余筛选条件直接加入
    else:
        params_q = Q(**params)
    # 按所给条件查询职位信息,并按id聚合,统计出不同的学历有多少职位
    data = {i['degreefrom_text']: i['count'] for i in Job.objects.filter(
        params_q).values('degreefrom_text').annotate(count=Count('id'))}
    # 用饼图展示数据
    c = (
        Pie()
        .add("", list(data.items()), label_opts=opts.LabelOpts(is_show=False))
        .set_global_opts(title_opts=opts.TitleOpts(title="学历水平分析", pos_left="40%"),
                         legend_opts=opts.LegendOpts(type_="scroll", pos_right="80%", orient="vertical"))
    )
    # 返回数据
    return HttpResponse(c.dump_options(), content_type="application/json")


源码获取:

🍅由于篇幅限制,获取完整文章或源码、代做项目的,查看我的【用户名】、【专栏名称】、【顶部选题链接】就可以找到我啦🍅

大家点赞、收藏、关注、评论啦 、查看👇🏻获取联系方式👇🏻

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值