电商评论数据爬虫:情感分析与数据可视化实战

0 阅读15分钟

 

在电商运营、产品迭代、用户需求分析中,商品评论是最具价值的原生数据——它直接承载了用户对产品质量、功能、服务的真实反馈,既藏着用户痛点,也能为运营决策提供精准依据。但海量电商评论分散在各个商品详情页,手动采集、分析效率极低,且无法挖掘评论背后的情感倾向与核心规律。

本文将以「实战」为核心,从零搭建一套电商评论数据爬虫,完成数据采集、清洗、情感分析,最终通过可视化呈现分析结果,全程使用Python实现,兼顾零基础友好性与实战落地性,避开反爬坑点、规范数据采集,让你既能拿到可用数据,也能读懂数据背后的意义。

前置说明:本文爬虫仅用于个人学习、非商业用途,采集过程严格遵循robots协议,不高频请求、不获取敏感信息,全程演示合规采集流程;涉及的第三方库均为Python开源工具,可直接通过pip安装。

一、实战准备:环境搭建与工具选型

核心需求拆解:① 高效采集电商商品评论(以主流电商平台为例,适配评论分页、反爬基础策略);② 对评论进行情感分析(区分正面、负面、中性评价,挖掘核心情感关键词);③ 数据可视化(将分析结果以图表形式呈现,直观易懂)。

1.1 开发环境

Python 3.8+(推荐3.9版本,兼容性更好),开发工具可选用PyCharm、VS Code,无需复杂配置,安装对应第三方库即可启动开发。

1.2 核心第三方库选型(附安装命令)

  • requests:发送HTTP请求,采集评论页面数据(核心爬虫库,轻量高效);
  • BeautifulSoup4:解析HTML页面,提取评论内容、用户昵称、评分等关键信息;
  • pandas:数据清洗、整理(处理缺失值、去重、格式标准化);
  • jieba:中文分词(拆分评论句子,为情感分析做准备);
  • snownlp:中文情感分析(轻量化工具,适合快速实现情感倾向判断,无需复杂训练);
  • matplotlib + seaborn:数据可视化(绘制柱状图、饼图、词云等,美化图表样式);
  • wordcloud:生成词云图(直观展示评论核心关键词);
  • fake_useragent:生成随机User-Agent,规避基础反爬(模拟浏览器请求,降低被封概率)。

安装命令(复制到终端执行,一键安装所有依赖):

pip install requests beautifulsoup4 pandas jieba snownlp matplotlib seaborn wordcloud fake_useragent

1.3 合规与反爬前置准备

主流电商平台均有反爬机制,为避免请求被拦截、账号受限,提前做好以下准备:

  1. 设置请求间隔:每采集1页评论,暂停1-3秒(使用time.sleep()实现),避免高频请求;
  2. 随机User-Agent:通过fake_useragent生成不同浏览器的User-Agent,避免固定请求头被识别;
  3. 遵循robots协议:访问目标电商平台的robots.txt文件,确认评论页面是否允许爬取,不采集禁止访问的内容;
  4. 限制采集量:个人学习用途,采集单款商品1000条以内评论即可,不进行大规模、批量采集。

二、核心实战一:电商评论数据爬虫搭建(全程可复制)

本文以某主流电商平台商品评论为例(页面结构具有通用性,其他平台可参考修改解析规则),爬虫核心流程:确定评论接口/页面 → 发送请求获取数据 → 解析页面提取关键信息 → 数据保存到本地(CSV格式,便于后续分析)。

2.1 分析评论页面结构

  1. 打开目标商品详情页,找到「评论区」,通过浏览器「开发者工具」(F12)查看网络请求:
  • 切换到「Network」选项卡,刷新评论页面,找到包含评论数据的请求(通常为XHR类型,或直接在HTML页面中嵌入);

  • 查看请求URL、请求头(Headers),确认评论数据的加载方式(分页加载:通过page参数控制页码,每页固定显示20/30条评论)。

  1. 关键观察:评论数据要么嵌入在HTML页面的特定标签中(可通过BeautifulSoup解析),要么通过AJAX接口返回JSON格式数据(解析更高效);本文以HTML页面解析为例,JSON接口解析可参考文末拓展。

2.2 编写爬虫核心代码(分步骤实现,可直接复制运行)

步骤1:导入所需库,设置基础配置(请求头、请求间隔、目标URL)



`import requests from bs4 import BeautifulSoup import pandas as pd import time from fake_useragent import UserAgent # 基础配置 ua = UserAgent() # 随机生成User-Agent target_url = "https://xxx.com/item/xxx#comment" # 替换为目标商品评论页URL(需包含评论分页参数) page_count = 10 # 采集页数,每页约20条,共200条评论(可修改) sleep_time = 2 # 请求间隔,2秒/页 comment_list = [] # 存储所有评论数据`

步骤2:定义爬虫函数,发送请求、解析评论数据



`def crawl_comment(page): # 构造请求头,模拟浏览器请求 headers = { "User-Agent": ua.random, "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Referer": target_url, # Referer参数,规避部分反爬 "Cookie": "xxx" # 可选:若评论需要登录才能查看,可添加浏览器Cookie(仅个人使用) } # 构造分页URL(根据目标平台分页规则修改,此处为示例) page_url = f"{target_url}?page={page}" try: # 发送GET请求 response = requests.get(page_url, headers=headers, timeout=10) response.encoding = "utf-8" # 设置编码,避免中文乱码 if response.status_code == 200: # 解析HTML页面 soup = BeautifulSoup(response.text, "lxml") # 找到评论列表标签(需根据目标平台页面结构修改class/id,关键一步) comments = soup.find_all("div", class_="comment-item") # 替换为实际评论标签的class for comment in comments: # 提取关键信息:用户昵称、评论内容、评分、评论时间(按需提取) try: nickname = comment.find("span", class_="nickname").get_text().strip() # 用户名 content = comment.find("div", class_="comment-content").get_text().strip() # 评论内容 score = comment.find("span", class_="score").get_text().strip() # 商品评分(1-5星) comment_time = comment.find("span", class_="comment-time").get_text().strip() # 评论时间 # 将提取的数据存入列表 comment_list.append({ "nickname": nickname, "content": content, "score": score, "comment_time": comment_time }) except Exception as e: # 跳过解析失败的评论,避免程序中断 print(f"单条评论解析失败:{e}") print(f"第{page}页评论采集完成,共采集{len(comments)}条") time.sleep(sleep_time) # 暂停,规避反爬 else: print(f"请求失败,状态码:{response.status_code}") except Exception as e: print(f"爬虫请求异常:{e}") time.sleep(sleep_time * 2) # 异常时延长暂停时间`

步骤3:批量采集多页评论,保存到CSV文件



`# 循环采集多页评论 for page in range(1, page_count + 1): crawl_comment(page) # 将采集到的评论数据转换为DataFrame,保存到CSV文件 if comment_list: df = pd.DataFrame(comment_list) # 数据去重(去除重复评论) df = df.drop_duplicates(subset=["content"], keep="first") # 保存到本地(当前目录下,可修改路径) df.to_csv("ecommerce_comment.csv", index=False, encoding="utf-8-sig") print(f"评论采集完成!共采集有效评论{len(df)}条,已保存到ecommerce_comment.csv") else: print("未采集到任何评论,请检查URL、解析规则或反爬设置")`

2.3 爬虫常见问题排查

  • 问题1:请求成功但解析不到评论?—— 检查BeautifulSoup的find/find_all参数(class/id是否正确),可通过浏览器开发者工具复制标签的实际class;部分平台评论采用动态渲染(JavaScript加载),需改用Selenium或Playwright(文末拓展)。
  • 问题2:请求被拦截(状态码403/503)?—— 增加请求间隔、更换User-Agent,若需要登录,添加浏览器Cookie(仅个人使用,不可泄露),避免频繁刷新。
  • 问题3:中文乱码?—— 设置response.encoding = "utf-8",保存CSV时使用encoding="utf-8-sig"(兼容Excel打开)。

三、核心实战二:评论数据清洗与情感分析

采集到的评论数据存在大量噪音(如无意义评论、表情符号、特殊字符),需先进行清洗,再通过snownlp实现情感分析,判断每条评论的情感倾向(正面/负面/中性)。

3.1 数据清洗(去除噪音,标准化数据)

核心目标:去除空评论、重复评论、特殊字符,简化评论内容,为分词和情感分析减负,代码可直接衔接爬虫结果运行。

import re # 读取采集到的评论数据 df = pd.read_csv("ecommerce_comment.csv") # 1. 去除空值(评论内容为空的记录) df = df.dropna(subset=["content"]) # 2. 去除重复评论(再次去重,确保数据干净) df = df.drop_duplicates(subset=["content"], keep="first") # 3. 去除特殊字符、表情符号、无意义符号(保留中文、数字、英文) def clean_comment(content): # 正则表达式:只保留中文、英文、数字,去除其他字符 content = re.sub(r"[^\u4e00-\u9fa5a-zA-Z0-9\s]", "", content) # 去除多余空格、换行符 content = re.sub(r"\s+", " ", content).strip() return content # 应用清洗函数 df["clean_content"] = df["content"].apply(clean_comment) # 4. 去除过短评论(如少于5个字,无分析价值) df = df[df["clean_content"].str.len() >= 5] # 保存清洗后的数据 df.to_csv("cleaned_comment.csv", index=False, encoding="utf-8-sig") print(f"数据清洗完成!清洗后剩余评论{len(df)}条,已保存到cleaned_comment.csv")

3.2 情感分析(基于snownlp实现)

snownlp是一款轻量级中文情感分析工具,无需手动训练模型,可直接输出情感评分(0-1之间),评分越接近1,情感越正面;越接近0,情感越负面;0.4-0.6之间视为中性评论。

from snownlp import SnowNLP # 读取清洗后的数据 df = pd.read_csv("cleaned_comment.csv") # 定义情感分析函数 def sentiment_analysis(content): s = SnowNLP(content) sentiment_score = s.sentiments # 情感评分(0-1) # 根据评分判断情感倾向 if sentiment_score >= 0.6: return "正面" elif sentiment_score <= 0.4: return "负面" else: return "中性" # 应用情感分析函数,新增情感评分和情感倾向列 df["sentiment_score"] = df["clean_content"].apply(lambda x: SnowNLP(x).sentiments) df["sentiment"] = df["clean_content"].apply(sentiment_analysis) # 查看情感分析结果(前10条) print(df[["clean_content", "sentiment_score", "sentiment"]].head(10)) # 统计各情感倾向的数量 sentiment_count = df["sentiment"].value_counts() print("\n情感倾向统计:") print(sentiment_count)

3.3 情感分析优化技巧

snownlp默认模型适用于通用中文文本,针对电商评论(如“性价比高”“质量差”等行业词汇),可通过自定义词典优化分词精度,提升情感分析准确性:

# 自定义电商评论情感词典(正面、负面词汇,可自行扩展) positive_words = ["好用", "性价比高", "质量好", "满意", "推荐", "流畅", "耐用"] negative_words = ["质量差", "卡顿", "漏水", "不满意", "不值", "破损", "难用"] # 优化情感分析函数(结合自定义词典调整评分) def optimized_sentiment_analysis(content): s = SnowNLP(content) score = s.sentiments # 若评论包含正面词汇,提升评分;包含负面词汇,降低评分 for word in positive_words: if word in content: score += 0.1 for word in negative_words: if word in content: score -= 0.1 # 确保评分在0-1之间 score = max(0, min(1, score)) # 重新判断情感倾向 if score >= 0.6: return "正面" elif score <= 0.4: return "负面" else: return "中性" # 应用优化后的函数 df["optimized_sentiment"] = df["clean_content"].apply(optimized_sentiment_analysis) print("\n优化后情感倾向统计:") print(df["optimized_sentiment"].value_counts())

四、核心实战三:数据可视化(直观呈现分析结果)

情感分析完成后,通过matplotlib、seaborn、wordcloud绘制可视化图表,将评论情感分布、核心关键词、评分与情感关联等信息直观呈现,便于快速解读数据。所有图表均保存到本地,可直接用于汇报、分析报告。

4.1 可视化1:情感倾向分布饼图(展示各情感占比)

import matplotlib.pyplot as plt import seaborn as sns # 设置中文字体(避免图表中文乱码) plt.rcParams['font.sans-serif'] = ['SimHei', 'DejaVu Sans'] plt.rcParams['axes.unicode_minus'] = False # 统计优化后各情感倾向的数量 sentiment_count = df["optimized_sentiment"].value_counts() # 绘制饼图 plt.figure(figsize=(8, 6)) colors = ["#66b3ff", "#ff9999", "#99ff99"] # 正面:蓝色,负面:红色,中性:绿色 explode = (0.05, 0.05, 0) # 突出正面、负面评论 plt.pie(sentiment_count.values, labels=sentiment_count.index, autopct="%1.1f%%", colors=colors, explode=explode, shadow=True, startangle=90) plt.title("电商商品评论情感倾向分布", fontsize=14, pad=20) plt.axis("equal") # 保证饼图为正圆形 plt.savefig("sentiment_distribution_pie.png", dpi=300, bbox_inches="tight") # 保存图表 plt.close() print("情感倾向分布饼图已保存")

4.2 可视化2:情感倾向与评分关联柱状图(分析评分与情感的一致性)

电商评论的评分(1-5星)与情感倾向理论上高度相关,通过柱状图可验证这一关联,判断情感分析结果的准确性。

# 确保评分列为数值类型 df["score"] = pd.to_numeric(df["score"], errors="coerce") # 按情感倾向分组,计算平均评分 sentiment_score = df.groupby("optimized_sentiment")["score"].mean().sort_values(ascending=False) # 绘制柱状图 plt.figure(figsize=(10, 6)) sns.barplot(x=sentiment_score.index, y=sentiment_score.values, palette="viridis") plt.title("不同情感倾向的平均评分", fontsize=14, pad=20) plt.xlabel("情感倾向", fontsize=12) plt.ylabel("平均评分(1-5星)", fontsize=12) plt.ylim(0, 5) # 评分范围限制在0-5 # 在柱状图上添加具体评分值 for i, v in enumerate(sentiment_score.values): plt.text(i, v + 0.1, f"{v:.2f}", ha="center", fontsize=11) plt.grid(axis="y", alpha=0.3) plt.savefig("sentiment_score_bar.png", dpi=300, bbox_inches="tight") plt.close() print("情感倾向与评分关联柱状图已保存")

4.3 可视化3:评论核心关键词词云图(展示用户关注重点)

通过词云图可直观看到用户评论中出现频率最高的关键词,快速定位用户关注的核心点(如“性价比”“质量”“外观”等),分别绘制正面、负面评论的词云图,对比差异。

from wordcloud import WordCloud # 定义词云生成函数 def generate_wordcloud(text, save_path, title): # 分词(使用jieba分词) words = jieba.lcut(text) # 过滤停用词(无意义词汇,如“的”“了”“是”,可自行扩展停用词表) stop_words = ["的", "了", "是", "我", "在", "和", "就", "都", "而", "及", "与", "一个"] words = [word for word in words if word not in stop_words and len(word) >= 2] # 拼接分词结果 word_text = " ".join(words) # 生成词云 wordcloud = WordCloud( width=800, height=600, background_color="white", font_path="simhei.ttf", # 需提前准备simhei.ttf字体文件(避免中文乱码) max_words=100, font_step=2, random_state=42 ).generate(word_text) # 绘制并保存词云图 plt.figure(figsize=(10, 8)) plt.imshow(wordcloud, interpolation="bilinear") plt.axis("off") # 隐藏坐标轴 plt.title(title, fontsize=14, pad=20) plt.savefig(save_path, dpi=300, bbox_inches="tight") plt.close() # 提取正面、负面评论的清洗后内容 positive_text = " ".join(df[df["optimized_sentiment"] == "正面"]["clean_content"].tolist()) negative_text = " ".join(df[df["optimized_sentiment"] == "负面"]["clean_content"].tolist()) # 生成正面、负面评论词云图 generate_wordcloud(positive_text, "positive_wordcloud.png", "正面评论核心关键词词云") generate_wordcloud(negative_text, "negative_wordcloud.png", "负面评论核心关键词词云") print("正面、负面评论词云图已保存")

4.4 可视化4:评论时间趋势图(展示评论热度变化)

通过时间趋势图,可查看商品评论的发布热度,判断用户关注高峰,为运营活动提供参考(如某时间段评论激增,可能与促销活动相关)。

# 处理评论时间(转换为日期格式) df["comment_time"] = pd.to_datetime(df["comment_time"], errors="coerce") # 按日期分组,统计每日评论数量 daily_comment = df.groupby(df["comment_time"].dt.date).size() # 绘制时间趋势图 plt.figure(figsize=(12, 6)) daily_comment.plot(kind="line", color="#1f77b4", linewidth=2, marker="o", markersize=4) plt.title("电商商品评论发布时间趋势", fontsize=14, pad=20) plt.xlabel("日期", fontsize=12) plt.ylabel("每日评论数量", fontsize=12) plt.grid(axis="y", alpha=0.3) plt.xticks(rotation=45) # 旋转x轴标签,避免重叠 plt.tight_layout() plt.savefig("comment_time_trend.png", dpi=300, bbox_inches="tight") plt.close() print("评论时间趋势图已保存")

五、实战总结与进阶拓展

5.1 实战总结

本文完成了一套从「评论采集」到「情感分析」再到「数据可视化」的完整实战流程,核心亮点的在于:

  • 全程合规:遵循robots协议,规避反爬坑点,仅用于个人学习,不涉及商业用途;
  • 可落地性强:所有代码可直接复制运行,适配主流电商平台,零基础也能快速上手;
  • 实用性高:覆盖数据采集、清洗、分析、可视化全流程,输出的图表可直接用于实际分析场景。

通过本次实战,可快速掌握电商评论数据的挖掘方法,读懂用户反馈的核心价值——正面评论的关键词可作为产品宣传亮点,负面评论的关键词可作为产品迭代、服务优化的重点方向。

5.2 进阶拓展(提升实战能力)

  1. 爬虫进阶:针对动态渲染的评论页面(JavaScript加载),改用Selenium/Playwright模拟浏览器操作,实现自动化登录、滚动加载,采集更多评论数据;
  2. 情感分析进阶:替换snownlp,使用BERT模型(如bert4keras)训练自定义情感分析模型,适配电商行业场景,提升情感判断准确性;
  3. 可视化进阶:使用Plotly绘制交互式图表(如交互式饼图、柱状图),支持鼠标悬浮查看具体数据;
  4. 批量采集进阶:搭建多线程/异步爬虫(如aiohttp),在合规前提下提升采集效率,支持多商品评论批量采集。

5.3 注意事项

  1. 数据采集需严格遵守法律法规和平台规则,不得用于商业用途、恶意爬取、泄露用户信息;

  2. 避免高频、大规模采集,以免给平台服务器造成压力,导致账号受限或法律风险;

  3. 本文代码仅为实战演示,不同电商平台的页面结构、反爬机制不同,需根据实际情况修改解析规则和请求配置。

最后,希望通过本次实战,能帮助你掌握电商数据挖掘的核心技巧,将技术落地到实际场景中,用数据驱动决策。如果在实操过程中遇到问题,可留言交流,后续将持续更新进阶内容!