把 Selenium 和文本挖掘串起来做留言数据分析这件事,我断断续续折腾了大概两个月,踩了不少坑,也攒下了一套可以复用的流程。这套方案不依赖现成的数据分析平台,完全用 Python 生态自建,从数据采集、清洗,到情感分析、主题建模、关键词提取、文本分类,一条线打通。
这次就把这套完整思路分享出来,内容包括架构设计、Selenium 采集环节的避坑要点、文本挖掘各个环节的模型选型和代码示例,最后附带一份高频踩坑实录。适合刚接触爬虫和 NLP 的开发者照着复现,也适合已经在做留言分析但想优化流程的朋友参考。
1. 整体设计与方案选型
1.1 先想清楚:为什么要用 Selenium 做数据采集
留言数据的来源通常分三类:一是公开的评论接口,直接返回 JSON 数据;二是服务端渲染的 HTML 页面,用 Requests 就能拿到完整页面;三是前端 JS 动态渲染的页面——这个才是 Selenium 真正发挥作用的场景。
现在主流的内容平台、社区论坛、商品评价页面,大量数据都是前端渲染的。Requests 拿到的 HTML 里根本没有评论内容,数据是通过 JS 异步请求加载后渲染出来的,甚至很多是经过 JS 混淆或者加密参数生成的。这时候用 Selenium 模拟真实浏览器请求,是最稳定的方案。
有人可能说太笨重了。我承认 Selenium 启动浏览器、加载页面的开销确实很大,并发能力也比不上纯 HTTP 请求。但做留言分析这个场景,数据量不会像搜索引擎那样动辄数亿,一天处理万级甚至十万级留言,单机完全够用。我更看重的是它有两个好处:
第一,不需要逆向解析加密的 XHR 接口参数。很多平台的接口参数带 timestamp、sign 之类的签名逻辑,但 Selenium 是真实浏览器操作,这些参数根本不用管。
第二,能够稳定处理登录态、翻页、滚动加载这类需要真实行为的场景。像一些需要登录后查看评论的平台,Requests 加 Cookie 很容易失效,Selenium 只要保持浏览器会话,整个过程自动维护。
1.2 文本挖掘选型逻辑:轻量优先,重模型兜底
留言数据的文本挖掘,常见任务有四种:情感分析、关键词提取、主题建模、文本分类。不同任务的成熟度和工具选型差异很大,我按照“轻量优先、重模型兜底”的原则来做选型。
首先明确一个判断标准:数据量是千级、万级还是十万级以上?标注资源有没有?业务对实时性要求如何?这三个问题直接决定技术路线。
如果数据量在万级以内、对准确率要求不是极端敏感,传统机器学习方案完全够用。比如情感分析用 SnowNLP 或者基于情感词典的规则方法,文本分类用朴素贝叶斯或者 SVM,关键词提取和主题建模用 TF-IDF、TextRank、LDA。这类方案的好处是环境依赖低、速度快、结果可解释,适合业务冷启动。
如果数据量大、准确率要求高、有标注数据,那就得上深度学习模型。情感分析用预训练模型做微调(比如基于 BERT 的中文模型),文本分类用 TextCNN 或者 FastText。这里有一个折中方案:用预训练模型做 embedding 层,下游接一个简单的分类器,训练成本不高,效果却有明显提升。
提示:我自己的建议是——不要一开始就上大模型。先把传统方案跑通,产出一个基线(baseline),再评估是否需要上更强的模型。很多留言数据的情感分布和主题分布其实比较集中,传统方案已经能解决大部分问题。
1.3 整体技术架构
这里放一个我在项目中使用的完整架构,可以做参考:
- 数据采集层:Python + Selenium,负责打开页面、模拟登录、滚动加载、翻页、抓取留言内容。
- 数据清洗层:Pandas + jieba + 正则表达式,负责去重、去噪、分句、分词。
- 分析层:分成四个模块——
- 情感分析:初版用 SnowNLP,后续基于标注数据微调了一个 FastText 模型。
- 关键词提取:jieba 内置的 TF-IDF 算法和 TextRank 算法。
- 主题建模:用 gensim 的 LDA 模型。
- 文本分类:先用朴素贝叶斯跑通全流程,后用 FastText 提升准确率。
- 可视化与展示:Matplotlib + WordCloud,实现词云、主题分布、情感占比的可视化。
这套架构的核心思路是专门为留言数据定制的,数据量级集中在几千到十万条之间,全部部署在单机上也可以流畅运行。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与关键依赖配置
2.1 必装环境清单与版本选择
开始之前,先把环境打造好。我用的是 Python 3.9,这个版本对 Selenium 4.x、gensim、transformers 都有不错的兼容性。以下几个库是标配:
bash复制pip install selenium pandas jieba gensim scikit-learn wordcloud matplotlib
这里补充一个细节:如果你打算跑深度学习模型,建议把 numpy 固定到 1.23.5 或者 1.24.x,不要直接装 numpy 2.x。很多旧版本的 gensim、scikit-learn 对 numpy 2.x 存在兼容问题,报错信息五花八门,排查起来非常痛苦。
Selenium 方面,我用的是 4.10 以上版本。有一个比较大的体验变化是 Selenium 4 内置了 webdriver_manager 这样的第三方驱动管理库,不再需要手动下载 Driver。不过依然要理解 Driver 和浏览器版本之间的匹配逻辑——这个坑很常见,后面会细说。
2.2 Selenium 浏览器驱动的正确姿势
关于浏览器驱动的选择,很多人第一反应是去下载 ChromeDriver。这里有个核心认知:
ChromeDriver 的版本必须和 Chrome 浏览器的主版本保持一致。
什么意思呢?比如你的 Chrome 是 120.0.6099.109,那 ChromeDriver 必须是 120.x.x.x,小版本可以不严格一致,但大版本必须匹配。不匹配的时候,Selenium 会报 SessionNotCreatedException。
下载驱动的正确姿势有两种:
方式一:手动下载。访问 ChromeDriver 官方下载页(或国内镜像站)下载对应版本的驱动,解压后把可执行文件放到 Python 的 Scripts 目录或者项目根目录。
方式二:用第三方库自动管理。安装 webdriver-manager 之后,每次运行代码自动检测浏览器版本并下载匹配的驱动:
python复制from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
方式二对新手来说更省心,但如果你用的是公司内部网络,无法访问外网下载驱动,方式一更稳妥。我自己的习惯是手动下载并放到固定目录,然后通过 Service 指定路径,这样部署到服务器时不会因为网络问题卡壳。
2.3 关键配置参数
Selenium 启动浏览器时有一些参数,对稳定性和效率影响很大。
python复制from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument("--headless=new") # 无头模式
options.add_argument("--disable-gpu")
options.add_argument("--no-sandbox")
options.add_argument("--ignore-certificate-errors")
options.add_argument("--window-size=1920,1080")
options.add_argument('--blink-settings=imagesEnabled=false') # 禁用图片加速加载
options.add_experimental_option("excludeSwitches", ["enable-automation"])
driver = webdriver.Chrome(options=options)
这里说下几个参数的作用:
--headless=new:新版无头模式,比旧版更稳定,很多 JS 渲染异常在无头模式下也能正常执行。--blink-settings=imagesEnabled=false:留言页面上的图片、头像这类资源对数据分析毫无价值,禁用之后页面加载速度提升 30% 以上,这是实打实的效果。window-size:模拟浏览器的窗口尺寸。有些页面在窄屏情况下只渲染部分数据
