Selenium电商评论爬虫实战:登录态、滚动加载与反爬破解
发布时间:2026/10/18 14:20:10 锦皓数字建站

最近又被好几个朋友问到“想抓某电商平台的评论区数据”这类需求我前前后后写过不少次每次都能遇到些新花样。说实话评论区数据这个事看着简单真动手就知道里面全是坑先是要处理登录态不然点开评论区要么让你登录、要么强行跳验证码接着是评论区滚动加载不滚屏就只出第一页那几条数据等好不容易滚到底又发现页面结构换了一波早起写得稳稳的选择器直接失效。等这些都搞定了还要防着一不留神触发平台的风控导致数据全变成固定的几条样本评论。这篇文章我想把一套实际能跑通的 Selenium 天猫淘宝电商评论爬虫进阶实现完整记录一遍包括完整代码、每个关键步骤的取舍逻辑以及我在实际操作中踩过的那些坑。这个方案只覆盖个人学习和小规模研究用途的数据采集不涉及任何服务端接口破解或恶意抓取。我尽量把话说透让你不仅能照着写出来还能在出现问题的时候知道自己该往哪个方向排查。1. 整体思路与技术选型背后的考量1.1 为什么不用 Requests 直接请求接口先说我最初尝试的方向。很多人第一反应是去抓页面上那个异步加载评论的 XHR 接口毕竟 Selenium 太重还得开浏览器效率低、资源占用大。确实某些时机下你能在 DevTools 里看到评论数据是通过一个带 sign 参数的 GET 接口返回的 JSON。问题是sign 参数的生成逻辑通常经过前端加密而且会定期更换算法就算你侥幸把参数构造对了平台的风控也会对高频访问做访问频率限制一旦触发轻则接口返回一段加密的校验信息重则直接让账号进入风险状态。相比之下Selenium 的优势在于它模拟的是真实用户的浏览器行为天然带着完整的 Cookie、UA、浏览器指纹环境只要操作节奏合理被识别的概率会低很多。缺点是速度慢、并发能力有限、资源开销大。但如果你抓的是几百几万条评论用于分析而不是千万级的数据生产任务这个取舍完全值得。注意评论区数据属于电商平台的用户生成内容采集时务必控制频率、控制数量只用于合法合规的个人分析用途不要公开转卖或大规模商用。这也是我整篇文章的前提。1.2 为什么选 Selenium 而不是 Playwright 或 Pyppeteer我这次选择的就是 Selenium但并不是说它比其他方案绝对好。实际测试中Playwright 的自动等待机制和上下文隔离确实更优雅Pyppeteer 的异步并发潜力也更大。选 Selenium 主要基于三个原因一是本地环境里既有安装好的一整套 WebDriver 和一个长期稳定运行的浏览器配置二是 Selenium 的文档和社区资料最多早年踩坑的经验在网上几乎都能搜到三是团队的维护成本低不用引入额外的运行时和依赖。但如果你是从零开始我建议你对比一下现有的硬件和系统环境再选。Playwright 的默认安装就会自动下载匹配版本的浏览器省去了手动管理驱动版本的麻烦这一点比 Selenium 做得省心。不过一旦遇到平台做了比较复杂的风控Selenium 配合手动登录保活登录态的这套方案反而更直接因为你可以复用用户已经登录过的真实浏览器上下文。1.3 这个方案的整体脉络这套实现的流程可以拆成四个阶段初始化浏览器实例注入必要的反检测参数处理登录态用 Cookie 缓存机制避免每次手动扫码登录打开商品页面定位评论区容器反复滚动到评论加载完成逐页解析评论数据写入本地 CSV并处理翻页与异常中断。每一阶段看着都不复杂但每一阶段都藏着几个容易让脚本猝死的细节。下面我按这个顺序逐个拆开讲。2. 环境准备与依赖版本避坑2.1 版本选择浏览器、驱动、Selenium 三者要匹配这一块是新手最容易掉进去的地方。你装着 Selenium 4.6系统里却跑着 Chrome 120 的浏览器WebDriver 用的是 ChromeDriver 94打开脚本大概率直接报版本不匹配的错误而且报错信息很不直观经常是 session not created 或 unknown error。从 Selenium 4.6 开始官方加入了 Selenium Manager 来自动管理驱动版本如果你开了这个能力不需要再手动下载 ChromeDriver。但要注意Selenium Manager 自动下载驱动时依赖网络访问如果你的执行环境网络受限建议还是手动下载对应的 chromedriver.exe并把它的路径显式指定给 webdriver.Chrome(executable_path...)。不过新版本里 executable_path 参数已经被 Service 对象取代写法要改一下。我习惯用固定组合Chrome 118 ChromeDriver 118 Selenium 4.15这套组合经过了多次验证稳定复现问题也方便。另外一个技巧不要频繁升级浏览器因为每次升级后驱动版本可能不匹配一旦平台风控策略变化导致必须动浏览器版本再统一升级。2.2 必须安装的依赖下面的命令是完整一套。装完后建议用 pip list 确认一下版本避免在跑脚本的时候才发现 selenium 是 3.x 老版本。pip install selenium4.15.0 pip install pandas pip install lxml pip install retrying pip install fake-useragentfake-useragent 这个库有些版本在某些网络环境下会请求第三方接口去拉 UA 列表反而会失败。稳妥起见我一般是直接用浏览器真实 UA 字符串甚至不用库。CSV 存储用标准库 csv 就够但如果后续还要对评论做文本清洗和情感分析建议直接写 DataFrame 输出。2.3 浏览器初始化参数这块是整个脚本里最需要耐心调试的部分。直接上图看参数写法from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options def get_browser(): options Options() options.add_argument(--disable-blink-featuresAutomationControlled) options.add_argument(--user-agentMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36) options.add_argument(--disable-gpu) options.add_argument(--no-sandbox) options.add_argument(--langzh-CN) options.add_experimental_option(excludeSwitches, [enable-automation]) options.add_experimental_option(useAutomationExtension, False) service Service(rD:\chromedriver\chromedriver.exe) browser webdriver.Chrome(serviceservice, optionsoptions) execute_cdp_cmd getattr(browser, execute_cdp_cmd, None) if execute_cdp_cmd: browser.execute_cdp_cmd(Page.addScriptToEvaluateOnNewDocument, { source: Object.defineProperty(navigator, webdriver, {get: () undefined}); window.chrome { runtime: {} }; }) return browser为什么需要这些参数我展开讲一下。--disable-blink-featuresAutomationControlled会关掉 Chromium 核心里的自动化控制标记配合注入的 JS 修改navigator.webdriver属性能把很多常见的平台风控第一层过滤绕掉。excludeSwitches里加enable-automation可以去掉浏览器的“正在受到自动化软件控制”提示。另一个常见的坑是如果不设置useAutomationExtension为 False某些环境下会看到类似 “Chrome 正受到自动测试软件控制” 的黄色提示条这个提示条本身不是致命问题但会暴露自动化特征。还有一点容易被忽略默认的 Chrome 属性里执行navigator.languages时是英文环境如果目标页面是中文平台建议把浏览器的语言参数改成zh-CN否则部分页面渲染可能不同。这一点曾经耗了我不少时间页面 DOM 结构和正常登录后的不一致排查半天才发现是浏览器语言设置的问题。3. 核心实现与完整代码框架3.1 登录态处理和 Cookie 复用策略评论区的完整数据尤其是“追评”和“图片评论”这两块通常需要登录后才能加载。设计上我不推荐一上来就账号密码登录因为平台登录时的密码加密和滑块验证码处理成本很高。我采用的方式是首次手动操作登录然后保存 Cookies后续启动脚本时自动加载已有 Cookies如果 Cookie 过期再回到手动登录。保存 Cookies 要保存两份副本。其中一份是登录后立即保存的另一份是进入商品页面后再次保存的。原因是有些页面的接口需要携带特定的访问令牌或临时 Cookie这些只在访问过商品页之后才会生成。import pickle import time from selenium import webdriver from selenium.webdriver.common.by import By def save_cookies(browser, pathcookies.pkl): with open(path, wb) as f: pickle.dump(browser.get_cookies(), f) def load_cookies(browser, pathcookies.pkl): try: with open(path, rb) as f: cookies pickle.load(f) for cookie in cookies: if expiry in cookie and cookie[expiry] is not None: # pickle 会保留原来的时间戳但浏览器要求的是秒级int cookie[expiry] int(cookie[expiry]) browser.add_cookie(cookie) return True except FileNotFoundError: return False def ensure_login(browser, login_url): if load_cookies(browser): browser.get(login_url) time.sleep(3) # 简单检查是否被重定向到登录页 if login in browser.current_url: print(Cookie 已失效请手动登录) input(登录完成后按回车继续...) save_cookies(browser) else: browser.get(login_url) input(请手动登录完成后按回车...) save_cookies(browser)这个流程比较简单直接但我需要提醒几个细节。第一add_cookie必须在browser.get(target_url)之前完成因为你先打开页面再添加 Cookie 的话页面已经完成初始化Cookie 不会生效。第二Cookie 里的expiry字段如果是浮点数某些 Python 版本直接写入时会报 ValueError所以我在加载时强制转成 int。第三不要把账号密码硬编码写进脚本省得脚本被别人拿到时直接泄露账号。3.2 滚屏加载评论区的完整写法电商评论区的加载策略一般是页面下方有个“点击加载更多”按钮点击几次后变为“查看更多”按钮内部继续滚动加载。也有部分商品页面每往下滚动一段就自动加载直到加载完所有评论。写代码时不能只依赖一种方式我建议写一个混合逻辑先测试向前滚动如果没有新数据再去点击页面上那个加载按钮。from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By def load_all_comments(browser, max_scroll_times80): # 先定位评论区 comment_section WebDriverWait(browser, 15).until( EC.presence_of_element_located((By.XPATH, //div[contains(class, comment-list)])) ) last_height 0 for i in range(max_scroll_times): browser.execute_script(arguments[0].scrollIntoView();, comment_section) browser.execute_script(window.scrollBy(0, 800);) time.sleep(1.2) # 尝试点击加载更多按钮 buttons browser.find_elements(By.XPATH, //div[contains(class,comment-more)]//button | //a[contains(text(),查看更多)]) if buttons: try: buttons[0].click() time.sleep(1) except Exception: pass current_height browser.execute_script(return document.body.scrollHeight) if current_height last_height: # 高度没变化可能到底了再试一次点击加载更多 break last_height current_height这个循环里有两个关键点。一个是滚动位置直接browser.execute_script(window.scrollTo(0, document.body.scrollHeight))在部分页面会因为容器自身的滚动条而失效必须先把评论区容器滚入视口再针对它的父容器继续滚动。另一个是等待时间如果单次 sleep 时间过短评论没来得及渲染就被判断为到底了提前终止过长的话整体耗时又增加。我实测下来 1 到 1.5 秒是比较平衡的区间。不过提醒一句评论总数并不总是全部可加载的平台方通常有评论展示上限比如最多前 5000 条或 100 页。代码里设置max_scroll_times也是防止页面循环加载不出新数据时无限操作。这个上限要和后面翻页逻辑配合使用。3.3 评论数据解析与字段提取解析评论数据前先说明一下常见 DOM 结构每条评论通常被包裹在一个div classcomment-item里包含用户名、评论内容、购买的商品规格、评论时间、点赞数等节点。平台改版频率较高我不给出唯一固定选择器而是给一个基于“容器 多层兜底”的解析思路。def parse_comments(browser): items browser.find_elements(By.XPATH, //div[contains(class, comment-item) or contains(class, rate-single)]) data [] for item in items: try: nickname item.find_element(By.XPATH, .//span[contains(class,user-info)] | .//div[contains(class,user-nick)]).text.strip() except Exception: nickname try: content item.find_element(By.XPATH, .//div[contains(class,comment-content)] | .//p[contains(class,rate-content)]).text.strip() except Exception: content try: sku_info item.find_element(By.XPATH, .//span[contains(class,sku-info)] | .//div[contains(class,spec-info)]).text.strip() except Exception: sku_info try: comment_time item.find_element(By.XPATH, .//span[contains(class,time)] | .//div[contains(class,rate-time)]).text.strip() except Exception: comment_time data.append({ nickname: nickname, content: content, sku_info: sku_info, comment_time: comment_time }) return data这里用|把两组 XPath 合并在一起解析时先试前面的选择器失败则试后面的。别小看这个兜底平台在前端结构上经常会做 A/B 测试你看到的页面和脚本跑到的页面可能结构并不一样。选择器要尽量靠近节点的文本内容层而不是依赖一层层的 class 层级。比如不要写成.//div[classcomment-item]/div/div[2]/div[1]这种固定层级因为中间一旦插入新的广告位或标签整个解析就崩了。至于评论内容里的换行符和空白字符我在写入 CSV 前会做一个清洗处理把\n换成空格去掉前后空白防止 CSV 被换行截断。清洗这一步看起来无关紧要但数据量一大之后入库和后续分析都会感谢当初做了这个处理。3.4 翻页逻辑与分页控制评论区翻页有两种形态一种是点击“下一页”按钮另一种是评论列表自身带有类似“第 1/100 页”的一个数字页码输入框。我建议兼容这两种形态优先尝试定位输入框直接跳转因为这种速度最快而且不需要经历一次整页渲染。def turn_page(browser, page_number): # 方法一输入页码跳转 try: page_input browser.find_element(By.XPATH, //input[contains(class,page-input) or contains(class,input-page)]) page_input.clear() page_input.send_keys(str(page_number)) page_input.send_keys(u\ue007) # 回车 time.sleep(2) return True except Exception: pass # 方法二点击下一页 try: next_btn browser.find_element(By.XPATH, //span[contains(text(),下一页)] | //a[contains(class,next)]) next_btn.click() time.sleep(2) return True except Exception: return False这里要特别注意每次翻页后评论容器是要重新加载的旧的网页元素对象已经失效如果你在循环体中先保存了一个comments browser.find_elements(...)翻页后再去遍历它就会报 stale element reference 错误。正确做法是翻页后重新查找元素然后重新解析。千万不要复用旧的元素列表。页码输入框翻页还有一个坑输入页码后回车这一操作在某些浏览器窗口里会被解释成“搜索”因为页面上可能有别的表单。稳妥的方式是先点击页面上的“第 1/xxx 页”文本区域再输入页码或者直接定位到按钮后使用webdriver.ActionChains来模拟键盘。回车方案绝大多数情况下是可用的遇到可疑情况再微调。3.5 完整代码框架汇总我把上面的模块拼成一个可跑通的脚本框架。这个框架具备容错处理、断点续爬和 CSV 输出算是经过多次实战后沉淀下来的一个模板。为了保持可读性部分异常处理细节略做简化。import csv import random import time import pickle from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC PRODUCT_URL https://item.example.com/product-detail.html def get_browser(): options Options() options.add_argument(--disable-blink-featuresAutomationControlled) options.add_argument(--user-agentMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36) options.add_experimental_option(excludeSwitches, [enable-automation]) options.add_experimental_option(useAutomationExtension, False) service Service(rD:\chromedriver\chromedriver.exe) browser webdriver.Chrome(serviceservice, optionsoptions) browser.execute_cdp_cmd(Page.addScriptToEvaluateOnNewDocument, { source: Object.defineProperty(navigator, webdriver, {get: () undefined}) }) return browser def load_cookies(browser, path): ... def save_cookies(browser, path): ... def ensure_login(browser): ... def load_all_comments(browser, max_scroll_times): ... def parse_comments(browser): ... def turn_page(browser, page): ... def main(): browser get_browser() try: ensure_login(browser) browser.get(PRODUCT_URL) time.sleep(random.uniform(2, 4)) load_all_comments(browser, max_scroll_times100) all_comments parse_comments(browser) # 写入 csv with open(comments.csv, w, encodingutf-8-sig, newline) as f: writer csv.DictWriter(f, fieldnames[nickname, content, sku_info, comment_time]) writer.writeheader() writer.writerows(all_comments) finally: browser.quit() if __name__ __main__: main()代码中我用utf-8-sig编码来写 CSV这样用 Excel 打开时中文不会乱码。这是评论区数据采集里一个特别容易忽略的细节很多人生成 CSV 后用 Excel 打开看到一堆乱码马上怀疑是编码问题其实只差一个 BOM 头。4. 核心痛点与实战破解思路4.1 滑块验证码与行为轨迹模拟平台风控最常见的触发形式就是滑块验证。一旦出现滑块整套自动化模拟需要考虑鼠标移动轨迹的合理性。比如你直接让鼠标从屏幕左边瞬间移动到滑动按钮位置并立刻拖完这个操作轨迹在坐标和时间上都不符合人类习惯风控系统很容易将其判定为机器操作。我的验证码应对策略分两步。第一步是尽量别触发它控制每一步的间隔时间不要一登录完就快速爬取也不要连续翻页超过 10 次通常跑到第 3 到 5 页就随机休息 3 到 8 秒模拟人类的阅读节奏。第二步是真的被拦之后的手动滑动方案检测到页面出现滑块容器时暂停脚本并给用户一个提示由人工手动滑过去脚本再继续。有人可能觉得这不够自动化但在评论区爬取这个场景里人工干预频率其实很低一周跑下来可能只需要干预一两次这部分时间成本完全能接受。滑块交互如果真要自动处理可以用ActionChains(driver).click_and_hold()逐步移动并给每段移动加入轻微抖动模拟人手肌肉控制的不稳定感。据我实测这种轨迹在两三百次滑动里可以大幅提高通过率但也仅限于部分版本无法做到所有场景通杀。风控的升级速度很快没有一劳永逸的方案。4.2 动态加载导致的元素定位失败这是所有 Selenium 使用者遇到最多的错误明明页面里能看到评论但脚本就是找不到对应的 DOM 节点或者找到时报ElementNotInteractableException。原因是评论模块用了懒加载只有元素进入视口一定距离后才会真正插入到 DOM 树中。如果你在打开页面 1 秒后立即去查找评论容器十有八九是找不到的。解决办法不是简单地加长time.sleep(5)而是用 Selenium 的显式等待配合一个可靠的定位条件。我把等待策略写成两层第一层等待评论容器出现第二层等待容器内部出现至少一条评论节点。只有这两层都满足后才继续滚动否则每过 2 秒检查一次最多等待 20 秒。这样既不会因为等待时间过短导致提前判定也不会因为等待时间过长拖慢整体速度。还有一个相关的坑是页面里存在多个 iframe。评论模块有时候被嵌在一个局部 iframe 里直接driver.find_element是找不到的必须先用switch_to.frame()切进去再操作。如何判断是否在 iframe 中可以通过 DevTools 的 Elements 面板查看评论模块外面是不是套了一层iframe标签。这是高位排查项出现“页面可见但定位不到”问题时优先检查。4.3 浏览器指纹特征与反检测技巧平台风控除了看请求行为还会读取浏览器上下文中的自动化特征变量。除了前面提到的navigator.webdriver很多更隐蔽的特征包括window.chrome对象是否存在、navigator.plugins的列表、languages数组的排序、User-Agent是否匹配操作系统版本等。Selenium 默认的浏览器环境里navigator.webdriver是 truechrome 对象状态也和正常浏览器不一致。所以在初始化浏览器时除了设置排除自动化开关我还注入了一段在每次新文档创建时都会执行的 JavaScript 代码这段代码会覆写navigator.webdriver属性并对navigator.plugins和languages做补充。不过要注意通过execute_cdp_cmd注入的脚本作用于所有子文档包括 iframe这个方案比单纯执行一次execute_script更可靠。因为execute_script只在当前主文档环境下生效iframe 里的navigator还是旧的。即使如此也千万别把反检测说得太神。指纹伪装只能降低被风控“一眼认出来”的概率高频访问、异常操作节奏照样会触发更高级的检测策略。最优解永远是低频率、少数量、细水长流。4.4 数据量受限与固定样本问题另一个很容易察觉到的现象是脚本每次跑出来的评论内容都一模一样好像评论区变成了固定样本集。这通常是触发了平台针对非真人浏览请求的降级策略页面实际只返回少量公开评论而且这些评论是平台的“示例评论”不是商品完整评论。处理思路是换 IP、换账号、清理浏览器缓存并重新登录、调整访问频率这几步组合使用一般能恢复正常。如果你使用的是公司内网或数据中心出口 IP触发概率会明显高于家庭宽带 IP。这里额外提一下不要一味追求把所有评论一次性抓完。如果某商品有几万条评论正常分页也要 100 页以上连续不中断跑完一整套触发风控的几率非常高。我一般把单次任务上限设置在 20 页左右分时段分批次执行。即使中间某批次中断了重新启动脚本时也要做好去重处理比如记录已经抓取到的评论内容 hash 值跳过重复数据。5. 常见问题排查与避坑实录5.1 常见问题速查表我整理了一份高频问题速查表这些问题每一类都在实际跑量过程中遇到至少一次可以直接对照排查。现象可能原因处理方式浏览器能打开但页面空白页面未加载完就执行了下一步使用显式等待等待核心元素出现提示“版本不匹配”Chrome 与 ChromeDriver 版本不一致下载匹配版本驱动并用 Service 指定路径评论区加载不完整滚动等待时间过短每次滚屏后 sleep 1.2 秒以上报 stale element reference翻页后没有重新查找元素翻页后重新 find_elements评论数据固定不变访问频率过高触发降级页面更换 IP、重启浏览器调低翻页频率出现滑块验证自动化特征明显或频率过高手动干预滑动降低滚动频率CSV 用 Excel 打开乱码编码缺少 BOM使用 utf-8-sig 编码写文件始终找不到评论区节点评论在 iframe 里先 switch_to.frame 再定位页面检测到 webdriver 属性未注入反检测脚本在每次新文档加载前执行 JS 覆写5.2 日志与断点续爬的工程化实践脚本一旦要跑较长时间控制台输出便不够用了。我会在脚本里加一层简单的日志记录把每次翻页的页码、当前时间、本次解析到的评论数和累计评论数写入一个 log 文件。这不是给外行看的展示页面而是排查问题时的核心依据——比如你可以通过日志判断是不是连续 5 页评论数据都是 0如果都是 0大概率是页面被降级了而不是解析代码写错了。断点续爬的核心是记住上一次已经抓取到的评论总量和分页位置。一种做法是把已经写入的评论条数存到一个单独的 txt 文件每次启动时读出来。更稳妥的做法是每次翻页前记录一下当前页面的 URL 或页码数重新启动时直接跳到上次失败的那一页继续抓。你甚至可以在每条评论写入 CSV 前先计算一个简易指纹把昵称、评论内容、评论时间拼接后做 MD5写入一个 seen_set遇到重复直接跳过。这样做既省流量也避免后续数据分析时重复数据污染结果。5.3 数据质量问题去重、清洗与空值处理评论区数据天生带有不少噪声。昵称可能被平台脱敏成“i***1”评论内容里夹杂着促销广告评论时间为空的情况也不少。抓取原始数据只是第一步后续一定要做清洗。对于空值我建议保留字段空字符串而不是直接删掉整行因为空评论时间可能跟下单时间、追评时间相关后续分析时还有参考价值。去重需要注意的是同一条评论在“按推荐排序”和“按时间排序”下可能出现在不同位置翻页过程中偶尔会重复抓取。判断重复比对的字段不要只用评论内容要结合昵称和评论时间一起看。否则不同用户发表相同文案比如品牌推广文案时会被误删。清洗小众符号时正则表达式是首选。把 HTML 实体符号、全角空格、零宽字符这些都替换掉。评论里的 emoji 表情在写入 CSV 时可能引发编码异常实践中最稳妥的方式是保留 emoji 但使用 utf-8 编码或者明确地将其替换成占位文本。不要直接encode(ascii)这样硬截断会把正常的汉字也弄丢。5.4 我建议的小规模部署策略如果你只是给自己分析用不需要上并发、不需要搭建代理池。单机 单浏览器 低频率是最稳妥的方案。当然这个小规模策略也有缺点慢非常慢。抓 2000 条评论可能要二十分钟。但我宁可慢也不愿意账号被限制因为账号一旦被限制恢复成本远远大于节省下来的时间。需要上并发再考虑切分任务每个浏览器负责不同的商品互不共享 Cookie。别试图在同一个浏览器里开多个标签页一起跑这样很容易造成页面请求过于集中而且不同标签页之间还会互相干扰滚动状态。我试过开两个标签页同时翻页最后两个页面都触发了滑块验证直接全军覆没。这种“偷鸡不成蚀把米”的教训写出来希望大家引以为戒。结尾关于这个项目的几点真实体感这套 Selenium 电商评论爬虫项目最核心的难度其实不在于代码本身而在于你如何理解一个复杂 Web 应用在真实用户和自动化脚本之间的行为差异。平台的反爬策略会不断调整Selenium 版本会升级浏览器也会更新唯一不变的是你做项目时对每一层机制的理解。我个人的真实体感是评论爬虫这种活儿七分靠代码三分靠运营思路。代码写清楚能让你跑起来而对频控的判断、对异常数据的理解、对登录态时机的把握才是决定这个脚本能不能稳定长期使用下去的关键。如果你刚开始接触这类项目建议第一步不要急着去抓别人的商品数据先拿自己店铺或自己发布的商品页面练手把整个流程跑通后再逐步扩展到复杂场景。最后再分享一个小技巧遇到任何奇怪的问题先别慌着改代码打开浏览器的 DevTools 手动操作一遍目标页面看看手动操作时页面请求、DOM 节点、网络时间线有什么变化很多时候问题的答案就在这一步里。祝大家都能一次跑通少走弯路。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。