☰
基于机器学习的商品评论分析系统:爬虫与情感分析实战
2026/9/28 7:22:36 网站建设 项目流程

简介:这是一套面向计算机相关专业学生与初学者的机器学习实战项目源码,以商品评论分析为完整案例,串联网络爬虫与文本情感分析两条主线。爬虫部分基于selenium抓取京东评论,并针对淘宝反爬机制采用已有链接采集策略;情感分析同时实现情感词典与SnowNLP两种方案,后者在准确率与召回率上表现更优,最终通过tkinter图形界面整合,用户输入商品链接即可爬取评论、表格展示、词云可视化并统计好评差评数量。资源包共906个文件,以401个py源码、392个pyc字节码、25个pyd扩展及17个exe可执行文件为主,另含csv评论样本、txt说明、jpg截图与xml配置等,压缩包约18.79MB,目录结构清晰便于按模块学习。已有392人学习下载,适合课程设计、毕业设计或项目立项演示,也可在现有代码基础上二次开发扩展功能。

1. 从一份课程设计拆起:这套商品评论分析系统到底能跑出什么

京东商品页链接粘进去,评论表格刷出来,词云图跟着渲染,好评差评数字直接统计——这套基于机器学习的商品评论分析系统,干的就是把「爬评论」和「判情感」两件事串成一条流水线。资源包里带了完整源代码、文档说明,还有手机、牙刷、运动鞋、洗衣粉四个品类的 CSV 样本数据,以及activate.bat、pyvenv.cfg这套虚拟环境配置。说白了,它不是一个玩具 demo,而是一个能直接跑通「输入链接→爬取→展示→分析」闭环的课程设计级项目,答辩平均分 94.5 不是白给的。

适合谁?计算机、人工智能、通信工程这些专业的在校生拿来做课设或毕设底子,企业里想快速验证评论分析流程的也能拿来改。它解决的核心痛点是:你不用从零搭爬虫框架、不用自己标情感词典、不用纠结 GUI 怎么串逻辑,代码里已经跑通了一条可复现的路径。接下来我按「资源里有什么→怎么装怎么跑→爬虫和情感分析怎么改→坑在哪」的顺序拆一遍。

2. 资源结构与运行环境:venv 配置和四份 CSV 怎么用

2.1 先看清目录里有什么,别急着 pip install

拿到包先别双击activate.bat。资源根目录下这几个文件决定了你能不能一次跑通:activate和activate.bat是虚拟环境激活脚本,deactivate.bat负责退出,sysconfig.cfg和pyvenv.cfg是 Python 虚拟环境的配置文件,记录了解释器路径和版本信息。四份 CSV——手机.csv、牙刷.csv、运动鞋.csv、洗衣粉.csv——是已经爬好的评论样本,用来在你还没跑爬虫时先验证情感分析模块能不能出结果。test.csv通常是测试用的小批量数据。

我一般会先做一件事:确认pyvenv.cfg里的home指向的 Python 路径在你机器上存在。这个文件长这样:

home = C:\Users\你的用户名\AppData\Local\Programs\Python\Python39 include-system-site-packages = false version = 3.9.0

如果home路径不对,激活脚本会直接报错退出。改法很简单,把home改成你本机 Python 安装目录,version保持大版本一致即可。注意 Python 3.9 和 3.10 在 tkinter 和 SnowNLP 依赖上表现基本一致,但 3.12 之后部分老版本 SnowNLP 会有兼容问题,建议就用 3.9 或 3.10。

2.2 激活环境与依赖安装的完整命令

Windows 下双击activate.bat或者在命令行里执行:

# 进入项目根目录后激活虚拟环境 activate.bat # 确认激活成功,命令行前面会出现环境名 python --version # 安装核心依赖,版本按资源文档说明里的来 pip install snownlp selenium jieba wordcloud matplotlib pandas tkinter

这里有几个参数要说明。snownlp是情感分析主力,它自带一个基于购物评论训练的模型,对电商短文本的准确率比通用情感词典高不少,这也是摘要里说「SnowNLP 准确率和召回率较高」的原因。selenium负责驱动浏览器爬京东评论,需要配合 ChromeDriver 使用。jieba做中文分词,wordcloud生成词云,matplotlib负责把词云画出来,tkinter是 GUI 框架,Python 自带但部分精简版系统需要单独装。

提示:如果你用的是 Anaconda,tkinter一般已内置,不用重复装;如果 pip 装tkinter报错,说明你的 Python 是精简版,换官方完整版安装包重装即可。

2.3 用 CSV 样本先验证分析链路,再碰爬虫

新手最容易犯的错是一上来就跑爬虫,结果 selenium 版本不对、驱动没配、京东页面结构变了,卡半天连一条评论都没爬到,直接劝退。正确顺序是先用现成 CSV 把情感分析跑通。下面这段代码读手机.csv并调用 SnowNLP 做情感打分:

import pandas as pd from snownlp import SnowNLP # 读取已爬好的评论样本,注意编码,Windows 下常见 gbk df = pd.read_csv('手机.csv', encoding='gbk') comments = df['评论内容'].dropna().tolist() pos, neg = 0, 0 for c in comments: score = SnowNLP(str(c)).sentiments # 返回 0~1 的情感值 if score > 0.5: pos += 1 else: neg += 1 print(f'好评 {pos} 条,差评 {neg} 条,好评率 {pos/(pos+neg):.2%}')

逻辑说明:SnowNLP(text).sentiments返回一个 0 到 1 的浮点数,越接近 1 越正面。阈值 0.5 是默认分界,实际项目里可以根据业务调整——比如差评容忍度低的场景可以设 0.6,把中性偏负的都归到差评侧。encoding='gbk'是因为这些 CSV 大概率是在 Windows 下用 Excel 保存的,UTF-8 读取会乱码,如果报UnicodeDecodeError就换gb18030再试。

这一步跑通,说明你的 Python 环境、SnowNLP、pandas 都没问题,再去折腾 selenium 爬虫才有意义。

3. 爬虫模块拆解:selenium 爬京东与淘宝链接的边界

3.1 京东评论爬取的 selenium 驱动配置

资源里爬京东用的是 selenium,核心思路是模拟浏览器打开商品页,滚动加载评论区域,抓取评论 DOM 节点文本。先看驱动配置部分:

from selenium import webdriver from selenium.webdriver.chrome.options import Options opts = Options() opts.add_argument('--headless') # 无头模式,不弹浏览器窗口 opts.add_argument('--disable-gpu') # 禁用 GPU 加速,避免部分环境崩溃 opts.add_argument('--no-sandbox') # 容器或权限受限环境需要 opts.add_argument('--window-size=1920,1080') driver = webdriver.Chrome(options=opts) driver.get('https://item.jd.com/商品ID.html')

参数逐个说:--headless让浏览器后台跑,适合服务器或不想被弹窗干扰的场景,但调试阶段建议先注释掉,能看到页面才知道卡在哪。--disable-gpu在 Windows 上一般不需要,但加上不影响。--no-sandbox在 Linux 容器里必须加,Windows 下可省。--window-size设大一点是为了让评论区的懒加载触发更完整,窗口太小会导致部分评论不渲染。

驱动版本必须和本机 Chrome 大版本匹配,Chrome 120 就下 ChromeDriver 120,版本错位会直接抛SessionNotCreatedException。这是 selenium 最经典的翻车点,没有之一。

3.2 淘宝评论为什么只能按链接爬

摘要里写得很直白:淘宝反爬措施到位,目前只能根据已有评论链接爬取。这不是代码写得差,是淘宝的登录态校验、滑块验证、请求签名机制叠在一起,纯 selenium 模拟很难稳定绕过。资源里的做法是:你手动拿到某条评论的详情链接,代码去请求那个链接解析评论,而不是从商品页自动翻页爬全量。

常见做法是维护一个链接列表,循环请求:

import time from selenium.common.exceptions import NoSuchElementException comment_links = [ 'https://rate.taobao.com/detail.htm?xxx', # 更多评论链接 ] all_comments = [] for link in comment_links: driver.get(link) time.sleep(2) # 等页面渲染,太短抓不到,太长效率低 try: items = driver.find_elements('css selector', '.comment-content') for it in items: all_comments.append(it.text) except NoSuchElementException: print(f'链接解析失败:{link}')

time.sleep(2)是经验值,淘宝评论页渲染大概 1 到 3 秒,设 2 秒能覆盖大部分情况。find_elements用 CSS 选择器定位评论内容节点,这个选择器会随淘宝改版失效,如果抓不到就打开开发者工具重新确认 class 名。注意这里没有做翻页,因为淘宝评论翻页需要登录态和签名参数,资源里没覆盖这块,属于已知边界。

3.3 爬取结果落盘与字段设计

爬完的评论要存成 CSV 供后续分析,字段设计直接影响情感分析能不能跑。建议至少保留三列:

字段名含义示例
评论内容评论文本主体手机手感不错,续航给力
评分用户打星5
时间评论发布时间2024-03-15
import pandas as pd df = pd.DataFrame(all_comments, columns=['评论内容']) df['评分'] = '' # 如果页面能抓到评分就填,抓不到留空 df.to_csv('新爬取评论.csv', index=False, encoding='utf-8-sig')

encoding='utf-8-sig'是为了 Excel 打开不乱码,比纯utf-8多一个 BOM 头。如果你后续只用 pandas 读,用utf-8也行,但既然要给人看,加 sig 更省心。字段里「评分」列如果爬不到就留空,SnowNLP 只依赖文本,不依赖评分,不影响分析。

4. 情感分析双路对比:情感词典与 SnowNLP 怎么选

4.1 情感词典法的实现与局限

资源里做了两套情感分析,一套是情感词典,一套是 SnowNLP。情感词典法的逻辑是:准备一个正面词表和负面词表,对评论分词后统计命中词数,正面词多于负面词判好评,反之判差评。

import jieba pos_words = set(['好', '棒', '满意', '喜欢', '推荐', '给力']) neg_words = set(['差', '烂', '失望', '退货', '垃圾', '卡']) def dict_sentiment(text): words = jieba.lcut(str(text)) p = sum(1 for w in words if w in pos_words) n = sum(1 for w in words if w in neg_words) if p > n: return '好评' elif n > p: return '差评' return '中性'

逻辑很直白,但局限也明显:词表覆盖不全就漏判,「不推荐」这种带否定词的会被误判成正面(因为命中了「推荐」)。而且电商评论里大量口语化表达、反讽、谐音,词典法基本抓不住。所以资源里把它作为对照方案,主力还是 SnowNLP。

4.2 SnowNLP 情感打分的调用与阈值调整

SnowNLP 自带一个朴素贝叶斯模型,训练语料就是购物评论,所以对「手机续航崩了」「牙刷毛太硬」这类句子判断比词典准得多。调用就一行:

from snownlp import SnowNLP text = '手机手感不错,但是续航太差了' score = SnowNLP(text).sentiments print(score) # 输出类似 0.42

这个 0.42 表示模型认为整体偏负面,因为「续航太差」的负面权重压过了「手感不错」的正面权重。阈值默认 0.5,但实际用的时候我一般会看分布:如果大部分评论得分集中在 0.3 到 0.7 之间,说明模型对这批数据区分度不高,可以画个直方图确认,再决定阈值往哪偏。

import matplotlib.pyplot as plt scores = [SnowNLP(str(c)).sentiments for c in comments] plt.hist(scores, bins=20) plt.title('情感得分分布') plt.show()

如果分布是双峰,说明好评差评分得开,0.5 阈值够用;如果挤在中间,要么换模型,要么接受「中性」这个第三类,别硬分好坏。

4.3 两种方法的结果对比与选型建议

拿同一批手机.csv数据跑两套方法,对比一下:

方法好评数差评数特点
情感词典偏多偏少漏判负面,否定词处理差
SnowNLP较均衡较均衡召回率高,但偶有误判

选型建议:如果只是课设演示,SnowNLP 一套就够,代码少、效果稳。如果要做对比实验写论文,两套都跑,用准确率和召回率说话。资源里两套都留了,方便你按需取用。注意 SnowNLP 对超短评论(比如「好」「差」)判断也一般,因为模型依赖上下文,单字输入信息量不够。

5. 避坑与常见问题排查:从驱动版本到编码乱码

5.1 现象:selenium 启动报 SessionNotCreatedException

原因:ChromeDriver 版本和本机 Chrome 大版本不匹配,或者 driver 不在 PATH 里。解决:打开 Chrome 设置看版本号,去 ChromeDriver 官网下对应大版本,把 driver 可执行文件放到项目目录或加入系统 PATH。别用「最新版 driver 配旧版 Chrome」,必崩。

5.2 现象:CSV 读取报 UnicodeDecodeError

原因:文件编码是 gbk 或 gb18030,代码里用了 utf-8。解决:pd.read_csv的encoding参数改成gbk,还报错就换gb18030。反过来,如果文件是 utf-8 你用了 gbk,也会报错,两个都试一遍最快。

5.3 现象:词云生成全是方框

原因:wordcloud 默认字体不支持中文,找不到中文字体路径。解决:指定font_path参数,Windows 下一般用C:/Windows/Fonts/simhei.ttf,Mac 下用/System/Library/Fonts/PingFang.ttc。不指定字体,中文词云就是一堆豆腐块。

5.4 现象:tkinter 界面能开但按钮点了没反应

原因:GUI 主循环里做了耗时操作(比如爬虫请求),阻塞了事件循环。解决:把爬虫和情感分析放到独立线程里跑,用threading.Thread包一层,主线程只负责界面刷新。这是 tkinter 的经典坑,同步跑爬虫界面必卡死。

5.5 现象:SnowNLP 对某些评论打分明显反了

原因:模型训练语料和你的实际评论领域不匹配,比如用购物评论模型去判数码产品专业评测。解决:要么接受误差,要么用snownlp提供的训练接口拿自己的标注数据微调模型。资源里没带微调脚本,但 SnowNLP 官方文档有示例,属于进阶操作。

6. 进阶改造与验证:把词云和统计接进 tkinter 主流程

6.1 用线程池把爬虫和 GUI 解耦

原始代码里爬虫和界面大概率是串行写的,点一下按钮界面就假死。改造思路是把爬取和分析包成一个函数,丢进线程执行,完成后用after回调刷新界面:

import threading import tkinter as tk def start_analysis(): url = entry.get() threading.Thread(target=run_pipeline, args=(url,), daemon=True).start() def run_pipeline(url): comments = crawl_comments(url) # 爬虫 pos, neg = analyze(comments) # 情感分析 root.after(0, lambda: update_ui(comments, pos, neg)) # 回主线程刷界面 root = tk.Tk() entry = tk.Entry(root) tk.Button(root, text='开始分析', command=start_analysis).pack() root.mainloop()

daemon=True保证主窗口关闭时子线程跟着退出,不会残留进程。root.after(0, ...)是 tkinter 里跨线程更新界面的标准做法,直接在其他线程操作控件会出玄学 bug。

6.2 词云参数调优与统计结果落盘

词云不是词越多越好,max_words设 100 到 200 比较合适,太多会糊成一团。background_color设白色方便贴文档。统计结果除了界面显示,建议同时写一份 CSV,方便写报告时引用:

from wordcloud import WordCloud text_all = ' '.join(comments) wc = WordCloud( font_path='C:/Windows/Fonts/simhei.ttf', max_words=150, background_color='white', width=800, height=500 ).generate(text_all) wc.to_file('评论词云.png') with open('统计结果.txt', 'w', encoding='utf-8') as f: f.write(f'好评:{pos}\n差评:{neg}\n好评率:{pos/(pos+neg):.2%}')

6.3 验证方法:拿已知倾向的评论做回归测试

改完代码怎么确认没改坏?我一般会准备一小批「已知答案」的评论,比如「质量很好下次还买」应该判好评,「用两天就坏了」应该判差评,跑一遍看结果对不对。这批数据不用多,十条就够,但每次改完情感分析逻辑都跑一次,能快速发现阈值调歪了或者模型加载错了。这个习惯是从一次答辩前夜改崩代码的血泪经验里养成的,从那以后我每次动核心逻辑都强制走一遍回归测试。

希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询