首页 > 解决方案 > Scrapy迭代页面上的元素列表

问题描述

我的scrapy项目有问题。我想在列表中提取页面上的所有添加,然后遍历该列表以提取和保存每个添加的数据。我确定我做错了什么,但我不知道是什么。我怀疑问题出在 .extract_first() 命令上,但我在列表中的单个对象上调用它,而不是整个响应。到目前为止,蜘蛛只提取符合它在页面上找到的 xpath 的第一个数据。这是代码:

class OddajastanovanjeljmestoSpider(scrapy.Spider):
    name = 'OddajaStanovanjeLjMesto'
    allowed_domains = ['www.nepremicnine.net']
    start_urls = ['https://www.nepremicnine.net/oglasi-oddaja/ljubljana-mesto/stanovanje/']

    def parse(self, response):
        oglasi = response.xpath('//div[@itemprop="item"]')
        for oglas in oglasi:
            item = NepremicninenetItem()
            item['velikost'] = oglas.xpath('//div[@class="main-data"]/span[@class="velikost"]/text()').extract_first(default="NaN")
            item['leto'] = oglas.xpath('//div[@class="atributi"]/span[@class="atribut leto"]/strong/text()').extract_first(default="NaN")
            item['zemljisce'] = oglas.xpath('//div[@class="atributi"]/span[@class="atribut"][text()="Zemljišče: "]/strong/text()').extract_first(default="NaN")

            request = scrapy.Request("https://www.nepremicnine.net" + response.xpath('//div[@itemprop="item"]/h2[@itemprop="name"]/a[@itemprop="url"]/@href').extract_first(), callback=self.parse_item_page)
            request.meta['item'] = item

            yield request

        next_page_url = response.xpath('//div[@id="pagination"]//a[@class="next"]/@href').extract_first()
        if next_page_url:
            absolute_next_page_url = response.urljoin(next_page_url)
            yield scrapy.Request(absolute_next_page_url)

    def parse_item_page(self, response):
        item = response.meta['item']

        item['referencnaStevilka'] = response.xpath('//div[@id="opis"]/div[@class="dsc"][preceding-sibling::div[@class="lbl"][text()="Referenčna št.:"]]/strong/text()').extract_first(default="NaN")
        item['tipOglasa'] = response.xpath('//li[@itemprop="itemListElement"]/a[../meta[@content="1"]]/@title').extract_first(default="NaN")
        item['cena'] = response.xpath('//div[@class="galerija-container"]/meta[@itemprop="price"]/@content').extract_first(default="NaN")
        item['valuta'] = response.xpath('//div[@class="galerija-container"]/meta[@itemprop="priceCurrency"]/@content').extract_first(default="NaN")
        item['vrstaNepremicnine'] = response.xpath('//li[@itemprop="itemListElement"]/a[../meta[@content="5"]]/@title').extract_first(default="NaN")
        item['tipNepremicnine'] = response.xpath('//li[@itemprop="itemListElement"]/a[../meta[@content="6"]]/@title').extract_first(default="NaN")
        item['regija'] = response.xpath('//li[@itemprop="itemListElement"]/a[../meta[@content="2"]]/@title').extract_first(default="NaN")
        item['upravnaEnota'] = response.xpath('//li[@itemprop="itemListElement"]/a[../meta[@content="3"]]/@title').extract_first(default="NaN")
        item['obcina'] = response.xpath('//li[@itemprop="itemListElement"]/a[../meta[@content="4"]]/@title').extract_first(default="NaN")
        item['prodajalec'] = response.xpath('//div[@itemprop="seller"]/meta[@itemprop="name"]/@content').extract_first(default="NaN")

        yield item

parse_item_page 方法正常工作并返回适当的数据,但 parse 方法只返回它在页面上看到的第一个数据......

标签: pythonpython-3.xweb-scrapingscrapyiteration

解决方案


看起来问题出在您的 xpath 表达式上。看起来您需要在迭代中使用相对 xpath 表达式,这意味着它们需要以“。”开头。

item['velikost'] = oglas.xpath(
    './/div[@class="maindata"]/span[@class="velikost"]/text()'
).extract_first(default="NaN")

item['leto'] = oglas.xpath(
    './/div[@class="atributi"]/span[@class="atribut leto"]/strong/text()'
).extract_first(default="NaN")

如果您粘贴示例 HTML 代码块,我可能能够确认。


推荐阅读