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

Scrapy遍历选择器列表仅返回单个数据项问题求助

解决Scrapy爬取亚马逊畅销书仅返回单个数据的问题

问题根源

核心问题是XPath路径的搜索范围错误:

  • 在循环子选择器(data)时用//开头的XPath,会从整个文档根节点重新搜索,每次都取页面第一个匹配元素,所以循环输出的全是同一条数据。
  • 直接调用response.xpath(...).get()本身就只会返回第一个匹配元素,自然只能拿到单条结果。

修正方案1:遍历子选择器时用相对路径

修改XPath为.//开头,限定在当前data节点下搜索子元素:

def parse_page(self, response):
    product_data = response.xpath("//div[@id='gridItemRoot']") # 获取所有商品的根选择器列表

    for data in product_data:
        # 用.//限定从当前data节点下搜索
        product_name = data.xpath(".//div[@class='a-section a-spacing-mini _cDEzb_noop_3Xbw5']//img/@alt").get()
        product_rank = data.xpath(".//span[@class='zg-bdg-text']/text()").get()
        
        yield {
            "name": product_name,
            "rank": product_rank
        }

修正方案2:批量获取后配对数据

如果不想遍历子选择器,可以批量获取所有匹配结果,再通过zip配对输出:

def parse_page(self, response):
    # 直接定位到每个gridItemRoot下的名称和排名,获取全部结果
    product_names = response.xpath("//div[@id='gridItemRoot']//div[@class='a-section a-spacing-mini _cDEzb_noop_3Xbw5']//img/@alt").getall()
    product_ranks = response.xpath("//div[@id='gridItemRoot']//span[@class='zg-bdg-text']/text()").getall()
    
    # 配对每条数据并输出
    for name, rank in zip(product_names, product_ranks):
        yield {
            "name": name,
            "rank": rank
        }

关键注意点

  • 子选择器内查询必须用.//,表示相对当前节点搜索,避免全局重复匹配。
  • .get()取单个元素,.getall()取所有匹配元素组成的列表。
  • 优先用方案1,能保证名称和排名的对应关系更可靠,避免页面结构变动导致数据错位。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 03:40:22