Duplicate results in Xpath and not CSS selectors in scrapy
<p>So I am playing around with scrapy through the <a href="https://doc.scrapy.org/en/latest/intro/tutorial.html" rel="nofollow">tutorial</a>. I am trying to scrape the text, author and tags of each quote in the <a href="http://quotes.toscrape.com/page/1/" rel="nofollow">companion website</a>
when using CSS selectors like mentioned there:</p>

<pre><code>for quote in response.css('div.quote'):
    print quote.css('span.text::text').extract()
    print quote.css('span small::text').extract()
    print quote.css('div.tags a.tag::text').extract()
</code></pre>

<p>I get the desired result (i.e: print of each text, author and quotes once).
But once using Xpath selectors like this:</p>

<pre><code>for quote in response.xpath("//*[@class='quote']"):
    print quote.xpath("//*[@class='text']/text()").extract()
    print quote.xpath("//*[@class='author']/text()").extract()
    print quote.xpath("//*[@class='tag']/text()").extract()
</code></pre>

<p>I get duplicates results! </p>

<p>I still can't find why there is such a difference between the 2.</p>

<p>Try <code>.//</code> instead of <code>//</code> for your relative searches e.g. </p>

<p><code>print quote.xpath(".//*[@class='text']/text()").extract()</code></p>

<p>When you use <code>//</code>, although you're searching from <code>quote</code>, it takes this to mean an absolute search so its context is still the root of the document. <code>.//</code> however, means to search from <code>.</code> - the current node - and the context of this search will be limited to the elements nested under <code>quote</code>.</p>

<p>As a side note, if you're looking to get the exact same results, you should consider changing <code>*</code> to the tags you used in the CSS search - <code>span</code> or <code>div</code>. In this case it doesn't make any difference but just a head's up for future reference.</p>

python xpath css-selectors scrapy