#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
функцию?