当前位置:   article > 正文

计算机毕业设计:基于python旅游推荐系统+爬虫 +django框架(包含文档+源码+部署教程)_基于python的旅游推荐系统

基于python的旅游推荐系统

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

感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助更多的人 。

在这里插入图片描述

摘 要

时代在进步,科技在进步,互联网改变了世界,在互联网时代,各行各业的人们都在寻求增长点,人们的日常生活越来越离不开互联网。以旅游信息为例,线下大量的各种旅游信息基本只会出现在旅游会上,但是现如今,人们越来越重视时间成本,所以越来越多的年轻人在网上查找自己想要查找的旅游就业信息。然而,在互联网信息和海量数据源混合的情况下,如何快速精确的找到自己想要的数据是一个值得探讨的问题。
本系统主要针对解决获取旅游信息滞后、参加线下旅行社和人工检索时间成本高等问题,运用网络爬虫信息技术设计思想,实现了一个基于Python的旅游信息推荐系统。本系统以Python计算机设计语言为基础,使用 requests对去哪儿旅游信息源进行抓取,针对网页信息编写抽取规则,对旅游信息进行必要的过滤和提取,使用MySql对旅游信息进行数据存储。然后使用 Python 开源web框架 Django进行系统搭建,基于旅游信息完成对用户的旅游信息推荐,完成整个爬取以及数据检索到成功进行旅游推荐的网页端操作展示。

根据对系统的需求分析,此系统需包含供用户使用的web端和供管理员管理的web端。针对不同的需求,分模块设计出相应的功能。本模块的任务是根据需求分析设计出具体的系统功能框架

在这里插入图片描述

1、景点搜索界面
在这里插入图片描述
2、景点详情页
在这里插入图片描述
3、首页

在这里插入图片描述

4、类似景点推荐和评论评分页面
在这里插入图片描述
5、我的收藏
在这里插入图片描述

6、后台数据管理页面
在这里插入图片描述

7、数据采集页面

在这里插入图片描述

8、推荐模块设计与实现
系统为用户提供四种推荐,分别为热门推荐——根据爬取的评分高低进行排序推荐,随机推荐——随机选取景点进行推荐,猜你喜欢——基于深度学习的推荐,类似推荐——基于地点的推荐。。推荐模块结构图如图4-8所示。
在这里插入图片描述

图 推荐模块结构图

9、 热门推荐模块设计与实现
热门推荐是为了给用户提供评分最高的景点,也就是大多数人所喜欢的景点。在热门推荐模块下,评分就是通过网络爬虫爬取去哪儿网的多项数据经过处理得到的。因为爬取的多项数据均可反应景点的热门程度,所以单看一项数据来判断景点的热门程度是不合理的。本文的评分是将爬取的景点点评数量、驴友去过比例和景点星级数据按比例所综合得出的。由于各项数据的数值相差过大,直接相加会放大某项因素对最终评分的影响,所以要对数据进行相关处理,得到在一个区间的数值。经过观察,多数热门景点点评数量在一万左右,驴友去过比例在0%-100%之间,景点星级为0-5星,所以将点评数量缩小100倍,驴友去过比例去掉%,景点星级扩大20倍,可以将所有数据限定在0-100之间。之后对其相加,得到景点综合评分。

在这里插入图片描述

图 热门推荐流程图

部分代码

# coding:utf-8
from django.views.decorators.csrf import csrf_exempt
from django.shortcuts import render, redirect, HttpResponse
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.db.models import Q
from .algorithm import addr, ItemCF, UserCF
from tour.recomand import UserCf
from .models import *
import random
import json



@login_required(login_url='/login')
def init(request):
    # 推荐处理,根据游客的评分进行推荐
    recProducts = []
    datas = {}
    for user in User.objects.all():
        score = Score.objects.filter(user_id=user.id)
        dict = {}
        for sco in score:
            dict[sco.view_id] = sco.rate
        datas[user.username] = dict
    print("datas是",datas)

    userCf = UserCf(data=datas)

    recommandList = userCf.recomand(request.user.username, 10)  # 推荐10条 推荐列表  request.session.get('username')
    print("最终推荐:",recommandList)
    gue=View.objects.none()
    for r in recommandList:
        tables = View.objects.none()
        s_tables = tables.none()
        print(r)

        pro =View.objects.get(id=r[0])
        #s_tables += tables.filter(id=r[0])
        #gue=gue + View.objects.filter(id=r[0])
        recProducts.append({'id': pro.id, 'name': pro.view_name})

    print('pro ',pro )
    #print('s_tables ', s_tables)
    print(recProducts)

    if request.method == 'GET':
        # 热门推荐 按评分排序

        hot = View.objects.order_by('view_rate')[::-1]

        # 随机推荐某一地区景点


        #rand = View.objects.order_by('?')[:10]
        #rand = View.objects.filter(city=u'北京').order_by('view_rate')[::-1]
        rand = View.objects.all()

        # 猜你喜欢
        guess = recProducts

        data = {
            'hot': hot,
            'rand': rand,
            'guess': guess
        }
        print('随机猜测rand:', rand)
        print('guess:' ,guess)

        return render(request, 'index.html', data)


@csrf_exempt
@login_required(login_url='/login')
def detail(request):
    if request.method == 'GET':
        view_id = request.GET.get('id', False)
        view = View.objects.filter(id=view_id).first()

        # 类似推荐
        sim = View.objects.filter(city=view.city)

        # 该景点的评论
        comments = Comment.objects.filter(view=view).order_by('comment_date')[::-1]

        # 评分统计
        score = Score.objects.filter(view=view)
        pn = len(score)
        rate = round(sum(int(s.rate) for s in score) * 1.0 / pn, 1) if pn else 0.0#一位数平均

        collection = Collection.objects.filter(view=view, user=request.user)

        data = {
            'view': view,
            'sim': sim,
            'pn': pn,
            'comments': comments,
            'rate': rate,
            'collection': collection
        }
        print('view:' ,view)
        print('sim:', sim)
        print('comments:', comments)
        print('rate:', rate)
        print('collection:', collection)
        return render(request, 'detail.html', data)

    elif request.method == 'POST':
        comment = request.POST.get('text', False)
        view_id = request.POST.get('id', False)
        score = request.POST.get('score', False)
        collection = request.POST.get('collection', False)

        view = View.objects.get(id=view_id)

        msg = {
            'msg': '发生未知错误',
            'type': 'danger'
        }
        if comment:
            Comment.objects.create(user=request.user, view=view, comment=comment)
            msg['msg'] = '评论提交成功,页面即将刷新!'
            msg['type'] = 'success'

            return HttpResponse(json.dumps(msg), content_type='application/json')

        if score:
            score = int(score)
            s = Score.objects.filter(user=request.user, view=view)
            if s:
                s[0].rate = score
                s[0].save()
            else:
                Score.objects.create(user=request.user, view=view, rate=score)
            msg['msg'] = '感谢您的评分!'
            msg['type'] = 'success'
            return HttpResponse(json.dumps(msg), content_type='application/json')

        if collection:
            if collection == 'collection-true':
                Collection.objects.create(user=request.user, view=view)
                msg['msg'] = '收藏成功!'

            elif collection == 'collection-false':
                Collection.objects.filter(user=request.user, view=view).delete()
                msg['msg'] = '已取消收藏!'

            msg['type'] = 'success'
            return HttpResponse(json.dumps(msg), content_type='application/json')

        return HttpResponse(json.dumps(msg), content_type='application/json')


@csrf_exempt
def sign_in(request):
    if request.method == 'POST':
        username = request.POST.get('username', False)
        pw = request.POST.get('pw', False)
        user = authenticate(username=username, password=pw)
        if user:
            login(request, user)
            return redirect('/')

    if request.method == 'GET':
        username = request.GET.get('username', False)
        pw = request.GET.get('pw', False)
        if not username or not pw:
            return render(request, 'login.html')
        user = authenticate(username=username, password=pw)
        msg = {
            'msg': '登录成功,页面正在跳转!',
            'type': 'success'
        }
        if not user:
            msg['msg'] = '账号或密码错误,请检查后重新登录!'
            msg['type'] = 'danger'
        return HttpResponse(json.dumps(msg), content_type='application/json')


@csrf_exempt
def register(request):
    if request.method == 'POST':
        username = request.POST.get('username', False)
        pw = request.POST.get('pw', False)
        email = request.POST.get('email', False)

        # 生成随机编号
        number = random.randint(1000000, 9999999)
        if not ExtUser.objects.filter(number=number):
            user = User.objects.create_user(username=username, password=pw, email=email)
            ExtUser.objects.create(user=user, number=number)
            user = authenticate(username=username, password=pw)
            login(request, user)
            return redirect('/')

    elif request.method == 'GET':
        username = request.GET.get('username', False)
        pw = request.GET.get('pw', False)
        rpw = request.GET.get('rpw', False)
        if not username or not pw:
            return render(request, 'register.html')
        msg = {
            'msg': '账号注册成功!',
            'type': 'success'
        }
        if not pw.isalnum():
            msg['msg'] = '密码只能由数字字母组成!'
            msg['type'] = 'danger'
        if pw != rpw:
            msg['msg'] = '两次输入的密码不一致!'
            msg['type'] = 'danger'
        if len(pw) < 6:
            msg['msg'] = '密码至少需要6个字符!'
            msg['type'] = 'danger'
        if User.objects.filter(username=username):
            msg['msg'] = '用户名已经存在!'
            msg['type'] = 'danger'

        return HttpResponse(json.dumps(msg), content_type='application/json')


def sign_out(request):
    logout(request)
    return redirect('/')


def search(request):
    if request.method == 'GET':
        word = request.GET.get('word', False)
        views = View.objects.filter(Q(province__contains=word) | Q(view_name__contains=word) | Q(city__contains=word))

        for v in views:
            score = Score.objects.filter(view=v)
            v.view_rate = sum(s.rate for s in score)*1.0/len(score) if score else 0

        return render(request, 'search.html', {'views': views})


@login_required(login_url='/login')
def collection(request):
    views = Collection.objects.filter(user=request.user)
    return render(request, 'collection.html', {'views': views})



@login_required(login_url='/login')
@csrf_exempt
def info(request):
    if request.method == 'GET':
        return render(request, 'info.html')
    elif request.method == 'POST':
        username = request.POST.get('username', False)
        password = request.POST.get('password', False)
        sex = request.POST.get('sex', False)
        age = request.POST.get('age', False)
        address = request.POST.get('address', False)

        user = request.user
        user.username = username
        if password:
            user.set_password(password)
        user.extuser.sex = sex
        user.extuser.age = age
        user.extuser.address = address
        user.extuser.save()
        user.save()

        return redirect('/login')


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270

源码获取:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/194925
推荐阅读
相关标签