项目介绍
重庆旅游景点数据分析系统是一个专门为旅游管理部门和景点运营商设计的信息化工具,它通过集成和分析各种数据来优化景点管理和提升游客体验。该系统能够实时收集游客流量、景点信息、满意度反馈等关键信息,帮助管理者洞察游客行为和市场趋势。系统利用统计分析和数据挖掘技术,能够从大量数据中提取有价值的信息,如景点热度排名、高峰时段预测、游客评分分析等。这些分析结果对于制定营销策略、调整运营时间和改善服务设施具有重要意义。重庆旅游景点数据分析系统为旅游业提供了一个科学、高效的决策支持工具,它不仅能够增强景点吸引力和提高游客满意度,还能促进重庆旅游业的整体发展和竞争力。
本文主要讨论了以Python为编程语言,Django为框架,MySQL数据库以及开发易于使用的重庆旅游景点数据分析系统建设计划的主要思想。在这篇文章中,系统研究的背景和意义、开发技术、系统分析、数据库设计、详细的系统设计等信息系统的设计和开发过程的焦点。
技术介绍
开发语言:Python
python框架:Django
软件版本:python3.7/python3.8
数据库:mysql 5.7或更高版本
数据库工具:Navicat11
开发软件:PyCharm/vs code
前端框架:vue.js
功能介绍
重庆旅游景点数据分析系统设计主要有管理员和用户两个功能模块。以下将对这两个功能的作用进行详细的剖析。
管理员模块:管理员是系统中的核心用户,管理员登录后,可以对后台系统进行管理。主要包括有系统首页、用户、旅游信息、系统管理、个人资料等功能。
用户:用户注册登录进入系统可以对首页、旅游信息、系统公告、个人中心等进行操作。
核心代码
# 数据爬取文件
import scrapy
import pymysql
import pymssql
from ..items import LvyoujingdianItem
import time
import re
import random
import platform
import json
import os
import urllib
from urllib.parse import urlparse
import requests
import emoji
# 旅游景点
class LvyoujingdianSpider(scrapy.Spider):
name = 'lvyoujingdianSpider'
spiderUrl = 'https://you.ctrip.com/sight/lanzhou231/s0-p{}.html'
start_urls = spiderUrl.split(";")
protocol = ''
hostname = ''
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def start_requests(self):
plat = platform.system().lower()
if plat == 'linux' or plat == 'windows':
connect = self.db_connect()
cursor = connect.cursor()
if self.table_exists(cursor, '5295r_lvyoujingdian') == 1:
cursor.close()
connect.close()
self.temp_data()
return
pageNum = 1 + 1
for url in self.start_urls:
if '{}' in url:
for page in range(1, pageNum):
next_link = url.format(page)
yield scrapy.Request(
url=next_link,
callback=self.parse
)
else:
yield scrapy.Request(
url=url,
callback=self.parse
)
# 列表解析
def parse(self, response):
_url = urlparse(self.spiderUrl)
self.protocol = _url.scheme
self.hostname = _url.netloc
plat = platform.system().lower()
if plat == 'windows_bak':
pass
elif plat == 'linux' or plat == 'windows':
connect = self.db_connect()
cursor = connect.cursor()
if self.table_exists(cursor, '5295r_lvyoujingdian') == 1:
cursor.close()
connect.close()
self.temp_data()
return
list = response.css('div.list_wide_mod2 div.list_mod2')
for item in list:
fields = LvyoujingdianItem()
if '(.*?)' in '''dt a::attr(href)''':
fields["laiyuan"] = re.findall(r'''dt a::attr(href)''', response.text, re.DOTALL)[0].strip()
else:
fields["laiyuan"] = self.remove_html(item.css('dt a::attr(href)').extract_first())
if '(.*?)' in '''div.leftimg a img::attr(src)''':
fields["fengmian"] = re.findall(r'''div.leftimg a img::attr(src)''', response.text, re.DOTALL)[0].strip()
else:
fields["fengmian"] = self.remove_html(item.css('div.leftimg a img::attr(src)').extract_first())
if '(.*?)' in '''div.rdetailbox dl dt a::text''':
fields["biaoti"] = re.findall(r'''div.rdetailbox dl dt a::text''', response.text, re.DOTALL)[0].strip()
else:
fields["biaoti"] = self.remove_html(item.css('div.rdetailbox dl dt a::text').extract_first())
if '(.*?)' in '''b.hot_score_number::text''':
fields["redu"] = re.findall(r'''b.hot_score_number::text''', response.text, re.DOTALL)[0].strip()
else:
fields["redu"] = self.remove_html(item.css('b.hot_score_number::text').extract_first())
if '(.*?)' in '''dd.ellipsis::text''':
fields["dizhi"] = re.findall(r'''dd.ellipsis::text''', response.text, re.DOTALL)[0].strip()
else:
fields["dizhi"] = self.remove_html(item.css('dd.ellipsis::text').extract_first())
if '(.*?)' in '''a.score strong::text''':
fields["pingfen"] = re.findall(r'''a.score strong::text''', response.text, re.DOTALL)[0].strip()
else:
fields["pingfen"] = self.remove_html(item.css('a.score strong::text').extract_first())
if '(.*?)' in '''a.recomment::text''':
fields["pinglun"] = re.findall(r'''a.recomment::text''', response.text, re.DOTALL)[0].strip()
else:
fields["pinglun"] = self.remove_html(item.css('a.recomment::text').extract_first())
if '(.*?)' in '''p[class="bottomcomment ellipsis open_popupbox_a"]''':
fields["dianping"] = re.findall(r'''p[class="bottomcomment ellipsis open_popupbox_a"]''', response.text, re.DOTALL)[0].strip()
else:
fields["dianping"] = self.remove_html(item.css('p[class="bottomcomment ellipsis open_popupbox_a"]').extract_first())
detailUrlRule = item.css('dt a::attr(href)').extract_first()
if self.protocol in detailUrlRule:
pass
elif detailUrlRule.startswith('//'):
detailUrlRule = self.protocol + ':' + detailUrlRule
else:
detailUrlRule = self.protocol + '://' + self.hostname + detailUrlRule
fields["laiyuan"] = detailUrlRule
yield scrapy.Request(url=detailUrlRule, meta={'fields': fields}, callback=self.detail_parse, dont_filter=True)
# 详情解析
def detail_parse(self, response):
fields = response.meta['fields']
try:
if '(.*?)' in '''<div class="baseInfoItem"><p class="baseInfoTitle">官方电话</p><p class="baseInfoText">(.*?)</p></div>''':
fields["gfdh"] = re.findall(r'''<div class="baseInfoItem"><p class="baseInfoTitle">官方电话</p><p class="baseInfoText">(.*?)</p></div>''', response.text, re.S)[0].strip()
else:
if 'gfdh' != 'xiangqing' and 'gfdh' != 'detail' and 'gfdh' != 'pinglun' and 'gfdh' != 'zuofa':
fields["gfdh"] = self.remove_html(response.css('''<div class="baseInfoItem"><p class="baseInfoTitle">官方电话</p><p class="baseInfoText">(.*?)</p></div>''').extract_first())
else:
fields["gfdh"] = emoji.demojize(response.css('''<div class="baseInfoItem"><p class="baseInfoTitle">官方电话</p><p class="baseInfoText">(.*?)</p></div>''').extract_first())
except:
pass
try:
if '(.*?)' in '''div[class="detailModule normalModule"]''':
fields["detail"] = re.findall(r'''div[class="detailModule normalModule"]''', response.text, re.S)[0].strip()
else:
if 'detail' != 'xiangqing' and 'detail' != 'detail' and 'detail' != 'pinglun' and 'detail' != 'zuofa':
fields["detail"] = self.remove_html(response.css('''div[class="detailModule normalModule"]''').extract_first())
else:
fields["detail"] = emoji.demojize(response.css('''div[class="detailModule normalModule"]''').extract_first())
except:
pass
return fields
# 去除多余html标签
def remove_html(self, html):
if html == None:
return ''
pattern = re.compile(r'<[^>]+>', re.S)
return pattern.sub('', html).strip()
# 数据库连接
def db_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', '')
if type == '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
# 断表是否存在
def table_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:
return 1
else:
return 0
# 数据缓存源
def temp_data(self):
connect = self.db_connect()
cursor = connect.cursor()
sql = '''
insert into `lvyoujingdian`(
id
,laiyuan
,fengmian
,biaoti
,redu
,dizhi
,pingfen
,pinglun
,dianping
,gfdh
,detail
)
select
id
,laiyuan
,fengmian
,biaoti
,redu
,dizhi
,pingfen
,pinglun
,dianping
,gfdh
,detail
from `5295r_lvyoujingdian`
where(not exists (select
id
,laiyuan
,fengmian
,biaoti
,redu
,dizhi
,pingfen
,pinglun
,dianping
,gfdh
,detail
from `lvyoujingdian` where
`lvyoujingdian`.id=`5295r_lvyoujingdian`.id
))
limit {0}
'''.format(random.randint(10,15))
cursor.execute(sql)
connect.commit()
connect.close()
数据库参考
--
-- Current Database: `python3oe8563i`
--
/*!40000 DROP DATABASE IF EXISTS `python3oe8563i`*/;
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `python3oe8563i` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;
USE `python3oe8563i`;
--
-- Table structure for table `aboutus`
--
DROP TABLE IF EXISTS `aboutus`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `aboutus` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`addtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`title` varchar(200) NOT NULL COMMENT '标题',
`subtitle` varchar(200) DEFAULT NULL COMMENT '副标题',
`content` longtext NOT NULL COMMENT '内容',
`picture1` longtext COMMENT '图片1',
`picture2` longtext COMMENT '图片2',
`picture3` longtext COMMENT '图片3',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='关于我们';
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `aboutus`
--
LOCK TABLES `aboutus` WRITE;
/*!40000 ALTER TABLE `aboutus` DISABLE KEYS */;
INSERT INTO `aboutus` VALUES (1,'2024-03-30 02:07:07','关于我们','ABOUT US','当你设想门外是寒冷可怕的世界时,你还应该开门出去看看,是否真的如此。如果你有信心,你对前途就不犹豫了。如果你有勇气,你就不怕前途是否有困难或危险了每个人心中都应有两盏灯,一盏是希望的灯,一盏是勇气的灯。有了这两盏灯,我们就不怕海上的黑暗和风涛的险恶了。人的一生很像是在雾中行走。远远望去,只是迷蒙一片,辨不出方向和吉凶。可是,当你鼓起勇气,放下恐惧和怀疑,一步一步向前走去的时候,你就会发现,每走一步,你都能把下一步路看得清楚一点。“往前走,别站在远远的地方观望!”你就可以找到你的方向。','upload/aboutus_picture1.jpg','upload/aboutus_picture2.jpg','upload/aboutus_picture3.jpg');
/*!40000 ALTER TABLE `aboutus` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `config`
--
DROP TABLE IF EXISTS `config`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `config` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(100) NOT NULL COMMENT '配置参数名称',
`value` varchar(100) DEFAULT NULL COMMENT '配置参数值',
`url` varchar(500) DEFAULT NULL COMMENT 'url',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='配置文件';
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `config`
--
LOCK TABLES `config` WRITE;
/*!40000 ALTER TABLE `config` DISABLE KEYS */;
INSERT INTO `config` VALUES (1,'picture1','upload/picture1.jpg',NULL),(2,'picture2','upload/picture2.jpg',NULL),(3,'picture3','upload/picture3.jpg',NULL);
/*!40000 ALTER TABLE `config` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `discusslvyouxinxi`
--
DROP TABLE IF EXISTS `discusslvyouxinxi`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `discusslvyouxinxi` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`addtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`refid` bigint(20) NOT NULL COMMENT '关联表id',
`userid` bigint(20) NOT NULL COMMENT '用户id',
`avatarurl` longtext COMMENT '头像',
`nickname` varchar(200) DEFAULT NULL COMMENT '用户名',
`content` longtext NOT NULL COMMENT '评论内容',
`reply` longtext COMMENT '回复内容',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='lvyouxinxi评论表';
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `discusslvyouxinxi`
--
LOCK TABLES `discusslvyouxinxi` WRITE;
/*!40000 ALTER TABLE `discusslvyouxinxi` DISABLE KEYS */;
/*!40000 ALTER TABLE `discusslvyouxinxi` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `discusszhoubianmeishi`
--
DROP TABLE IF EXISTS `discusszhoubianmeishi`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `discusszhoubianmeishi` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`addtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`refid` bigint(20) NOT NULL COMMENT '关联表id',
`userid` bigint(20) NOT NULL COMMENT '用户id',
`avatarurl` longtext COMMENT '头像',
`nickname` varchar(200) DEFAULT NULL COMMENT '用户名',
`content` longtext NOT NULL COMMENT '评论内容',
`reply` longtext COMMENT '回复内容',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='周边美食评论表';
/*!40101 SET character_set_client = @saved_cs_client */;
系统效果图
文章目录
目 录
第一章 绪 论 1
1.1研究背景与意义 1
1.2系统研究现状 1
1.3 研究的主要内容 2
第二章 开发工具和开发技术 3
2.1 Python语言 3
2.2 Django框架 3
2.3 Hadoop介绍 3
2.4 Scrapy介绍 3
2.5 MYSQL数据库 4
2.6 B/S架构 4
第三章 需求分析 5
3.1 需求描述 5
3.2系统可行性分析 5
3.2.1技术可行性分析 5
3.2.2 经济可行性分析 5
3.2.3 环境运行可行性分析 6
3.2.4 法律可行性分析 6
3.3 系统功能需求分析 6
3.4 非功能性需求分析 7
3.5 系统流程分析 7
3.5.1 登录流程 7
3.5.2 添加流程 8
3.5.3 删除信息流程 8
3.6 本章小结 9
第四章 系统设计 10
4.1 系统总体设计 10
4.2 数据库设计 10
4.2.1 数据库逻辑设计 10
4.2.2 数据库表设计 11
4.3 本章小结 12
第五章 详细设计与实现 13
5.1系统登录注册实现 13
5.2管理员功能实现 14
5.3用户功能实现 17
5.4 本章小结 17
第六章 系统测试 18
6.1 测试目的 18
6.2 测试用例 18
6.3 本章小结 19
结 论 20
参考文献 21
致 谢 22