Вопрос или проблема
https://adrianahoyos.com/our-products/living-room/sofa-loveseats/caramelo-tufted-sofa-140/
Сайт загружается через 5 секунд, показывая текст, но мне нужно получить текст из [“Загрузка..”]
по умолчанию установлен текст. Как мне дождаться получения правильного текста на сайте? Я добавил код ниже, чтобы проверить и подтвердить, чтобы написать ответ
ваш текст
Перед показом элементов через 5 секунд
Загрузка…
после 5 секунд показа элементов
CM12-140
def parse_navigation(self, response):
for level1 in response.xpath('//div[@id="en-menu-products"]//ul/li/a'):
label1 = level1.xpath('text()').get().strip() # Получить текст
url = level1.xpath('@href').get() # Получить атрибут href
meta = deepcopy(response.meta)
meta['cat'] = label1
if label1 in ["Диваны и loveseat"]:
yield response.follow(url, self.parse_collection, meta=meta)
def parse_collection(self, response):
# Выбрать как ссылки, так и заголовки вместе
rug_items = response.css('.products .product')
for rug in rug_items:
# Извлечь имя коврика из правильного элемента
name = rug.css('.woocommerce-loop-product__title::text').get(default="").strip()
meta = deepcopy(response.meta)
meta['product_name'] = name
url = rug.css('.woocommerce-LoopProduct-link::attr(href)').get(default="")
yield Request(url,self.parse_detail, meta=meta, dont_filter=True)
def parse_detail(self, response):
time.sleep(5)
item = OrderedDict()
item['category'] = response.meta['cat']
item['name'] = response.meta.get('product_name', '')
item['Url'] = response.url
# item['Attr_Collection'] = ''
sku = response.xpath('//div[@class="et_pb_text_inner"]//p[@id="sku-id"]/text()').get(default="").strip()
item['SKU'] = sku # Добавить SKU к элементу
description = response.xpath('//div[@class="et_pb_text_inner"]//p[@id="description"]/text()').getall()
print("Извлеченное описание:", description) # Отладочная строка
full_description = ' '.join(description).strip()
item['Description'] = full_description # Добавить описание к элементу
# item['brand'] = 'Adriana Hoyos'
# item['Original Price'] = ''
item['MetaKeywords'] = response.css('[name="keywords"]::attr(content)').get('').strip()
item['MetaDescription'] = response.css('[name="description"]::attr(content)').get('').strip()
yield item
Проблема в следующем коде означает, что описание получает текст из загрузки
item[‘SKU’] = sku # Добавить SKU к элементу
description = response.xpath(‘//div[@class=”et_pb_text_inner”]//p[@id=”description”]/text()’).getall()
print(“Извлеченное описание:”, description) # Отладочная строка
full_description = ‘ ‘.join(description).strip()
item[‘Description’] = full_description # Добавить описание к элементу
Получить правильный текст для сайта
Ответ или решение
Чтобы правильно извлечь текст с веб-страницы, где есть задержка при загрузке контента (например, текст появляется через 5 секунд после загрузки), необходимо использовать более подходящий подход к ожиданию загрузки элементов, чем просто использование time.sleep()
. В библиотеке Scrapy
, на которой, как видно из вашего кода, вы работаете, можно использовать Scrapy
и scrapy-selenium
или scrapy-playwright
для автоматизации взаимодействия с JavaScript на странице. Рассмотрим некоторые ключевые моменты.
Почему текст "Loading…" вам не подходит?
Когда вы делаете запрос к веб-странице, некоторые части контента могут загружаться асинхронно (с помощью JavaScript) и сначала вы видите текст "Loading…". Вам нужно дождаться завершения загрузки контента, прежде чем пытаться извлекать данные.
Как вы можете решить эту проблему?
Вот как вы можете модифицировать ваш код, чтобы подождать появления нужного контента перед его извлечением.
-
Установка
scrapy-selenium
илиscrapy-playwright
:
Установите один из пакетов, чтобы интегрировать управление браузером вScrapy
. Для начала установимscrapy-selenium
:pip install scrapy-selenium
-
Настройка
scrapy-selenium
:В вашем
settings.py
добавьте следующий код:from shutil import which DOWNLOADER_MIDDLEWARES = { 'scrapy_selenium.SeleniumMiddleware': 800, } SELENIUM_DRIVER_NAME = 'firefox' # или 'chrome' SELENIUM_DRIVER_EXECUTABLE_PATH = which('geckodriver') # укажите путь к geckodriver или chromedriver SELENIUM_DRIVER_ARGUMENTS = ['-headless'] # если вы хотите запустить браузер в фоновом режиме
-
Измените ваш
parse_detail
метод:
Вместо использованияtime.sleep()
, вы можете немного подождать, чтобы дать возможность JavaScript загружать нужные элементы.from scrapy_selenium import SeleniumRequest def parse_collection(self, response): rug_items = response.css('.products .product') for rug in rug_items: name = rug.css('.woocommerce-loop-product__title::text').get(default="").strip() meta = deepcopy(response.meta) meta['product_name'] = name url = rug.css('.woocommerce-LoopProduct-link::attr(href)').get(default="") yield SeleniumRequest(url=url, callback=self.parse_detail, dont_filter=True, meta=meta) def parse_detail(self, response): # Здесь контейнер для ожидания загрузки 'Loading…' loading_element = response.xpath('//p[text()="Loading..."]') if loading_element: self.logger.info("Дождитесь завершения загрузки страниц...") sku = response.xpath('//div[@class="et_pb_text_inner"]//p[@id="sku-id"]/text()').get(default="").strip() description = response.xpath('//div[@class="et_pb_text_inner"]//p[@id="description"]/text()').getall() item = OrderedDict() item['category'] = response.meta['cat'] item['name'] = response.meta.get('product_name', '') item['Url'] = response.url item['SKU'] = sku full_description = ' '.join(description).strip() item['Description'] = full_description item['MetaKeywords'] = response.css('[name="keywords"]::attr(content)').get('').strip() item['MetaDescription'] = response.css('[name="description"]::attr(content)').get('').strip() yield item
Пояснение изменений:
- Мы заменили
Request
наSeleniumRequest
, который работает сscrapy-selenium
и позволяет вам взаимодействовать с JavaScript на странице. - Вместо простого ожидания 5 секунд, мы теперь дожидаемся, когда текст "Loading…" исчезнет, прежде чем продолжить с извлечением информации.
С помощью указанных выше шагов вы сможете получить нужный текст с сайта, избегая проблем с асинхронной загрузкой данных. Убедитесь, что ваш код протестирован, чтобы гарантировать его корректную работу.