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
相关产品推荐
相关产品推荐

