Неудачный соскоб с помощью селена и скрапа - PullRequest
0 голосов
/ 23 января 2020

Я пытаюсь очистить эту страницу (далее главная страница ), используя selenium + scrapy.

Весь контент загружается с javascript при прокрутке страницы вниз. Я очищаю каждую страницу продукта методом parse (ссылки a.product-list__item.normal.size-normal на главной странице). Я нахожу здесь решение для прокрутки , но, похоже, оно не работает. После вызова метода ScrollUntilLoaded (метод start_request) в webdriver отображаются только 29 URL-тегов. Все страницы продуктов также обрабатываются webdriver, поскольку они загружаются javascript (метод parse).

Но это не единственная проблема. Из этих 29 страниц только из 24 страниц данные сканируются. Поэтому я добавляю wait.until изображение товара, которое появляется перед извлечением данных со страниц. Но это не помогает.

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

import time
import scrapy
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException

class SilpoSpider(scrapy.Spider):
    name = 'SilpoSpider'

    def __init__(self):
        self.driver = webdriver.Chrome()
        self.wait = WebDriverWait(self.driver, 10)

    def ScrollUntilLoaded(self):
        """scroll webdriver`s content (web page) to the bottom
        the purpose of this method is to load all content that loads with javascript"""
        check_height = self.driver.execute_script("return document.body.scrollHeight;")
        while True:
            self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
            try:
                self.wait.until(lambda driver: self.driver.execute_script("return document.body.scrollHeight;")  > check_height)
                check_height = self.driver.execute_script("return document.body.scrollHeight;") 
            except TimeoutException:
                break

    def start_requests(self):
        # load all content from the page with references to all products
        self.main_url = 'https://silpo.ua/offers'
        self.driver.get(self.main_url)
        self.ScrollUntilLoaded()
        # get all URLs to all particular products pages
        urls = [ref.get_attribute('href') \
            for ref in self.driver.find_elements_by_css_selector('a.product-list__item.normal.size-normal')]
        # len(urls) == 29
        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse)

        self.driver.quit()

    def parse(self, response):
        self.driver.get(response.url)
        self.wait.until(
            EC.presence_of_element_located((By.CSS_SELECTOR, ".image-holder img"))
        )
        yield {"image": self.driver.find_element_by_css_selector(".image-holder img").get_attribute('src'),
            "name": self.driver.find_element_by_css_selector('h1.heading3.product-preview__title span').text,
            "banknotes": int(self.driver.find_element_by_css_selector('.product-price__integer').text),
            "coins": int(self.driver.find_element_by_css_selector('.product-price__fraction').text),
            "old_price": float(self.driver.find_element_by_css_selector('.product-price__old').text),
            "market":"silpo"
            }

1 Ответ

1 голос
/ 23 января 2020

Избавьтесь от существующего метода ScrollUntilLoaded() и попробуйте следующее вместо этого. Оказывается, что вышеупомянутый метод не прокручивается вообще. Было бы лучше, если бы вы дали больше времени для загрузки этой страницы.

def ScrollUntilLoaded(self):
    while True:
        footer = self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "h4.footer__site-map-heading")))
        current_len = len(self.wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "a.product-list__item"))))
        try:
            self.driver.execute_script("arguments[0].scrollIntoView();", footer)
            self.wait.until(lambda driver: len(self.driver.find_elements_by_css_selector("a.product-list__item")) > current_len)
        except TimeoutException:
            break
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...