Вы должны выдать запрос, не запускать его напрямую и использовать meta=
для отправки данных в следующий анализатор
yield response.follow(link, callback=self.get_title, meta={'item': yas})
, а в следующем анализаторе вы можете получить его
yas = response.meta['item']
а затем вы можете добавить новые значения и получить все данные
yas["title"] = response.css('h1::text').extract()
yield yas
См. другой пример в Scrap получить элементы из нескольких запросов
Do c: Запрос и ответ , Специальные ключи Request.meta
Минимальный рабочий код , который можно поместить в один файл и запустить как обычно скрипт (python script.py
) без создания проекта.
Есть и другие изменения.
Не следует складывать все книги в один список, а отдавать каждую книгу отдельно. Scrapy сохранит все результаты, и когда вы используете опцию для сохранения в csv, он сохранит все результаты.
Для каждой книги вы должны создать новый словарь. Если вы используете один и тот же словарь много раз, он перезапишет данные, и вы можете получить много результатов с одними и теми же данными.
import scrapy
class QuotesSpider(scrapy.Spider):
name = 'quotes'
start_urls = ['http://books.toscrape.com/']
def parse(self, response):
all_links = response.css('.nav-list ul li')
for links in all_links:
link = links.css('a::attr(href)').get()
yield response.follow(link, callback=self.books_detail)
def books_detail(self, response):
all_divs = response.css('.col-lg-3')
for div in all_divs:
# every book in separated dictionary and it has to be new dictionary - because it could overwrite old data
book = {
'category': response.css('h1::text').extract(),
'price': div.css('.price_color::text').extract()[0].strip(),
'availability': div.css('.availability::text')[1].extract().strip(),
}
link = div.css('.product_pod a::attr(href)').get()
yield response.follow(link, callback=self.get_title, meta={'item': book})
def get_title(self, response):
book = response.meta['item']
print('testing:', response.url)
book["title"] = response.css('h1::text').extract()[0].strip()
yield book
# --- run without project and save in `output.csv` ---
from scrapy.crawler import CrawlerProcess
c = CrawlerProcess({
'USER_AGENT': 'Mozilla/5.0',
# save in file CSV, JSON or XML
'FEED_FORMAT': 'csv', # csv, json, xml
'FEED_URI': 'output.csv', #
})
c.crawl(QuotesSpider)
c.start()