1. 项目背景与核心价值
在本地生活服务领域,餐饮商户的线上点评数据蕴含着巨大的商业价值。作为美团平台上的第三方开发者,我们经常需要处理海量商户评价数据,但官方API往往存在调用限制和功能缺失。这个基于Python Flask框架开发的系统,正是为了解决以下痛点:
- 数据采集困境:美团网页端对点评数据的反爬措施日益严格,直接爬取容易被封IP
- 分析维度单一:平台自带的数据看板无法满足深度运营需求(如情感分析、关键词提取)
- 管理效率低下:商户需要同时处理多个平台的评价,缺乏统一管理界面
这个系统通过Flask提供Web管理界面,集成以下核心功能模块:
python复制# 系统架构示意
app = Flask(__name__)
app.register_blueprint(data_crawler) # 数据采集模块
app.register_blueprint(analysis) # 数据分析模块
app.register_blueprint(visualization) # 可视化模块
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术栈选型与配置
2.1 为什么选择Flask?
相比Django等全功能框架,Flask的轻量级特性更适合这个项目:
- 灵活性:可以自由组合扩展库(如爬虫用Scrapy-Splash,分析用Pandas)
- 低开销:商户端服务器通常配置较低,Flask内存占用更友好
- 快速原型:路由定义和模板渲染更加直观
提示:实际部署时建议搭配Gunicorn+Gevent提升并发性能,配置示例:
bash复制gunicorn -w 4 -k gevent -b 0.0.0.0:5000 app:app
2.2 必备Python库清单
通过requirements.txt管理依赖:
text复制flask==2.3.2
flask-sqlalchemy==3.0.3
pandas==2.0.3
jieba==0.42.1 # 中文分词
snownlp==0.12.3 # 情感分析
selenium==4.10.0 # 动态页面渲染
安装时建议使用清华源加速:
bash复制pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
3. 核心功能实现细节
3.1 点评数据采集方案
由于美团对API调用有严格限制,我们采用混合采集策略:
- 基础信息获取:通过美团开放平台官方API(需申请开发者资质)
- 点评内容抓取:基于Selenium的自动化方案
python复制from selenium.webdriver import ChromeOptions
options = ChromeOptions()
options.add_argument("--headless") # 无界面模式
driver = webdriver.Chrome(options=options)
driver.get("https://www.meituan.com/meishi/12345/") # 示例商户页
# 使用显式等待应对动态加载
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CLASS_NAME, "comment-list"))
)
重要:必须设置合理的采集间隔(建议≥5秒/次),并在headers中添加真实User-Agent
3.2 数据存储设计
使用MySQL+Redis组合方案:
- 结构化数据:商户信息、用户基础数据用MySQL存储
- 非结构化数据:点评原文、图片链接存入MongoDB
- 缓存层:Redis缓存热门商户的统计结果
表结构示例:
sql复制CREATE TABLE `merchant_reviews` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`merchant_id` varchar(20) NOT NULL COMMENT '美团商户ID',
`user_id` varchar(32) NOT NULL,
`content` text NOT NULL,
`rating` tinyint(1) NOT NULL COMMENT '1-5星评分',
`sentiment_score` float DEFAULT NULL COMMENT '情感分析得分',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_merchant` (`merchant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
3.3 情感分析实现
使用SnowNLP结合自定义词典提升餐饮领域准确率:
python复制from snownlp import SnowNLP
# 加载餐饮领域词典
with open('catering_words.txt', encoding='utf-8') as f:
custom_words = [line.strip() for line in f]
def analyze_sentiment(text):
s = SnowNLP(text)
s.words = custom_words + s.words # 合并词典
return s.sentiments
实测准确率对比:
| 方案 | 通用语料准确率 | 加入餐饮词典后 |
|---|---|---|
| 好评识别 | 78.2% | 89.7% |
| 差评识别 | 82.1% | 93.4% |
4. 可视化与报表生成
4.1 动态看板实现
使用ECharts+Flask模板渲染:
python复制@app.route('/dashboard/<merchant_id>')
def dashboard(merchant_id):
data = get_analysis_data(merchant_id) # 从数据库获取处理好的数据
return render_template('dashboard.html',
rating_dist=data['ratings'],
wordcloud=data['keywords'])
前端关键代码(基于Bootstrap+ECharts):
javascript复制// 评分分布饼图
let chart = echarts.init(document.getElementById('chart'));
chart.setOption({
series: [{
type: 'pie',
data: [
{value: {{ rating_dist.5 }}, name: '五星'},
{value: {{ rating_dist.4 }}, name: '四星'},
// ...其他数据
]
}]
});
4.2 自动周报生成
结合Jinja2模板引擎生成PDF报告:
python复制from weasyprint import HTML
def generate_weekly_report(merchant_id):
data = get_weekly_data(merchant_id)
html = render_template('report_template.html', data=data)
HTML(string=html).write_pdf(f'reports/{merchant_id}.pdf')
报告模板示例片段:
html复制<div class="section">
<h3>本周差评关键词TOP5</h3>
<ul>
{% for word in data.top_negative_words %}
<li>{{ word.text }} (出现次数: {{ word.count }})</li>
{% endfor %}
</ul>
</div>
5. 部署与性能优化
5.1 生产环境配置
推荐使用Docker Compose部署:
yaml复制version: '3'
services:
web:
build: .
ports:
- "5000:5000"
depends_on:
- redis
- mysql
redis:
image: redis:alpine
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: example
5.2 性能提升技巧
- SQL查询优化:
python复制# 错误做法:N+1查询
reviews = Merchant.query.get(id).reviews.all()
for r in reviews:
print(r.user.username) # 每次循环都查询user表
# 正确做法:join预加载
reviews = (db.session.query(Review)
.options(joinedload(Review.user))
.filter_by(merchant_id=id).all())
- 缓存策略:
python复制from flask_caching import Cache
cache = Cache(config={'CACHE_TYPE': 'RedisCache'})
@app.route('/stats/<merchant_id>')
@cache.cached(timeout=3600, key_prefix='merchant_stats')
def get_stats(merchant_id):
return compute_heavy_analysis(merchant_id)
6. 常见问题解决方案
6.1 反爬虫应对措施
当遇到验证码或IP封锁时:
- 使用付费代理IP轮询(推荐Luminati等专业服务)
- 添加随机操作延迟:
python复制import random
from time import sleep
def random_delay():
sleep(random.uniform(1, 5)) # 1-5秒随机延迟
- 模拟真实浏览器指纹:
python复制options.add_argument("--disable-blink-features=AutomationControlled")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
6.2 数据不一致处理
建立数据校验机制:
python复制def check_data_quality(review):
if len(review['content']) < 5 and review['rating'] == 5:
raise ValueError("疑似虚假好评")
if '美团' in review['content'] and '券' in review['content']:
return False # 过滤广告评价
return True
7. 项目扩展方向
- 竞品对比分析:接入饿了么等平台数据
- 预警系统:当差评率突增时触发企业微信通知
- 回复建议:基于NLP生成回复话术草稿
python复制def generate_reply(review):
if review.sentiment < 0.3:
return f"非常抱歉给您带来不好的体验,{review.keywords[0]}问题我们已记录"
else:
return "感谢您的认可,我们会继续努力!"
这个系统在我们团队已稳定运行8个月,日均处理10万+条点评数据。最实用的三个经验:
- 一定要做请求频率控制,我们曾因高频访问被封禁账号
- 情感分析模型需要定期用新数据retrain
- 前端表格一定要做分页,超过500条数据时浏览器会明显卡顿
