Привет, у меня нет большого опыта в очистке сети или использовании скрапа и селена. Сначала извинитесь, если в моем коде слишком много плохих практик.
Краткая справка по моему коду: я пытался собрать информацию о продуктах с нескольких веб-сайтов, используя scrapy, и я также использую селен, потому что мне нужно нажимать кнопки «Просмотреть больше» и «Нет, спасибо» на веб-странице. Поскольку на веб-сайте есть раздел href для разных категорий, мне также нужно запросить эти «подссылки», чтобы убедиться, что я не пропускаю элементы, не показанные на корневой странице.
Проблема в том, что в цикле for l in product_links:
я замечаю, что скрап и селен действуют странно. Например, я ожидаю, что response.url == self.driver.current_url
всегда будет правдой. Тем не менее, они становятся другими в середине этого цикла. Кроме того, self.driver
, кажется, захватывает некоторые элементы, не существующие в текущем URL в products = self.driver.find_elements_by_xpath('//div[@data-url]')
, и затем не может получить их снова в sub = self.driver.find_elements_by_xpath('//div[(@class="shelf-container") and (.//div/@data-url="' + l + '")]//h2')
Большое спасибо. Я действительно смущен.
from webScrape.items import ProductItem
from scrapy import Spider, Request
from selenium import webdriver
class MySpider(Spider):
name = 'name'
domain = 'https://uk.burberry.com'
def __init__(self):
super().__init__()
self.driver = webdriver.Chrome('path to driver')
self.start_urls = [self.domain + '/' + k for k in ('womens-clothing', 'womens-bags', 'womens-scarves',
'womens-accessories', 'womens-shoes', 'make-up', 'womens-fragrances')]
self.pool = set()
def parse(self, response):
sub_links = response.xpath('//h2[starts-with(@class, "shelf1-section-title")]/a/@href').extract()
if len(sub_links) > 0:
for l in sub_links:
yield Request(self.domain + l, callback = self.parse)
self.driver.get(response.url)
email_reg = self.driver.find_element_by_xpath('//button[@class="dc-reset dc-actions-btn js-data-capture-newsletter-block-cancel"]')
if email_reg.is_displayed():
email_reg.click()
# Make sure to click all the "load more" buttons
load_more_buttons = self.driver.find_elements_by_xpath('//div[@class="load-assets-button js-load-assets-button ga-shelf-load-assets-button"]')
for button in load_more_buttons:
if button.is_displayed():
button.click()
products = self.driver.find_elements_by_xpath('//div[@data-url]')
product_links = [item.get_attribute('data-url') for item in products if item.get_attribute('data-url').split('-')[-1][1:] not in self.pool]
for l in product_links:
sub = self.driver.find_elements_by_xpath('//div[(@class="shelf-container") and (.//div/@data-url="' + l + '")]//h2')
if len(sub) > 0:
sub_category = ', '.join(set([s.get_attribute('data-ga-shelf-title') for s in sub]))
else:
sub_category = ''
yield Request(self.domain + l, callback = self.parse_product, meta = {'sub_category': sub_category})
def parse_product(self, response):
item = ProductItem()
item['id'] = response.url.split('-')[-1][1:]
item['sub_category'] = response.meta['sub_category']
item['name'] = response.xpath('//h1[@class="product-title transaction-title ta-transaction-title"]/text()').extract()[0].strip()
self.pool.add(item['id'])
yield item
others = response.xpath('//input[@data-url]/@data-url').extract()
for l in others:
if l.split('-')[-1][1:] not in self.pool:
yield Request(self.domain + l, callback = self.parse_product, meta = response.meta)