Я пытаюсь очистить эту страницу (далее главная страница ), используя 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"
}