Извлечение всех следующих страниц с веб-сайта с помощью Scrapy

#python #xpath #web-scraping #scrapy #web-crawler

#python #xpath #очистка веб-страниц #scrapy #веб-сканер

Вопрос:

Я пытаюсь очистить все страницы с этого URL: https://www.residentialpeople.com/za/property-for-sale/cape-town/?country=zaamp;listing_type=residentialamp;transaction_type=saleamp;longitude=18.49144amp;latitude=-33.98983amp;size_qualifier=square_feetamp;location_slug=cape-townamp;sort_by=closest_to_farthestamp;offset=0amp;limit=10amp;active=1amp;_radius_expansion=0amp;_location=Cape Town, South Africaamp;status_available_only=0

Однако ему удается очистить только первые 4 страницы, а затем он останавливается Вот код:

     def parse(self, response):
        # follow links to property pages
        for href in response.xpath('//div[@class="listings-item-bottom"]//a[@class="link link--minimal"]/@href').getall():
            yield response.follow(href, self.parse_property)

        # follow pagination links
        old_offset = self.page_counter
        old_offset = str(old_offset)   '0' if old_offset != 0 else str(old_offset)

        try:
            max_page = int(''.join(response.css('div.custom-pagination-select::text').re(r'd ')))
        except:
            max_page = None

        self.page_counter  = 1
        if self.page_counter < max_page:
            new_offset = str(self.page_counter)   '0'

            next_page_url = response._get_url().replace(f'offset={old_offset}', f'offset={new_offset}')
            next_page = response.urljoin(next_page_url)
            yield scrapy.Request(next_page, callback=self.parse)
  

У кого-нибудь есть какие-либо предложения о том, что здесь может быть не так?
Заранее благодарю вас!

Ответ №1:

Я думаю, единственное, что вам нужно заменить, — это смещение в URL, чтобы перейти на следующую страницу.

Очевидно, что вы можете обобщить это, чтобы вы всегда могли получить каждую страницу на основе количества результатов поиска.

Пример кода

 def parse(self,response):
    for href in response.xpath('//div[@class="listings-item-bottom"]//a[@class="link link--minimal"]/@href').getall():
        yield response.follow(href, self.parse_property)
    
    results_num = int(response.xpath('//div[@class="total-available-results"]/span/text()').get())

    for i in range(10,results_num 10,10):
        url = f'https://www.residentialpeople.com/za/property-for-sale/cape-town/?country=zaamp;listing_type=residentialamp;transaction_type=saleamp;longitude=18.49144amp;latitude=-33.98983amp;size_qualifier=square_feetamp;location_slug=cape-townamp;sort_by=closest_to_farthestamp;offset={i}amp;limit=10amp;active=1amp;status_available_only=0amp;_radius_expansion=0amp;_location=Cape Town, South Africa'
        yield scrapy.Request(url=url, callback=self.parse,dont_filter=True)
  

Объяснение

results_num дает нам общее количество свойств. Мы используем цикл for, начинающийся со смещения 10, вплоть до 15720 в этом случае, помните, что нам нужно добавить 10 к конечному аргументу, поскольку конечный аргумент в диапазоне не включает до results_num . Аргумент шага 10 — это то, что мы хотим.

Мы создаем URL-адрес динамически для каждого запроса, используя f-строки в цикле for, мы присваиваем переменной i значение, которое мы хотим объяснить выше. Мы можем использовать его для создания новой строки URL для требуемого смещения для каждой итерации цикла for. Затем мы можем сделать запрос на итерацию с обратным вызовом функции parse. Помните, поскольку база URL-адреса одна и та же, scrapy отфильтрует это, поэтому в Request мы указываем dont_filter=True

Комментарии:

1. Привет, большое вам спасибо за ваше объяснение! Когда я пытаюсь это сделать, я по-прежнему получаю только несколько очищенных свойств вместо всех свойств со страниц 1572.. Может ли проблема в чем-то другом? @АаронС

2. Забыл добавить оператор yield, извините за это! Обновлен код.

3. Всегда пожалуйста! Если вы раньше не использовали f-strings, я бы настоятельно рекомендовал их! Не так полезно для изменения нескольких переменных в строке, но было введено в python 3.6, поскольку формат был немного громоздким. realpython.com/python-f-strings полезно! По сути, я сделал этот фрагмент кода намного проще.

4. Да, это довольно мило, не видел такого раньше! Еще раз спасибо за отличное объяснение! @АаронС

5. Мне очень жаль беспокоить вас, но, может быть, вы могли бы помочь мне с одной последней вещью: я даже не могу получить результаты с главной страницы этого веб-сайта: myproperty.co.za/… Извините за беспокойство и спасибо за ваше время 🙂 @AaronS