技术栈
- 开发语言:Python 3.8
- Web 框架:Flask
- 数据库:MySQL 5.7
- 数据库工具:Navicat 12
- 开发环境:PyCharm
- 爬虫框架:Scrapy
系统功能概述
系统采用 B/S(浏览器/服务器)架构,核心功能包括系统首页、个人中心、用户管理、景点信息管理、景点类型管理、景点门票管理、在线反馈及系统管理等模块。通过智能化手段降低运营成本,提高信息处理速度和精确度。
界面展示
系统首页

景点与门票信息

管理与反馈
基于 Python 和 Flask 框架开发的旅游景点推荐系统,采用 MySQL 数据库存储数据。系统包含首页展示、个人中心、用户管理、景点及门票信息管理、在线反馈等功能模块。后端使用 Scrapy 爬虫采集景点数据,结合 B/S 架构实现智能化信息管理。旨在降低人工成本,提高数据处理速度与精确度,实现景点推荐的标准化与程序化管理。

系统采用 B/S(浏览器/服务器)架构,核心功能包括系统首页、个人中心、用户管理、景点信息管理、景点类型管理、景点门票管理、在线反馈及系统管理等模块。通过智能化手段降低运营成本,提高信息处理速度和精确度。



微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online



系统使用 Scrapy 框架采集景点门票数据,包含标题、价格、描述、位置、评分等信息。以下为部分核心代码逻辑:
# 景点门票爬虫类 JingdianmenpiaoSpider
class JingdianmenpiaoSpider(scrapy.Spider):
name = 'jingdianmenpiaoSpider'
spiderUrl = 'https://piao.qunar.com/ticket/list.htm?keyword=%E4%B8%89%E4%B8%9A®ion=%E4%B8%89%E4%B8%9A&from=mpshouye_hotcity&page={}'
start_urls = spiderUrl.split(";")
headers = {
# 此处为示例 Cookie,实际使用时请替换有效凭证
"cookie": "SECKEY_ABVK=..."
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def start_requests(self):
plat = platform.system().lower()
if plat in ['linux', 'windows']:
connect = self.db_connect()
cursor = connect.cursor()
if self.table_exists(cursor, '2nn2j_jingdianmenpiao') == 1:
cursor.close()
connect.close()
self.temp_data()
return
pageNum = 2
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, headers=self.headers, 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
list = response.css('div#search-list div[class~="sight_item"]')
for item in list:
fields = JingdianmenpiaoItem()
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:
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}, headers=self.headers, callback=self.detail_parse)
def detail_parse(self, response):
fields = response.meta['fields']
try:
fields["biaoti"] = self.remove_html(response.css('''div.mp-description-detail div.mp-description-view span.mp-description-name::text''').extract_first())
fields["fengmian"] = self.remove_html(response.css('''div#mp-slider-content div.mp-description-image img::attr(src)''').extract_first())
fields["miaoshu"] = self.remove_html(response.css('''div.mp-description-onesentence::text''').extract_first())
fields["weizhi"] = self.remove_html(response.css('''span.mp-description-address::text''').extract_first())
fields["dianping"] = self.remove_html(response.css('''span#mp-description-commentscore''').extract_first())
fields["pinglun"] = self.remove_html(response.css('''span.mp-description-commentCount a::text''').extract_first())
fields["tese"] = self.remove_html(response.css('''div.mp-charact-intro div.mp-charact-desc''').extract_first())
fields["kaifangshijian"] = self.remove_html(response.css('''div.mp-charact-content div.mp-charact-desc''').extract_first())
except:
pass
return fields
def remove_html(self, html):
if html is 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
系统测试贯穿整个开发周期,涵盖功能、数据及硬件检测。通过测试发现并修复需求矛盾,确保软件符合预期。
项目整体达到设计目的,实现了景点信息的智能化推荐与管理。后续可进一步优化算法精度,丰富系统功能。开发过程中注重细节与耐心,提升了工程实践能力。