0


基于Python+大数据的旅游景区推荐系统设计与实现

💗博主介绍:✌全网粉丝10W+,CSDN全栈领域优质创作者,博客之星、掘金/华为云/阿里云等平台优质作者。
👇🏻 精彩专栏 推荐订阅👇🏻
计算机毕业设计精品项目案例-200套
🌟文末获取源码+数据库+文档🌟
感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以和学长沟通,希望帮助更多的人

一.前言

在这里插入图片描述
近些年来,随着科技的飞速发展,互联网的普及逐渐延伸到各行各业中,给人们生活带来了十分的便利,旅游景区推荐系统利用计算机网络实现信息化管理,使整个旅游景区推荐的发展和服务水平有显著提升。
本文拟采用PyCharm开发工具,Python语言、Django框架进行开发,后台使用MySQL数据库进行信息管理,设计开发的旅游景区推荐系统。通过调研和分析,系统拥有管理员和用户两个角色,主要具备注册登录、个人信息修改、用户、景点分类、景点信息、旅游景区等功能模块。将纸质管理有效实现为在线管理,极大提高工作效率。


二.技术环境

开发语言:Python
python框架:django
软件版本:python3.7/python3.8
数据库:mysql 5.7或更高版本
数据库工具:Navicat11
爬虫框架:Scrapy
开发软件:PyCharm/vs code
前端框架:vue.js


三.功能设计

系统用例图如图3-1、图3-2、图3-3、图3-4所示。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

系统功能结构图是系统设计阶段,系统功能结构图只是这个阶段一个基础,整个系统的架构决定了系统的整体模式,是系统的根据。本系统的整个设计结构如图所示。
在这里插入图片描述

四.数据设计

概念模型的设计是为了抽象真实世界的信息,并对信息世界进行建模。它是数据库设计的强大工具。数据库概念模型设计可以通过E-R图描述现实世界的概念模型。系统的E-R图显示了系统中实体之间的链接。而且Mysql数据库是自我保护能力比较强的数据库,下图主要是对数据库实体的E-R图:
在这里插入图片描述

在这里插入图片描述

五.部分效果展示

系统前台功能实现效果

当游客打开系统的网址后,首先看到的就是首页界面。在这里,游客能够看到旅游景区推荐系统的导航条显示首页、景点信息、旅游景区、景点资讯、个人中心。系统首页界面如图所示:
在这里插入图片描述

在系统首页点击中间的注册/登录按钮,然后页面跳转到注册登录界面,后来输入信息完成后,单击注册或者登录操作,如图所示:

在这里插入图片描述

用户点击景点信息,在景点信息页面的搜索栏输入景点名称、景点分类、景点星级、景点地址,进行查询,然后可以查看景点名称、景点分类、景点星级、景点图片、景点地址、营业时间、咨询热线,还可以对景点信息进行收藏或者评论操作;如图所示:

在这里插入图片描述

景点资讯;在景点资讯页面查看标题、内容、发布时间等信息进行详细操作,如图所示:
在这里插入图片描述

在个人中心页面可以输入个人详细信息,进行信息更新操作,还可以对我的收藏进行详细操作,如图所示:
在这里插入图片描述

系统管理员功能实现效果

管理员登录,通过登录页面填写用户名和密码等信息,点击登录操作,如图所示。

在这里插入图片描述

管理员登录进入系统可以查看系统首页、个人中心、用户管理、景点分类管理、景点信息管理、旅游景区管理、系统管理等功能,进行详细操作,如图所示。

在这里插入图片描述

管理员点击用户管理;在用户管理页面输入用户名、姓名、性别、头像、年龄、手机等信息,进行查询,新增或删除用户信息等操作;如图所示。

在这里插入图片描述

管理员点击景点信息管理;在景点信息管理页面输入景点名称、景点分类、景点星级、景点图片、景点地址、营业时间、咨询热线等信息,进行查询、新增或删除景点信息等操作;如图所示。
在这里插入图片描述

管理员点击旅游景区管理;在旅游景区管理页面对标题、封面、位置、价格、点评、评论等信息,进行查询或删除旅游景区等操作;如图所示。
在这里插入图片描述

管理员点击系统管理;在系统管理页面对系统简介、轮播图管理、景点资讯等信息,进行查询系统信息等操作;如图所示。

在这里插入图片描述

数据可视化分析大屏展示实现效果

旅游景区推荐系统展示图,如图所示。

在这里插入图片描述

在性别统计页面用饼状图进行展示所示。
在这里插入图片描述

在用户年龄分布统计页面用条形图进行展示所示。

在这里插入图片描述

六.部分功能代码

# 数据爬取文件import scrapy
import pymysql
import pymssql
from..items import QingdaolvyouItem
import time
import re
import random
import platform
import json
import os
from urllib.parse import urlparse
import requests
import emoji

# 旅游票务classQingdaolvyouSpider(scrapy.Spider):
    name ='qingdaolvyouSpider'
    spiderUrl ='https://piao.qunar.com/ticket/list.htm?keyword=%E9%9D%92%E5%B2%9B&region=%E9%9D%92%E5%B2%9B&from=mpshouye_hotcity&page={}'
    start_urls = spiderUrl.split(";")
    protocol =''
    hostname =''
    headers ={"cookie":"SECKEY_ABVK=vlhpRLsLQG31Po7dyp9LqZqIVWCqTw4N5fBZ1DsuytI%3D; BMAP_SECKEY=fYAVeumEoDJpvS6t9mUnIfl7ylS6g05LSr9A_ZA18UssrV2x9Nvb--l3q9TLiknfzexlawoBsTebfVGIHzfyqOYfo51s-Ty6bZN2gB7dr1ALnVPRdfYiZs3FsCl2tC0PoI6DkXokTEOHVASpbWqBKuvneDEGUXxubzmT6qyM8jikWfPePl74wseQQxqH3SH3; QN1=00008c0031984ca726d0ccdd; HN1=v1d5a05c0541e94af107a046147dde57e6; HN2=qungnknsnqczr; QN300=s%3Dbaidu; _i=DFiEuMlwNifDZ7e6ttNii8l8C0yw; QN269=3C0E7D80A48D11EDA4E6FA163E7C276C; fid=c122ef21-269d-44af-816b-a3af77b6e9a0; ctt_june=1654604625968##iK3wWsjmahPwawPwa%3DXNWK0GE2GIaRkTESWRa%3Da8aDkGES0REDPsXPWGWKj8iK3siK3saKj%2BWKPnWsj%2BaSjnVuPwaUvt; ctf_june=1654604625968##iK3wVRtnahPwawPwasWGa%3DasWK2naS2%3DaSETVPDmWSXNWSvmXSWGX%3DPOVRDniK3siK3saKj%2BWKPnWsjmaSj%3DWwPwaUvt; cs_june=a4e7c8acd60e0c8483c9c4af0f303f81fd7bf3054fa1059b680a62984007c656679c337a756eb8f3b21f18c3ca84c016ab0131ff331f4cb4e98fa22f3456d33eb17c80df7eee7c02a9c1a6a5b97c117961a58ae707d2d19d229b1e3a0abd1ac65a737ae180251ef5be23400b098dd8ca; qunar-assist={%22version%22:%2220211215173359.925%22%2C%22show%22:false%2C%22audio%22:false%2C%22speed%22:%22middle%22%2C%22zomm%22:1%2C%22cursor%22:false%2C%22pointer%22:false%2C%22bigtext%22:false%2C%22overead%22:false%2C%22readscreen%22:false%2C%22theme%22:%22default%22}; QN205=organic; QN277=organic; csrfToken=CHPGSBwmGivAQIY68e9qdAdiTV3ndNSv; QN57=16773851843530.3742666257450069; Hm_lvt_15577700f8ecddb1a927813c81166ade=1677385185; QN267=9396775017807b72f; _vi=kLcz4BXbLA-Z_dmzAME0UN9x6XaB-aiI3ZQP-imSw9FAo6neFHeLQ5sMT6sMGgFb5a8IfmLRa7vmEMF3xiAAC7OMS4j9DgEidNCIF7BZoBbk58pE_3MLJ42UlqZfLutL8q10pZv62VI2_1_qG1wdurlugFXSrwHiB_htc5SdZS6G; QN58=1677387675012%7C1677387675012%7C1; ariaDefaultTheme=undefined; Hm_lpvt_15577700f8ecddb1a927813c81166ade=1677387675; __qt=v1%7CVTJGc2RHVmtYMS9NUFFkYWJvb2FuMVkzNDhtbjNjU0lZQUhsdmlmeUlENW91YjBzZTdodm9FVGdOWTVFUzh6dnVJTFVtUDNVQjFMa1RRVy82NjZoTWRYY2NKcGIxMGlnZnhqOG9tMy9sYjdjbUthUGdQVC92T0U2RTNJR0lKaWc5elpiMzBpWGxJZ0o4UjlueEMvMmZnPT0%3D%7C1677387675401%7CVTJGc2RHVmtYMTlEUVJsa1RGdmswaFhyMXFlQkZOUnFvNCt0OGxtTGtjNWt4VzdmbDluZFBBZVdlRGptcTFJZXAyOXIxaFRqQk5RY0pCdms3bzkwRmc9PQ%3D%3D%7CVTJGc2RHVmtYMStqelpiM1RGUERkbHpQY1J2MHo5Nk9wcWYvRnlDOUxERUk4RVExOTllczRSNUlhSGxmUmlsRXpzdTBGN052RjVzVmRwcG4raFRQWHRUNXdhbFNyR1RLNU9iY0hRU1BMK05UaHRRUTcwbUwvbWdMeEI4RnY2Y3l3SlV2ZFBFTHZGV2tobVJlcG5aUXhyL3FPcHRkZmx0VXZtR3hoRUJxcjh1ZjBJcFZVS1l5RmQ4NC9Xa0VjbGoySEVZcG03S2pKVEVSaWlVVHU2Z2haTExReXJoOFAvN3pKOUJjWnBQZmJSVWxsUk9Yd0tCZk53Uk9wSXZ0Z29LNTdSN3JrSHV1MFlZc20xdWxkQVZ6bUx3THBLcEcwNDhiRGhSNHlpWngrU01uVG10YjFKMC9jb2VtSmI3ajlkRDAzd3VLcTBNVGY4R0FBQTd1SlozdWpPMkVFdDRBT0l1UVVsblpJbXdXSXI3eWRSZG4vMnNkK00wR0xSU2JxZU8zNlROU2xQcGQxVkNKT3ZQK1diaVA3NzZjeHpObkE2bnRhTG52R3FqaStkQkN5UVpQaTd3amwySVlvaEtXdGlNcjByQWNzRHo0Njd2TzJlVFVaaVdla1U5RUIzRU5veFJCWXZkU2haYUpyeHRjY0t2M3pOd0U2a0JsM2pnakRZbCtTVE12QWNpR0dXS2Z6T3oxNVoxeHBXVzVSeEUzNU1OZ2Ezc2RKcFg1STVHWkZvL0ZHMWtIS0doRDlpQnNWK0Y5UkxnaklCc2p5alZFdTRxaEVsVkdjQThNV1N0L29QaVBmR3l2RDRneHNVUUhMU3ZOdnVlMi8rb3VaeWFFcm9VUDh1T1NiZURBblVCSHJkNjlDSU1QbUdJcTNvbWpUb0tJNFE0cUZLSDI4ckw5bmpCSjFtK1Q0ZVRXWml6aDgrWWx1VU9SMnJkVUFHVmVtSmhGZHJ0RWI4TFp2eUVPSFZLalB1M29WcVlSb1oxQXZTVWhESW5ycVhnek4wSjNTYjNnRFNNK2JObXlVTXRpcFhiUEh2SkRzenMzSWdsdi9xOE9QeHI4VFRiUHdoZDFIWUlFL0E0SVVtL2NjdFlMY0hhNQ%3D%3D; JSESSIONID=F90B651C1C838D80BE882B24C9D63F8A; QN271=217bc6aa-758f-4cb5-8d18-a95283b08907"}def__init__(self,*args,**kwargs):super().__init__(*args,**kwargs)defstart_requests(self):

        plat = platform.system().lower()if plat =='linux'or plat =='windows':
            connect = self.db_connect()
            cursor = connect.cursor()if self.table_exists(cursor,'2o7ww_qingdaolvyou')==1:
                cursor.close()
                connect.close()
                self.temp_data()return

        pageNum =1+1for url in self.start_urls:if'{}'in url:for page inrange(1, pageNum):
                    next_link = url.format(page)yield scrapy.Request(
                        url=next_link,
                        headers=self.headers,
                        callback=self.parse
                    )else:yield scrapy.Request(
                    url=url,
                    callback=self.parse
                )# 列表解析defparse(self, response):
        
        _url = urlparse(self.spiderUrl)
        self.protocol = _url.scheme
        self.hostname = _url.netloc
        plat = platform.system().lower()if plat =='windows_bak':passelif plat =='linux'or plat =='windows':
            connect = self.db_connect()
            cursor = connect.cursor()if self.table_exists(cursor,'2o7ww_qingdaolvyou')==1:
                cursor.close()
                connect.close()
                self.temp_data()returnlist= response.css('div#search-list div[class~="sight_item"]')for item inlist:

            fields = QingdaolvyouItem()

            fields["laiyuan"]= self.remove_html(item.css('h3.sight_item_caption a.name::attr(href)').extract_first())
            fields["jiage"]= self.remove_html(item.css('span.sight_item_price em::text').extract_first())

            detailUrlRule = item.css('h3.sight_item_caption a.name::attr(href)').extract_first()if self.protocol in detailUrlRule:passelif detailUrlRule.startswith('//'):
                detailUrlRule = self.protocol +':'+ detailUrlRule
            else:
                detailUrlRule = self.protocol +'://'+ self.hostname + detailUrlRule
                fields["laiyuan"]= detailUrlRule

            yield scrapy.Request(url=detailUrlRule, meta={'fields': fields}, headers=self.headers, callback=self.detail_parse)# 详情解析defdetail_parse(self, response):
        fields = response.meta['fields']try:if'(.*?)'in'''div.mp-description-detail div.mp-description-view span.mp-description-name::text''':
                fields["biaoti"]= re.findall(r'''div.mp-description-detail div.mp-description-view span.mp-description-name::text''', response.text, re.S)[0].strip()else:if'biaoti'!='xiangqing'and'biaoti'!='detail'and'biaoti'!='pinglun'and'biaoti'!='zuofa':
                    fields["biaoti"]= self.remove_html(response.css('''div.mp-description-detail div.mp-description-view span.mp-description-name::text''').extract_first())else:
                    fields["biaoti"]= emoji.demojize(response.css('''div.mp-description-detail div.mp-description-view span.mp-description-name::text''').extract_first())except:passtry:if'(.*?)'in'''div#mp-slider-content div.mp-description-image img::attr(src)''':
                fields["fengmian"]= re.findall(r'''div#mp-slider-content div.mp-description-image img::attr(src)''', response.text, re.S)[0].strip()else:if'fengmian'!='xiangqing'and'fengmian'!='detail'and'fengmian'!='pinglun'and'fengmian'!='zuofa':
                    fields["fengmian"]= self.remove_html(response.css('''div#mp-slider-content div.mp-description-image img::attr(src)''').extract_first())else:
                    fields["fengmian"]= emoji.demojize(response.css('''div#mp-slider-content div.mp-description-image img::attr(src)''').extract_first())except:passtry:if'(.*?)'in'''div.mp-description-onesentence::text''':
                fields["miaoshu"]= re.findall(r'''div.mp-description-onesentence::text''', response.text, re.S)[0].strip()else:if'miaoshu'!='xiangqing'and'miaoshu'!='detail'and'miaoshu'!='pinglun'and'miaoshu'!='zuofa':
                    fields["miaoshu"]= self.remove_html(response.css('''div.mp-description-onesentence::text''').extract_first())else:
                    fields["miaoshu"]= emoji.demojize(response.css('''div.mp-description-onesentence::text''').extract_first())except:passtry:if'(.*?)'in'''span.mp-description-address::text''':
                fields["weizhi"]= re.findall(r'''span.mp-description-address::text''', response.text, re.S)[0].strip()else:if'weizhi'!='xiangqing'and'weizhi'!='detail'and'weizhi'!='pinglun'and'weizhi'!='zuofa':
                    fields["weizhi"]= self.remove_html(response.css('''span.mp-description-address::text''').extract_first())else:
                    fields["weizhi"]= emoji.demojize(response.css('''span.mp-description-address::text''').extract_first())except:passtry:if'(.*?)'in'''span#mp-description-commentscore''':
                fields["dianping"]= re.findall(r'''span#mp-description-commentscore''', response.text, re.S)[0].strip()else:if'dianping'!='xiangqing'and'dianping'!='detail'and'dianping'!='pinglun'and'dianping'!='zuofa':
                    fields["dianping"]= self.remove_html(response.css('''span#mp-description-commentscore''').extract_first())else:
                    fields["dianping"]= emoji.demojize(response.css('''span#mp-description-commentscore''').extract_first())except:passtry:if'(.*?)'in'''span.mp-description-commentCount a::text''':
                fields["pinglun"]= re.findall(r'''span.mp-description-commentCount a::text''', response.text, re.S)[0].strip()else:if'pinglun'!='xiangqing'and'pinglun'!='detail'and'pinglun'!='pinglun'and'pinglun'!='zuofa':
                    fields["pinglun"]= self.remove_html(response.css('''span.mp-description-commentCount a::text''').extract_first())else:
                    fields["pinglun"]= emoji.demojize(response.css('''span.mp-description-commentCount a::text''').extract_first())except:passtry:if'(.*?)'in'''div.mp-charact-intro div.mp-charact-desc''':
                fields["tese"]= re.findall(r'''div.mp-charact-intro div.mp-charact-desc''', response.text, re.S)[0].strip()else:if'tese'!='xiangqing'and'tese'!='detail'and'tese'!='pinglun'and'tese'!='zuofa':
                    fields["tese"]= self.remove_html(response.css('''div.mp-charact-intro div.mp-charact-desc''').extract_first())else:
                    fields["tese"]= emoji.demojize(response.css('''div.mp-charact-intro div.mp-charact-desc''').extract_first())except:passtry:if'(.*?)'in'''div.mp-charact-content div.mp-charact-desc''':
                fields["kaifangshijian"]= re.findall(r'''div.mp-charact-content div.mp-charact-desc''', response.text, re.S)[0].strip()else:if'kaifangshijian'!='xiangqing'and'kaifangshijian'!='detail'and'kaifangshijian'!='pinglun'and'kaifangshijian'!='zuofa':
                    fields["kaifangshijian"]= self.remove_html(response.css('''div.mp-charact-content div.mp-charact-desc''').extract_first())else:
                    fields["kaifangshijian"]= emoji.demojize(response.css('''div.mp-charact-content div.mp-charact-desc''').extract_first())except:passreturn fields

    # 去除多余html标签defremove_html(self, html):if html ==None:return''
        pattern = re.compile(r'<[^>]+>', re.S)return pattern.sub('', html).strip()# 数据库连接defdb_connect(self):type= self.settings.get('TYPE','mysql')
        host = self.settings.get('HOST','localhost')
        port =int(self.settings.get('PORT',3306))
        user = self.settings.get('USER','root')
        password = self.settings.get('PASSWORD','123456')try:
            database = self.databaseName
        except:
            database = self.settings.get('DATABASE','')iftype=='mysql':
            connect = pymysql.connect(host=host, port=port, db=database, user=user, passwd=password, charset='utf8')else:
            connect = pymssql.connect(host=host, user=user, password=password, database=database)return connect

    # 断表是否存在deftable_exists(self, cursor, table_name):
        cursor.execute("show tables;")
        tables =[cursor.fetchall()]
        table_list = re.findall('(\'.*?\')',str(tables))
        table_list =[re.sub("'",'',each)for each in table_list]if table_name in table_list:return1else:return0# 数据缓存源deftemp_data(self):

        connect = self.db_connect()
        cursor = connect.cursor()
        sql ='''
            insert into qingdaolvyou(
                laiyuan
                ,biaoti
                ,fengmian
                ,miaoshu
                ,weizhi
                ,dianping
                ,pinglun
                ,jiage
                ,tese
                ,kaifangshijian
            )
            select
                laiyuan
                ,biaoti
                ,fengmian
                ,miaoshu
                ,weizhi
                ,dianping
                ,pinglun
                ,jiage
                ,tese
                ,kaifangshijian
            from 2o7ww_qingdaolvyou
            where(not exists (select
                laiyuan
                ,biaoti
                ,fengmian
                ,miaoshu
                ,weizhi
                ,dianping
                ,pinglun
                ,jiage
                ,tese
                ,kaifangshijian
            from qingdaolvyou where
             qingdaolvyou.laiyuan=2o7ww_qingdaolvyou.laiyuan
            and qingdaolvyou.biaoti=2o7ww_qingdaolvyou.biaoti
            and qingdaolvyou.fengmian=2o7ww_qingdaolvyou.fengmian
            and qingdaolvyou.miaoshu=2o7ww_qingdaolvyou.miaoshu
            and qingdaolvyou.weizhi=2o7ww_qingdaolvyou.weizhi
            and qingdaolvyou.dianping=2o7ww_qingdaolvyou.dianping
            and qingdaolvyou.pinglun=2o7ww_qingdaolvyou.pinglun
            and qingdaolvyou.jiage=2o7ww_qingdaolvyou.jiage
            and qingdaolvyou.tese=2o7ww_qingdaolvyou.tese
            and qingdaolvyou.kaifangshijian=2o7ww_qingdaolvyou.kaifangshijian
            ))
            limit {0}
        '''.format(random.randint(20,30))

        cursor.execute(sql)
        connect.commit()

        connect.close()

最后

最新计算机毕业设计选题篇-选题推荐(值得收藏)
计算机毕业设计精品项目案例-200套(值得订阅)

标签: python 大数据 旅游

本文转载自: https://blog.csdn.net/qq_15801219/article/details/135965849
版权归原作者 一点毕设 所有, 如有侵权,请联系我们删除。

“基于Python+大数据的旅游景区推荐系统设计与实现”的评论:

还没有评论