Невозможно нажать на кнопку «Далее» при разбивке на страницы

#python #selenium #web-scraping #scrapy

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

Вопрос:

Я использую scrapy с scrapy-selenium, и я не могу обработать разбивку на страницы, потому что href содержит только символ # .

 class PropertyScraperSpider(scrapy.Spider):
    name = 'property_scraper'
    allowed_domains = ['www.samtrygg.se']



    def start_requests(self):
        yield SeleniumRequest(
            url='https://www.samtrygg.se/RentalObject/NewSearch',
            wait_time=3,
            headers=self.headers,
            callback=self.parse_links
        )
        

    def parse_links(self, response):
        cards = response.xpath("//div[@class='owl-carousel owl-theme show-nav-hover']/div/a")

        for card in cards:
            link = card.xpath(".//@href").get()

            print('nn:link',len(link))

            yield SeleniumRequest(
                url= link,
                wait_time=3,
                headers=self.headers,
                callback=self.parse,
            )
        next_page = response.xpath("//a[@id='next']/@href").get()

        print('nnnNEXT_PAGE',next_page)
        if next_page:
            absolute_url = f'https://www.samtrygg.se/RentalObject/NewSearch{next_page}'
            yield SeleniumRequest(
                url=absolute_url,
                headers=self.headers,
                wait_time=3,
                callback=self.parse_links
            )
            
    def parse(self,response):
        pass

  

Мне нужна помощь с этой проблемой разбивки на страницы. как я могу с этим справиться? Любая помощь была бы высоко оценена.

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

1. не могли бы вы описать, что вы подразумеваете под разбивкой на страницы?

2. @MZ Разбивка на страницы означает, что я пытаюсь перейти к следующим страницам.

Ответ №1:

Приближаемся к динамическому контенту в Scrapy

То, что говорит Райан, верно. Чтобы подробнее остановиться на этом, динамический контент можно использовать несколькими способами.

  1. Путем реорганизации HTTP-запросов

Это, безусловно, лучший способ захвата динамического контента, если это возможно, он наиболее эффективный и менее хрупкий, чем selenium. Это зависит от того, запускает ли javascript HTTP-запрос для сбора данных для веб-страницы. В этом случае это так, и его следует попробовать сначала, прежде чем прибегать к другим средствам

  1. Использование Splash (активность браузера)

У Scrapy есть промежуточное программное обеспечение, которое интегрирует splash. Splash предварительно отображает страницы, что позволяет получить доступ к HTML, загруженному javascript. Он также обладает некоторой функциональностью активности в браузере. Менее трудоемкий, чем selenium, но все же это активность браузера.

  1. Использование selenium_scrapy (активность браузера)

Это решение, которое вы пытаетесь здесь, проблема в том, что на самом деле оно не дает большого количества опций для выполнения сложных действий в браузере. Таким образом, его реальная цель заключается в том, чтобы иметь возможность захватывать HTML, который действительно был загружен javascript.

  1. Использование selenium в промежуточных программах (активность браузера)

Вы можете использовать промежуточные программы для фильтрации запросов, используя полный пакет selenium. Это нормально, когда альтернативы нет, и вы хотите что-то для каждого запроса. Или вы хотите настроить его в зависимости от типа запроса, который вы делаете

  1. Использование selenium прямо в скрипте spider. (Активность браузера)

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

Реинжиниринг запросов

Итак, теперь у вас есть базовое представление о том, что это такое. Ваш браузер (я предпочитаю Chrome) имеет доступ ко всем запросам, которые браузер делает для отображения сайта, который вы видите. Если вы проверите страницу -> сетевые инструменты -> XHR, вы увидите все запросы AJAX (обычно там, где находятся конечные точки API).

введите описание изображения здесь

Вы можете видеть весь запрос, сортировка по размеру обычно работает, поскольку обычно данные будут представлять собой запрос большего размера. Когда вы нажимаете на запрос, вы получаете доступ к заголовкам, которые он отправляет, предварительный просмотр ответа и самого ответа.

введите описание изображения здесь

Итак, здесь у нас есть предварительный просмотр данных, которые вы, вероятно, хотите. Затем я скопирую этот запрос в форме cURL и введу его на веб-сайт, подобный curl.trillworks.com.

введите описание изображения здесь

Это дает вам заголовки, параметры и файлы cookie, если это необходимо для выполнения правильного запроса Scrapy. В этом случае вам фактически нужен только один из параметров, чтобы имитировать HTTP-запрос. Я обычно использую пакет запросов, чтобы поиграть с тем, что мне действительно нужно, поскольку копирование запроса дает вам все в запросе, некоторые if, которые вам не понадобятся.

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

1. Да, вы правы. Но API не предоставляет данные, которые я хочу очистить, и я заметил, что это GET API.

2. Вы должны быть конкретны в том, какие вам нужны данные, потому что из вашего кода неясно, чего вы хотите, кроме разбивки на страницы. Действительно, файл json содержит все 394 свойства из API, что делает разбиение на страницы необязательным.

3. В API нет описания, размещения и удобств, которые я также ищу.

4. Однако в нем есть ссылки на отдельные страницы (RentalObjectLink: «object / 5mxvvqzhng4nqpnd8ois / stockholm / jarfalla / kaplanvagen-5/2-rok»), которые вы могли бы использовать для извлечения этой информации из отдельных ссылок.

Ответ №2:

Веб-сайт использует API, который виден, если вы посмотрите на запросы, сделанные вашим веб-браузером при открытииhttps://www.samtrygg.se/RentalObject/NewSearch

URL API:https://www.samtrygg.se/RentalObject/SearchResult?search=sverigeamp;neLat=amp;neLng=amp;swLat=amp;swLng =

Вы могли бы просто сделать один запрос к URL API с помощью Scrapy, чтобы получить все списки.

Кажется, что на веб-сайте нет никакой фактической «разбивки на страницы». Он просто загружает все данные по первому запросу, а затем выполняет некоторые манипуляции с интерфейсом, чтобы показать частичное количество результатов в зависимости от «страницы», на которой находится пользователь.

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

1. Да, вы правы. Но API не предоставляет данные, которые я хочу очистить, и я заметил, что это GET API.

2. API предоставляет вам все URL-адреса для каждого списка. Теперь вам нужно удалить требуемые данные из списка и больше не беспокоиться о разбивке на страницы

3. И если вы посмотрите на источник каждого отдельного списка, вы можете увидеть, что у них есть данные в формате json.

Ответ №3:

Я проверил, есть ли API, и я его не нашел.

Итак, в этом случае, если вы используете Selenium, вам нужно проверить, доступна ли кнопка «Следующая страница», если да, то вы нажимаете на нее, а затем вставляете HTML-разметку в массив.

Пример:

 
responses = []
next = driver.find_elements_by_xpath("XPATH")
while len(next) > 0:
    next.click()
    responses.append(driver.page_source)
  

С уважением,
Ахмед

Ответ №4:

 import scrapy
import json
 
NIFTY_FIFTY = "https://www.samtrygg.se/RentalObject/SearchResult?search=sverigeamp;neLat=amp;neLng=amp;swLat=amp;swLng="
 
 
class LiveSpider(scrapy.Spider):
    name = "esos_nortes"
    start_urls = [NIFTY_FIFTY]
    allowed_domains = ["www.samtrygg.se"]
 
    # Custom Settings are needed to send the User Agent.         
    custom_settings = {
        'USER_AGENT' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36'
    }
 
    def parse(self, response):
        json_response = json.loads(response.body.decode("utf-8"))
        
        # We want the full first 25 addresses, for example:
        for firsts_25 in range(24):
            print(json_response['SearchResult'][firsts_25]['FullAddress'])
  

URL-адрес NIFTY_FIFTY получен, как объяснил АаронС, наблюдая за инструментами вашего браузера