скрипты python возвращают вывод только первый результат каждой страницы вместо всех

#python #scrapy

Вопрос:

Я выполняю задачу очистки веб-страниц, в которой я выводлю все данные в файл json. Если я выведу файл с помощью scrapy crawl ufcspider -o quotes.json терминала, я получу все ожидаемые результаты, но когда я запускаю scrapy crawl ufcspider только сценарий, я получаю только все страницы, созданные в соответствии со сценарием, но в файлы выводится только первый результат каждой страницы вместо всех десяти выходных данных.

Я также замечаю, что на терминале все результаты выводятся, как и ожидалось.

скрипт

 import scrapy import json  class ExampleSpider(scrapy.Spider):  name = "ufcspider"   start_urls = [  'http://quotes.toscrape.com/page/1/',  ]   def parse(self, response):  for quote in response.css('div.quote'):   result = {  'text': quote.css('span.text::text').get(),  'author': quote.css('small.author::text').get(),  'link': 'http://quotes.toscrape.com'   quote.css("span a::attr(href)").get(),  'tags': quote.css('div.tags a.tag::text').getall()  }   yield result   next_page = response.css("li.next a::attr(href)").get()  if next_page is not None:  # next_page = response.urljoin(next_page)  yield response.follow(next_page, callback=self.parse)   page = response.url.split("/")[-2]  filename = f'quotes-{page}.json'  with open(filename, 'w') as f:  f.write(json.dumps(result))  f.close()  self.log(f'Saved file {filename}')  

Ответ №1:

Это потому, что вы переопределяете result в цикле for.

Замена на это должна сработать:

 import scrapy import json  class ExampleSpider(scrapy.Spider):  name = "ufcspider"   start_urls = [  'http://quotes.toscrape.com/page/1/',  ]   def parse(self, response):  results = []  for quote in response.css('div.quote'):  result = {  'text': quote.css('span.text::text').get(),  'author': quote.css('small.author::text').get(),  'link': 'http://quotes.toscrape.com'   quote.css("span a::attr(href)").get(),  'tags': quote.css('div.tags a.tag::text').getall()  }  results.append(result)  yield result   next_page = response.css("li.next a::attr(href)").get()  if next_page is not None:  # next_page = response.urljoin(next_page)  yield response.follow(next_page, callback=self.parse)   page = response.url.split("/")[-2]  filename = f'quotes-{page}.json'  with open(filename, 'w') as f:  f.write(json.dumps(results))  f.close()  self.log(f'Saved file {filename}')