Scrapy + Selenium 3 уровня глубинной пагинации Spider - PullRequest
0 голосов
/ 25 января 2020

Пожалуйста, дайте мне совет, как решить мою проблему, я буду очень признателен! Мне нужно почистить данные с сайта tirebuyer.com. Я хочу собрать всю информацию о каждой шине, которую они имеют, начиная с сбора названия бренда, а затем разбивая страницы на несколько страниц одной марки с помощью Selenium (потому что у них есть только 10 моделей на каждой странице и кнопки нумерации страниц, которые управляются javascript или чем-то подобным) , И после всего этого, когда я получил список всех возможных ссылок, go перебрал и отсканировал каждую таблицу данных о шинах.
К сожалению, документы Scrapy мало что говорят о том, как реализовать многостраничный вложенный обход. Я застрял с Selenium, пытаясь разбить страницу на страницы одной модели бренда, селен открывает браузер Firefox, но открывает первую страницу, затем переходит на другую страницу бренда (но он предполагает остаться на одном бренде и разбивать на страницы до последней страницы) Кроме того, он никогда не идет дальше, чем второй бренд, а затем останавливается.
Я предполагаю, что, поскольку запрос Scrapy вызывает функцию, которая все еще обрабатывает нумерацию страниц с помощью Selenium, но я не уверен. Пожалуйста, дайте мне подсказку, как решить этот конкретный шаг. Я прочитал все связанные темы здесь, попробовал некоторые фрагменты, но все еще не повезло.

import scrapy
import re
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


class MySpider(scrapy.Spider):
    name = 'tires'
    url = 'https://www.tirebuyer.com/tires/brands'
    basic_link = 'https://www.tirebuyer.com/'

    allowed_domains = ['tirebuyer.com']
    brand_links = []
    model_links = []
    links_pack = {}
    driver = webdriver.Firefox(executable_path=r'./geckodriver')

    def start_requests(self):
        yield scrapy.Request(self.url, self.parse_brands)

    def parse_brands(self, response):
        for brand_link in response.css('.mv a::attr(href)').getall():
            self.brand_links.append(brand_link)

        for single_brand_link in self.brand_links:
            full_brand_link = re.sub(r"[^a-zA-Z0-9] | : | /","",self.basic_link + single_brand_link)
            yield scrapy.Request(
                full_brand_link[:-1], #Because browser adds a hashtag to the end of link
                callback=self.parse_models,
                dont_filter=True,
                )

    def parse_models(self, response):
        self.driver.get(response.url)

        for models in response.css('#noFitmentMoreInfoBtn::attr(href)').getall():
            yield models

        while True:
            next = self.driver.find_element_by_css_selector('li.at_pl_pagination_next')

            try:
                element = WebDriverWait(driver, 10).until(
                EC.presence_of_element_located((By.CSS, "li.at_pl_pagination_next"))
                )
                next.click()
                for models in response.css('#noFitmentMoreInfoBtn::attr(href)').getall():
                    yield models
            except:
                break
            finally:
                driver.quit()

...