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

Scrapy中XPath选择器爬取重复返回首条数据的问题求助

问题分析与解决方案

哦,这个问题我太熟了!你遇到的是XPath相对路径和绝对路径的典型坑——你的XPath表达式用了//开头,这会让Scrapy从整个HTML文档的根节点重新开始搜索,而不是从当前遍历的quote节点下查找子元素,所以每次循环都拿到第一条quote的内容,自然就全部重复了。

修正后的XPath Spider代码

把每个子元素的XPath表达式改成相对路径(去掉//,或者用./开头)就行:

class QuotesSpiderXpath(scrapy.Spider):
    name = 'quotes_xpath'
    start_urls = [
        'http://quotes.toscrape.com/page/1/'
    ]

    def parse(self, response):
        quotes = response.xpath('//div[@class="quote"]')
        for quote in quotes:
            yield {
                # 用相对路径,从当前quote节点下查找
                'text': quote.xpath('./span[@class="text"]/text()').extract_first(),
                'author': quote.xpath('./small[@class="author"]/text()').extract_first(),
                'tags': quote.xpath('./div[@class="tags"]/text()').extract()
            }

为什么会这样?

  • 你原来的//span[@class='text']/text()://是绝对路径语法,不管当前在哪个节点,都会从整个文档的根开始匹配所有符合条件的元素,extract_first()就会取第一个匹配的结果(也就是第一条quote的文本)。
  • 改成./span[@class='text']/text():./表示从**当前节点(也就是循环里的每个quote)**开始,查找它的子元素span,这样就只会匹配当前quote下的内容,和CSS选择器的行为一致了。

另外,也可以省略./,直接写span[@class='text']/text(),效果是一样的,因为XPath默认会从当前节点的子节点开始查找。

修正后运行,你就能得到和CSS版本完全一致的预期结果啦!

内容的提问来源于stack exchange,提问作者Raúl Chirinos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:35:44