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

