You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scrapy-Splash爬取动态网站面包屑时无法获取指定元素的问题

问题:Scrapy-Splash抓取动态面包屑元素返回空列表

问题描述

我尝试抓取一个基于动态JS内容的电商网站页面面包屑,该面包屑由4个类名为.breadcrumbs-link的元素组成。使用Scrapy-Splash编写了如下代码:

import scrapy
from scrapy_splash import SplashRequest

class MySpider(scrapy.Spider):
    name = "quotes4"
    start_urls = ["https://www.woolworths.com.au/shop/browse/drinks/cordials-juices-iced-teas/iced-teas"]
    
    def start_requests(self):
        for url in self.start_urls:
            yield SplashRequest(url=url, callback=self.parse, endpoint='render.html',args= {'wait': 10})
            
    def parse(self, response):
        print ('Result:')
        print(len(response.css('.breadcrumbs-link').extract())) # OUTPUT: 0
        print(response.css('.breadcrumbs-link').extract()) # OUTPUT: []

运行后输出显示获取到的元素数量为0,结果列表为空。请问我的实现方法存在什么问题?

问题分析与解决方案

我帮你排查了下,大概率是以下几个原因导致的,对应解决方案也给你整理好了:

  • 元素选择器不准确:你用的.breadcrumbs-link可能不是页面最终渲染后的真实类名,或者元素结构有嵌套变化。建议你打开Chrome开发者工具,找到面包屑元素后用「Copy selector」功能直接复制准确的选择器,避免手动写类名出错。比如有些动态渲染的元素会附加随机后缀类名,或者面包屑是嵌套在某个容器里的,需要更精确的层级选择器。

  • 固定等待时间不够可靠:虽然你设置了wait:10,但有些网站的JS渲染逻辑可能需要更长时间,或者需要等待特定元素加载完成。更可靠的方式是改用Splash的execute endpoint,编写Lua脚本明确等待目标元素出现后再返回页面:

def start_requests(self):
    lua_script = """
    function main(splash, args)
        splash:go(args.url)
        -- 等待目标元素出现,最长等待15秒
        splash:wait_for_element('.breadcrumbs-link', 15)
        return splash:html()
    end
    """
    for url in self.start_urls:
        yield SplashRequest(
            url=url,
            callback=self.parse,
            endpoint='execute',
            args={'lua_source': lua_script}
        )

这种方式会一直等到目标元素加载完成才返回,比固定等待10秒更适配动态渲染的场景。

  • 请求头被反爬识别:电商网站通常有反爬机制,Splash默认的请求头可能会被识别为爬虫。你可以添加真实浏览器的请求头来模拟正常访问:
yield SplashRequest(
    url=url,
    callback=self.parse,
    endpoint='render.html',
    args={'wait': 10},
    headers={
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36',
        'Accept-Language': 'en-US,en;q=0.9'
    }
)

模拟真实用户的请求头,降低被拦截的概率。

  • 验证渲染结果是否正确:你可以在parse方法里把Splash渲染后的页面保存为HTML文件,直观检查是否包含目标元素:
def parse(self, response):
    # 保存渲染后的页面到本地
    with open('rendered_page.html', 'w', encoding='utf-8') as f:
        f.write(response.text)
    # 再检查这个HTML文件里是否存在.breadcrumbs-link元素
    print ('Result:')
    print(len(response.css('.breadcrumbs-link').extract()))
    print(response.css('.breadcrumbs-link').extract())

如果保存的HTML里确实没有目标元素,那可能是网站需要登录、Cookie验证,或者Splash的渲染环境缺少某些JS支持(比如需要启用JS、图片加载等)。

内容的提问来源于stack exchange,提问作者alioua walid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 19:08:10