Scrapy使用CSS选择器抓取eBay商品页面文本失败,疑似与::before伪元素有关
嘿,我来帮你捋捋这个问题~你猜的没错,问题确实出在那个::before伪元素上!
你看到的「Monday, 9:30 AM」并不是直接写在HTML标签里的文本,而是浏览器通过CSS伪元素::before的content属性渲染出来的。Scrapy的response.css()和xpath()只能抓取实际存在于DOM结构中的内容,伪元素属于CSS渲染层面的产物,根本不在HTML源码里,所以你用常规选择器自然抓不到空数组啦。
给你两个可行的解决方案:
从页面的JavaScript数据里提取:eBay这类电商网站通常会把动态渲染的数据(包括倒计时时间)打包在页面的
<script>标签里,比如JSON格式的初始化数据。你可以在Scrapy shell里先定位到包含时间信息的脚本块:# 先找到包含timeLeft相关的脚本 script = response.xpath('//script[contains(text(), "timeLeft")]/text()').get()找到脚本后,用正则或者JSON解析工具把里面的时间数据抽出来。举个例子(具体字段要根据实际脚本结构调整):
import re import json # 用正则匹配出JSON结构部分 match_result = re.search(r'window.__INITIAL_STATE__ = (.*?);', script) if match_result: data = json.loads(match_result.group(1)) # 假设时间在这个路径下,实际要根据你找到的JSON结构调整 target_time = data['item']['timer']['timeLeft'] print(target_time)模拟浏览器渲染页面:如果数据是纯动态加载的,也可以用
scrapy-splash或者playwright这类工具模拟浏览器渲染整个页面,这样就能获取到渲染后的完整DOM(包括伪元素生成的文本)。不过这种方法会比直接抓静态数据慢一些,适合更复杂的动态场景。
最后教你个验证方法:打开浏览器DevTools的「Elements」面板,找到那个span.ux-timer__time-left元素,你会发现它的文本内容是空的;再切换到「Styles」面板,就能看到::before的content属性里正好是你要的时间文本,这就实锤了内容是伪元素生成的~
备注:内容来源于stack exchange,提问作者Lord Elrond

