Python — Возможно ли, чтобы scrapy заходил на страницы каждого продукта и очищал данные?

#python #web-scraping #scrapy

#python #веб-очистка #scrapy

Вопрос:

Я новичок в python и веб-очистке, и мне интересно, можно ли очистить страницы продукта с помощью scrapy.

Пример: я ищу мониторы на amazon.com Я бы хотел, чтобы scrapy переходил на страницу каждого продукта и очищал ее оттуда, а не просто очищал данные со страницы результатов поиска.

Я кое-что читал о xpath, но я не уверен, возможно ли это с этим, и все другие ресурсы, которые я нашел, похоже, выполняют очистку с помощью других вещей, таких как beautiful soup и т. Д. У меня правильно есть проект scrapy, который очищается со страницы результатов поиска, но я хотел бы улучшить его, чтобы очистить со страницы продуктов.

Редактировать:

Вот мой измененный spider.py основываясь на ваших предложениях:

 class TestSpiderSpider(scrapy.Spider):
name = 'testscraper'
page_number = 2
start_urls = ['https://jamaicaclassifiedonline.com/auto/cars/']

def parse(self, response):
for car in response.css('.col.l3.s12.m6'):
items = scrapeItem()

product_title = response.css('.jco-card-title::text').extract()
product_link = car.css('.tooltipped valign').css('[target]::text').get()
url = response.urljoin(product_link)
yield Request(url, cb_kwargs={'product_title': product_title},callback=self.parse_car)

def parse_car(self, response, product_title):
product_description = car.css('.wysiwyg::text').get()
product_imagelink = response.css('.responsive-img img::attr(data-src)').getall()
items['product_title'] = product_title
items['product_imagelink'] = product_imagelink
items.append('items')

yield items
  

Он код для items.py:

 class scrapeItem(scrapy.Item):
product_title = scrapy.Field()
product_imagelink = scrapy.Field()

pass
  

В настоящее время возникает ошибка и, когда я пытаюсь ее запустить. Похоже, связано с

запрос выхода

Надеюсь, я на правильном пути.

Я также добавил цикл в код.

Комментарии:

1. @renatodvc Я добавил свой код и внес некоторые изменения, основываясь на вашем предложении, но в настоящее время присутствует ошибка, которую я вижу до сих пор. Может быть, больше, но я не уверен.

2. Вы не опубликовали ошибку, с которой столкнулись, но я предполагаю, что это a NameError , вы не забыли импортировать Request , как в моем примере? В вашем примере parse метод выдаст только один новый запрос, это то, что вы хотите?

3. Я опубликовал ошибки, а также добавил цикл в код. @renatodvc

Ответ №1:

На этот вопрос лучше ответить на конкретном примере, когда вы предоставляете свой код и объясняете, что вы уже пытались сделать.

В общем, вот как вы это делаете:

  • Запросите страницу поиска (вы упоминаете, что уже сделали это)
  • Выберите нужные результаты, для этого вы можете использовать либо селекторы XPath, либо селекторы CSS (подробнее о селекторах)
  • Извлеките href атрибут (то есть URL) элементов, которые вы хотите запросить на странице продукта. (Это можно сделать с помощью селекторов)
  • Отправьте новый запрос на страницу продукта. Если вам нужно передать данные, вы можете использовать cb_kwargs (рекомендуется) или meta. (Также хорошее объяснение здесь)
  • Когда Scrapy получит ответ на ваш новый запрос, он вызовет функцию синтаксического анализа (определяемую callback атрибутом)
  • В этой функции синтаксического анализа вы используете селекторы для очистки интересующих вас данных, создания и получения ваших товаров.

Чтобы было более понятно, вот очень широкий пример (на самом деле он не работает, он предназначен для иллюстрации):

 from scrapy import Request, Spider


class ExampleSpider(Spider):
    name = "example"
    start_urls = ['https://www.example.com']

    def parse(self, resposne):
        products = response.xpath('//div[@class="products"]')
        for product in products:
            product_name = product.xpath('a/text()').get()
            href = product.xpath('a/@href').get()
            url = response.urljoin(href) # This builds a full URL when href is a relative url
            yield Request(url, cb_kwargs={'product_name': product_name}, callback=self.parse_product)

    def parse_product(self, response, product_name): # Notice it will receive a new arg here, as passed in cb_kwargs
        description = response.xpath('//article[@id="desc"]//text()').getall()
        price = response.xpath('//div[@id="price"]/text()').get()
        yield {
            'product_name': product_name,
            'price': price,
            'description': description
        }
  

Комментарии:

1. Нет ли лучшего решения, без передачи данных, но возвращающего результат запроса в parse функцию?