在页面上的元素列表上进行草率的迭代

时间:2018-12-13 11:09:58

标签: python python-3.x web-scraping scrapy iteration

我的拼凑项目有问题。我想提取列表中页面上的所有添加,然后遍历该列表以提取并保存每个添加的数据。我确定我做错了什么,但我不知道怎么办。我怀疑问题出在.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方法仅返回它在页面上看到的第一个数据...

1 个答案:

答案 0 :(得分:1)

看起来问题出在您的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代码块,我也许可以确认。