How to make indexing work with ItemLoader's add_xpath method
<p>I'm trying to rewrite this piece of code to use <code>ItemLoader</code> class:</p>

<pre><code>import scrapy

from ..items import Book


class BasicSpider(scrapy.Spider):
    ...
    def parse(self, response):
        item = Book()

        # notice I only grab the first book among many there are on the page             
        item['title'] = response.xpath('//*[@class="link linkWithHash detailsLink"]/@title')[0].extract()
        return item
</code></pre>

<p>The above works perfectly well. And now the same with <code>ItemLoader</code>:</p>

<pre><code>from scrapy.loader import ItemLoader

class BasicSpider(scrapy.Spider):
    ...    
    def parse(self, response):
        l = ItemLoader(item=Book(), response=response)

        l.add_xpath('title', '//*[@class="link linkWithHash detailsLink"]/@title'[0])  # this does not work - returns an empty dict
        # l.add_xpath('title', '//*[@class="link linkWithHash detailsLink"]/@title')  # this of course work but returns every book title there is on page, not just the first one which is required
        return l.load_item()
</code></pre>

<p>So I only want to grab the first book title, how do I achieve that?</p>

<p>A problem with your code is that Xpath uses one-based indexing. Another problem is that the index bracket should be inside the string you pass to the add_xpath method.</p>

<p>So the correct code would look like this:</p>

<pre><code>l.add_xpath('title', '(//*[@class="link linkWithHash detailsLink"]/@title)[1]')
</code></pre>

python xpath scrapy